├── .editorconfig
├── .github
├── dependabot.yml
├── maven-cd-settings.xml
├── maven-ci-settings.xml
└── workflows
│ ├── ci-4.x.yml
│ ├── ci-5.x-stable.yml
│ ├── ci-5.x.yml
│ ├── ci-matrix-5.x.yml
│ ├── ci.yml
│ └── deploy.yml
├── .gitignore
├── LICENSE.txt
├── README.md
├── pom.xml
└── src
├── main
├── asciidoc
│ └── index.adoc
├── java
│ ├── examples
│ │ ├── Examples.java
│ │ ├── SomeDatabaseService.java
│ │ ├── SomeDatabaseServiceImpl.java
│ │ └── package-info.java
│ ├── io
│ │ └── vertx
│ │ │ └── serviceproxy
│ │ │ ├── AuthenticationInterceptor.java
│ │ │ ├── AuthorizationInterceptor.java
│ │ │ ├── HelperUtils.java
│ │ │ ├── ProxyHandler.java
│ │ │ ├── ProxyUtils.java
│ │ │ ├── ServiceBinder.java
│ │ │ ├── ServiceException.java
│ │ │ ├── ServiceExceptionMessageCodec.java
│ │ │ ├── ServiceInterceptor.java
│ │ │ ├── ServiceProxyBuilder.java
│ │ │ ├── generator
│ │ │ ├── GeneratorUtils.java
│ │ │ ├── ServiceProxyGen.java
│ │ │ ├── ServiceProxyGenLoader.java
│ │ │ ├── ServiceProxyHandlerGen.java
│ │ │ └── model
│ │ │ │ ├── ProxyMethodInfo.java
│ │ │ │ ├── ProxyModel.java
│ │ │ │ └── ProxyModelProvider.java
│ │ │ ├── impl
│ │ │ ├── AuthenticationInterceptorImpl.java
│ │ │ ├── AuthorizationInterceptorImpl.java
│ │ │ ├── InterceptorHolder.java
│ │ │ ├── InterceptorPriority.java
│ │ │ └── utils
│ │ │ │ └── InterceptorUtils.java
│ │ │ └── package-info.java
│ └── module-info.java
└── resources
│ └── META-INF
│ ├── services
│ ├── io.vertx.codegen.processor.GeneratorLoader
│ └── io.vertx.codegen.processor.ModelProvider
│ └── vertx
│ └── vertx-service-proxy
│ ├── class_header.txt
│ ├── handler_close_accessed.txt
│ ├── handler_constructor_body.txt
│ ├── handler_gen_import.txt
│ ├── proxy_gen_import.txt
│ └── roger.txt
└── test
├── java
└── io
│ └── vertx
│ └── serviceproxy
│ └── tests
│ ├── FuturizedServiceProxyTest.java
│ ├── SecureServiceBinderTest.java
│ ├── ServiceBinderTest.java
│ ├── ServiceProxyTest.java
│ ├── clustered
│ ├── ClusteredTest.java
│ ├── LocalServiceProviderVerticle.java
│ ├── Service.java
│ ├── ServiceProvider.java
│ ├── ServiceProviderVerticle.java
│ └── package-info.java
│ ├── codegen
│ ├── ProxyTest.java
│ ├── future
│ │ ├── FuturizedProxy.java
│ │ └── package-info.java
│ └── proxytestapi
│ │ ├── Concrete.java
│ │ ├── InvalidClose1.java
│ │ ├── InvalidClose2.java
│ │ ├── InvalidClose3.java
│ │ ├── InvalidOverloaded.java
│ │ ├── InvalidParams1.java
│ │ ├── InvalidParams2.java
│ │ ├── InvalidParams3.java
│ │ ├── InvalidParams4.java
│ │ ├── InvalidParamsDataObject.java
│ │ ├── InvalidReturn1.java
│ │ ├── InvalidReturn2.java
│ │ ├── InvalidReturn3.java
│ │ ├── ProxyConnection.java
│ │ ├── ProxyDataObject.java
│ │ ├── ProxyDataObjectParent.java
│ │ ├── ProxyDataObjectWithParent.java
│ │ ├── ProxyDataObjectWithParentOverride.java
│ │ ├── SomeEnum.java
│ │ ├── ValidProxy.java
│ │ ├── ValidProxyCloseWithFuture.java
│ │ └── package-info.java
│ ├── testmodel
│ ├── Mappers.java
│ ├── MyServiceException.java
│ ├── MyServiceExceptionMessageCodec.java
│ ├── OKService.java
│ ├── OKServiceImpl.java
│ ├── SomeEnum.java
│ ├── SomeEnumWithCustomConstructor.java
│ ├── SomeVertxEnum.java
│ ├── StringDataObject.java
│ ├── TestBaseImportsService.java
│ ├── TestConnection.java
│ ├── TestDataObject.java
│ ├── TestService.java
│ ├── impl
│ │ ├── TestConnectionImpl.java
│ │ ├── TestServiceImpl.java
│ │ └── TestSubConnectionImpl.java
│ ├── package-info.java
│ └── sub
│ │ └── TestSubConnection.java
│ ├── testmodel2
│ ├── FuturizedTestService.java
│ ├── impl
│ │ └── FuturizedTestServiceImpl.java
│ └── package-info.java
│ └── utils
│ └── InterceptorUtilsTest.java
└── resources
├── META-INF
└── vertx
│ └── json-mappers.properties
└── keystore.jceks
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | charset = utf-8
5 | indent_style = space
6 | indent_size = 2
7 | trim_trailing_whitespace = true
8 | end_of_line = lf
9 | insert_final_newline = true
10 |
11 | [**/examples/**.java]
12 | # 84 looks like a odd number, however
13 | # it accounts for 4 spaces (class and example method indentation)
14 | max_line_length = 84
15 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: "maven"
4 | directory: "/"
5 | schedule:
6 | interval: "daily"
7 |
--------------------------------------------------------------------------------
/.github/maven-cd-settings.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
18 |
19 | false
20 |
21 |
22 |
23 | vertx-snapshots-repository
24 | ${env.VERTX_NEXUS_USERNAME}
25 | ${env.VERTX_NEXUS_PASSWORD}
26 |
27 |
28 |
29 |
30 |
31 | google-mirror
32 |
33 | true
34 |
35 |
36 |
37 | google-maven-central
38 | GCS Maven Central mirror EU
39 | https://maven-central.storage-download.googleapis.com/maven2/
40 |
41 | true
42 |
43 |
44 | false
45 |
46 |
47 |
48 |
49 |
50 | google-maven-central
51 | GCS Maven Central mirror
52 | https://maven-central.storage-download.googleapis.com/maven2/
53 |
54 | true
55 |
56 |
57 | false
58 |
59 |
60 |
61 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/.github/maven-ci-settings.xml:
--------------------------------------------------------------------------------
1 |
16 |
17 |
18 |
19 | false
20 |
21 |
22 |
23 | google-mirror
24 |
25 | true
26 |
27 |
28 |
29 | google-maven-central
30 | GCS Maven Central mirror EU
31 | https://maven-central.storage-download.googleapis.com/maven2/
32 |
33 | true
34 |
35 |
36 | false
37 |
38 |
39 |
40 |
41 |
42 | google-maven-central
43 | GCS Maven Central mirror
44 | https://maven-central.storage-download.googleapis.com/maven2/
45 |
46 | true
47 |
48 |
49 | false
50 |
51 |
52 |
53 |
54 |
55 |
56 |
--------------------------------------------------------------------------------
/.github/workflows/ci-4.x.yml:
--------------------------------------------------------------------------------
1 | name: vertx-service-proxy (4.x)
2 | on:
3 | schedule:
4 | - cron: '0 4 * * *'
5 | jobs:
6 | CI:
7 | strategy:
8 | matrix:
9 | include:
10 | - os: ubuntu-latest
11 | jdk: 8
12 | - os: ubuntu-latest
13 | jdk: 17
14 | uses: ./.github/workflows/ci.yml
15 | with:
16 | branch: 4.x
17 | jdk: ${{ matrix.jdk }}
18 | os: ${{ matrix.os }}
19 | secrets: inherit
20 | Deploy:
21 | if: ${{ github.repository_owner == 'vert-x3' && (github.event_name == 'push' || github.event_name == 'schedule') }}
22 | needs: CI
23 | uses: ./.github/workflows/deploy.yml
24 | with:
25 | branch: 4.x
26 | jdk: 8
27 | secrets: inherit
28 |
--------------------------------------------------------------------------------
/.github/workflows/ci-5.x-stable.yml:
--------------------------------------------------------------------------------
1 | name: vertx-service-proxy (5.x-stable)
2 | on:
3 | push:
4 | branches:
5 | - '5.[0-9]+'
6 | pull_request:
7 | branches:
8 | - '5.[0-9]+'
9 | schedule:
10 | - cron: '0 6 * * *'
11 | jobs:
12 | CI-CD:
13 | uses: ./.github/workflows/ci-matrix-5.x.yml
14 | secrets: inherit
15 | with:
16 | branch: ${{ github.event_name == 'schedule' && vars.VERTX_5_STABLE_BRANCH || github.event.pull_request.head.sha || github.ref_name }}
17 |
--------------------------------------------------------------------------------
/.github/workflows/ci-5.x.yml:
--------------------------------------------------------------------------------
1 | name: vertx-service-proxy (5.x)
2 | on:
3 | push:
4 | branches:
5 | - master
6 | pull_request:
7 | branches:
8 | - master
9 | schedule:
10 | - cron: '0 5 * * *'
11 | jobs:
12 | CI-CD:
13 | uses: ./.github/workflows/ci-matrix-5.x.yml
14 | secrets: inherit
15 | with:
16 | branch: ${{ github.event.pull_request.head.sha || github.ref_name }}
17 |
--------------------------------------------------------------------------------
/.github/workflows/ci-matrix-5.x.yml:
--------------------------------------------------------------------------------
1 | name: CI matrix (5.x)
2 | on:
3 | workflow_call:
4 | inputs:
5 | branch:
6 | required: true
7 | type: string
8 | jobs:
9 | CI:
10 | strategy:
11 | matrix:
12 | include:
13 | - os: ubuntu-latest
14 | jdk: 11
15 | - os: ubuntu-latest
16 | jdk: 21
17 | uses: ./.github/workflows/ci.yml
18 | with:
19 | branch: ${{ inputs.branch }}
20 | jdk: ${{ matrix.jdk }}
21 | os: ${{ matrix.os }}
22 | secrets: inherit
23 | Deploy:
24 | if: ${{ github.repository_owner == 'vert-x3' && (github.event_name == 'push' || github.event_name == 'schedule') }}
25 | needs: CI
26 | uses: ./.github/workflows/deploy.yml
27 | with:
28 | branch: ${{ inputs.branch }}
29 | jdk: 11
30 | secrets: inherit
31 |
--------------------------------------------------------------------------------
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | name: CI
2 | on:
3 | workflow_call:
4 | inputs:
5 | branch:
6 | required: true
7 | type: string
8 | jdk:
9 | default: 8
10 | type: string
11 | os:
12 | default: ubuntu-latest
13 | type: string
14 | jobs:
15 | Test:
16 | name: Run tests
17 | runs-on: ${{ inputs.os }}
18 | steps:
19 | - name: Checkout
20 | uses: actions/checkout@v2
21 | with:
22 | ref: ${{ inputs.branch }}
23 | - name: Install JDK
24 | uses: actions/setup-java@v2
25 | with:
26 | java-version: ${{ inputs.jdk }}
27 | distribution: temurin
28 | - name: Run tests
29 | run: mvn -s .github/maven-ci-settings.xml -q clean verify -B
30 |
--------------------------------------------------------------------------------
/.github/workflows/deploy.yml:
--------------------------------------------------------------------------------
1 | name: Deploy
2 | on:
3 | workflow_call:
4 | inputs:
5 | branch:
6 | required: true
7 | type: string
8 | jdk:
9 | default: 8
10 | type: string
11 | jobs:
12 | Deploy:
13 | name: Deploy to OSSRH
14 | runs-on: ubuntu-latest
15 | env:
16 | VERTX_NEXUS_USERNAME: ${{ secrets.VERTX_NEXUS_USERNAME }}
17 | VERTX_NEXUS_PASSWORD: ${{ secrets.VERTX_NEXUS_PASSWORD }}
18 | steps:
19 | - name: Checkout
20 | uses: actions/checkout@v2
21 | with:
22 | ref: ${{ inputs.branch }}
23 | - name: Install JDK
24 | uses: actions/setup-java@v2
25 | with:
26 | java-version: ${{ inputs.jdk }}
27 | distribution: temurin
28 | - name: Get project version
29 | run: echo "PROJECT_VERSION=$(mvn org.apache.maven.plugins:maven-help-plugin:evaluate -Dexpression=project.version -q -DforceStdout | grep -v '\[')" >> $GITHUB_ENV
30 | - name: Maven deploy
31 | if: ${{ endsWith(env.PROJECT_VERSION, '-SNAPSHOT') }}
32 | run: mvn deploy -s .github/maven-cd-settings.xml -DskipTests -B
33 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .vertx
2 | .DS_Store
3 | .gradle
4 | .idea
5 | .classpath
6 | .project
7 | .settings
8 | .yardoc
9 | .yardopts
10 | bin
11 | build
12 | target
13 | out
14 | *.iml
15 | *.ipr
16 | *.iws
17 | test-output
18 | Scratch.java
19 | ScratchTest.java
20 | test-results
21 | test-tmp
22 | *.class
23 | src/gen
24 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "{}"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright {yyyy} {name of copyright owner}
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Service Proxies
2 |
3 | [](https://github.com/vert-x3/vertx-service-proxy/actions/workflows/ci-5.x.yml)
4 | [](https://github.com/vert-x3/vertx-service-proxy/actions/workflows/ci-4.x.yml)
5 |
6 | Please see the main documentation on the web-site for a full description:
7 |
8 | * [Web-site documentation](https://vertx.io/docs/vertx-service-proxy/java/)
9 |
10 | Many Vert.x applications include various services which do useful things and often can be reused from one application
11 | to another. An example would be a database service.
12 |
13 | Usually those services run in their own verticle and interact with other verticles by receiving and sending messages, e.g.
14 |
15 | // Assume database service is already deployed somewhere....
16 |
17 | // Save some data in the database
18 |
19 | JsonObject message = new JsonObject();
20 | message.putString("collection", "mycollection");
21 | message.putObject("document", new JsonObject().putString("name", "tim"));
22 | DeliveryOptions options = new DeliveryOptions().addHeader("action", "save");
23 | vertx.eventBus().send("database-service-address", message, options, res2 -> {
24 | if (res2.succeeded()) {
25 | // done
26 | }
27 | }
28 |
29 |
30 | When creating a service there's a certain amount of boiler-plate code to listen on the eventbus for incoming messages,
31 | route them to the appropriate method and return results on the event bus.
32 |
33 | With Vert.x service proxies, you can avoid writing all that boiler-plate code and concentrate on writing your service.
34 |
35 | You write your service as a Java interface and annotate it with the `@ProxyGen` annotation, for example:
36 |
37 | @ProxyGen
38 | public interface SomeDatabaseService {
39 |
40 | // A couple of factory methods to create an instance and a proxy
41 |
42 | static SomeDatabaseService create(Vertx vertx) {
43 | return new SomeDatabaseServiceImpl(vertx);
44 | }
45 |
46 | static SomeDatabaseService createProxy(Vertx vertx, String address) {
47 | return new SomeDatabaseServiceVertxEBProxy(vertx, address);
48 | }
49 |
50 | // Actual service operations here...
51 |
52 | void save(String collection, JsonObject document, Handler> resultHandler);
53 | }
54 |
55 | Given the interface, Vert.x will generate all the boiler-plate required to access your service over the event bus, and it
56 | will also generate a *client side proxy* for your service, so your clients can use a rich idiomatic API for your
57 | service instead of having to manually craft event bus messages to send. The client side proxy will work irrespective
58 | of where your service actually lives on the event bus (potentially on a different machine).
59 |
60 | That means you can interact with your service like this:
61 |
62 | // Assume database service is already deployed somewhere....
63 |
64 | // Create a proxy
65 | SomeDatabaseService service = SomeDatabaseService.createProxy(vertx, "database-service-address");
66 |
67 | // Save some data in the database - this time using the proxy
68 | service.save("mycollection", new JsonObject().putString("name", "tim"), res2 -> {
69 | if (res2.succeeded()) {
70 | // done
71 | }
72 | });
73 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | io.vertx
6 | vertx5-parent
7 | 12
8 |
9 |
10 | 4.0.0
11 |
12 | vertx-service-proxy
13 | 5.1.0-SNAPSHOT
14 |
15 |
16 | scm:git:git@github.com:vert-x3/vertx-service-proxy.git
17 | scm:git:git@github.com:vert-x3/vertx-service-proxy.git
18 | git@github.com:vert-x3/vertx-service-proxy.git
19 |
20 |
21 |
22 | false
23 | ${path.separator}
24 |
25 |
26 |
27 |
28 |
29 | io.vertx
30 | vertx-dependencies
31 | ${project.version}
32 | pom
33 | import
34 |
35 |
36 | junit
37 | junit
38 | 4.13.2
39 |
40 |
41 |
42 |
43 |
44 |
45 | io.vertx
46 | vertx-codegen-api
47 |
48 |
49 | io.vertx
50 | vertx-codegen-json
51 |
52 |
53 | io.vertx
54 | vertx-codegen-processor
55 |
56 |
57 | io.vertx
58 | vertx-core
59 |
60 |
61 | io.vertx
62 | vertx-auth-jwt
63 | true
64 |
65 |
66 |
67 | io.vertx
68 | vertx-docgen-api
69 | true
70 |
71 |
72 |
73 | junit
74 | junit
75 | test
76 |
77 |
78 | com.fasterxml.jackson.core
79 | jackson-databind
80 | test
81 |
82 |
83 | io.vertx
84 | vertx-core
85 | test-jar
86 | test
87 |
88 |
89 | io.vertx
90 | vertx-codegen-processor
91 | test-jar
92 | test
93 |
94 |
95 |
96 | org.assertj
97 | assertj-core
98 | 3.3.0
99 | test
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 | maven-jar-plugin
108 |
109 |
110 | default-jar
111 |
112 |
113 | META-INF/services/javax.annotation.processing.Processor
114 | examples/**
115 |
116 |
117 |
118 |
119 |
120 |
121 | maven-compiler-plugin
122 |
123 |
124 | default-compile
125 |
126 |
127 |
128 | io.vertx
129 | vertx-docgen-processor
130 | processor
131 |
132 |
133 |
134 |
135 |
136 | default-testCompile
137 |
138 | false
139 |
140 | io.vertx.codegen.processor.Processor
141 |
142 |
143 | **/InvalidParamsDataObject.java
144 | **/InvalidOverloaded.java
145 | **/InvalidParams1.java
146 | **/InvalidParams2.java
147 | **/InvalidParams3.java
148 | **/InvalidParams4.java
149 | **/InvalidReturn1.java
150 | **/InvalidReturn2.java
151 | **/InvalidReturn3.java
152 | **/InvalidClose1.java
153 | **/InvalidClose2.java
154 | **/InvalidClose3.java
155 |
156 |
157 | ${project.build.directory}/classes${s}${io.vertx:vertx-codegen-api:jar}${s}${io.vertx:vertx-codegen-processor:jar}
158 |
159 |
160 |
161 |
162 |
163 |
164 | org.apache.maven.plugins
165 | maven-surefire-plugin
166 |
167 |
168 | default-test
169 |
170 |
171 | ${project.build.testSourceDirectory}
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 | org.apache.maven.plugins
183 | maven-dependency-plugin
184 |
185 |
186 | initialize
187 |
188 | properties
189 |
190 |
191 |
192 |
193 |
194 | maven-assembly-plugin
195 |
196 |
197 | package-docs
198 |
199 | single
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
--------------------------------------------------------------------------------
/src/main/java/examples/Examples.java:
--------------------------------------------------------------------------------
1 | package examples;
2 |
3 | import io.vertx.core.Vertx;
4 | import io.vertx.core.eventbus.DeliveryOptions;
5 | import io.vertx.core.eventbus.MessageConsumer;
6 | import io.vertx.core.json.JsonObject;
7 | import io.vertx.ext.auth.authorization.PermissionBasedAuthorization;
8 | import io.vertx.ext.auth.authorization.RoleBasedAuthorization;
9 | import io.vertx.ext.auth.jwt.JWTAuth;
10 | import io.vertx.ext.auth.jwt.JWTAuthOptions;
11 | import io.vertx.ext.auth.jwt.authorization.JWTAuthorization;
12 | import io.vertx.serviceproxy.AuthenticationInterceptor;
13 | import io.vertx.serviceproxy.AuthorizationInterceptor;
14 | import io.vertx.serviceproxy.ServiceBinder;
15 | import io.vertx.serviceproxy.ServiceProxyBuilder;
16 |
17 | /**
18 | * @author Clement Escoffier
19 | */
20 | public class Examples {
21 |
22 | public void example1(Vertx vertx) {
23 | // Assume database service is already deployed somewhere....
24 | // Save some data in the database
25 | JsonObject message = new JsonObject();
26 |
27 | message
28 | .put("collection", "mycollection")
29 | .put("document", new JsonObject().put("name", "tim"));
30 |
31 | DeliveryOptions options = new DeliveryOptions().addHeader("action", "save");
32 |
33 | vertx.eventBus()
34 | .request("database-service-address", message, options)
35 | .onSuccess(msg -> {
36 | // done
37 | }).onFailure(err -> {
38 | // failure
39 | });
40 | }
41 |
42 | public void example2(Vertx vertx) {
43 | // Assume database service is already deployed somewhere....
44 |
45 | // Create a proxy
46 | SomeDatabaseService service = SomeDatabaseService
47 | .createProxy(vertx, "database-service-address");
48 |
49 | // Save some data in the database - this time using the proxy
50 | service.save(
51 | "mycollection",
52 | new JsonObject().put("name", "tim")).onComplete(
53 | res2 -> {
54 | if (res2.succeeded()) {
55 | // done
56 | }
57 | });
58 | }
59 |
60 | public void register(Vertx vertx) {
61 | // Create an instance of your service implementation
62 | SomeDatabaseService service = new SomeDatabaseServiceImpl();
63 | // Register the handler
64 | new ServiceBinder(vertx)
65 | .setAddress("database-service-address")
66 | .register(SomeDatabaseService.class, service);
67 | }
68 |
69 | public void unregister(Vertx vertx) {
70 | ServiceBinder binder = new ServiceBinder(vertx);
71 |
72 | // Create an instance of your service implementation
73 | SomeDatabaseService service = new SomeDatabaseServiceImpl();
74 | // Register the handler
75 | MessageConsumer consumer = binder
76 | .setAddress("database-service-address")
77 | .register(SomeDatabaseService.class, service);
78 |
79 | // ....
80 |
81 | // Unregister your service.
82 | binder.unregister(consumer);
83 | }
84 |
85 | public void proxyCreation(Vertx vertx, DeliveryOptions options) {
86 | ServiceProxyBuilder builder = new ServiceProxyBuilder(vertx)
87 | .setAddress("database-service-address");
88 |
89 | SomeDatabaseService service = builder.build(SomeDatabaseService.class);
90 | // or with delivery options:
91 | SomeDatabaseService service2 = builder.setOptions(options)
92 | .build(SomeDatabaseService.class);
93 | }
94 |
95 | public void secure(Vertx vertx) {
96 | // Create an instance of your service implementation
97 | SomeDatabaseService service = new SomeDatabaseServiceImpl();
98 | // Register the handler
99 | new ServiceBinder(vertx)
100 | .setAddress("database-service-address")
101 | // Secure the messages in transit
102 | .addInterceptor(
103 | "action",
104 | // Tokens will be validated using JWT authentication
105 | AuthenticationInterceptor.create(
106 | JWTAuth.create(vertx, new JWTAuthOptions())))
107 | .addInterceptor(
108 | AuthorizationInterceptor.create(JWTAuthorization.create("permissions"))
109 | // optionally we can secure permissions too:
110 | // an admin
111 | .addAuthorization(RoleBasedAuthorization.create("admin"))
112 | // that can print
113 | .addAuthorization(PermissionBasedAuthorization.create("print")))
114 | .register(SomeDatabaseService.class, service);
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/src/main/java/examples/SomeDatabaseService.java:
--------------------------------------------------------------------------------
1 | package examples;
2 |
3 | import io.vertx.codegen.annotations.ProxyGen;
4 | import io.vertx.core.Future;
5 | import io.vertx.core.Vertx;
6 | import io.vertx.core.json.JsonObject;
7 |
8 | /**
9 | * @author Clement Escoffier
10 | */
11 | @ProxyGen
12 | public interface SomeDatabaseService {
13 |
14 | Future save(String collection, JsonObject document);
15 |
16 | Future foo(String collection, JsonObject document);
17 |
18 | static SomeDatabaseService createProxy(Vertx vertx, String address) {
19 | return null;
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/main/java/examples/SomeDatabaseServiceImpl.java:
--------------------------------------------------------------------------------
1 | package examples;
2 |
3 | import io.vertx.core.AsyncResult;
4 | import io.vertx.core.Future;
5 | import io.vertx.core.Handler;
6 | import io.vertx.core.json.JsonObject;
7 |
8 | /**
9 | * @author Clement Escoffier
10 | */
11 | public class SomeDatabaseServiceImpl implements SomeDatabaseService {
12 |
13 | @Override
14 | public Future save(String collection, JsonObject document) {
15 | return null;
16 | }
17 |
18 | @Override
19 | public Future foo(String collection, JsonObject document) {
20 | return null;
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/main/java/examples/package-info.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2011-2015 The original author or authors
3 | * ------------------------------------------------------
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the Eclipse Public License v1.0
6 | * and Apache License v2.0 which accompanies this distribution.
7 | *
8 | * The Eclipse Public License is available at
9 | * http://www.eclipse.org/legal/epl-v10.html
10 | *
11 | * The Apache License v2.0 is available at
12 | * http://www.opensource.org/licenses/apache2.0.php
13 | *
14 | * You may elect to redistribute this code under either of these licenses.
15 | */
16 |
17 | @Source(translate = false)
18 | @ModuleGen(name = "examples", groupPackage = "examples")
19 | package examples;
20 |
21 | import io.vertx.codegen.annotations.ModuleGen;
22 | import io.vertx.docgen.Source;
23 |
--------------------------------------------------------------------------------
/src/main/java/io/vertx/serviceproxy/AuthenticationInterceptor.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 Red Hat, Inc.
3 | *
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the Eclipse Public License v1.0
6 | * and Apache License v2.0 which accompanies this distribution.
7 | *
8 | * The Eclipse Public License is available at
9 | * http://www.eclipse.org/legal/epl-v10.html
10 | *
11 | * The Apache License v2.0 is available at
12 | * http://www.opensource.org/licenses/apache2.0.php
13 | *
14 | * You may elect to redistribute this code under either of these licenses.
15 | */
16 | package io.vertx.serviceproxy;
17 |
18 | import io.vertx.codegen.annotations.VertxGen;
19 | import io.vertx.ext.auth.authentication.AuthenticationProvider;
20 | import io.vertx.serviceproxy.impl.AuthenticationInterceptorImpl;
21 |
22 | /**
23 | * Create an event bus service interceptor that will provide an authentication check
24 | */
25 | @VertxGen
26 | public interface AuthenticationInterceptor extends ServiceInterceptor {
27 |
28 | static AuthenticationInterceptor create(AuthenticationProvider authenticationProvider) {
29 | return new AuthenticationInterceptorImpl(authenticationProvider);
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/main/java/io/vertx/serviceproxy/AuthorizationInterceptor.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 Red Hat, Inc.
3 | *
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the Eclipse Public License v1.0
6 | * and Apache License v2.0 which accompanies this distribution.
7 | *
8 | * The Eclipse Public License is available at
9 | * http://www.eclipse.org/legal/epl-v10.html
10 | *
11 | * The Apache License v2.0 is available at
12 | * http://www.opensource.org/licenses/apache2.0.php
13 | *
14 | * You may elect to redistribute this code under either of these licenses.
15 | */
16 | package io.vertx.serviceproxy;
17 |
18 | import io.vertx.codegen.annotations.VertxGen;
19 | import io.vertx.ext.auth.authorization.Authorization;
20 | import io.vertx.ext.auth.authorization.AuthorizationProvider;
21 | import io.vertx.serviceproxy.impl.AuthorizationInterceptorImpl;
22 |
23 | import java.util.Set;
24 |
25 | /**
26 | * Create an event bus service interceptor that will provide an authorization check
27 | */
28 | @VertxGen
29 | public interface AuthorizationInterceptor extends ServiceInterceptor {
30 |
31 | static AuthorizationInterceptor create(AuthorizationProvider authorizationProvider) {
32 | return new AuthorizationInterceptorImpl(authorizationProvider);
33 | }
34 |
35 | /**
36 | * Set the required authorities for the service, once a JWT is validated it will be
37 | * queried for these authorities. If authorities are missing a error 403 is returned.
38 | *
39 | * @param authorizations set of authorities
40 | * @return self
41 | */
42 | AuthorizationInterceptor setAuthorizations(Set authorizations);
43 |
44 | /**
45 | * Add a single authority to the authorities set.
46 | *
47 | * @param authorization authority
48 | * @return self
49 | */
50 | AuthorizationInterceptor addAuthorization(Authorization authorization);
51 | }
52 |
--------------------------------------------------------------------------------
/src/main/java/io/vertx/serviceproxy/HelperUtils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 Red Hat, Inc.
3 | *
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the Eclipse Public License v1.0
6 | * and Apache License v2.0 which accompanies this distribution.
7 | *
8 | * The Eclipse Public License is available at
9 | * http://www.eclipse.org/legal/epl-v10.html
10 | *
11 | * The Apache License v2.0 is available at
12 | * http://www.opensource.org/licenses/apache2.0.php
13 | *
14 | * You may elect to redistribute this code under either of these licenses.
15 | */
16 | package io.vertx.serviceproxy;
17 |
18 | import io.vertx.core.AsyncResult;
19 | import io.vertx.core.Handler;
20 | import io.vertx.core.eventbus.Message;
21 | import io.vertx.core.json.JsonArray;
22 | import io.vertx.core.json.JsonObject;
23 |
24 | import java.util.*;
25 |
26 | /**
27 | * @author Francesco Guardiani @slinkydeveloper
28 | */
29 | @SuppressWarnings({"unchecked", "rawtypes"})
30 | public class HelperUtils {
31 |
32 | public static Handler> createHandler(Message msg, boolean includeDebugInfo) {
33 | return res -> {
34 | if (res.failed()) {
35 | manageFailure(msg, res.cause(), includeDebugInfo);
36 | } else {
37 | if (res.result() != null && res.result().getClass().isEnum()) {
38 | msg.reply(((Enum) res.result()).name());
39 | } else {
40 | msg.reply(res.result());
41 | }
42 | }
43 | };
44 | }
45 |
46 | public static Handler>> createListHandler(Message msg, boolean includeDebugInfo) {
47 | return res -> {
48 | if (res.failed()) {
49 | manageFailure(msg, res.cause(), includeDebugInfo);
50 | } else {
51 | msg.reply(new JsonArray(res.result()));
52 | }
53 | };
54 | }
55 |
56 | public static Handler>> createSetHandler(Message msg, boolean includeDebugInfo) {
57 | return res -> {
58 | if (res.failed()) {
59 | manageFailure(msg, res.cause(), includeDebugInfo);
60 | } else {
61 | msg.reply(new JsonArray(new ArrayList<>(res.result())));
62 | }
63 | };
64 | }
65 |
66 | public static Handler>> createMapHandler(Message msg, boolean includeDebugInfo) {
67 | return res -> {
68 | if (res.failed()) {
69 | manageFailure(msg, res.cause(), includeDebugInfo);
70 | } else {
71 | msg.reply(new JsonObject(new HashMap<>(res.result())));
72 | }
73 | };
74 | }
75 |
76 | public static Handler>> createListCharHandler(Message msg, boolean includeDebugInfo) {
77 | return res -> {
78 | if (res.failed()) {
79 | manageFailure(msg, res.cause(), includeDebugInfo);
80 | } else {
81 | JsonArray arr = new JsonArray();
82 | for (Character chr: res.result()) {
83 | arr.add((int) chr);
84 | }
85 | msg.reply(arr);
86 | }
87 | };
88 | }
89 |
90 | public static Handler>> createSetCharHandler(Message msg, boolean includeDebugInfo) {
91 | return res -> {
92 | if (res.failed()) {
93 | manageFailure(msg, res.cause(), includeDebugInfo);
94 | } else {
95 | JsonArray arr = new JsonArray();
96 | for (Character chr: res.result()) {
97 | arr.add((int) chr);
98 | }
99 | msg.reply(arr);
100 | }
101 | };
102 | }
103 |
104 | public static Handler>> createMapCharHandler(Message msg, boolean includeDebugInfo) {
105 | return res -> {
106 | if (res.failed()) {
107 | manageFailure(msg, res.cause(), includeDebugInfo);
108 | } else {
109 | JsonObject obj = new JsonObject();
110 | for (Map.Entry chr: res.result().entrySet()) {
111 | obj.put(chr.getKey(), (int) chr.getValue());
112 | }
113 | msg.reply(obj);
114 | }
115 | };
116 | }
117 |
118 | public static void manageFailure(Message msg, Throwable cause, boolean includeDebugInfo) {
119 | if (cause instanceof ServiceException) {
120 | msg.reply(cause);
121 | } else {
122 | if (includeDebugInfo)
123 | msg.reply(new ServiceException(-1, cause.getMessage(), generateDebugInfo(cause)));
124 | else
125 | msg.reply(new ServiceException(-1, cause.getMessage()));
126 | }
127 | }
128 |
129 | public static Map convertMap(Map map) {
130 | return (Map)map;
131 | }
132 |
133 | public static List convertList(List list) {
134 | return (List)list;
135 | }
136 |
137 | public static Set convertSet(List list) {
138 | return new HashSet((List)list);
139 | }
140 |
141 | public static JsonObject generateDebugInfo(Throwable cause) {
142 | if (cause == null) return null;
143 | JsonObject obj = new JsonObject();
144 | obj.put("causeName", cause.getClass().getCanonicalName());
145 | obj.put("causeMessage", cause.getMessage());
146 | obj.put("causeStackTrace", convertStackTrace(cause));
147 | return obj;
148 | }
149 |
150 | public static JsonArray convertStackTrace(Throwable cause) {
151 | if (cause == null || cause.getStackTrace() == null) return new JsonArray();
152 | return Arrays
153 | .stream(cause.getStackTrace())
154 | .map(StackTraceElement::toString)
155 | .collect(JsonArray::new, JsonArray::add, JsonArray::addAll);
156 | }
157 |
158 | }
159 |
--------------------------------------------------------------------------------
/src/main/java/io/vertx/serviceproxy/ProxyHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2014 Red Hat, Inc.
3 | *
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the Eclipse Public License v1.0
6 | * and Apache License v2.0 which accompanies this distribution.
7 | *
8 | * The Eclipse Public License is available at
9 | * http://www.eclipse.org/legal/epl-v10.html
10 | *
11 | * The Apache License v2.0 is available at
12 | * http://www.opensource.org/licenses/apache2.0.php
13 | *
14 | * You may elect to redistribute this code under either of these licenses.
15 | */
16 |
17 | package io.vertx.serviceproxy;
18 |
19 | import io.vertx.core.Handler;
20 | import io.vertx.core.Vertx;
21 | import io.vertx.core.eventbus.EventBus;
22 | import io.vertx.core.eventbus.Message;
23 | import io.vertx.core.eventbus.MessageConsumer;
24 | import io.vertx.core.eventbus.ReplyException;
25 | import io.vertx.core.json.JsonObject;
26 | import io.vertx.serviceproxy.impl.InterceptorHolder;
27 |
28 | import java.util.HashMap;
29 | import java.util.List;
30 | import java.util.Map;
31 | import java.util.Objects;
32 |
33 | /**
34 | * @author Tim Fox
35 | */
36 | public abstract class ProxyHandler implements Handler> {
37 |
38 | protected boolean closed;
39 | protected MessageConsumer consumer;
40 |
41 | public void close() {
42 | consumer.unregister();
43 | closed = true;
44 | }
45 |
46 | /**
47 | * Register the proxy handle on the event bus.
48 | *
49 | * @param eventBus the event bus
50 | * @param address the proxy address
51 | */
52 | public MessageConsumer register(EventBus eventBus, String address) {
53 | consumer = eventBus.consumer(address, this);
54 | return consumer;
55 | }
56 |
57 | /**
58 | * Register the proxy handle on the event bus.
59 | *
60 | * @param vertx the VertX instance
61 | * @param address the proxy address
62 | * @param interceptorHolders the interceptorHolders
63 | */
64 | public MessageConsumer register(Vertx vertx, String address,
65 | List interceptorHolders) {
66 | Objects.requireNonNull(interceptorHolders);
67 | Handler> handler = configureHandler(vertx, interceptorHolders);
68 | consumer = vertx.eventBus().consumer(address, handler);
69 | return consumer;
70 | }
71 |
72 | /**
73 | * Register the local proxy handle on the event bus.
74 | * The registration will not be propagated to other nodes in the cluster.
75 | *
76 | * @param eventBus the event bus
77 | * @param address the proxy address
78 | */
79 | public MessageConsumer registerLocal(EventBus eventBus, String address) {
80 | consumer = eventBus.localConsumer(address, this);
81 | return consumer;
82 | }
83 |
84 | /**
85 | * Register the local proxy handle on the event bus.
86 | * The registration will not be propagated to other nodes in the cluster.
87 | *
88 | * @param vertx the VertX instance
89 | * @param address the proxy address
90 | * @param interceptorHolders the {@link InterceptorHolder} interceptorHolders
91 | */
92 | public MessageConsumer registerLocal(Vertx vertx, String address,
93 | List interceptorHolders) {
94 | Objects.requireNonNull(interceptorHolders);
95 | Handler> handler = configureHandler(vertx, interceptorHolders);
96 | consumer = vertx.eventBus().localConsumer(address, handler);
97 | return consumer;
98 | }
99 |
100 | private Handler> configureHandler(Vertx vertx, List interceptorHolders) {
101 | Handler> handler = this;
102 | Map context = new HashMap<>();
103 | // construct the handler backwards, this allows the checks to be performed in the correct order
104 | for (int i = interceptorHolders.size() - 1; i >= 0; i--) {
105 | final InterceptorHolder interceptorHolder = interceptorHolders.get(i);
106 | Handler> prev = handler;
107 | handler = msg -> {
108 | String action = msg.headers().get("action");
109 | String holderAction = interceptorHolder.action();
110 | if (holderAction == null || action.equals(holderAction)) {
111 | interceptorHolder.interceptor().intercept(vertx, context, msg)
112 | .onSuccess(prev)
113 | .onFailure(err -> {
114 | ReplyException exception = (ReplyException) err;
115 | msg.fail(exception.failureCode(), exception.getMessage());
116 | });
117 | } else {
118 | prev.handle(msg);
119 | }
120 | };
121 | }
122 | return handler;
123 | }
124 |
125 | }
126 |
--------------------------------------------------------------------------------
/src/main/java/io/vertx/serviceproxy/ProxyUtils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 Red Hat, Inc.
3 | *
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the Eclipse Public License v1.0
6 | * and Apache License v2.0 which accompanies this distribution.
7 | *
8 | * The Eclipse Public License is available at
9 | * http://www.eclipse.org/legal/epl-v10.html
10 | *
11 | * The Apache License v2.0 is available at
12 | * http://www.opensource.org/licenses/apache2.0.php
13 | *
14 | * You may elect to redistribute this code under either of these licenses.
15 | */
16 | package io.vertx.serviceproxy;
17 |
18 | import io.vertx.core.json.JsonArray;
19 | import io.vertx.core.json.JsonObject;
20 |
21 | import java.util.*;
22 | import java.util.function.Function;
23 | import java.util.stream.Collectors;
24 |
25 | /**
26 | * @author Francesco Guardiani @slinkydeveloper
27 | */
28 | @SuppressWarnings({"unchecked", "rawtypes"})
29 | public class ProxyUtils {
30 |
31 | public static List convertToListChar(JsonArray arr) {
32 | return arr.stream().map(ProxyUtils::javaObjToChar).collect(Collectors.toList());
33 | }
34 |
35 | public static Set convertToSetChar(JsonArray arr) {
36 | return arr.stream().map(ProxyUtils::javaObjToChar).collect(Collectors.toSet());
37 | }
38 |
39 | public static Map convertToMapChar(JsonObject obj) {
40 | return obj.stream().collect(Collectors.toMap(Map.Entry::getKey, e -> javaObjToChar(e.getValue())));
41 | }
42 |
43 | public static Character javaObjToChar(Object obj) {
44 | Integer jobj = (Integer)obj;
45 | return (char)(int)jobj;
46 | }
47 |
48 | public static Map convertMap(Map map) {
49 | if (map.isEmpty()) {
50 | return (Map) map;
51 | }
52 |
53 | Object elem = map.values().stream().findFirst().get();
54 | if (!(elem instanceof Map) && !(elem instanceof List)) {
55 | return (Map) map;
56 | } else {
57 | Function