├── .editorconfig ├── .github ├── 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.adoc ├── pom.xml └── src ├── main ├── asciidoc │ └── index.adoc ├── generated │ └── io │ │ └── vertx │ │ └── spi │ │ └── cluster │ │ └── ignite │ │ ├── IgniteCacheOptionsConverter.java │ │ ├── IgniteDiscoveryOptionsConverter.java │ │ ├── IgniteMetricExporterOptionsConverter.java │ │ ├── IgniteOptionsConverter.java │ │ └── IgniteSslOptionsConverter.java ├── java │ ├── examples │ │ ├── Examples.java │ │ └── package-info.java │ └── io │ │ └── vertx │ │ └── spi │ │ └── cluster │ │ └── ignite │ │ ├── IgniteCacheOptions.java │ │ ├── IgniteClusterManager.java │ │ ├── IgniteDiscoveryOptions.java │ │ ├── IgniteMetricExporterOptions.java │ │ ├── IgniteOptions.java │ │ ├── IgniteSslOptions.java │ │ ├── impl │ │ ├── AsyncMapImpl.java │ │ ├── ClusterSerializationUtils.java │ │ ├── IgniteNodeInfo.java │ │ ├── IgniteRegistrationInfo.java │ │ ├── MapImpl.java │ │ ├── SubsMapHelper.java │ │ ├── Throttling.java │ │ └── VertxLogger.java │ │ ├── package-info.java │ │ └── util │ │ └── ConfigHelper.java └── resources │ ├── META-INF │ └── services │ │ └── io.vertx.core.spi.VertxServiceProvider │ └── default-ignite.json └── test ├── java └── io │ └── vertx │ ├── Lifecycle.java │ ├── LoggingTestWatcher.java │ ├── core │ ├── IgniteComplexHATest.java │ ├── IgniteHATest.java │ ├── eventbus │ │ ├── IgniteClusteredEventbusTest.java │ │ ├── IgniteFaultToleranceTest.java │ │ └── IgniteNodeInfoTest.java │ └── shareddata │ │ ├── IgniteClusteredAsyncMapTest.java │ │ ├── IgniteClusteredAsynchronousLockTest.java │ │ └── IgniteClusteredSharedCounterTest.java │ ├── ext │ └── web │ │ └── sstore │ │ └── IgniteClusteredSessionHandlerTest.java │ ├── it │ └── core │ │ └── ServiceProviderTest.java │ ├── servicediscovery │ └── impl │ │ └── IgniteDiscoveryImplClusteredTest.java │ └── spi │ └── cluster │ └── ignite │ ├── IgniteOptionsTest.java │ ├── impl │ └── ThrottlingTest.java │ └── util │ └── ClasspathHelperTest.java └── resources ├── ca.p12 ├── ca.pem ├── ignite-test.xml ├── ignite.json ├── logback-test.xml ├── server-cert.pem ├── server-key.pem ├── server-keystore.p12 └── server.jks /.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 | -------------------------------------------------------------------------------- /.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-ignite (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 | uses: ./.github/workflows/ci.yml 13 | with: 14 | branch: 4.x 15 | jdk: ${{ matrix.jdk }} 16 | os: ${{ matrix.os }} 17 | secrets: inherit 18 | Deploy: 19 | if: ${{ github.repository_owner == 'vert-x3' && (github.event_name == 'push' || github.event_name == 'schedule') }} 20 | needs: CI 21 | uses: ./.github/workflows/deploy.yml 22 | with: 23 | branch: 4.x 24 | jdk: 8 25 | secrets: inherit 26 | -------------------------------------------------------------------------------- /.github/workflows/ci-5.x-stable.yml: -------------------------------------------------------------------------------- 1 | name: vertx-ignite (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-ignite (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 -B -DtestLogLevel=OFF test 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 | .DS_Store 2 | .gradle 3 | .idea 4 | .classpath 5 | .project 6 | .settings 7 | .yardoc 8 | .yardopts 9 | build 10 | out 11 | *.iml 12 | *.ipr 13 | *.iws 14 | .vertx 15 | test-output 16 | src/scratchpad 17 | test-results 18 | test-tmp 19 | *.class 20 | *.swp 21 | *.jar 22 | hs_err_pid* 23 | target 24 | pom.xml.tag 25 | pom.xml.releaseBackup 26 | pom.xml.versionsBackup 27 | pom.xml.next 28 | release.properties 29 | dependency-reduced-pom.xml 30 | buildNumber.properties 31 | .mvn/timing.properties 32 | /ignite 33 | -------------------------------------------------------------------------------- /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.adoc: -------------------------------------------------------------------------------- 1 | = Apache Ignite Cluster Manager 2 | 3 | image:https://github.com/vert-x3/vertx-ignite/actions/workflows/ci-5.x.yml/badge.svg["Build Status (5.x)",link="https://github.com/vert-x3/vertx-ignite/actions/workflows/ci-5.x.yml"] 4 | image:https://github.com/vert-x3/vertx-ignite/actions/workflows/ci-4.x.yml/badge.svg["Build Status (4.x)",link="https://github.com/vert-x3/vertx-ignite/actions/workflows/ci-4.x.yml"] 5 | 6 | This is a cluster manager implementation for Vert.x that uses http://ignite.apache.org/index.html[Apache Ignite]. 7 | 8 | Vert.x cluster manager is pluggable component. So you can replace default Vert.x cluster manager by this implementation. 9 | 10 | Please see the main documentation on the web-site for a full description: 11 | 12 | * https://vertx.io/docs/vertx-ignite/java/[Web-site documentation] 13 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4.0.0 4 | 5 | 6 | io.vertx 7 | vertx5-parent 8 | 12 9 | 10 | 11 | vertx-ignite 12 | 5.1.0-SNAPSHOT 13 | 14 | Vert.x Ignite Cluster Manager 15 | 16 | 17 | scm:git:git@github.com:vert-x3/vertx-ignite.git 18 | scm:git:git@github.com:vert-x3/vertx-ignite.git 19 | git@github.com:vert-x3/vertx-ignite.git 20 | 21 | 22 | 23 | 2.17.0 24 | ${project.basedir}/src/main/asciidoc 25 | 26 | 27 | 28 | 29 | 30 | io.vertx 31 | vertx-dependencies 32 | ${project.version} 33 | pom 34 | import 35 | 36 | 37 | 38 | 39 | 40 | 41 | io.vertx 42 | vertx-core 43 | 44 | 45 | org.apache.ignite 46 | ignite-core 47 | ${ignite.version} 48 | 49 | 50 | 51 | io.vertx 52 | vertx-codegen-api 53 | true 54 | 55 | 56 | io.vertx 57 | vertx-codegen-json 58 | true 59 | 60 | 61 | io.vertx 62 | vertx-docgen-api 63 | true 64 | 65 | 66 | 67 | junit 68 | junit 69 | 4.13.2 70 | test 71 | 72 | 73 | org.apache.ignite 74 | ignite-spring 75 | ${ignite.version} 76 | test 77 | 78 | 79 | org.apache.ignite 80 | ignite-indexing 81 | 82 | 83 | org.springframework 84 | spring-aop 85 | 86 | 87 | org.springframework 88 | spring-tx 89 | 90 | 91 | org.springframework 92 | spring-jdbc 93 | 94 | 95 | org.jetbrains 96 | annotations 97 | 98 | 99 | 100 | 101 | 102 | org.jetbrains 103 | annotations 104 | 13.0 105 | 106 | 107 | io.vertx 108 | vertx-core 109 | test-jar 110 | test 111 | 112 | 113 | io.vertx 114 | vertx-web 115 | test 116 | 117 | 118 | io.vertx 119 | vertx-web 120 | test-jar 121 | test 122 | 123 | 124 | ch.qos.logback 125 | logback-classic 126 | 1.4.14 127 | test 128 | 129 | 130 | io.vertx 131 | vertx-service-discovery 132 | test 133 | 134 | 135 | io.vertx 136 | vertx-service-proxy 137 | test 138 | 139 | 140 | io.vertx 141 | vertx-service-discovery 142 | test-jar 143 | test 144 | 145 | 146 | org.assertj 147 | assertj-core 148 | 3.3.0 149 | test 150 | 151 | 152 | com.jayway.awaitility 153 | awaitility 154 | 1.7.0 155 | test 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | maven-compiler-plugin 164 | 165 | 166 | default-compile 167 | 168 | 169 | 170 | io.vertx 171 | vertx-codegen 172 | processor 173 | 174 | 175 | io.vertx 176 | vertx-docgen-processor 177 | processor 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | org.apache.maven.plugins 186 | maven-surefire-plugin 187 | 188 | false 189 | 190 | true 191 | true 192 | true 193 | false 194 | 1000 195 | io.vertx.core.logging.SLF4JLogDelegateFactory 196 | PARANOID 197 | ${project.build.directory} 198 | ${project.version} 199 | 200 | 201 | 202 | -Xms512M -Xmx1200M 203 | 204 | --add-opens=java.base/java.nio=ALL-UNNAMED 205 | --add-opens=java.base/java.util=ALL-UNNAMED 206 | --add-opens=java.base/java.lang.invoke=ALL-UNNAMED 207 | --add-opens=java.base/java.lang=ALL-UNNAMED 208 | 209 | 1 210 | true 211 | 212 | **/it/**/*Test.java 213 | 214 | 215 | 216 | 217 | org.apache.maven.plugins 218 | maven-failsafe-plugin 219 | 2.19.1 220 | 221 | false 222 | 223 | true 224 | true 225 | true 226 | false 227 | 1000 228 | io.vertx.core.logging.SLF4JLogDelegateFactory 229 | PARANOID 230 | ${project.build.directory} 231 | ${project.version} 232 | 233 | 234 | 235 | -Xms512M -Xmx1200M 236 | 237 | --add-opens=java.base/java.nio=ALL-UNNAMED 238 | --add-opens=java.base/java.util=ALL-UNNAMED 239 | --add-opens=java.base/java.lang.invoke=ALL-UNNAMED 240 | --add-opens=java.base/java.lang=ALL-UNNAMED 241 | 242 | 1 243 | true 244 | 245 | 246 | 247 | 248 | 249 | 250 | maven-surefire-plugin 251 | 252 | 253 | **/it/**/*Test.java 254 | 255 | 256 | 257 | 258 | maven-failsafe-plugin 259 | 260 | 261 | core 262 | 263 | integration-test 264 | verify 265 | 266 | integration-test 267 | 268 | 269 | **/it/core/*Test.java 270 | 271 | 272 | io.vertx:vertx-core:test-jar 273 | 274 | 275 | 276 | 277 | 278 | 279 | maven-assembly-plugin 280 | 281 | 282 | package-docs 283 | 284 | single 285 | 286 | 287 | 288 | 289 | 290 | 291 | -------------------------------------------------------------------------------- /src/main/asciidoc/index.adoc: -------------------------------------------------------------------------------- 1 | = Apache Ignite Cluster Manager for Vert.x 2 | 3 | This is a cluster manager implementation for Vert.x that uses http://ignite.apache.org/index.html[Apache Ignite]. 4 | 5 | In Vert.x a cluster manager is used for various functions including: 6 | 7 | * Discovery and group membership of Vert.x nodes in a cluster 8 | * Maintaining cluster wide topic subscriber lists (so we know which nodes are interested in which event bus 9 | addresses) 10 | * Distributed Map support 11 | * Distributed Locks 12 | * Distributed Counters 13 | 14 | Cluster managersdo not* handle the event bus inter-node transport, this is done directly by Vert.x with TCP 15 | connections. 16 | 17 | Vert.x cluster manager is a pluggable component, so you can pick the one you want, or the one that is the most 18 | adapted to your environment. So you can replace default Vert.x cluster manager by this implementation. 19 | 20 | == Using Ignite cluster manager 21 | 22 | If the jar is on your classpath then Vert.x will automatically detect this and use it as the cluster manager. 23 | Please make sure you don’t have any other cluster managers on your classpath or Vert.x might choose the wrong one. 24 | 25 | Alternatively, you can configure the following system property to instruct vert.x to use this cluster manager: 26 | `-Dvertx.clusterManagerFactory=io.vertx.spi.cluster.ignite.IgniteClusterManager` 27 | 28 | === Using Vert.x from command line 29 | 30 | `vertx-ignite-${maven.version}.jar` should be in the `lib` directory of the Vert.x installation. 31 | 32 | === Using Vert.x in Maven or Gradle project 33 | 34 | Add a dependency to the artifact. 35 | 36 | * Maven (in your `pom.xml`): 37 | 38 | [source,xml,subs="+attributes"] 39 | ---- 40 | 41 | ${maven.groupId} 42 | ${maven.artifactId} 43 | ${maven.version} 44 | 45 | ---- 46 | 47 | * Gradle (in your `build.gradle` file): 48 | 49 | [source,groovy,subs="+attributes"] 50 | ---- 51 | compile '${maven.groupId}:${maven.artifactId}:${maven.version}' 52 | ---- 53 | 54 | === Programmatically specifying cluster manager 55 | 56 | You can also specify the cluster manager programmatically. In order to do this just specify it on the options 57 | when you are creating your Vert.x instance, for example: 58 | 59 | [source,java] 60 | ---- 61 | ClusterManager clusterManager = new IgniteClusterManager(); 62 | 63 | VertxOptions options = new VertxOptions().setClusterManager(clusterManager); 64 | Vertx.clusteredVertx(options, res -> { 65 | if (res.succeeded()) { 66 | Vertx vertx = res.result(); 67 | } else { 68 | // failed! 69 | } 70 | }); 71 | ---- 72 | 73 | == Configuring cluster manager 74 | 75 | Note: Starting with version 2.0, Apache Ignite has introduced a new off-heap memory architecture. All caches use 76 | off-heap memory by default. New memory architecture is described in 77 | https://apacheignite.readme.io/docs/page-memory[Ignite Virtual Memory] article. 78 | 79 | === Using configuration file 80 | 81 | The cluster manager is configured by a file `default-ignite.json` which is packaged inside the jar. 82 | 83 | If you want to override this configuration you can provide `ignite.json` file on your classpath and this will be 84 | used instead. The config maps to {@link io.vertx.spi.cluster.ignite.IgniteOptions} where you can find more details on 85 | each individual option. 86 | 87 | In the example below the default config is extended to activate TLS for cluster communication. 88 | [source,json] 89 | ---- 90 | { 91 | "cacheConfiguration": [{ 92 | "name": "__vertx.*", 93 | "cacheMode": "REPLICATED", 94 | "atomicityMode": "ATOMIC", 95 | "writeSynchronizationMode": "FULL_SYNC" 96 | }, { 97 | "name": "*", 98 | "cacheMode": "PARTITIONED", 99 | "backups": 1, 100 | "readFromBackup": false, 101 | "atomicityMode": "ATOMIC", 102 | "writeSynchronizationMode": "FULL_SYNC" 103 | }], 104 | "sslContextFactory": { 105 | "protocol": "TLSv1.2", 106 | "jksKeyCertOptions": { 107 | "path": "server.jks", 108 | "password": "changeme", 109 | }, 110 | "jksTrustOptions": { 111 | "path": "server.jks", 112 | "password": "changeme", 113 | }, 114 | "trustAll": false 115 | }, 116 | "metricsLogFrequency": 0, 117 | "shutdownOnSegmentation": true 118 | } 119 | ---- 120 | 121 | As an alternative to the json format you can use the native Ignite XML configuration. You can provide an `ignite.xml` file 122 | on your classpath and it will be used instead. 123 | 124 | First, add the `ignite-spring` dependency. 125 | 126 | * Maven (in your `pom.xml`): 127 | 128 | [source,xml,subs="+attributes"] 129 | ---- 130 | 131 | org.apache.ignite 132 | ignite-spring 133 | ${ignite.version} 134 | 135 | ---- 136 | 137 | * Gradle (in your `build.gradle` file): 138 | 139 | [source,groovy,subs="+attributes"] 140 | ---- 141 | compile 'org.apache.ignite:ignite-spring:${ignite.version}' 142 | ---- 143 | 144 | Then add an `ignite.xml` file like this one: 145 | 146 | [source,xml,subs="+attributes"] 147 | ---- 148 | 149 | 150 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | ---- 200 | 201 | The json format is a simplified version of the xml config described in details at 202 | https://apacheignite.readme.io/docs[Apache Ignite documentation]. 203 | 204 | === Configuring programmatically 205 | 206 | You can also specify configuration programmatically: 207 | 208 | [source,java] 209 | ---- 210 | IgniteConfiguration cfg = new IgniteConfiguration(); 211 | // Configuration code (omitted) 212 | 213 | ClusterManager clusterManager = new IgniteClusterManager(cfg); 214 | 215 | VertxOptions options = new VertxOptions().setClusterManager(clusterManager); 216 | Vertx.clusteredVertx(options, res -> { 217 | if (res.succeeded()) { 218 | Vertx vertx = res.result(); 219 | } else { 220 | // failed! 221 | } 222 | }); 223 | ---- 224 | 225 | === Discovery and network transport configuration 226 | 227 | The default configuration uses `TcpDiscoveryMulticastIpFinder` so you must have multicast enabled on your network. 228 | For cases when multicast is disabled `TcpDiscoveryVmIpFinder` should be used with pre-configured list of IP addresses. 229 | Please see http://apacheignite.readme.io/docs/cluster-config[Cluster Configuration] section 230 | at Apache Ignite documentation for details. 231 | 232 | == Trouble shooting clustering 233 | 234 | If the default multicast configuration is not working here are some common causes: 235 | 236 | === Multicast not enabled on the machine. 237 | 238 | By default the cluster manager is using `TcpDiscoveryMulticastIpFinder`, so IP multicasting is required, 239 | on some systems, multicast route(s) need to be added to the routing table otherwise, the default route will be used. 240 | 241 | Note that some systems don't consult the routing table for IP multicast routing, only for unicast routing 242 | 243 | MacOS example: 244 | 245 | [source,shell] 246 | ---- 247 | # Adds a multicast route for 224.0.0.1-231.255.255.254 248 | sudo route add -net 224.0.0.0/5 127.0.0.1 249 | 250 | # Adds a multicast route for 232.0.0.1-239.255.255.254 251 | sudo route add -net 232.0.0.0/5 192.168.1.3 252 | ---- 253 | 254 | Please google for more information. 255 | 256 | === Using wrong network interface 257 | 258 | If you have more than one network interface on your machine (and this can also be the case if you are running 259 | VPN software on your machine), then Apache Ignite may be using the wrong one. 260 | 261 | To tell Ignite to use a specific interface you can provide the IP address of the interface to the 262 | bean of `IgniteConfiguration` type using `localHost` property. For example: 263 | 264 | [source,json] 265 | ---- 266 | { 267 | "localHost": "192.168.1.20" 268 | } 269 | ---- 270 | 271 | When running Vert.x is in clustered mode, you should also make sure that Vert.x knows about the correct interface. 272 | When running at the command line this is done by specifying the `cluster-host` option: 273 | 274 | [source,shell] 275 | ---- 276 | vertx run myverticle.js -cluster -cluster-host your-ip-address 277 | ---- 278 | 279 | Where `your-ip-address` is the same IP address you specified in the Apache Ignite configuration. 280 | 281 | If using Vert.x programmatically you can specify this using {@link io.vertx.core.VertxOptions#getEventBusOptions().setHost(java.lang.String)}. 282 | 283 | === Using a VPN 284 | 285 | This is a variation of the above case. 286 | VPN software often works by creating a virtual network interface which often doesn't support multicast. 287 | If you have a VPN running and you do not specify the correct interface to use in both the Ignite configuration and to Vert.x then the VPN interface may be chosen instead of the correct interface. 288 | 289 | So, if you have a VPN running you may have to configure both the Ignite and Vert.x to use the correct interface as described in the previous section. 290 | 291 | === When multicast is not available 292 | 293 | In some cases you may not be able to use multicast as it might not be available in your environment. 294 | In that case you should configure another transport using corresponding IP finder, e.g. `TcpDiscoveryVmIpFinder` to use TCP sockets, or `TcpDiscoveryS3IpFinder` to use Amazon S3. 295 | 296 | For more information on available Ignite transports and how to configure them please consult the 297 | https://apacheignite.readme.io/docs/clustering[Ignite Clustering] documentation. 298 | 299 | === Enabling logging 300 | 301 | When trouble-shooting clustering issues it's often useful to get some logging output from Ignite to see if it's forming a cluster properly. 302 | You can do this (when using the default JUL logging) by adding a file called `vertx-default-jul-logging.properties` on your classpath. 303 | This is a standard java.util.loging (JUL) configuration file. 304 | Inside it set: 305 | 306 | [source,properties] 307 | ---- 308 | org.apache.ignite.level=INFO 309 | ---- 310 | 311 | and also 312 | 313 | [source,properties] 314 | ---- 315 | java.util.logging.ConsoleHandler.level=INFO 316 | java.util.logging.FileHandler.level=INFO 317 | ---- 318 | 319 | 320 | === JDK17 and later 321 | 322 | Add VM options: 323 | 324 | [source,properties] 325 | ---- 326 | --add-opens=java.base/java.nio=ALL-UNNAMED 327 | --add-opens=java.base/java.util=ALL-UNNAMED 328 | --add-opens=java.base/java.lang.invoke=ALL-UNNAMED 329 | --add-opens=java.base/java.lang=ALL-UNNAMED 330 | ---- 331 | -------------------------------------------------------------------------------- /src/main/generated/io/vertx/spi/cluster/ignite/IgniteCacheOptionsConverter.java: -------------------------------------------------------------------------------- 1 | package io.vertx.spi.cluster.ignite; 2 | 3 | import io.vertx.core.json.JsonObject; 4 | import io.vertx.core.json.JsonArray; 5 | import java.time.Instant; 6 | import java.time.format.DateTimeFormatter; 7 | 8 | /** 9 | * Converter and mapper for {@link io.vertx.spi.cluster.ignite.IgniteCacheOptions}. 10 | * NOTE: This class has been automatically generated from the {@link io.vertx.spi.cluster.ignite.IgniteCacheOptions} original class using Vert.x codegen. 11 | */ 12 | public class IgniteCacheOptionsConverter { 13 | 14 | static void fromJson(Iterable> json, IgniteCacheOptions obj) { 15 | for (java.util.Map.Entry member : json) { 16 | switch (member.getKey()) { 17 | case "name": 18 | if (member.getValue() instanceof String) { 19 | obj.setName((String)member.getValue()); 20 | } 21 | break; 22 | case "cacheMode": 23 | if (member.getValue() instanceof String) { 24 | obj.setCacheMode((String)member.getValue()); 25 | } 26 | break; 27 | case "backups": 28 | if (member.getValue() instanceof Number) { 29 | obj.setBackups(((Number)member.getValue()).intValue()); 30 | } 31 | break; 32 | case "readFromBackup": 33 | if (member.getValue() instanceof Boolean) { 34 | obj.setReadFromBackup((Boolean)member.getValue()); 35 | } 36 | break; 37 | case "atomicityMode": 38 | if (member.getValue() instanceof String) { 39 | obj.setAtomicityMode((String)member.getValue()); 40 | } 41 | break; 42 | case "writeSynchronizationMode": 43 | if (member.getValue() instanceof String) { 44 | obj.setWriteSynchronizationMode((String)member.getValue()); 45 | } 46 | break; 47 | case "copyOnRead": 48 | if (member.getValue() instanceof Boolean) { 49 | obj.setCopyOnRead((Boolean)member.getValue()); 50 | } 51 | break; 52 | case "eagerTtl": 53 | if (member.getValue() instanceof Boolean) { 54 | obj.setEagerTtl((Boolean)member.getValue()); 55 | } 56 | break; 57 | case "encryptionEnabled": 58 | if (member.getValue() instanceof Boolean) { 59 | obj.setEncryptionEnabled((Boolean)member.getValue()); 60 | } 61 | break; 62 | case "groupName": 63 | if (member.getValue() instanceof String) { 64 | obj.setGroupName((String)member.getValue()); 65 | } 66 | break; 67 | case "invalidate": 68 | if (member.getValue() instanceof Boolean) { 69 | obj.setInvalidate((Boolean)member.getValue()); 70 | } 71 | break; 72 | case "maxConcurrentAsyncOperations": 73 | if (member.getValue() instanceof Number) { 74 | obj.setMaxConcurrentAsyncOperations(((Number)member.getValue()).intValue()); 75 | } 76 | break; 77 | case "onheapCacheEnabled": 78 | if (member.getValue() instanceof Boolean) { 79 | obj.setOnheapCacheEnabled((Boolean)member.getValue()); 80 | } 81 | break; 82 | case "partitionLossPolicy": 83 | if (member.getValue() instanceof String) { 84 | obj.setPartitionLossPolicy((String)member.getValue()); 85 | } 86 | break; 87 | case "rebalanceMode": 88 | if (member.getValue() instanceof String) { 89 | obj.setRebalanceMode((String)member.getValue()); 90 | } 91 | break; 92 | case "rebalanceOrder": 93 | if (member.getValue() instanceof Number) { 94 | obj.setRebalanceOrder(((Number)member.getValue()).intValue()); 95 | } 96 | break; 97 | case "rebalanceDelay": 98 | if (member.getValue() instanceof Number) { 99 | obj.setRebalanceDelay(((Number)member.getValue()).longValue()); 100 | } 101 | break; 102 | case "maxQueryInteratorsCount": 103 | if (member.getValue() instanceof Number) { 104 | obj.setMaxQueryInteratorsCount(((Number)member.getValue()).intValue()); 105 | } 106 | break; 107 | case "eventsDisabled": 108 | if (member.getValue() instanceof Boolean) { 109 | obj.setEventsDisabled((Boolean)member.getValue()); 110 | } 111 | break; 112 | case "expiryPolicy": 113 | if (member.getValue() instanceof JsonObject) { 114 | obj.setExpiryPolicy(((JsonObject)member.getValue()).copy()); 115 | } 116 | break; 117 | case "metricsEnabled": 118 | if (member.getValue() instanceof Boolean) { 119 | obj.setMetricsEnabled((Boolean)member.getValue()); 120 | } 121 | break; 122 | } 123 | } 124 | } 125 | 126 | static void toJson(IgniteCacheOptions obj, JsonObject json) { 127 | toJson(obj, json.getMap()); 128 | } 129 | 130 | static void toJson(IgniteCacheOptions obj, java.util.Map json) { 131 | if (obj.getName() != null) { 132 | json.put("name", obj.getName()); 133 | } 134 | if (obj.getCacheMode() != null) { 135 | json.put("cacheMode", obj.getCacheMode()); 136 | } 137 | json.put("backups", obj.getBackups()); 138 | json.put("readFromBackup", obj.isReadFromBackup()); 139 | if (obj.getAtomicityMode() != null) { 140 | json.put("atomicityMode", obj.getAtomicityMode()); 141 | } 142 | if (obj.getWriteSynchronizationMode() != null) { 143 | json.put("writeSynchronizationMode", obj.getWriteSynchronizationMode()); 144 | } 145 | json.put("copyOnRead", obj.isCopyOnRead()); 146 | json.put("eagerTtl", obj.isEagerTtl()); 147 | json.put("encryptionEnabled", obj.isEncryptionEnabled()); 148 | if (obj.getGroupName() != null) { 149 | json.put("groupName", obj.getGroupName()); 150 | } 151 | json.put("invalidate", obj.isInvalidate()); 152 | json.put("maxConcurrentAsyncOperations", obj.getMaxConcurrentAsyncOperations()); 153 | json.put("onheapCacheEnabled", obj.isOnheapCacheEnabled()); 154 | if (obj.getPartitionLossPolicy() != null) { 155 | json.put("partitionLossPolicy", obj.getPartitionLossPolicy()); 156 | } 157 | if (obj.getRebalanceMode() != null) { 158 | json.put("rebalanceMode", obj.getRebalanceMode()); 159 | } 160 | json.put("rebalanceOrder", obj.getRebalanceOrder()); 161 | json.put("rebalanceDelay", obj.getRebalanceDelay()); 162 | json.put("maxQueryInteratorsCount", obj.getMaxQueryInteratorsCount()); 163 | json.put("eventsDisabled", obj.isEventsDisabled()); 164 | if (obj.getExpiryPolicy() != null) { 165 | json.put("expiryPolicy", obj.getExpiryPolicy()); 166 | } 167 | json.put("metricsEnabled", obj.isMetricsEnabled()); 168 | } 169 | } 170 | -------------------------------------------------------------------------------- /src/main/generated/io/vertx/spi/cluster/ignite/IgniteDiscoveryOptionsConverter.java: -------------------------------------------------------------------------------- 1 | package io.vertx.spi.cluster.ignite; 2 | 3 | import io.vertx.core.json.JsonObject; 4 | import io.vertx.core.json.JsonArray; 5 | import java.time.Instant; 6 | import java.time.format.DateTimeFormatter; 7 | 8 | /** 9 | * Converter and mapper for {@link io.vertx.spi.cluster.ignite.IgniteDiscoveryOptions}. 10 | * NOTE: This class has been automatically generated from the {@link io.vertx.spi.cluster.ignite.IgniteDiscoveryOptions} original class using Vert.x codegen. 11 | */ 12 | public class IgniteDiscoveryOptionsConverter { 13 | 14 | static void fromJson(Iterable> json, IgniteDiscoveryOptions obj) { 15 | for (java.util.Map.Entry member : json) { 16 | switch (member.getKey()) { 17 | case "type": 18 | if (member.getValue() instanceof String) { 19 | obj.setType((String)member.getValue()); 20 | } 21 | break; 22 | case "properties": 23 | if (member.getValue() instanceof JsonObject) { 24 | obj.setProperties(((JsonObject)member.getValue()).copy()); 25 | } 26 | break; 27 | } 28 | } 29 | } 30 | 31 | static void toJson(IgniteDiscoveryOptions obj, JsonObject json) { 32 | toJson(obj, json.getMap()); 33 | } 34 | 35 | static void toJson(IgniteDiscoveryOptions obj, java.util.Map json) { 36 | if (obj.getType() != null) { 37 | json.put("type", obj.getType()); 38 | } 39 | if (obj.getProperties() != null) { 40 | json.put("properties", obj.getProperties()); 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/generated/io/vertx/spi/cluster/ignite/IgniteMetricExporterOptionsConverter.java: -------------------------------------------------------------------------------- 1 | package io.vertx.spi.cluster.ignite; 2 | 3 | import io.vertx.core.json.JsonObject; 4 | import io.vertx.core.json.JsonArray; 5 | import java.time.Instant; 6 | import java.time.format.DateTimeFormatter; 7 | 8 | /** 9 | * Converter and mapper for {@link io.vertx.spi.cluster.ignite.IgniteMetricExporterOptions}. 10 | * NOTE: This class has been automatically generated from the {@link io.vertx.spi.cluster.ignite.IgniteMetricExporterOptions} original class using Vert.x codegen. 11 | */ 12 | public class IgniteMetricExporterOptionsConverter { 13 | 14 | static void fromJson(Iterable> json, IgniteMetricExporterOptions obj) { 15 | for (java.util.Map.Entry member : json) { 16 | switch (member.getKey()) { 17 | } 18 | } 19 | } 20 | 21 | static void toJson(IgniteMetricExporterOptions obj, JsonObject json) { 22 | toJson(obj, json.getMap()); 23 | } 24 | 25 | static void toJson(IgniteMetricExporterOptions obj, java.util.Map json) { 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/main/generated/io/vertx/spi/cluster/ignite/IgniteOptionsConverter.java: -------------------------------------------------------------------------------- 1 | package io.vertx.spi.cluster.ignite; 2 | 3 | import io.vertx.core.json.JsonObject; 4 | import io.vertx.core.json.JsonArray; 5 | import java.time.Instant; 6 | import java.time.format.DateTimeFormatter; 7 | 8 | /** 9 | * Converter and mapper for {@link io.vertx.spi.cluster.ignite.IgniteOptions}. 10 | * NOTE: This class has been automatically generated from the {@link io.vertx.spi.cluster.ignite.IgniteOptions} original class using Vert.x codegen. 11 | */ 12 | public class IgniteOptionsConverter { 13 | 14 | static void fromJson(Iterable> json, IgniteOptions obj) { 15 | for (java.util.Map.Entry member : json) { 16 | switch (member.getKey()) { 17 | case "localHost": 18 | if (member.getValue() instanceof String) { 19 | obj.setLocalHost((String)member.getValue()); 20 | } 21 | break; 22 | case "localPort": 23 | if (member.getValue() instanceof Number) { 24 | obj.setLocalPort(((Number)member.getValue()).intValue()); 25 | } 26 | break; 27 | case "connectionsPerNode": 28 | if (member.getValue() instanceof Number) { 29 | obj.setConnectionsPerNode(((Number)member.getValue()).intValue()); 30 | } 31 | break; 32 | case "connectTimeout": 33 | if (member.getValue() instanceof Number) { 34 | obj.setConnectTimeout(((Number)member.getValue()).longValue()); 35 | } 36 | break; 37 | case "idleConnectionTimeout": 38 | if (member.getValue() instanceof Number) { 39 | obj.setIdleConnectionTimeout(((Number)member.getValue()).longValue()); 40 | } 41 | break; 42 | case "maxConnectTimeout": 43 | if (member.getValue() instanceof Number) { 44 | obj.setMaxConnectTimeout(((Number)member.getValue()).longValue()); 45 | } 46 | break; 47 | case "reconnectCount": 48 | if (member.getValue() instanceof Number) { 49 | obj.setReconnectCount(((Number)member.getValue()).intValue()); 50 | } 51 | break; 52 | case "metricsLogFrequency": 53 | if (member.getValue() instanceof Number) { 54 | obj.setMetricsLogFrequency(((Number)member.getValue()).longValue()); 55 | } 56 | break; 57 | case "discoverySpi": 58 | if (member.getValue() instanceof JsonObject) { 59 | obj.setDiscoverySpi(new io.vertx.spi.cluster.ignite.IgniteDiscoveryOptions((io.vertx.core.json.JsonObject)member.getValue())); 60 | } 61 | break; 62 | case "cacheConfiguration": 63 | if (member.getValue() instanceof JsonArray) { 64 | java.util.ArrayList list = new java.util.ArrayList<>(); 65 | ((Iterable)member.getValue()).forEach( item -> { 66 | if (item instanceof JsonObject) 67 | list.add(new io.vertx.spi.cluster.ignite.IgniteCacheOptions((io.vertx.core.json.JsonObject)item)); 68 | }); 69 | obj.setCacheConfiguration(list); 70 | } 71 | break; 72 | case "sslContextFactory": 73 | if (member.getValue() instanceof JsonObject) { 74 | obj.setSslContextFactory(new io.vertx.spi.cluster.ignite.IgniteSslOptions((io.vertx.core.json.JsonObject)member.getValue())); 75 | } 76 | break; 77 | case "shutdownOnSegmentation": 78 | if (member.getValue() instanceof Boolean) { 79 | obj.setShutdownOnSegmentation((Boolean)member.getValue()); 80 | } 81 | break; 82 | case "pageSize": 83 | if (member.getValue() instanceof Number) { 84 | obj.setPageSize(((Number)member.getValue()).intValue()); 85 | } 86 | break; 87 | case "defaultRegionInitialSize": 88 | if (member.getValue() instanceof Number) { 89 | obj.setDefaultRegionInitialSize(((Number)member.getValue()).longValue()); 90 | } 91 | break; 92 | case "defaultRegionMaxSize": 93 | if (member.getValue() instanceof Number) { 94 | obj.setDefaultRegionMaxSize(((Number)member.getValue()).longValue()); 95 | } 96 | break; 97 | case "defaultRegionMetricsEnabled": 98 | if (member.getValue() instanceof Boolean) { 99 | obj.setDefaultRegionMetricsEnabled((Boolean)member.getValue()); 100 | } 101 | break; 102 | case "shutdownOnNodeStop": 103 | if (member.getValue() instanceof Boolean) { 104 | obj.setShutdownOnNodeStop((Boolean)member.getValue()); 105 | } 106 | break; 107 | case "metricsUpdateFrequency": 108 | if (member.getValue() instanceof Number) { 109 | obj.setMetricsUpdateFrequency(((Number)member.getValue()).longValue()); 110 | } 111 | break; 112 | case "clientFailureDetectionTimeout": 113 | if (member.getValue() instanceof Number) { 114 | obj.setClientFailureDetectionTimeout(((Number)member.getValue()).longValue()); 115 | } 116 | break; 117 | case "metricsHistorySize": 118 | if (member.getValue() instanceof Number) { 119 | obj.setMetricsHistorySize(((Number)member.getValue()).intValue()); 120 | } 121 | break; 122 | case "metricsExpireTime": 123 | if (member.getValue() instanceof Number) { 124 | obj.setMetricsExpireTime(((Number)member.getValue()).longValue()); 125 | } 126 | break; 127 | case "metricExporterSpi": 128 | if (member.getValue() instanceof JsonObject) { 129 | obj.setMetricExporterSpi(new io.vertx.spi.cluster.ignite.IgniteMetricExporterOptions((io.vertx.core.json.JsonObject)member.getValue())); 130 | } 131 | break; 132 | case "delayAfterStart": 133 | if (member.getValue() instanceof Number) { 134 | obj.setDelayAfterStart(((Number)member.getValue()).longValue()); 135 | } 136 | break; 137 | } 138 | } 139 | } 140 | 141 | static void toJson(IgniteOptions obj, JsonObject json) { 142 | toJson(obj, json.getMap()); 143 | } 144 | 145 | static void toJson(IgniteOptions obj, java.util.Map json) { 146 | if (obj.getLocalHost() != null) { 147 | json.put("localHost", obj.getLocalHost()); 148 | } 149 | json.put("localPort", obj.getLocalPort()); 150 | json.put("connectionsPerNode", obj.getConnectionsPerNode()); 151 | json.put("connectTimeout", obj.getConnectTimeout()); 152 | json.put("idleConnectionTimeout", obj.getIdleConnectionTimeout()); 153 | json.put("maxConnectTimeout", obj.getMaxConnectTimeout()); 154 | json.put("reconnectCount", obj.getReconnectCount()); 155 | json.put("metricsLogFrequency", obj.getMetricsLogFrequency()); 156 | if (obj.getDiscoverySpi() != null) { 157 | json.put("discoverySpi", obj.getDiscoverySpi().toJson()); 158 | } 159 | if (obj.getCacheConfiguration() != null) { 160 | JsonArray array = new JsonArray(); 161 | obj.getCacheConfiguration().forEach(item -> array.add(item.toJson())); 162 | json.put("cacheConfiguration", array); 163 | } 164 | if (obj.getSslContextFactory() != null) { 165 | json.put("sslContextFactory", obj.getSslContextFactory().toJson()); 166 | } 167 | json.put("shutdownOnSegmentation", obj.isShutdownOnSegmentation()); 168 | json.put("pageSize", obj.getPageSize()); 169 | json.put("defaultRegionInitialSize", obj.getDefaultRegionInitialSize()); 170 | json.put("defaultRegionMaxSize", obj.getDefaultRegionMaxSize()); 171 | json.put("defaultRegionMetricsEnabled", obj.isDefaultRegionMetricsEnabled()); 172 | json.put("shutdownOnNodeStop", obj.isShutdownOnNodeStop()); 173 | json.put("metricsUpdateFrequency", obj.getMetricsUpdateFrequency()); 174 | json.put("clientFailureDetectionTimeout", obj.getClientFailureDetectionTimeout()); 175 | json.put("metricsHistorySize", obj.getMetricsHistorySize()); 176 | json.put("metricsExpireTime", obj.getMetricsExpireTime()); 177 | if (obj.getMetricExporterSpi() != null) { 178 | json.put("metricExporterSpi", obj.getMetricExporterSpi().toJson()); 179 | } 180 | json.put("delayAfterStart", obj.getDelayAfterStart()); 181 | } 182 | } 183 | -------------------------------------------------------------------------------- /src/main/generated/io/vertx/spi/cluster/ignite/IgniteSslOptionsConverter.java: -------------------------------------------------------------------------------- 1 | package io.vertx.spi.cluster.ignite; 2 | 3 | import io.vertx.core.json.JsonObject; 4 | import io.vertx.core.json.JsonArray; 5 | import java.time.Instant; 6 | import java.time.format.DateTimeFormatter; 7 | 8 | /** 9 | * Converter and mapper for {@link io.vertx.spi.cluster.ignite.IgniteSslOptions}. 10 | * NOTE: This class has been automatically generated from the {@link io.vertx.spi.cluster.ignite.IgniteSslOptions} original class using Vert.x codegen. 11 | */ 12 | public class IgniteSslOptionsConverter { 13 | 14 | static void fromJson(Iterable> json, IgniteSslOptions obj) { 15 | for (java.util.Map.Entry member : json) { 16 | switch (member.getKey()) { 17 | case "protocol": 18 | if (member.getValue() instanceof String) { 19 | obj.setProtocol((String)member.getValue()); 20 | } 21 | break; 22 | case "keyAlgorithm": 23 | if (member.getValue() instanceof String) { 24 | obj.setKeyAlgorithm((String)member.getValue()); 25 | } 26 | break; 27 | case "keyStoreType": 28 | if (member.getValue() instanceof String) { 29 | obj.setKeyStoreType((String)member.getValue()); 30 | } 31 | break; 32 | case "keyStoreFilePath": 33 | if (member.getValue() instanceof String) { 34 | obj.setKeyStoreFilePath((String)member.getValue()); 35 | } 36 | break; 37 | case "keyStorePassword": 38 | if (member.getValue() instanceof String) { 39 | obj.setKeyStorePassword((String)member.getValue()); 40 | } 41 | break; 42 | case "trustStoreType": 43 | if (member.getValue() instanceof String) { 44 | obj.setTrustStoreType((String)member.getValue()); 45 | } 46 | break; 47 | case "trustStoreFilePath": 48 | if (member.getValue() instanceof String) { 49 | obj.setTrustStoreFilePath((String)member.getValue()); 50 | } 51 | break; 52 | case "trustStorePassword": 53 | if (member.getValue() instanceof String) { 54 | obj.setTrustStorePassword((String)member.getValue()); 55 | } 56 | break; 57 | case "pemKeyCertOptions": 58 | if (member.getValue() instanceof JsonObject) { 59 | obj.setPemKeyCertOptions(new io.vertx.core.net.PemKeyCertOptions((io.vertx.core.json.JsonObject)member.getValue())); 60 | } 61 | break; 62 | case "pemTrustOptions": 63 | if (member.getValue() instanceof JsonObject) { 64 | obj.setPemTrustOptions(new io.vertx.core.net.PemTrustOptions((io.vertx.core.json.JsonObject)member.getValue())); 65 | } 66 | break; 67 | case "pfxKeyCertOptions": 68 | if (member.getValue() instanceof JsonObject) { 69 | obj.setPfxKeyCertOptions(new io.vertx.core.net.PfxOptions((io.vertx.core.json.JsonObject)member.getValue())); 70 | } 71 | break; 72 | case "pfxTrustOptions": 73 | if (member.getValue() instanceof JsonObject) { 74 | obj.setPfxTrustOptions(new io.vertx.core.net.PfxOptions((io.vertx.core.json.JsonObject)member.getValue())); 75 | } 76 | break; 77 | case "jksKeyCertOptions": 78 | if (member.getValue() instanceof JsonObject) { 79 | obj.setJksKeyCertOptions(new io.vertx.core.net.JksOptions((io.vertx.core.json.JsonObject)member.getValue())); 80 | } 81 | break; 82 | case "jksTrustOptions": 83 | if (member.getValue() instanceof JsonObject) { 84 | obj.setJksTrustOptions(new io.vertx.core.net.JksOptions((io.vertx.core.json.JsonObject)member.getValue())); 85 | } 86 | break; 87 | case "trustAll": 88 | if (member.getValue() instanceof Boolean) { 89 | obj.setTrustAll((Boolean)member.getValue()); 90 | } 91 | break; 92 | } 93 | } 94 | } 95 | 96 | static void toJson(IgniteSslOptions obj, JsonObject json) { 97 | toJson(obj, json.getMap()); 98 | } 99 | 100 | static void toJson(IgniteSslOptions obj, java.util.Map json) { 101 | if (obj.getProtocol() != null) { 102 | json.put("protocol", obj.getProtocol()); 103 | } 104 | if (obj.getKeyAlgorithm() != null) { 105 | json.put("keyAlgorithm", obj.getKeyAlgorithm()); 106 | } 107 | if (obj.getKeyStoreType() != null) { 108 | json.put("keyStoreType", obj.getKeyStoreType()); 109 | } 110 | if (obj.getKeyStoreFilePath() != null) { 111 | json.put("keyStoreFilePath", obj.getKeyStoreFilePath()); 112 | } 113 | if (obj.getKeyStorePassword() != null) { 114 | json.put("keyStorePassword", obj.getKeyStorePassword()); 115 | } 116 | if (obj.getTrustStoreType() != null) { 117 | json.put("trustStoreType", obj.getTrustStoreType()); 118 | } 119 | if (obj.getTrustStoreFilePath() != null) { 120 | json.put("trustStoreFilePath", obj.getTrustStoreFilePath()); 121 | } 122 | if (obj.getTrustStorePassword() != null) { 123 | json.put("trustStorePassword", obj.getTrustStorePassword()); 124 | } 125 | if (obj.getPemKeyCertOptions() != null) { 126 | json.put("pemKeyCertOptions", obj.getPemKeyCertOptions().toJson()); 127 | } 128 | if (obj.getPemTrustOptions() != null) { 129 | json.put("pemTrustOptions", obj.getPemTrustOptions().toJson()); 130 | } 131 | if (obj.getPfxKeyCertOptions() != null) { 132 | json.put("pfxKeyCertOptions", obj.getPfxKeyCertOptions().toJson()); 133 | } 134 | if (obj.getPfxTrustOptions() != null) { 135 | json.put("pfxTrustOptions", obj.getPfxTrustOptions().toJson()); 136 | } 137 | if (obj.getJksKeyCertOptions() != null) { 138 | json.put("jksKeyCertOptions", obj.getJksKeyCertOptions().toJson()); 139 | } 140 | if (obj.getJksTrustOptions() != null) { 141 | json.put("jksTrustOptions", obj.getJksTrustOptions().toJson()); 142 | } 143 | json.put("trustAll", obj.isTrustAll()); 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /src/main/java/examples/Examples.java: -------------------------------------------------------------------------------- 1 | package examples; 2 | 3 | import io.vertx.core.Vertx; 4 | import io.vertx.core.VertxOptions; 5 | import io.vertx.core.eventbus.EventBusOptions; 6 | import io.vertx.core.http.ClientAuth; 7 | import io.vertx.core.net.PemKeyCertOptions; 8 | import io.vertx.core.net.PemTrustOptions; 9 | import io.vertx.core.spi.cluster.ClusterManager; 10 | import io.vertx.spi.cluster.ignite.IgniteClusterManager; 11 | import io.vertx.spi.cluster.ignite.IgniteOptions; 12 | import io.vertx.spi.cluster.ignite.IgniteSslOptions; 13 | import org.apache.ignite.Ignite; 14 | import org.apache.ignite.configuration.IgniteConfiguration; 15 | 16 | /** 17 | * @author Clement Escoffier 18 | */ 19 | public class Examples { 20 | 21 | public void example1() { 22 | ClusterManager clusterManager = new IgniteClusterManager(); 23 | 24 | Vertx.builder().withClusterManager(clusterManager).buildClustered().onComplete(res -> { 25 | if (res.succeeded()) { 26 | Vertx vertx = res.result(); 27 | } else { 28 | // failed! 29 | } 30 | }); 31 | } 32 | 33 | public void example2() { 34 | IgniteConfiguration cfg = new IgniteConfiguration(); 35 | // Configuration code (omitted) 36 | 37 | ClusterManager clusterManager = new IgniteClusterManager(cfg); 38 | 39 | Vertx.builder().withClusterManager(clusterManager).buildClustered().onComplete(res -> { 40 | if (res.succeeded()) { 41 | Vertx vertx = res.result(); 42 | } else { 43 | // failed! 44 | } 45 | }); 46 | } 47 | 48 | public void example3(Ignite ignite) { 49 | // Configuration code (omitted) 50 | 51 | ClusterManager clusterManager = new IgniteClusterManager(ignite); 52 | 53 | Vertx.builder().withClusterManager(clusterManager).buildClustered().onComplete(res -> { 54 | if (res.succeeded()) { 55 | Vertx vertx = res.result(); 56 | } else { 57 | // failed! 58 | } 59 | }); 60 | } 61 | 62 | public void example4() { 63 | PemKeyCertOptions pemKeyCert = new PemKeyCertOptions() 64 | .addCertPath("cert.pem") 65 | .addKeyPath("key.pem"); 66 | PemTrustOptions pemTrust = new PemTrustOptions() 67 | .addCertPath("ca.pem"); 68 | 69 | IgniteOptions igniteOptions = new IgniteOptions() 70 | // Configuration code (omitted) 71 | .setSslContextFactory(new IgniteSslOptions() 72 | .setProtocol("TLSv1.2") 73 | .setPemKeyCertOptions(pemKeyCert) 74 | .setPemTrustOptions(pemTrust)); 75 | 76 | EventBusOptions eventBusOptions = new EventBusOptions() 77 | .setSsl(true) 78 | .setClientAuth(ClientAuth.REQUIRED) 79 | .setKeyCertOptions(pemKeyCert) 80 | .setTrustOptions(pemTrust); 81 | 82 | VertxOptions options = new VertxOptions() 83 | .setEventBusOptions(eventBusOptions); 84 | 85 | Vertx.builder() 86 | .with(options) 87 | .withClusterManager(new IgniteClusterManager(igniteOptions)) 88 | .buildClustered().onComplete(res -> { 89 | if (res.succeeded()) { 90 | Vertx vertx = res.result(); 91 | } else { 92 | // failed! 93 | } 94 | }); 95 | } 96 | } 97 | -------------------------------------------------------------------------------- /src/main/java/examples/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 The original author or authors 3 | * --------------------------------- 4 | * 5 | * All rights reserved. This program and the accompanying materials 6 | * are made available under the terms of the Eclipse Public License v1.0 7 | * and Apache License v2.0 which accompanies this distribution. 8 | * 9 | * The Eclipse Public License is available at 10 | * http://www.eclipse.org/legal/epl-v10.html 11 | * 12 | * The Apache License v2.0 is available at 13 | * http://www.opensource.org/licenses/apache2.0.php 14 | * 15 | * You may elect to redistribute this code under either of these licenses. 16 | */ 17 | 18 | @Source 19 | package examples; 20 | 21 | import io.vertx.docgen.Source; -------------------------------------------------------------------------------- /src/main/java/io/vertx/spi/cluster/ignite/IgniteClusterManager.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 The original author or authors 3 | * --------------------------------- 4 | * 5 | * All rights reserved. This program and the accompanying materials 6 | * are made available under the terms of the Eclipse Public License v1.0 7 | * and Apache License v2.0 which accompanies this distribution. 8 | * 9 | * The Eclipse Public License is available at 10 | * http://www.eclipse.org/legal/epl-v10.html 11 | * 12 | * The Apache License v2.0 is available at 13 | * http://www.opensource.org/licenses/apache2.0.php 14 | * 15 | * You may elect to redistribute this code under either of these licenses. 16 | */ 17 | 18 | package io.vertx.spi.cluster.ignite; 19 | 20 | import io.vertx.core.*; 21 | import io.vertx.core.internal.VertxInternal; 22 | import io.vertx.core.internal.logging.Logger; 23 | import io.vertx.core.internal.logging.LoggerFactory; 24 | import io.vertx.core.json.JsonObject; 25 | import io.vertx.core.shareddata.AsyncMap; 26 | import io.vertx.core.shareddata.Counter; 27 | import io.vertx.core.shareddata.Lock; 28 | import io.vertx.core.spi.cluster.*; 29 | import io.vertx.spi.cluster.ignite.impl.*; 30 | import io.vertx.spi.cluster.ignite.util.ConfigHelper; 31 | import org.apache.ignite.*; 32 | import org.apache.ignite.cluster.ClusterNode; 33 | import org.apache.ignite.configuration.IgniteConfiguration; 34 | import org.apache.ignite.events.DiscoveryEvent; 35 | import org.apache.ignite.events.Event; 36 | import org.apache.ignite.failure.StopNodeFailureHandler; 37 | import org.apache.ignite.internal.processors.cache.IgniteCacheProxy; 38 | import org.apache.ignite.lang.IgnitePredicate; 39 | import org.apache.ignite.lifecycle.LifecycleEventType; 40 | import org.apache.ignite.plugin.segmentation.SegmentationPolicy; 41 | 42 | import javax.cache.CacheException; 43 | import javax.cache.configuration.Factory; 44 | import javax.cache.expiry.*; 45 | import java.net.URL; 46 | import java.util.*; 47 | import java.util.concurrent.Executor; 48 | import java.util.concurrent.ExecutorService; 49 | import java.util.concurrent.Executors; 50 | import java.util.concurrent.TimeUnit; 51 | import java.util.concurrent.atomic.AtomicBoolean; 52 | import java.util.function.Consumer; 53 | 54 | import static java.util.concurrent.TimeUnit.MILLISECONDS; 55 | import static java.util.concurrent.TimeUnit.NANOSECONDS; 56 | import static javax.cache.expiry.Duration.ETERNAL; 57 | import static org.apache.ignite.events.EventType.*; 58 | import static org.apache.ignite.internal.IgniteComponentType.SPRING; 59 | 60 | /** 61 | * Apache Ignite based cluster manager. 62 | * 63 | * @author Andrey Gura 64 | * @author Lukas Prettenthaler 65 | */ 66 | public class IgniteClusterManager implements ClusterManager { 67 | 68 | private static final Logger log = LoggerFactory.getLogger(IgniteClusterManager.class); 69 | 70 | // Default Ignite configuration file 71 | private static final String DEFAULT_CONFIG_FILE = "default-ignite.json"; 72 | // User defined Ignite configuration file 73 | private static final String CONFIG_FILE = "ignite.json"; 74 | // Fallback XML Ignite configuration file (requires ignite-spring dependency) 75 | private static final String XML_CONFIG_FILE = "ignite.xml"; 76 | 77 | private static final String VERTX_NODE_PREFIX = "vertx.ignite.node."; 78 | 79 | private static final String LOCK_SEMAPHORE_PREFIX = "__vertx."; 80 | 81 | private static final Factory DEFAULT_EXPIRY_POLICY_FACTORY = ModifiedExpiryPolicy.factoryOf(ETERNAL); 82 | 83 | private static final int[] IGNITE_EVENTS = new int[]{EVT_NODE_JOINED, EVT_NODE_LEFT, EVT_NODE_FAILED, EVT_NODE_SEGMENTED}; 84 | 85 | private VertxInternal vertx; 86 | private RegistrationListener registrationListener; 87 | 88 | private IgniteConfiguration extCfg; 89 | private IgniteOptions extOptions; 90 | private URL extConfigUrl; 91 | 92 | private Ignite ignite; 93 | private boolean customIgnite; 94 | private boolean shutdownOnSegmentation; 95 | private boolean shutdownOnNodeStop; 96 | private long delayAfterStart; 97 | 98 | private String nodeId; 99 | private NodeInfo nodeInfo; 100 | private IgniteCache nodeInfoMap; 101 | private SubsMapHelper subsMapHelper; 102 | private IgnitePredicate eventListener; 103 | 104 | private volatile boolean active; 105 | private volatile NodeListener nodeListener; 106 | 107 | private final Object monitor = new Object(); 108 | 109 | private ExecutorService lockReleaseExec; 110 | 111 | /** 112 | * Default constructor. Cluster manager will get configuration from classpath. 113 | */ 114 | @SuppressWarnings("unused") 115 | public IgniteClusterManager() { 116 | setIgniteProperties(); 117 | } 118 | 119 | /** 120 | * Creates cluster manager instance with given Ignite configuration. 121 | * Use this constructor in order to configure cluster manager programmatically. 122 | * 123 | * @param extCfg {@code IgniteConfiguration} instance. 124 | */ 125 | @SuppressWarnings("unused") 126 | public IgniteClusterManager(IgniteConfiguration extCfg) { 127 | setIgniteProperties(); 128 | this.extCfg = extCfg; 129 | } 130 | 131 | /** 132 | * Creates cluster manager instance with given Spring XML configuration file. 133 | * Use this constructor in order to configure cluster manager programmatically. 134 | * 135 | * @param configFile {@code URL} path to Spring XML configuration file. 136 | */ 137 | @SuppressWarnings("unused") 138 | public IgniteClusterManager(URL configFile) { 139 | setIgniteProperties(); 140 | this.extConfigUrl = configFile; 141 | } 142 | 143 | /** 144 | * Creates cluster manager instance with given JSON configuration. 145 | * Use this constructor in order to configure cluster manager programmatically. 146 | * 147 | * @param jsonConfig {@code JsonObject} JSON configuration. 148 | */ 149 | @SuppressWarnings("unused") 150 | public IgniteClusterManager(JsonObject jsonConfig) { 151 | this(new IgniteOptions(jsonConfig)); 152 | } 153 | 154 | /** 155 | * Creates cluster manager instance with given IgniteOptions. 156 | * Use this constructor in order to configure cluster manager programmatically. 157 | * 158 | * @param extOptions {@code IgniteOptions} options object. 159 | */ 160 | @SuppressWarnings("unused") 161 | public IgniteClusterManager(IgniteOptions extOptions) { 162 | setIgniteProperties(); 163 | this.extOptions = extOptions; 164 | } 165 | 166 | /** 167 | * Creates cluster manager instance with given {@code Ignite} instance. 168 | * 169 | * @param ignite {@code Ignite} instance. 170 | */ 171 | public IgniteClusterManager(Ignite ignite) { 172 | Objects.requireNonNull(ignite, "Ignite instance can't be null."); 173 | this.ignite = ignite; 174 | this.customIgnite = true; 175 | } 176 | 177 | /** 178 | * Returns instance of {@code Ignite}. 179 | * 180 | * @return {@code Ignite} instance. 181 | */ 182 | public Ignite getIgniteInstance() { 183 | return ignite; 184 | } 185 | 186 | @Override 187 | public void init(Vertx vertx) { 188 | this.vertx = (VertxInternal) vertx; 189 | } 190 | 191 | @Override 192 | public void registrationListener(RegistrationListener registrationListener) { 193 | this.registrationListener = registrationListener; 194 | } 195 | 196 | @Override 197 | public void nodeListener(NodeListener nodeListener) { 198 | this.nodeListener = nodeListener; 199 | } 200 | 201 | @Override 202 | public void getAsyncMap(String name, Completable> promise) { 203 | vertx.>executeBlocking(() -> new AsyncMapImpl<>(getCache(name), vertx)).onComplete(promise); 204 | } 205 | 206 | @Override 207 | public Map getSyncMap(String name) { 208 | return new MapImpl<>(getCache(name)); 209 | } 210 | 211 | @Override 212 | public void getLockWithTimeout(String name, long timeout, Completable promise) { 213 | vertx.executeBlocking(() -> { 214 | IgniteSemaphore semaphore = ignite.semaphore(LOCK_SEMAPHORE_PREFIX + name, 1, true, true); 215 | boolean locked; 216 | long remaining = timeout; 217 | do { 218 | long start = System.nanoTime(); 219 | locked = semaphore.tryAcquire(remaining, TimeUnit.MILLISECONDS); 220 | remaining = remaining - TimeUnit.MILLISECONDS.convert(System.nanoTime() - start, NANOSECONDS); 221 | } while (!locked && remaining > 0); 222 | if (locked) { 223 | return new LockImpl(semaphore, lockReleaseExec); 224 | } else { 225 | throw new VertxException("Timed out waiting to get lock " + name, true); 226 | } 227 | }, false).onComplete(promise); 228 | } 229 | 230 | @Override 231 | public void getCounter(String name, Completable promise) { 232 | vertx.executeBlocking(() -> new CounterImpl(ignite.atomicLong(name, 0, true))).onComplete(promise); 233 | } 234 | 235 | @Override 236 | public String getNodeId() { 237 | return nodeId; 238 | } 239 | 240 | @Override 241 | public void setNodeInfo(NodeInfo nodeInfo, Completable promise) { 242 | synchronized (this) { 243 | this.nodeInfo = nodeInfo; 244 | } 245 | IgniteNodeInfo value = new IgniteNodeInfo(nodeInfo); 246 | vertx.executeBlocking(() -> { 247 | nodeInfoMap.put(nodeId, value); 248 | return null; 249 | }, false).onComplete(promise); 250 | } 251 | 252 | @Override 253 | public synchronized NodeInfo getNodeInfo() { 254 | return nodeInfo; 255 | } 256 | 257 | @Override 258 | public void getNodeInfo(String id, Completable promise) { 259 | nodeInfoMap.getAsync(id).listen(fut -> { 260 | try { 261 | IgniteNodeInfo value = fut.get(); 262 | if (value != null) { 263 | promise.succeed(value.unwrap()); 264 | } else { 265 | promise.fail("Not a member of the cluster"); 266 | } 267 | } catch (IgniteException e) { 268 | promise.fail(e); 269 | } 270 | }); 271 | } 272 | 273 | @Override 274 | public List getNodes() { 275 | try { 276 | Collection nodes = ignite.cluster().nodes(); 277 | List nodeIds = new ArrayList<>(nodes.size()); 278 | for (ClusterNode node : nodes) { 279 | nodeIds.add(nodeId(node)); 280 | } 281 | return nodeIds; 282 | } catch (IllegalStateException e) { 283 | log.debug(e.getMessage()); 284 | return Collections.emptyList(); 285 | } 286 | } 287 | 288 | @Override 289 | public void join(Completable promise) { 290 | vertx.executeBlocking(() -> { 291 | synchronized (monitor) { 292 | if (!active) { 293 | active = true; 294 | 295 | lockReleaseExec = Executors.newCachedThreadPool(r -> new Thread(r, "vertx-ignite-service-release-lock-thread")); 296 | 297 | if (!customIgnite) { 298 | IgniteConfiguration cfg = prepareConfig(); 299 | cfg.setLifecycleBeans(e -> { 300 | if (e == LifecycleEventType.AFTER_NODE_STOP && shutdownOnNodeStop && active) { 301 | vertx.close(); 302 | } 303 | }); 304 | ignite = Ignition.start(cfg); 305 | } 306 | nodeId = nodeId(ignite.cluster().localNode()); 307 | 308 | eventListener = event -> { 309 | if (!isActive()) { 310 | return false; 311 | } 312 | 313 | vertx.executeBlocking(() -> { 314 | String id = nodeId(((DiscoveryEvent) event).eventNode()); 315 | switch (event.type()) { 316 | case EVT_NODE_JOINED: 317 | notifyNodeListener(listener -> listener.nodeAdded(id)); 318 | log.debug("node " + id + " joined the cluster"); 319 | return null; 320 | case EVT_NODE_LEFT: 321 | case EVT_NODE_FAILED: 322 | if (cleanNodeInfos(id)) { 323 | cleanSubs(id); 324 | } 325 | notifyNodeListener(listener -> listener.nodeLeft(id)); 326 | log.debug("node " + id + " left the cluster"); 327 | return null; 328 | case EVT_NODE_SEGMENTED: 329 | if (customIgnite || !shutdownOnSegmentation) { 330 | log.warn("node got segmented"); 331 | } else { 332 | log.warn("node got segmented and will be shut down"); 333 | vertx.close(); 334 | } 335 | throw new IllegalStateException("node is stopped"); 336 | default: 337 | throw new IllegalStateException("event not known"); 338 | } 339 | }); 340 | 341 | return true; 342 | }; 343 | 344 | ignite.events().localListen(eventListener, IGNITE_EVENTS); 345 | subsMapHelper = new SubsMapHelper(ignite, registrationListener, vertx); 346 | nodeInfoMap = ignite.getOrCreateCache("__vertx.nodeInfo"); 347 | 348 | MILLISECONDS.sleep(delayAfterStart); 349 | } 350 | return null; 351 | } 352 | }).onComplete(promise); 353 | } 354 | 355 | @Override 356 | public void leave(Completable promise) { 357 | vertx.executeBlocking(() -> { 358 | synchronized (monitor) { 359 | if (active) { 360 | active = false; 361 | lockReleaseExec.shutdown(); 362 | try { 363 | if (eventListener != null) { 364 | ignite.events().stopLocalListen(eventListener, IGNITE_EVENTS); 365 | } 366 | subsMapHelper.leave(); 367 | if (!customIgnite) { 368 | ignite.close(); 369 | } 370 | } catch (Exception e) { 371 | log.error(e); 372 | } 373 | subsMapHelper = null; 374 | nodeInfoMap = null; 375 | } 376 | } 377 | 378 | return null; 379 | }).onComplete(promise); 380 | } 381 | 382 | @Override 383 | public boolean isActive() { 384 | return active; 385 | } 386 | 387 | @Override 388 | public void addRegistration(String address, RegistrationInfo registrationInfo, Completable promise) { 389 | vertx.executeBlocking(() -> subsMapHelper.put(address, registrationInfo), false).onComplete(promise); 390 | } 391 | 392 | @Override 393 | public void removeRegistration(String address, RegistrationInfo registrationInfo, Completable promise) { 394 | vertx.executeBlocking(() -> subsMapHelper.remove(address, registrationInfo), false).onComplete(promise); 395 | } 396 | 397 | @Override 398 | public void getRegistrations(String address, Completable> promise) { 399 | vertx.executeBlocking(() -> subsMapHelper.get(address), false).onComplete(promise); 400 | } 401 | 402 | private void cleanSubs(String id) { 403 | subsMapHelper.removeAllForNode(id); 404 | } 405 | 406 | private boolean cleanNodeInfos(String nid) { 407 | try { 408 | return nodeInfoMap.remove(nid); 409 | } catch (IllegalStateException | CacheException e) { 410 | log.warn("Could not remove nodeInfo (" + nid + "): " + e.getMessage()); 411 | } 412 | return false; 413 | } 414 | 415 | private IgniteConfiguration prepareConfig() { 416 | IgniteConfiguration cfg = null; 417 | if (extCfg != null) { 418 | cfg = extCfg; 419 | } else { 420 | if (SPRING.inClassPath()) { 421 | try { 422 | cfg = ConfigHelper.lookupXmlConfiguration(this.getClass(), XML_CONFIG_FILE); 423 | } catch (VertxException e) { 424 | log.debug("xml config could not be loaded"); 425 | } 426 | } 427 | } 428 | if (extConfigUrl != null) { 429 | cfg = ConfigHelper.loadConfiguration(extConfigUrl); 430 | } 431 | if (cfg == null) { 432 | IgniteOptions options; 433 | if (extOptions == null) { 434 | options = new IgniteOptions(ConfigHelper.lookupJsonConfiguration(this.getClass(), CONFIG_FILE, DEFAULT_CONFIG_FILE)); 435 | } else { 436 | options = extOptions; 437 | } 438 | shutdownOnSegmentation = options.isShutdownOnSegmentation(); 439 | shutdownOnNodeStop = options.isShutdownOnNodeStop(); 440 | delayAfterStart = options.getDelayAfterStart(); 441 | cfg = ConfigHelper.toIgniteConfig(vertx, options) 442 | .setGridLogger(new VertxLogger()); 443 | } 444 | 445 | UUID uuid = UUID.randomUUID(); 446 | cfg.setNodeId(uuid); 447 | cfg.setIgniteInstanceName(VERTX_NODE_PREFIX + uuid); 448 | cfg.setSegmentationPolicy(SegmentationPolicy.NOOP); 449 | cfg.setFailureHandler(new StopNodeFailureHandler()); 450 | cfg.setAsyncContinuationExecutor(Runnable::run); 451 | return cfg; 452 | } 453 | 454 | private IgniteCache getCache(String name) { 455 | IgniteCache cache = ignite.getOrCreateCache(name); 456 | if (((IgniteCacheProxy) cache).context().expiry() == null) { 457 | return cache.withExpiryPolicy(DEFAULT_EXPIRY_POLICY_FACTORY.create()); 458 | } 459 | return cache; 460 | } 461 | 462 | private void notifyNodeListener(final Consumer notify) { 463 | if (null == notify) return; 464 | 465 | final NodeListener listener = nodeListener; 466 | if (null == listener) return; 467 | 468 | try { 469 | notify.accept(listener); 470 | } catch (final RuntimeException ignore) { 471 | // exception barrier 472 | } 473 | } 474 | 475 | private static String nodeId(ClusterNode node) { 476 | return node.id().toString(); 477 | } 478 | 479 | private static void setIgniteProperties() { 480 | System.setProperty("IGNITE_NO_SHUTDOWN_HOOK", "true"); 481 | System.setProperty("IGNITE_UPDATE_NOTIFIER", "false"); 482 | } 483 | 484 | private static class LockImpl implements Lock { 485 | private final IgniteSemaphore semaphore; 486 | private final Executor lockReleaseExec; 487 | private final AtomicBoolean released = new AtomicBoolean(); 488 | 489 | private LockImpl(IgniteSemaphore semaphore, Executor lockReleaseExec) { 490 | this.semaphore = semaphore; 491 | this.lockReleaseExec = lockReleaseExec; 492 | } 493 | 494 | @Override 495 | public void release() { 496 | if (released.compareAndSet(false, true)) { 497 | lockReleaseExec.execute(semaphore::release); 498 | } 499 | } 500 | } 501 | 502 | private class CounterImpl implements Counter { 503 | private final IgniteAtomicLong cnt; 504 | 505 | private CounterImpl(IgniteAtomicLong cnt) { 506 | this.cnt = cnt; 507 | } 508 | 509 | @Override 510 | public Future get() { 511 | return vertx.executeBlocking(cnt::get); 512 | } 513 | 514 | @Override 515 | public Future incrementAndGet() { 516 | return vertx.executeBlocking(cnt::incrementAndGet); 517 | } 518 | 519 | @Override 520 | public Future getAndIncrement() { 521 | return vertx.executeBlocking(cnt::getAndIncrement); 522 | } 523 | 524 | @Override 525 | public Future decrementAndGet() { 526 | return vertx.executeBlocking(cnt::decrementAndGet); 527 | } 528 | 529 | @Override 530 | public Future addAndGet(long value) { 531 | return vertx.executeBlocking(() -> cnt.addAndGet(value)); 532 | } 533 | 534 | @Override 535 | public Future getAndAdd(long value) { 536 | return vertx.executeBlocking(() -> cnt.getAndAdd(value)); 537 | } 538 | 539 | @Override 540 | public Future compareAndSet(long expected, long value) { 541 | return vertx.executeBlocking(() -> cnt.compareAndSet(expected, value)); 542 | } 543 | } 544 | } 545 | -------------------------------------------------------------------------------- /src/main/java/io/vertx/spi/cluster/ignite/IgniteDiscoveryOptions.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Red Hat, Inc. 3 | * 4 | * Red Hat licenses this file to you under the Apache License, version 2.0 5 | * (the "License"); you may not use this file except in compliance with the 6 | * License. You may obtain a copy of the License at: 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | package io.vertx.spi.cluster.ignite; 17 | 18 | import io.vertx.codegen.annotations.DataObject; 19 | import io.vertx.codegen.annotations.GenIgnore; 20 | import io.vertx.codegen.json.annotations.JsonGen; 21 | import io.vertx.core.json.JsonObject; 22 | import org.apache.ignite.spi.discovery.DiscoverySpi; 23 | 24 | /** 25 | * @author Lukas Prettenthaler 26 | */ 27 | @DataObject 28 | @JsonGen(publicConverter = false) 29 | public class IgniteDiscoveryOptions { 30 | private String type; 31 | private JsonObject properties; 32 | private DiscoverySpi customSpi; 33 | 34 | /** 35 | * Default constructor 36 | */ 37 | public IgniteDiscoveryOptions() { 38 | type = "TcpDiscoveryMulticastIpFinder"; 39 | properties = new JsonObject(); 40 | } 41 | 42 | /** 43 | * Copy constructor 44 | * 45 | * @param options the one to copy 46 | */ 47 | public IgniteDiscoveryOptions(IgniteDiscoveryOptions options) { 48 | this.type = options.type; 49 | } 50 | 51 | /** 52 | * Constructor from JSON 53 | * 54 | * @param options the JSON 55 | */ 56 | public IgniteDiscoveryOptions(JsonObject options) { 57 | this(); 58 | IgniteDiscoveryOptionsConverter.fromJson(options, this); 59 | } 60 | 61 | /** 62 | * Get the discovery implementation type. 63 | * 64 | * @return Type of the implementation. 65 | */ 66 | public String getType() { 67 | return type; 68 | } 69 | 70 | /** 71 | * Sets the discovery implementation type. 72 | * Defaults to TcpDiscoveryMulticastIpFinder 73 | * 74 | * @param type Implemenation type. 75 | * @return reference to this, for fluency 76 | */ 77 | public IgniteDiscoveryOptions setType(String type) { 78 | this.type = type; 79 | return this; 80 | } 81 | 82 | /** 83 | * Get the discovery implementation properties. 84 | * 85 | * @return Properties of the discovery implementation. 86 | */ 87 | public JsonObject getProperties() { 88 | return properties; 89 | } 90 | 91 | /** 92 | * Sets the properties used to configure the discovery implementation. 93 | * 94 | * @param properties Properties for the discovery implementation. 95 | * @return reference to this, for fluency 96 | */ 97 | public IgniteDiscoveryOptions setProperties(JsonObject properties) { 98 | this.properties = properties; 99 | return this; 100 | } 101 | 102 | /** 103 | * Get the custom DiscoverySpi instance. 104 | * 105 | * @return DiscoverySpi. 106 | */ 107 | @GenIgnore 108 | public DiscoverySpi getCustomSpi() { 109 | return customSpi; 110 | } 111 | 112 | /** 113 | * Sets a custom initialized DiscoverySpi. When a custom Spi is set all other properties are ignored. 114 | * 115 | * @param discoverySpi DiscoverySpi implementation. 116 | * @return reference to this, for fluency 117 | */ 118 | @GenIgnore 119 | public IgniteDiscoveryOptions setCustomSpi(DiscoverySpi discoverySpi) { 120 | this.customSpi = discoverySpi; 121 | return this; 122 | } 123 | 124 | /** 125 | * Convert to JSON 126 | * 127 | * @return the JSON 128 | */ 129 | public JsonObject toJson() { 130 | JsonObject json = new JsonObject(); 131 | IgniteDiscoveryOptionsConverter.toJson(this, json); 132 | return json; 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /src/main/java/io/vertx/spi/cluster/ignite/IgniteMetricExporterOptions.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Red Hat, Inc. 3 | * 4 | * Red Hat licenses this file to you under the Apache License, version 2.0 5 | * (the "License"); you may not use this file except in compliance with the 6 | * License. You may obtain a copy of the License at: 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | package io.vertx.spi.cluster.ignite; 17 | 18 | import io.vertx.codegen.annotations.DataObject; 19 | import io.vertx.codegen.annotations.GenIgnore; 20 | import io.vertx.codegen.json.annotations.JsonGen; 21 | import io.vertx.core.json.JsonObject; 22 | import org.apache.ignite.spi.metric.MetricExporterSpi; 23 | 24 | /** 25 | * @author Markus Spika 26 | */ 27 | @DataObject 28 | @JsonGen(publicConverter = false) 29 | public class IgniteMetricExporterOptions { 30 | 31 | private MetricExporterSpi customSpi; 32 | 33 | /** 34 | * Default Constructor 35 | */ 36 | public IgniteMetricExporterOptions() { 37 | } 38 | 39 | /** 40 | * Copy Constructor 41 | */ 42 | public IgniteMetricExporterOptions(final IgniteMetricExporterOptions options) { 43 | this.customSpi = options.customSpi; 44 | } 45 | 46 | /** 47 | * Constructor from JSON 48 | * 49 | * @param options the JSON 50 | */ 51 | public IgniteMetricExporterOptions(JsonObject options) { 52 | this(); 53 | IgniteMetricExporterOptionsConverter.fromJson(options, this); 54 | } 55 | 56 | @GenIgnore 57 | public MetricExporterSpi getCustomSpi() { 58 | return customSpi; 59 | } 60 | 61 | /** 62 | * Sets a custom MetricExporterSpi implementation. 63 | * 64 | * @param metricExporterSpi to set. 65 | * @return reference to this, for fluency 66 | */ 67 | @GenIgnore 68 | public IgniteMetricExporterOptions setCustomSpi(MetricExporterSpi metricExporterSpi) { 69 | this.customSpi = metricExporterSpi; 70 | return this; 71 | } 72 | 73 | /** 74 | * Convert to JSON 75 | * 76 | * @return the JSON 77 | */ 78 | public JsonObject toJson() { 79 | JsonObject json = new JsonObject(); 80 | IgniteMetricExporterOptionsConverter.toJson(this, json); 81 | return json; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/main/java/io/vertx/spi/cluster/ignite/IgniteOptions.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Red Hat, Inc. 3 | * 4 | * Red Hat licenses this file to you under the Apache License, version 2.0 5 | * (the "License"); you may not use this file except in compliance with the 6 | * License. You may obtain a copy of the License at: 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | package io.vertx.spi.cluster.ignite; 17 | 18 | import io.vertx.codegen.annotations.DataObject; 19 | import io.vertx.codegen.json.annotations.JsonGen; 20 | import io.vertx.core.json.JsonObject; 21 | 22 | import java.util.ArrayList; 23 | import java.util.List; 24 | 25 | import static org.apache.ignite.configuration.DataStorageConfiguration.*; 26 | import static org.apache.ignite.configuration.IgniteConfiguration.*; 27 | import static org.apache.ignite.spi.communication.tcp.TcpCommunicationSpi.*; 28 | 29 | /** 30 | * @author Lukas Prettenthaler 31 | */ 32 | @DataObject 33 | @JsonGen(publicConverter = false) 34 | public class IgniteOptions { 35 | private String localHost; 36 | private int localPort; 37 | private int connectionsPerNode; 38 | private long connectTimeout; 39 | private long idleConnectionTimeout; 40 | private long maxConnectTimeout; 41 | private int reconnectCount; 42 | private long metricsLogFrequency; 43 | private IgniteDiscoveryOptions discoveryOptions; 44 | private List cacheConfiguration; 45 | private IgniteSslOptions sslOptions; 46 | private boolean shutdownOnSegmentation; 47 | private int pageSize; 48 | private long defaultRegionInitialSize; 49 | private long defaultRegionMaxSize; 50 | private boolean defaultRegionMetricsEnabled; 51 | private boolean shutdownOnNodeStop; 52 | private long metricsUpdateFrequency; 53 | private long clientFailureDetectionTimeout; 54 | private int metricsHistorySize; 55 | private long metricsExpireTime; 56 | private IgniteMetricExporterOptions metricExporterOptions; 57 | private long delayAfterStart; 58 | 59 | /** 60 | * Default constructor 61 | */ 62 | public IgniteOptions() { 63 | localPort = DFLT_PORT; 64 | connectionsPerNode = DFLT_CONN_PER_NODE; 65 | connectTimeout = DFLT_CONN_TIMEOUT; 66 | idleConnectionTimeout = DFLT_IDLE_CONN_TIMEOUT; 67 | reconnectCount = DFLT_RECONNECT_CNT; 68 | maxConnectTimeout = DFLT_MAX_CONN_TIMEOUT; 69 | metricsLogFrequency = DFLT_METRICS_LOG_FREQ; 70 | discoveryOptions = new IgniteDiscoveryOptions(); 71 | cacheConfiguration = new ArrayList<>(); 72 | shutdownOnSegmentation = true; 73 | pageSize = DFLT_PAGE_SIZE; 74 | defaultRegionInitialSize = DFLT_DATA_REGION_INITIAL_SIZE; 75 | defaultRegionMaxSize = DFLT_DATA_REGION_MAX_SIZE; 76 | defaultRegionMetricsEnabled = DFLT_METRICS_ENABLED; 77 | shutdownOnNodeStop = false; 78 | metricsUpdateFrequency = DFLT_METRICS_UPDATE_FREQ; 79 | clientFailureDetectionTimeout = DFLT_CLIENT_FAILURE_DETECTION_TIMEOUT; 80 | metricsHistorySize = DFLT_METRICS_HISTORY_SIZE; 81 | metricsExpireTime = DFLT_METRICS_EXPIRE_TIME; 82 | metricExporterOptions = new IgniteMetricExporterOptions(); 83 | delayAfterStart = 100L; 84 | } 85 | 86 | /** 87 | * Copy constructor 88 | * 89 | * @param options the one to copy 90 | */ 91 | public IgniteOptions(IgniteOptions options) { 92 | this.localHost = options.localHost; 93 | this.localPort = options.localPort; 94 | this.connectionsPerNode = options.connectionsPerNode; 95 | this.connectTimeout = options.connectTimeout; 96 | this.idleConnectionTimeout = options.idleConnectionTimeout; 97 | this.reconnectCount = options.reconnectCount; 98 | this.maxConnectTimeout = options.maxConnectTimeout; 99 | this.metricsLogFrequency = options.metricsLogFrequency; 100 | this.discoveryOptions = options.discoveryOptions; 101 | this.cacheConfiguration = options.cacheConfiguration; 102 | this.sslOptions = options.sslOptions; 103 | this.shutdownOnSegmentation = options.shutdownOnSegmentation; 104 | this.pageSize = options.pageSize; 105 | this.defaultRegionInitialSize = options.defaultRegionInitialSize; 106 | this.defaultRegionMaxSize = options.defaultRegionMaxSize; 107 | this.defaultRegionMetricsEnabled = options.defaultRegionMetricsEnabled; 108 | this.shutdownOnNodeStop = options.shutdownOnNodeStop; 109 | this.metricsUpdateFrequency = options.metricsUpdateFrequency; 110 | this.clientFailureDetectionTimeout = options.clientFailureDetectionTimeout; 111 | this.metricsHistorySize = options.metricsHistorySize; 112 | this.metricsExpireTime = options.metricsExpireTime; 113 | this.metricExporterOptions = options.metricExporterOptions; 114 | this.delayAfterStart = options.delayAfterStart; 115 | } 116 | 117 | /** 118 | * Constructor from JSON 119 | * 120 | * @param options the JSON 121 | */ 122 | public IgniteOptions(JsonObject options) { 123 | this(); 124 | IgniteOptionsConverter.fromJson(options, this); 125 | } 126 | 127 | /** 128 | * Gets system-wide local address or host for all Ignite components to bind to. If provided it will 129 | * override all default local bind settings within Ignite or any of its SPIs. 130 | * 131 | * @return Local address or host to bind to. 132 | */ 133 | public String getLocalHost() { 134 | return localHost; 135 | } 136 | 137 | /** 138 | * Sets system-wide local address or host for all Ignite components to bind to. If provided it will 139 | * override all default local bind settings within Ignite or any of its SPIs. 140 | * 141 | * @param localHost Local IP address or host to bind to. 142 | * @return reference to this, for fluency 143 | */ 144 | public IgniteOptions setLocalHost(String localHost) { 145 | this.localHost = localHost; 146 | return this; 147 | } 148 | 149 | /** 150 | * See {@link #setLocalPort(int)}. 151 | * 152 | * @return Port number. 153 | */ 154 | public int getLocalPort() { 155 | return localPort; 156 | } 157 | 158 | /** 159 | * Sets local port for socket binding. 160 | * 161 | * @param localPort Port number. 162 | * @return reference to this, for fluency 163 | */ 164 | public IgniteOptions setLocalPort(int localPort) { 165 | this.localPort = localPort; 166 | return this; 167 | } 168 | 169 | /** 170 | * See {@link #setConnectionsPerNode(int)}. 171 | * 172 | * @return Number of connections per node. 173 | */ 174 | public int getConnectionsPerNode() { 175 | return connectionsPerNode; 176 | } 177 | 178 | /** 179 | * Sets number of connections to each remote node. 180 | * 181 | * @param connectionsPerNode Number of connections per node. 182 | * @return reference to this, for fluency 183 | */ 184 | public IgniteOptions setConnectionsPerNode(int connectionsPerNode) { 185 | this.connectionsPerNode = connectionsPerNode; 186 | return this; 187 | } 188 | 189 | /** 190 | * See {@link #setConnectTimeout(long)}. 191 | * 192 | * @return Connect timeout. 193 | */ 194 | public long getConnectTimeout() { 195 | return connectTimeout; 196 | } 197 | 198 | /** 199 | * Sets connect timeout used when establishing connection 200 | * with remote nodes. 201 | * 202 | * @param connectTimeout Connect timeout. 203 | * @return reference to this, for fluency 204 | */ 205 | public IgniteOptions setConnectTimeout(long connectTimeout) { 206 | this.connectTimeout = connectTimeout; 207 | return this; 208 | } 209 | 210 | /** 211 | * See {@link #setIdleConnectionTimeout(long)}. 212 | * 213 | * @return Maximum idle connection time. 214 | */ 215 | public long getIdleConnectionTimeout() { 216 | return idleConnectionTimeout; 217 | } 218 | 219 | /** 220 | * Sets maximum idle connection timeout upon which a connection 221 | * to client will be closed. 222 | * 223 | * @param idleConnectionTimeout Maximum idle connection time. 224 | * @return reference to this, for fluency 225 | */ 226 | public IgniteOptions setIdleConnectionTimeout(long idleConnectionTimeout) { 227 | this.idleConnectionTimeout = idleConnectionTimeout; 228 | return this; 229 | } 230 | 231 | /** 232 | * See {@link #setConnectTimeout(long)}. 233 | * 234 | * @return Connect timeout. 235 | */ 236 | public long getMaxConnectTimeout() { 237 | return maxConnectTimeout; 238 | } 239 | 240 | /** 241 | * Sets maximum connect timeout. If handshake is not established within connect timeout, 242 | * then SPI tries to repeat handshake procedure with increased connect timeout. 243 | * Connect timeout can grow till maximum timeout value, 244 | * if maximum timeout value is reached then the handshake is considered as failed. 245 | * 246 | * @param maxConnectTimeout Maximum connect timeout. 247 | * @return reference to this, for fluency 248 | */ 249 | public IgniteOptions setMaxConnectTimeout(long maxConnectTimeout) { 250 | this.maxConnectTimeout = maxConnectTimeout; 251 | return this; 252 | } 253 | 254 | /** 255 | * Gets maximum number of reconnect attempts used when establishing connection 256 | * with remote nodes. 257 | * 258 | * @return Reconnects count. 259 | */ 260 | public int getReconnectCount() { 261 | return reconnectCount; 262 | } 263 | 264 | /** 265 | * Sets maximum number of reconnect attempts used when establishing connection 266 | * with remote nodes. 267 | * 268 | * @param reconnectCount Maximum number of reconnection attempts. 269 | * @return reference to this, for fluency 270 | */ 271 | public IgniteOptions setReconnectCount(int reconnectCount) { 272 | this.reconnectCount = reconnectCount; 273 | return this; 274 | } 275 | 276 | /** 277 | * Gets frequency of metrics log print out. 278 | * 279 | * @return Frequency of metrics log print out. 280 | */ 281 | public long getMetricsLogFrequency() { 282 | return metricsLogFrequency; 283 | } 284 | 285 | /** 286 | * Sets frequency of metrics log print out. 287 | * 288 | * @param metricsLogFrequency Frequency of metrics log print out. 289 | * @return reference to this, for fluency 290 | */ 291 | public IgniteOptions setMetricsLogFrequency(long metricsLogFrequency) { 292 | this.metricsLogFrequency = metricsLogFrequency; 293 | return this; 294 | } 295 | 296 | /** 297 | * Should return fully configured discovery options. If not provided, 298 | * TcpDiscovery will be used by default. 299 | * 300 | * @return Grid discovery options {@link IgniteDiscoveryOptions}. 301 | */ 302 | public IgniteDiscoveryOptions getDiscoverySpi() { 303 | return discoveryOptions; 304 | } 305 | 306 | /** 307 | * Sets fully configured instance of {@link IgniteDiscoveryOptions}. 308 | * 309 | * @param discoveryOptions {@link IgniteDiscoveryOptions}. 310 | * @return reference to this, for fluency 311 | */ 312 | public IgniteOptions setDiscoverySpi(IgniteDiscoveryOptions discoveryOptions) { 313 | this.discoveryOptions = discoveryOptions; 314 | return this; 315 | } 316 | 317 | /** 318 | * Gets configuration (descriptors) for all caches. 319 | * 320 | * @return List of cache configurations. 321 | */ 322 | public List getCacheConfiguration() { 323 | return cacheConfiguration; 324 | } 325 | 326 | /** 327 | * Sets cache configurations. 328 | * 329 | * @param cacheConfiguration Cache configurations. 330 | * @return reference to this, for fluency 331 | */ 332 | public IgniteOptions setCacheConfiguration(List cacheConfiguration) { 333 | this.cacheConfiguration = cacheConfiguration; 334 | return this; 335 | } 336 | 337 | public IgniteSslOptions getSslContextFactory() { 338 | return sslOptions; 339 | } 340 | 341 | /** 342 | * Sets SSL options that will be used for creating a secure socket layer. 343 | * 344 | * @param sslOptions Ssl options. 345 | * @return reference to this, for fluency 346 | */ 347 | public IgniteOptions setSslContextFactory(IgniteSslOptions sslOptions) { 348 | this.sslOptions = sslOptions; 349 | return this; 350 | } 351 | 352 | public boolean isShutdownOnSegmentation() { 353 | return shutdownOnSegmentation; 354 | } 355 | 356 | /** 357 | * Sets that vertx will be shutdown when the cache goes into segmented state. 358 | * Defaults to true 359 | * 360 | * @param shutdownOnSegmentation boolean flag. 361 | * @return reference to this, for fluency 362 | */ 363 | public IgniteOptions setShutdownOnSegmentation(boolean shutdownOnSegmentation) { 364 | this.shutdownOnSegmentation = shutdownOnSegmentation; 365 | return this; 366 | } 367 | 368 | public int getPageSize() { 369 | return pageSize; 370 | } 371 | 372 | /** 373 | * Sets page size for all data regions. 374 | * Defaults to 4096 bytes 375 | * 376 | * @param pageSize size in bytes. 377 | * @return reference to this, for fluency 378 | */ 379 | public IgniteOptions setPageSize(int pageSize) { 380 | this.pageSize = pageSize; 381 | return this; 382 | } 383 | 384 | /** 385 | * Get default data region start size. 386 | * Default to 256 MB 387 | * 388 | * @return size in bytes. 389 | */ 390 | public long getDefaultRegionInitialSize() { 391 | return defaultRegionInitialSize; 392 | } 393 | 394 | /** 395 | * Sets default data region start size. 396 | * 397 | * @param defaultRegionInitialSize size in bytes. 398 | * @return reference to this, for fluency 399 | */ 400 | public IgniteOptions setDefaultRegionInitialSize(long defaultRegionInitialSize) { 401 | this.defaultRegionInitialSize = defaultRegionInitialSize; 402 | return this; 403 | } 404 | 405 | /** 406 | * Get default data region maximum size. 407 | * Default to 20% of physical memory available 408 | * 409 | * @return size in bytes. 410 | */ 411 | public long getDefaultRegionMaxSize() { 412 | return defaultRegionMaxSize; 413 | } 414 | 415 | /** 416 | * Sets default data region maximum size. 417 | * 418 | * @param defaultRegionMaxSize size in bytes. 419 | * @return reference to this, for fluency 420 | */ 421 | public IgniteOptions setDefaultRegionMaxSize(long defaultRegionMaxSize) { 422 | this.defaultRegionMaxSize = defaultRegionMaxSize; 423 | return this; 424 | } 425 | 426 | public boolean isDefaultRegionMetricsEnabled() { 427 | return defaultRegionMetricsEnabled; 428 | } 429 | 430 | /** 431 | * Sets default data region metrics enabled/disabled. 432 | * Defaults to false 433 | * 434 | * @param defaultRegionMetricsEnabled to set. 435 | * @return reference to this, for fluency 436 | */ 437 | public IgniteOptions setDefaultRegionMetricsEnabled(boolean defaultRegionMetricsEnabled) { 438 | this.defaultRegionMetricsEnabled = defaultRegionMetricsEnabled; 439 | return this; 440 | } 441 | 442 | public boolean isShutdownOnNodeStop() { 443 | return shutdownOnNodeStop; 444 | } 445 | 446 | /** 447 | * Sets that vertx will be shutdown when the node stops. 448 | * Defaults to false 449 | * 450 | * @param shutdownOnNodeStop to set. 451 | * @return reference to this, for fluency 452 | */ 453 | public IgniteOptions setShutdownOnNodeStop(boolean shutdownOnNodeStop) { 454 | this.shutdownOnNodeStop = shutdownOnNodeStop; 455 | return this; 456 | } 457 | 458 | public long getMetricsUpdateFrequency() { 459 | return metricsUpdateFrequency; 460 | } 461 | 462 | /** 463 | * Sets update frequency of metrics. 464 | * Defaults to 2 seconds 465 | * 466 | * @param metricsUpdateFrequency in milliseconds. 467 | * @return reference to this, for fluency 468 | */ 469 | public IgniteOptions setMetricsUpdateFrequency(long metricsUpdateFrequency) { 470 | this.metricsUpdateFrequency = metricsUpdateFrequency; 471 | return this; 472 | } 473 | 474 | public long getClientFailureDetectionTimeout() { 475 | return clientFailureDetectionTimeout; 476 | } 477 | 478 | /** 479 | * Sets client failure detection timeout. 480 | * Defaults to 30 seconds 481 | * 482 | * @param clientFailureDetectionTimeout in milliseconds. 483 | * @return reference to this, for fluency 484 | */ 485 | public IgniteOptions setClientFailureDetectionTimeout(long clientFailureDetectionTimeout) { 486 | this.clientFailureDetectionTimeout = clientFailureDetectionTimeout; 487 | return this; 488 | } 489 | 490 | public int getMetricsHistorySize() { 491 | return metricsHistorySize; 492 | } 493 | 494 | /** 495 | * Sets metrics history size. 496 | * Defaults to 10000 497 | * 498 | * @param metricsHistorySize to set. 499 | * @return reference to this, for fluency 500 | */ 501 | public IgniteOptions setMetricsHistorySize(int metricsHistorySize) { 502 | this.metricsHistorySize = metricsHistorySize; 503 | return this; 504 | } 505 | 506 | public long getMetricsExpireTime() { 507 | return metricsExpireTime; 508 | } 509 | 510 | /** 511 | * Sets metrics expire time. 512 | * Defaults to never expire 513 | * 514 | * @param metricsExpireTime in milliseconds. 515 | * @return reference to this, for fluency 516 | */ 517 | public IgniteOptions setMetricsExpireTime(long metricsExpireTime) { 518 | this.metricsExpireTime = metricsExpireTime; 519 | return this; 520 | } 521 | 522 | public IgniteMetricExporterOptions getMetricExporterSpi() { 523 | return metricExporterOptions; 524 | } 525 | 526 | /** 527 | * Sets fully configured instance of {@link IgniteMetricExporterOptions}. 528 | * 529 | * @param metricExporterOptions {@link IgniteMetricExporterOptions}. 530 | * @return reference to this, for fluency 531 | */ 532 | public IgniteOptions setMetricExporterSpi(IgniteMetricExporterOptions metricExporterOptions) { 533 | this.metricExporterOptions = metricExporterOptions; 534 | return this; 535 | } 536 | 537 | public long getDelayAfterStart() { 538 | return delayAfterStart; 539 | } 540 | 541 | /** 542 | * Sets delay in millisenconds after Ignite start. 543 | * Defaults to 100ms 544 | * 545 | * @param delayAfterStart in milliseconds. 546 | * @return reference to this, for fluency 547 | */ 548 | public IgniteOptions setDelayAfterStart(long delayAfterStart) { 549 | this.delayAfterStart = delayAfterStart; 550 | return this; 551 | } 552 | 553 | /** 554 | * Convert to JSON 555 | * 556 | * @return the JSON 557 | */ 558 | public JsonObject toJson() { 559 | JsonObject json = new JsonObject(); 560 | IgniteOptionsConverter.toJson(this, json); 561 | return json; 562 | } 563 | } 564 | -------------------------------------------------------------------------------- /src/main/java/io/vertx/spi/cluster/ignite/IgniteSslOptions.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Red Hat, Inc. 3 | * 4 | * Red Hat licenses this file to you under the Apache License, version 2.0 5 | * (the "License"); you may not use this file except in compliance with the 6 | * License. You may obtain a copy of the License at: 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | package io.vertx.spi.cluster.ignite; 17 | 18 | import io.vertx.codegen.annotations.DataObject; 19 | import io.vertx.codegen.json.annotations.JsonGen; 20 | import io.vertx.core.json.JsonObject; 21 | import io.vertx.core.net.*; 22 | 23 | import static org.apache.ignite.ssl.SslContextFactory.*; 24 | 25 | /** 26 | * @author Lukas Prettenthaler 27 | */ 28 | @DataObject 29 | @JsonGen(publicConverter = false) 30 | public class IgniteSslOptions { 31 | private String protocol; 32 | private String keyAlgorithm; 33 | private String keyStoreType; 34 | private String keyStoreFilePath; 35 | private String keyStorePassword; 36 | private String trustStoreType; 37 | private String trustStoreFilePath; 38 | private String trustStorePassword; 39 | private PemKeyCertOptions pemKeyCertOptions; 40 | private PemTrustOptions pemTrustOptions; 41 | private PfxOptions pfxKeyCertOptions; 42 | private PfxOptions pfxTrustOptions; 43 | private JksOptions jksKeyCertOptions; 44 | private JksOptions jksTrustOptions; 45 | private boolean trustAll; 46 | 47 | /** 48 | * Default constructor 49 | */ 50 | public IgniteSslOptions() { 51 | protocol = DFLT_SSL_PROTOCOL; 52 | keyAlgorithm = DFLT_KEY_ALGORITHM; 53 | keyStoreType = DFLT_STORE_TYPE; 54 | trustStoreType = DFLT_STORE_TYPE; 55 | trustAll = false; 56 | } 57 | 58 | /** 59 | * Copy constructor 60 | * 61 | * @param options the one to copy 62 | */ 63 | public IgniteSslOptions(IgniteSslOptions options) { 64 | this.protocol = options.protocol; 65 | this.keyAlgorithm = options.keyAlgorithm; 66 | this.keyStoreType = options.keyStoreType; 67 | this.keyStoreFilePath = options.keyStoreFilePath; 68 | this.keyStorePassword = options.keyStorePassword; 69 | this.trustStoreType = options.trustStoreType; 70 | this.trustStoreFilePath = options.trustStoreFilePath; 71 | this.trustStorePassword = options.trustStorePassword; 72 | this.pemKeyCertOptions = options.pemKeyCertOptions; 73 | this.pemTrustOptions = options.pemTrustOptions; 74 | this.pfxKeyCertOptions = options.pfxKeyCertOptions; 75 | this.pfxTrustOptions = options.pfxTrustOptions; 76 | this.jksKeyCertOptions = options.jksKeyCertOptions; 77 | this.jksTrustOptions = options.jksTrustOptions; 78 | this.trustAll = options.trustAll; 79 | } 80 | 81 | /** 82 | * Constructor from JSON 83 | * 84 | * @param options the JSON 85 | */ 86 | public IgniteSslOptions(JsonObject options) { 87 | this(); 88 | IgniteSslOptionsConverter.fromJson(options, this); 89 | } 90 | 91 | /** 92 | * Gets protocol for secure transport. 93 | * 94 | * @return SSL protocol name. 95 | */ 96 | public String getProtocol() { 97 | return protocol; 98 | } 99 | 100 | /** 101 | * Sets protocol for secure transport. 102 | * 103 | * @param protocol SSL protocol name. 104 | * @return reference to this, for fluency 105 | */ 106 | public IgniteSslOptions setProtocol(String protocol) { 107 | this.protocol = protocol; 108 | return this; 109 | } 110 | 111 | /** 112 | * Gets algorithm that will be used to create a key manager. 113 | * 114 | * @return Key manager algorithm. 115 | * @deprecated Use vert.x ssl certificate options instead. It will be removed in vert.x 4.1 116 | */ 117 | @Deprecated 118 | public String getKeyAlgorithm() { 119 | return keyAlgorithm; 120 | } 121 | 122 | /** 123 | * Sets key manager algorithm that will be used to create a key manager. Notice that in most cased default value 124 | * suites well, however, on Android platform this value need to be set to X509. 125 | * 126 | * @param keyAlgorithm Key algorithm name. 127 | * @return reference to this, for fluency 128 | * @deprecated Use vert.x ssl certificate options instead. It will be removed in vert.x 4.1 129 | */ 130 | @Deprecated 131 | public IgniteSslOptions setKeyAlgorithm(String keyAlgorithm) { 132 | this.keyAlgorithm = keyAlgorithm; 133 | return this; 134 | } 135 | 136 | /** 137 | * Gets key store type used for context creation. 138 | * 139 | * @return Key store type. 140 | * @deprecated Use vert.x ssl certificate options instead. It will be removed in vert.x 4.1 141 | */ 142 | @Deprecated 143 | public String getKeyStoreType() { 144 | return keyStoreType; 145 | } 146 | 147 | /** 148 | * Sets key store type used in context initialization. 149 | * 150 | * @param keyStoreType Key store type. 151 | * @return reference to this, for fluency 152 | * @deprecated Use vert.x ssl certificate options instead. It will be removed in vert.x 4.1 153 | */ 154 | @Deprecated 155 | public IgniteSslOptions setKeyStoreType(String keyStoreType) { 156 | this.keyStoreType = keyStoreType; 157 | return this; 158 | } 159 | 160 | /** 161 | * Gets path to the key store file. 162 | * 163 | * @return Path to key store file. 164 | * @deprecated Use vert.x jksKeyCertOptions.path instead. It will be removed in vert.x 4.1 165 | */ 166 | @Deprecated 167 | public String getKeyStoreFilePath() { 168 | return keyStoreFilePath; 169 | } 170 | 171 | /** 172 | * Sets path to the key store file. This is a mandatory parameter since 173 | * ssl context could not be initialized without key manager. 174 | * 175 | * @param keyStoreFilePath Path to key store file. 176 | * @return reference to this, for fluency 177 | * @deprecated Use vert.x jksKeyCertOptions.path instead. It will be removed in vert.x 4.1 178 | */ 179 | @Deprecated 180 | public IgniteSslOptions setKeyStoreFilePath(String keyStoreFilePath) { 181 | this.keyStoreFilePath = keyStoreFilePath; 182 | return this; 183 | } 184 | 185 | /** 186 | * Gets key store password. 187 | * 188 | * @return Key store password. 189 | * @deprecated Use vert.x jksKeyCertOptions.password instead. It will be removed in vert.x 4.1 190 | */ 191 | @Deprecated 192 | public String getKeyStorePassword() { 193 | return keyStorePassword; 194 | } 195 | 196 | /** 197 | * Sets key store password. 198 | * 199 | * @param keyStorePassword Key store password. 200 | * @return reference to this, for fluency 201 | * @deprecated Use vert.x jksKeyCertOptions.password instead. It will be removed in vert.x 4.1 202 | */ 203 | @Deprecated 204 | public IgniteSslOptions setKeyStorePassword(String keyStorePassword) { 205 | this.keyStorePassword = keyStorePassword; 206 | return this; 207 | } 208 | 209 | /** 210 | * Gets trust store type used for context creation. 211 | * 212 | * @return trust store type. 213 | * @deprecated Use vert.x jksTrustOptions instead. It will be removed in vert.x 4.1 214 | */ 215 | @Deprecated 216 | public String getTrustStoreType() { 217 | return trustStoreType; 218 | } 219 | 220 | /** 221 | * Sets trust store type used in context initialization. 222 | * 223 | * @param trustStoreType Trust store type. 224 | * @return reference to this, for fluency 225 | * @deprecated Use vert.x jksTrustOptions instead. It will be removed in vert.x 4.1 226 | */ 227 | @Deprecated 228 | public IgniteSslOptions setTrustStoreType(String trustStoreType) { 229 | this.trustStoreType = trustStoreType; 230 | return this; 231 | } 232 | 233 | /** 234 | * Gets path to the trust store file. 235 | * 236 | * @return Path to the trust store file. 237 | * @deprecated Use vert.x jksTrustOptions.path instead. It will be removed in vert.x 4.1 238 | */ 239 | @Deprecated 240 | public String getTrustStoreFilePath() { 241 | return trustStoreFilePath; 242 | } 243 | 244 | /** 245 | * Sets path to the trust store file. 246 | * 247 | * @param trustStoreFilePath Path to the trust store file. 248 | * @return reference to this, for fluency 249 | * @deprecated Use vert.x jksTrustOptions.path instead. It will be removed in vert.x 4.1 250 | */ 251 | @Deprecated 252 | public IgniteSslOptions setTrustStoreFilePath(String trustStoreFilePath) { 253 | this.trustStoreFilePath = trustStoreFilePath; 254 | return this; 255 | } 256 | 257 | /** 258 | * Gets trust store password. 259 | * 260 | * @return Trust store password. 261 | * @deprecated Use vert.x jksTrustOptions.password instead. It will be removed in vert.x 4.1 262 | */ 263 | @Deprecated 264 | public String getTrustStorePassword() { 265 | return trustStorePassword; 266 | } 267 | 268 | /** 269 | * Sets trust store password. 270 | * 271 | * @param trustStorePassword Trust store password. 272 | * @return reference to this, for fluency 273 | * @deprecated Use vert.x jksTrustOptions.password instead. It will be removed in vert.x 4.1 274 | */ 275 | @Deprecated 276 | public IgniteSslOptions setTrustStorePassword(String trustStorePassword) { 277 | this.trustStorePassword = trustStorePassword; 278 | return this; 279 | } 280 | 281 | public PemKeyCertOptions getPemKeyCertOptions() { 282 | return pemKeyCertOptions; 283 | } 284 | 285 | /** 286 | * Sets PemKeyCertOptions that will be used for creating a secure socket layer. 287 | * 288 | * @param pemKeyCertOptions Vertx PEM KeyCertOptions. 289 | * @return reference to this, for fluency 290 | */ 291 | public IgniteSslOptions setPemKeyCertOptions(PemKeyCertOptions pemKeyCertOptions) { 292 | this.pemKeyCertOptions = pemKeyCertOptions; 293 | return this; 294 | } 295 | 296 | public PemTrustOptions getPemTrustOptions() { 297 | return pemTrustOptions; 298 | } 299 | 300 | /** 301 | * Sets PemTrustOptions that will be used for creating a secure socket layer. 302 | * 303 | * @param pemTrustOptions Vertx PEM TrustOptions. 304 | * @return reference to this, for fluency 305 | */ 306 | public IgniteSslOptions setPemTrustOptions(PemTrustOptions pemTrustOptions) { 307 | this.pemTrustOptions = pemTrustOptions; 308 | return this; 309 | } 310 | 311 | public PfxOptions getPfxKeyCertOptions() { 312 | return pfxKeyCertOptions; 313 | } 314 | 315 | /** 316 | * Sets PfxKeyCertOptions that will be used for creating a secure socket layer. 317 | * 318 | * @param pfxKeyCertOptions Vertx PFX KeyCertOptions. 319 | * @return reference to this, for fluency 320 | */ 321 | public IgniteSslOptions setPfxKeyCertOptions(PfxOptions pfxKeyCertOptions) { 322 | this.pfxKeyCertOptions = pfxKeyCertOptions; 323 | return this; 324 | } 325 | 326 | public PfxOptions getPfxTrustOptions() { 327 | return pfxTrustOptions; 328 | } 329 | 330 | /** 331 | * Sets PfxTrustOptions that will be used for creating a secure socket layer. 332 | * 333 | * @param pfxTrustOptions Vertx PFX TrustOptions. 334 | * @return reference to this, for fluency 335 | */ 336 | public IgniteSslOptions setPfxTrustOptions(PfxOptions pfxTrustOptions) { 337 | this.pfxTrustOptions = pfxTrustOptions; 338 | return this; 339 | } 340 | 341 | public JksOptions getJksKeyCertOptions() { 342 | return jksKeyCertOptions; 343 | } 344 | 345 | /** 346 | * Sets JksKeyCertOptions that will be used for creating a secure socket layer. 347 | * 348 | * @param jksKeyCertOptions Vertx JKS KeyCertOptions. 349 | * @return reference to this, for fluency 350 | */ 351 | public IgniteSslOptions setJksKeyCertOptions(JksOptions jksKeyCertOptions) { 352 | this.jksKeyCertOptions = jksKeyCertOptions; 353 | return this; 354 | } 355 | 356 | public JksOptions getJksTrustOptions() { 357 | return jksTrustOptions; 358 | } 359 | 360 | /** 361 | * Sets JksTrustOptions that will be used for creating a secure socket layer. 362 | * 363 | * @param jksTrustOptions Vertx JKS TrustOptions. 364 | * @return reference to this, for fluency 365 | */ 366 | public IgniteSslOptions setJksTrustOptions(JksOptions jksTrustOptions) { 367 | this.jksTrustOptions = jksTrustOptions; 368 | return this; 369 | } 370 | 371 | /** 372 | * When using ssl, trust ALL certificates. 373 | * WARNING Trusting ALL certificates will open you up to potential security issues such as MITM attacks. 374 | * 375 | * @return Trust all flag. 376 | */ 377 | public boolean isTrustAll() { 378 | return trustAll; 379 | } 380 | 381 | /** 382 | * When using ssl, trust ALL certificates. 383 | * WARNING Trusting ALL certificates will open you up to potential security issues such as MITM attacks. 384 | * 385 | * @param trustAll Trust all flag. 386 | * @return reference to this, for fluency 387 | */ 388 | public IgniteSslOptions setTrustAll(boolean trustAll) { 389 | this.trustAll = trustAll; 390 | return this; 391 | } 392 | 393 | /** 394 | * Convert to JSON 395 | * 396 | * @return the JSON 397 | */ 398 | public JsonObject toJson() { 399 | JsonObject json = new JsonObject(); 400 | IgniteSslOptionsConverter.toJson(this, json); 401 | return json; 402 | } 403 | } 404 | -------------------------------------------------------------------------------- /src/main/java/io/vertx/spi/cluster/ignite/impl/AsyncMapImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 The original author or authors 3 | * --------------------------------- 4 | * 5 | * All rights reserved. This program and the accompanying materials 6 | * are made available under the terms of the Eclipse Public License v1.0 7 | * and Apache License v2.0 which accompanies this distribution. 8 | * 9 | * The Eclipse Public License is available at 10 | * http://www.eclipse.org/legal/epl-v10.html 11 | * 12 | * The Apache License v2.0 is available at 13 | * http://www.opensource.org/licenses/apache2.0.php 14 | * 15 | * You may elect to redistribute this code under either of these licenses. 16 | */ 17 | 18 | package io.vertx.spi.cluster.ignite.impl; 19 | 20 | import io.vertx.core.Future; 21 | import io.vertx.core.Vertx; 22 | import io.vertx.core.VertxException; 23 | import io.vertx.core.internal.VertxInternal; 24 | import io.vertx.core.shareddata.AsyncMap; 25 | import org.apache.ignite.IgniteCache; 26 | import org.apache.ignite.cache.query.ScanQuery; 27 | import org.apache.ignite.lang.IgniteFuture; 28 | 29 | import javax.cache.Cache; 30 | import javax.cache.expiry.Duration; 31 | import javax.cache.expiry.ModifiedExpiryPolicy; 32 | import java.util.*; 33 | import java.util.concurrent.TimeUnit; 34 | import java.util.function.Function; 35 | 36 | import static io.vertx.spi.cluster.ignite.impl.ClusterSerializationUtils.marshal; 37 | import static io.vertx.spi.cluster.ignite.impl.ClusterSerializationUtils.unmarshal; 38 | 39 | /** 40 | * Async wrapper for {@link MapImpl}. 41 | * 42 | * @author Andrey Gura 43 | */ 44 | public class AsyncMapImpl implements AsyncMap { 45 | 46 | private final VertxInternal vertx; 47 | private final IgniteCache cache; 48 | 49 | /** 50 | * Constructor. 51 | * 52 | * @param cache {@link IgniteCache} instance. 53 | * @param vertx {@link Vertx} instance. 54 | */ 55 | public AsyncMapImpl(IgniteCache cache, VertxInternal vertx) { 56 | this.cache = cache; 57 | this.vertx = vertx; 58 | } 59 | 60 | @Override 61 | public Future get(K k) { 62 | return execute(cache -> cache.getAsync(marshal(k))); 63 | } 64 | 65 | @Override 66 | public Future put(K k, V v) { 67 | return execute(cache -> cache.putAsync(marshal(k), marshal(v))); 68 | } 69 | 70 | @Override 71 | public Future put(K k, V v, long ttl) { 72 | return executeWithTtl(cache -> cache.putAsync(marshal(k), marshal(v)), ttl); 73 | } 74 | 75 | @Override 76 | public Future putIfAbsent(K k, V v) { 77 | return execute(cache -> cache.getAndPutIfAbsentAsync(marshal(k), marshal(v))); 78 | } 79 | 80 | @Override 81 | public Future putIfAbsent(K k, V v, long ttl) { 82 | return executeWithTtl(cache -> cache.getAndPutIfAbsentAsync(marshal(k), marshal(v)), ttl); 83 | } 84 | 85 | @Override 86 | public Future remove(K k) { 87 | return execute(cache -> cache.getAndRemoveAsync(marshal(k))); 88 | } 89 | 90 | @Override 91 | public Future removeIfPresent(K k, V v) { 92 | return execute(cache -> cache.removeAsync(marshal(k), marshal(v))); 93 | } 94 | 95 | @Override 96 | public Future replace(K k, V v) { 97 | return execute(cache -> cache.getAndReplaceAsync(marshal(k), marshal(v))); 98 | } 99 | 100 | @Override 101 | public Future replace(K k, V v, long ttl) { 102 | return executeWithTtl(cache -> cache.getAndReplaceAsync(marshal(k), marshal(v)), ttl); 103 | } 104 | 105 | @Override 106 | public Future replaceIfPresent(K k, V oldValue, V newValue) { 107 | return execute(cache -> cache.replaceAsync(marshal(k), marshal(oldValue), marshal(newValue))); 108 | } 109 | 110 | @Override 111 | public Future replaceIfPresent(K k, V oldValue, V newValue, long ttl) { 112 | return executeWithTtl(cache -> cache.replaceAsync(marshal(k), marshal(oldValue), marshal(newValue)), ttl); 113 | } 114 | 115 | @Override 116 | public Future clear() { 117 | return execute(IgniteCache::clearAsync); 118 | } 119 | 120 | @Override 121 | public Future size() { 122 | return execute(IgniteCache::sizeAsync); 123 | } 124 | 125 | @Override 126 | public Future> keys() { 127 | return entries().map(Map::keySet); 128 | } 129 | 130 | @Override 131 | public Future> values() { 132 | return entries().map(map -> new ArrayList<>(map.values())); 133 | } 134 | 135 | @Override 136 | public Future> entries() { 137 | return vertx.executeBlocking( 138 | () -> { 139 | try { 140 | List> all = cache.query(new ScanQuery()).getAll(); 141 | Map map = new HashMap<>(all.size()); 142 | for (Cache.Entry entry : all) { 143 | map.put(unmarshal(entry.getKey()), unmarshal(entry.getValue())); 144 | } 145 | return map; 146 | } catch (final RuntimeException cause) { 147 | throw new VertxException(cause, true); 148 | } 149 | } 150 | ); 151 | } 152 | 153 | private Future execute(Function, IgniteFuture> cacheOp) { 154 | return executeWithTtl(cacheOp, -1); 155 | } 156 | 157 | /** 158 | * @param ttl Time to live in ms. 159 | */ 160 | private Future executeWithTtl(Function, IgniteFuture> cacheOp, long ttl) { 161 | IgniteCache cache0 = ttl > 0 162 | ? cache.withExpiryPolicy(new ModifiedExpiryPolicy(new Duration(TimeUnit.MILLISECONDS, ttl))) 163 | : cache; 164 | 165 | return vertx.executeBlocking( 166 | () -> unmarshal(cacheOp.apply(cache0).get()) 167 | ); 168 | } 169 | } 170 | -------------------------------------------------------------------------------- /src/main/java/io/vertx/spi/cluster/ignite/impl/ClusterSerializationUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Red Hat, Inc. 3 | * 4 | * Red Hat licenses this file to you under the Apache License, version 2.0 5 | * (the "License"); you may not use this file except in compliance with the 6 | * License. You may obtain a copy of the License at: 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | package io.vertx.spi.cluster.ignite.impl; 17 | 18 | import io.vertx.core.buffer.Buffer; 19 | import io.vertx.core.shareddata.ClusterSerializable; 20 | 21 | import java.util.Arrays; 22 | import java.util.Objects; 23 | 24 | /** 25 | * Serialization/deserialization utils. Provides support of {@link ClusterSerializable} interface. 26 | * 27 | * @author Andrey Gura 28 | */ 29 | public class ClusterSerializationUtils { 30 | 31 | /** 32 | * Serializes and wraps to {@link ClusterSerializableValue} given object if it implements 33 | * {@link ClusterSerializable} interface, otherwise returns source value. 34 | * 35 | * @param obj Object. 36 | * @return {@link ClusterSerializableValue} instance as serialized form of passed object if it implements 37 | * {@link ClusterSerializable} interface, otherwise passed object itself. 38 | */ 39 | public static T marshal(T obj) { 40 | if (obj instanceof ClusterSerializable) { 41 | return (T) marshal0((ClusterSerializable) obj); 42 | } else { 43 | return obj; 44 | } 45 | } 46 | 47 | /** 48 | * Unwraps and deserializes {@link ClusterSerializableValue} or returns source value. 49 | * 50 | * @param obj Object. 51 | * @return Deserialized {@link ClusterSerializable} value or source value. 52 | */ 53 | public static T unmarshal(T obj) { 54 | if (obj instanceof ClusterSerializableValue) { 55 | return (T) unmarshal0((ClusterSerializableValue) obj); 56 | } else { 57 | return obj; 58 | } 59 | } 60 | 61 | private static ClusterSerializableValue marshal0(ClusterSerializable obj) { 62 | Buffer buffer = Buffer.buffer(); 63 | obj.writeToBuffer(buffer); 64 | return new ClusterSerializableValue(obj.getClass().getName(), buffer.getBytes()); 65 | } 66 | 67 | private static ClusterSerializable unmarshal0(ClusterSerializableValue value) { 68 | try { 69 | Class cls = Thread.currentThread().getContextClassLoader().loadClass(value.getClassName()); 70 | ClusterSerializable obj = (ClusterSerializable) cls.getDeclaredConstructor().newInstance(); 71 | obj.readFromBuffer(0, Buffer.buffer(value.getData())); 72 | return obj; 73 | } catch (Exception e) { 74 | throw new IllegalStateException("Failed to load class " + value.getClassName(), e); 75 | } 76 | } 77 | 78 | /** 79 | * Wrapper for serialized {@link ClusterSerializable}. 80 | */ 81 | public static class ClusterSerializableValue { 82 | private final String clsName; 83 | private final byte[] data; 84 | 85 | public ClusterSerializableValue(String clsName, byte[] data) { 86 | this.clsName = clsName; 87 | this.data = data; 88 | } 89 | 90 | public String getClassName() { 91 | return clsName; 92 | } 93 | 94 | public byte[] getData() { 95 | return data; 96 | } 97 | 98 | @Override 99 | public boolean equals(Object that) { 100 | if (this == that) 101 | return true; 102 | if (that == null || getClass() != that.getClass()) 103 | return false; 104 | ClusterSerializableValue value = (ClusterSerializableValue)that; 105 | return Objects.equals(clsName, value.clsName) && 106 | Arrays.equals(data, value.data); 107 | } 108 | 109 | @Override 110 | public int hashCode() { 111 | int result = Objects.hash(clsName); 112 | result = 31 * result + Arrays.hashCode(data); 113 | return result; 114 | } 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /src/main/java/io/vertx/spi/cluster/ignite/impl/IgniteNodeInfo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Red Hat, Inc. 3 | * 4 | * Red Hat licenses this file to you under the Apache License, version 2.0 5 | * (the "License"); you may not use this file except in compliance with the 6 | * License. You may obtain a copy of the License at: 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | package io.vertx.spi.cluster.ignite.impl; 17 | 18 | import io.vertx.core.buffer.Buffer; 19 | import io.vertx.core.json.JsonObject; 20 | import io.vertx.core.spi.cluster.NodeInfo; 21 | import org.apache.ignite.binary.BinaryObjectException; 22 | import org.apache.ignite.binary.BinaryReader; 23 | import org.apache.ignite.binary.BinaryWriter; 24 | import org.apache.ignite.binary.Binarylizable; 25 | 26 | /** 27 | * @author Thomas Segismont 28 | * @author Lukas Prettenthaler 29 | */ 30 | public class IgniteNodeInfo implements Binarylizable { 31 | private NodeInfo nodeInfo; 32 | 33 | public IgniteNodeInfo() { 34 | } 35 | 36 | public IgniteNodeInfo(NodeInfo nodeInfo) { 37 | this.nodeInfo = nodeInfo; 38 | } 39 | 40 | @Override 41 | public void writeBinary(BinaryWriter writer) throws BinaryObjectException { 42 | writer.writeString("host", nodeInfo.host()); 43 | writer.writeInt("port", nodeInfo.port()); 44 | JsonObject metadata = nodeInfo.metadata(); 45 | writer.writeByteArray("meta", metadata != null ? metadata.toBuffer().getBytes() : null); 46 | } 47 | 48 | @Override 49 | public void readBinary(BinaryReader reader) throws BinaryObjectException { 50 | String host = reader.readString("host"); 51 | int port = reader.readInt("port"); 52 | byte[] bytes = reader.readByteArray("meta"); 53 | nodeInfo = new NodeInfo(host, port, bytes != null ? new JsonObject(Buffer.buffer(bytes)) : null); 54 | } 55 | 56 | public NodeInfo unwrap() { 57 | return nodeInfo; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/main/java/io/vertx/spi/cluster/ignite/impl/IgniteRegistrationInfo.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Red Hat, Inc. 3 | * 4 | * Red Hat licenses this file to you under the Apache License, version 2.0 5 | * (the "License"); you may not use this file except in compliance with the 6 | * License. You may obtain a copy of the License at: 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | package io.vertx.spi.cluster.ignite.impl; 17 | 18 | import io.vertx.core.spi.cluster.RegistrationInfo; 19 | import org.apache.ignite.binary.BinaryObjectException; 20 | import org.apache.ignite.binary.BinaryReader; 21 | import org.apache.ignite.binary.BinaryWriter; 22 | import org.apache.ignite.binary.Binarylizable; 23 | 24 | import java.util.Objects; 25 | 26 | /** 27 | * @author Thomas Segismont 28 | * @author Lukas Prettenthaler 29 | */ 30 | public class IgniteRegistrationInfo implements Binarylizable, Comparable { 31 | private String address; 32 | private RegistrationInfo registrationInfo; 33 | 34 | public IgniteRegistrationInfo() { 35 | } 36 | 37 | public IgniteRegistrationInfo(String address, RegistrationInfo registrationInfo) { 38 | this.address = Objects.requireNonNull(address); 39 | this.registrationInfo = Objects.requireNonNull(registrationInfo); 40 | } 41 | 42 | public String address() { 43 | return address; 44 | } 45 | 46 | public RegistrationInfo registrationInfo() { 47 | return registrationInfo; 48 | } 49 | 50 | @Override 51 | public void writeBinary(BinaryWriter writer) throws BinaryObjectException { 52 | writer.writeString("address", address); 53 | writer.writeString("nodeId", registrationInfo.nodeId()); 54 | writer.writeLong("seq", registrationInfo.seq()); 55 | writer.writeBoolean("isLocalOnly", registrationInfo.localOnly()); 56 | } 57 | 58 | @Override 59 | public void readBinary(BinaryReader reader) throws BinaryObjectException { 60 | address = reader.readString("address"); 61 | registrationInfo = new RegistrationInfo(reader.readString("nodeId"), reader.readLong("seq"), reader.readBoolean("isLocalOnly")); 62 | } 63 | 64 | @Override 65 | public boolean equals(Object o) { 66 | if (this == o) return true; 67 | if (o == null || getClass() != o.getClass()) return false; 68 | 69 | IgniteRegistrationInfo that = (IgniteRegistrationInfo) o; 70 | 71 | if (!address.equals(that.address)) return false; 72 | return registrationInfo.equals(that.registrationInfo); 73 | } 74 | 75 | @Override 76 | public int hashCode() { 77 | int result = address.hashCode(); 78 | result = 31 * result + registrationInfo.hashCode(); 79 | return result; 80 | } 81 | 82 | @Override 83 | public int compareTo(IgniteRegistrationInfo other) { 84 | return Integer.compare(hashCode(), other.hashCode()); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/main/java/io/vertx/spi/cluster/ignite/impl/MapImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 The original author or authors 3 | * --------------------------------- 4 | * 5 | * All rights reserved. This program and the accompanying materials 6 | * are made available under the terms of the Eclipse Public License v1.0 7 | * and Apache License v2.0 which accompanies this distribution. 8 | * 9 | * The Eclipse Public License is available at 10 | * http://www.eclipse.org/legal/epl-v10.html 11 | * 12 | * The Apache License v2.0 is available at 13 | * http://www.opensource.org/licenses/apache2.0.php 14 | * 15 | * You may elect to redistribute this code under either of these licenses. 16 | */ 17 | 18 | package io.vertx.spi.cluster.ignite.impl; 19 | 20 | import org.apache.ignite.IgniteCache; 21 | 22 | import javax.cache.Cache; 23 | import java.util.*; 24 | 25 | import static io.vertx.spi.cluster.ignite.impl.ClusterSerializationUtils.marshal; 26 | import static io.vertx.spi.cluster.ignite.impl.ClusterSerializationUtils.unmarshal; 27 | 28 | /** 29 | * Represents Apache Ignite cache as {@link java.util.Map} interface implementation. 30 | * 31 | * @author Andrey Gura 32 | */ 33 | public class MapImpl implements Map { 34 | 35 | private final IgniteCache cache; 36 | 37 | /** 38 | * Constructor. 39 | * 40 | * @param cache Ignite cache instance. 41 | */ 42 | public MapImpl(IgniteCache cache) { 43 | this.cache = cache; 44 | } 45 | 46 | IgniteCache getCache() { 47 | return cache; 48 | } 49 | 50 | @Override 51 | public int size() { 52 | return cache.size(); 53 | } 54 | 55 | @Override 56 | public boolean isEmpty() { 57 | return cache.size() == 0; 58 | } 59 | 60 | @Override 61 | @SuppressWarnings("unchecked") 62 | public boolean containsKey(Object key) { 63 | return cache.containsKey((K) marshal(key)); 64 | } 65 | 66 | @Override 67 | public boolean containsValue(Object value) { 68 | for (Cache.Entry entry : cache) { 69 | V v = unmarshal(entry.getValue()); 70 | 71 | if (v.equals(value)) 72 | return true; 73 | } 74 | 75 | return false; 76 | } 77 | 78 | @Override 79 | @SuppressWarnings("unchecked") 80 | public V get(Object key) { 81 | return unmarshal(cache.get((K) marshal(key))); 82 | } 83 | 84 | @Override 85 | public V put(K key, V value) { 86 | return unmarshal(cache.getAndPut(marshal(key), marshal(value))); 87 | } 88 | 89 | @Override 90 | @SuppressWarnings("unchecked") 91 | public V remove(Object key) { 92 | return unmarshal(cache.getAndRemove((K) marshal(key))); 93 | } 94 | 95 | @Override 96 | public void putAll(Map map) { 97 | Map map0 = new HashMap<>(); 98 | 99 | for (Entry entry : map.entrySet()) { 100 | map0.put(marshal(entry.getKey()), marshal(entry.getValue())); 101 | } 102 | 103 | cache.putAll(map0); 104 | } 105 | 106 | @Override 107 | public void clear() { 108 | cache.clear(); 109 | } 110 | 111 | @Override 112 | public Set keySet() { 113 | Set res = new HashSet<>(); 114 | 115 | for (Cache.Entry entry : cache) { 116 | res.add(unmarshal(entry.getKey())); 117 | } 118 | 119 | return res; 120 | } 121 | 122 | @Override 123 | public Collection values() { 124 | Collection res = new ArrayList<>(); 125 | 126 | for (Cache.Entry entry : cache) { 127 | res.add(unmarshal(entry.getValue())); 128 | } 129 | 130 | return res; 131 | } 132 | 133 | @Override 134 | public Set> entrySet() { 135 | Set> res = new HashSet<>(); 136 | for (Cache.Entry entry : cache) { 137 | res.add(new AbstractMap.SimpleImmutableEntry<>(unmarshal(entry.getKey()), unmarshal(entry.getValue()))); 138 | } 139 | return res; 140 | } 141 | 142 | @Override 143 | public V putIfAbsent(K key, V value) { 144 | return unmarshal(cache.getAndPutIfAbsent(marshal(key), marshal(value))); 145 | } 146 | 147 | @Override 148 | @SuppressWarnings("unchecked") 149 | public boolean remove(Object key, Object value) { 150 | return cache.remove((K) marshal(key), (V) marshal(value)); 151 | } 152 | 153 | @Override 154 | public boolean replace(K key, V oldValue, V newValue) { 155 | return cache.replace(marshal(key), marshal(oldValue), marshal(newValue)); 156 | } 157 | 158 | @Override 159 | public V replace(K key, V value) { 160 | return unmarshal(cache.getAndReplace(marshal(key), marshal(value))); 161 | } 162 | } 163 | -------------------------------------------------------------------------------- /src/main/java/io/vertx/spi/cluster/ignite/impl/SubsMapHelper.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Red Hat, Inc. 3 | * 4 | * Red Hat licenses this file to you under the Apache License, version 2.0 5 | * (the "License"); you may not use this file except in compliance with the 6 | * License. You may obtain a copy of the License at: 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | package io.vertx.spi.cluster.ignite.impl; 17 | 18 | import io.vertx.core.Future; 19 | import io.vertx.core.Promise; 20 | import io.vertx.core.VertxException; 21 | import io.vertx.core.internal.VertxInternal; 22 | import io.vertx.core.internal.logging.Logger; 23 | import io.vertx.core.internal.logging.LoggerFactory; 24 | import io.vertx.core.spi.cluster.RegistrationInfo; 25 | import io.vertx.core.spi.cluster.RegistrationListener; 26 | import io.vertx.core.spi.cluster.RegistrationUpdateEvent; 27 | import org.apache.ignite.Ignite; 28 | import org.apache.ignite.IgniteCache; 29 | import org.apache.ignite.cache.query.ContinuousQuery; 30 | import org.apache.ignite.cache.query.ScanQuery; 31 | 32 | import javax.cache.Cache; 33 | import javax.cache.CacheException; 34 | import javax.cache.event.CacheEntryEvent; 35 | import java.util.*; 36 | import java.util.concurrent.ConcurrentHashMap; 37 | import java.util.concurrent.ConcurrentMap; 38 | import java.util.stream.StreamSupport; 39 | 40 | /** 41 | * @author Thomas Segismont 42 | * @author Lukas Prettenthaler 43 | */ 44 | public class SubsMapHelper { 45 | private static final Logger log = LoggerFactory.getLogger(SubsMapHelper.class); 46 | private final IgniteCache map; 47 | private final RegistrationListener registrationListener; 48 | private final ConcurrentMap> localSubs = new ConcurrentHashMap<>(); 49 | private final Throttling throttling; 50 | private volatile boolean shutdown; 51 | 52 | public SubsMapHelper(Ignite ignite, RegistrationListener registrationListener, VertxInternal vertxInternal) { 53 | map = ignite.getOrCreateCache("__vertx.subs"); 54 | this.registrationListener = registrationListener; 55 | throttling = new Throttling(vertxInternal, a -> getAndUpdate(a, vertxInternal)); 56 | shutdown = false; 57 | map.query(new ContinuousQuery() 58 | .setAutoUnsubscribe(true) 59 | .setTimeInterval(100L) 60 | .setPageSize(128) 61 | .setLocalListener(l -> listen(l, vertxInternal))); 62 | } 63 | 64 | public List get(String address) { 65 | if (shutdown) { 66 | return null; 67 | } 68 | try { 69 | List> remote = map 70 | .query(new ScanQuery((k, v) -> k.address().equals(address))) 71 | .getAll(); 72 | List infos; 73 | int size = remote.size(); 74 | Set local = localSubs.get(address); 75 | if (local != null) { 76 | synchronized (local) { 77 | size += local.size(); 78 | if (size == 0) { 79 | return Collections.emptyList(); 80 | } 81 | infos = new ArrayList<>(size); 82 | infos.addAll(local); 83 | } 84 | } else if (size == 0) { 85 | return Collections.emptyList(); 86 | } else { 87 | infos = new ArrayList<>(size); 88 | } 89 | for (Cache.Entry info : remote) { 90 | infos.add(info.getKey().registrationInfo()); 91 | } 92 | 93 | return infos; 94 | } catch (IllegalStateException | CacheException e) { 95 | throw new VertxException(e, true); 96 | } 97 | } 98 | 99 | public Void put(String address, RegistrationInfo registrationInfo) { 100 | if (shutdown) { 101 | throw new VertxException("shutdown in progress"); 102 | } 103 | try { 104 | if (registrationInfo.localOnly()) { 105 | localSubs.compute(address, (add, curr) -> addToSet(registrationInfo, curr)); 106 | fireRegistrationUpdateEvent(address); 107 | } else { 108 | map.put(new IgniteRegistrationInfo(address, registrationInfo), Boolean.TRUE); 109 | } 110 | } catch (IllegalStateException | CacheException e) { 111 | throw new VertxException(e); 112 | } 113 | return null; 114 | } 115 | 116 | private Set addToSet(RegistrationInfo registrationInfo, Set curr) { 117 | Set res = curr != null ? curr : Collections.synchronizedSet(new LinkedHashSet<>()); 118 | res.add(registrationInfo); 119 | return res; 120 | } 121 | 122 | public Void remove(String address, RegistrationInfo registrationInfo) { 123 | if (shutdown) { 124 | return null; 125 | } 126 | try { 127 | if (registrationInfo.localOnly()) { 128 | localSubs.computeIfPresent(address, (add, curr) -> removeFromSet(registrationInfo, curr)); 129 | fireRegistrationUpdateEvent(address); 130 | } else { 131 | map.remove(new IgniteRegistrationInfo(address, registrationInfo), Boolean.TRUE); 132 | } 133 | } catch (IllegalStateException | CacheException e) { 134 | throw new VertxException(e, true); 135 | } 136 | return null; 137 | } 138 | 139 | private Set removeFromSet(RegistrationInfo registrationInfo, Set curr) { 140 | curr.remove(registrationInfo); 141 | return curr.isEmpty() ? null : curr; 142 | } 143 | 144 | public void removeAllForNode(String nodeId) { 145 | List> toRemove = map 146 | .query(new ScanQuery((k, v) -> k.registrationInfo().nodeId().equals(nodeId))) 147 | .getAll(); 148 | for (Cache.Entry info : toRemove) { 149 | try { 150 | map.remove(info.getKey(), Boolean.TRUE); 151 | } catch (IllegalStateException | CacheException t) { 152 | log.warn("Could not remove subscriber: " + t.getMessage()); 153 | } 154 | } 155 | } 156 | 157 | public void leave() { 158 | shutdown = true; 159 | } 160 | 161 | private void fireRegistrationUpdateEvent(String address) { 162 | throttling.onEvent(address); 163 | } 164 | 165 | private Future> getAndUpdate(String address, VertxInternal vertxInternal) { 166 | Promise> prom = Promise.promise(); 167 | if (registrationListener.wantsUpdatesFor(address)) { 168 | prom.future().onSuccess(registrationInfos -> { 169 | registrationListener.registrationsUpdated(new RegistrationUpdateEvent(address, registrationInfos)); 170 | }); 171 | vertxInternal.executeBlocking(() -> 172 | get(address), false 173 | ).onComplete(prom); 174 | } else { 175 | prom.complete(); 176 | } 177 | return prom.future(); 178 | } 179 | 180 | private void listen(final Iterable> events, final VertxInternal vertxInternal) { 181 | vertxInternal.executeBlocking(() -> { 182 | StreamSupport.stream(events.spliterator(), false) 183 | .map(e -> e.getKey().address()) 184 | .distinct() 185 | .forEach(this::fireRegistrationUpdateEvent); 186 | return null; 187 | }, false); 188 | } 189 | } 190 | -------------------------------------------------------------------------------- /src/main/java/io/vertx/spi/cluster/ignite/impl/Throttling.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Red Hat, Inc. 3 | * 4 | * Red Hat licenses this file to you under the Apache License, version 2.0 5 | * (the "License"); you may not use this file except in compliance with the 6 | * License. You may obtain a copy of the License at: 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | package io.vertx.spi.cluster.ignite.impl; 18 | 19 | import io.vertx.core.Future; 20 | import io.vertx.core.internal.VertxInternal; 21 | 22 | import java.util.concurrent.ConcurrentHashMap; 23 | import java.util.concurrent.ConcurrentMap; 24 | import java.util.function.Function; 25 | 26 | public class Throttling { 27 | 28 | // @formatter:off 29 | private enum State { 30 | NEW { 31 | State pending() { 32 | return PENDING; 33 | } 34 | 35 | State start() { 36 | return RUNNING; 37 | } 38 | 39 | State done() { 40 | throw new IllegalStateException(); 41 | } 42 | 43 | State next() { 44 | throw new IllegalStateException(); 45 | } 46 | }, 47 | PENDING { 48 | State pending() { 49 | return this; 50 | } 51 | 52 | State start() { 53 | return RUNNING; 54 | } 55 | 56 | State done() { 57 | throw new IllegalStateException(); 58 | } 59 | 60 | State next() { 61 | throw new IllegalStateException(); 62 | } 63 | }, 64 | RUNNING { 65 | State pending() { 66 | return RUNNING_PENDING; 67 | } 68 | 69 | State start() { 70 | throw new IllegalStateException(); 71 | } 72 | 73 | State done() { 74 | return FINISHED; 75 | } 76 | 77 | State next() { 78 | throw new IllegalStateException(); 79 | } 80 | }, 81 | RUNNING_PENDING { 82 | State pending() { 83 | return this; 84 | } 85 | 86 | State start() { 87 | throw new IllegalStateException(); 88 | } 89 | 90 | State done() { 91 | return FINISHED_PENDING; 92 | } 93 | 94 | State next() { 95 | throw new IllegalStateException(); 96 | } 97 | }, 98 | FINISHED { 99 | State pending() { 100 | return FINISHED_PENDING; 101 | } 102 | 103 | State start() { 104 | throw new IllegalStateException(); 105 | } 106 | 107 | State done() { 108 | throw new IllegalStateException(); 109 | } 110 | 111 | State next() { 112 | return null; 113 | } 114 | }, 115 | FINISHED_PENDING { 116 | State pending() { 117 | return this; 118 | } 119 | 120 | State start() { 121 | throw new IllegalStateException(); 122 | } 123 | 124 | State done() { 125 | throw new IllegalStateException(); 126 | } 127 | 128 | State next() { 129 | return NEW; 130 | } 131 | }; 132 | 133 | abstract State pending(); 134 | 135 | abstract State start(); 136 | 137 | abstract State done(); 138 | 139 | abstract State next(); 140 | } 141 | // @formatter:on 142 | 143 | private final VertxInternal vertx; 144 | private final Function> action; 145 | private final ConcurrentMap map; 146 | 147 | public Throttling(VertxInternal vertx, Function> action) { 148 | this.vertx = vertx; 149 | this.action = action; 150 | map = new ConcurrentHashMap<>(); 151 | } 152 | 153 | public void onEvent(String address) { 154 | State curr = map.compute(address, (s, state) -> state == null ? State.NEW : state.pending()); 155 | if (curr == State.NEW) { 156 | run(address); 157 | } 158 | } 159 | 160 | private void run(String address) { 161 | map.computeIfPresent(address, (s, state) -> state.start()); 162 | action.apply(address).onComplete(ar -> { 163 | map.computeIfPresent(address, (s, state) -> state.done()); 164 | vertx.setTimer(20, l -> { 165 | checkState(address); 166 | }); 167 | }); 168 | } 169 | 170 | private void checkState(String address) { 171 | State curr = map.computeIfPresent(address, (s, state) -> state.next()); 172 | if (curr == State.NEW) { 173 | run(address); 174 | } 175 | } 176 | } 177 | -------------------------------------------------------------------------------- /src/main/java/io/vertx/spi/cluster/ignite/impl/VertxLogger.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Red Hat, Inc. 3 | * 4 | * Red Hat licenses this file to you under the Apache License, version 2.0 5 | * (the "License"); you may not use this file except in compliance with the 6 | * License. You may obtain a copy of the License at: 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | package io.vertx.spi.cluster.ignite.impl; 17 | 18 | import io.vertx.core.internal.logging.Logger; 19 | import io.vertx.core.internal.logging.LoggerFactory; 20 | import org.apache.ignite.IgniteLogger; 21 | import org.jetbrains.annotations.Nullable; 22 | 23 | /** 24 | * @author Lukas Prettenthaler 25 | */ 26 | public class VertxLogger implements IgniteLogger { 27 | private static final Logger logger = LoggerFactory.getLogger(IgniteLogger.class); 28 | 29 | @Override 30 | public IgniteLogger getLogger(Object ctgr) { 31 | return this; 32 | } 33 | 34 | @Override 35 | public void trace(String msg) { 36 | logger.trace(msg); 37 | } 38 | 39 | @Override 40 | public void debug(String msg) { 41 | logger.debug(msg); 42 | } 43 | 44 | @Override 45 | public void info(String msg) { 46 | logger.info(msg); 47 | } 48 | 49 | @Override 50 | public void warning(String msg, @Nullable Throwable e) { 51 | logger.warn(msg, e); 52 | } 53 | 54 | @Override 55 | public void error(String msg, @Nullable Throwable e) { 56 | logger.error(msg, e); 57 | } 58 | 59 | @Override 60 | public boolean isTraceEnabled() { 61 | return logger.isTraceEnabled(); 62 | } 63 | 64 | @Override 65 | public boolean isDebugEnabled() { 66 | return logger.isDebugEnabled(); 67 | } 68 | 69 | @Override 70 | public boolean isInfoEnabled() { 71 | return logger.isInfoEnabled(); 72 | } 73 | 74 | @Override 75 | public boolean isQuiet() { 76 | return false; 77 | } 78 | 79 | @Override 80 | public String fileName() { 81 | return null; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/main/java/io/vertx/spi/cluster/ignite/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 The original author or authors 3 | * --------------------------------- 4 | * 5 | * All rights reserved. This program and the accompanying materials 6 | * are made available under the terms of the Eclipse Public License v1.0 7 | * and Apache License v2.0 which accompanies this distribution. 8 | * 9 | * The Eclipse Public License is available at 10 | * http://www.eclipse.org/legal/epl-v10.html 11 | * 12 | * The Apache License v2.0 is available at 13 | * http://www.opensource.org/licenses/apache2.0.php 14 | * 15 | * You may elect to redistribute this code under either of these licenses. 16 | */ 17 | @ModuleGen(name = "vertx-ignite", groupPackage = "io.vertx") 18 | package io.vertx.spi.cluster.ignite; 19 | 20 | import io.vertx.codegen.annotations.ModuleGen; 21 | -------------------------------------------------------------------------------- /src/main/java/io/vertx/spi/cluster/ignite/util/ConfigHelper.java: -------------------------------------------------------------------------------- 1 | package io.vertx.spi.cluster.ignite.util; 2 | 3 | import io.vertx.core.Vertx; 4 | import io.vertx.core.VertxException; 5 | import io.vertx.core.json.DecodeException; 6 | import io.vertx.core.json.JsonArray; 7 | import io.vertx.core.json.JsonObject; 8 | import io.vertx.core.net.KeyCertOptions; 9 | import io.vertx.core.net.TrustOptions; 10 | import io.vertx.spi.cluster.ignite.*; 11 | import org.apache.ignite.IgniteCheckedException; 12 | import org.apache.ignite.IgniteException; 13 | import org.apache.ignite.cache.*; 14 | import org.apache.ignite.configuration.CacheConfiguration; 15 | import org.apache.ignite.configuration.DataRegionConfiguration; 16 | import org.apache.ignite.configuration.DataStorageConfiguration; 17 | import org.apache.ignite.configuration.IgniteConfiguration; 18 | import org.apache.ignite.internal.IgnitionEx; 19 | import org.apache.ignite.internal.util.typedef.F; 20 | import org.apache.ignite.spi.communication.tcp.TcpCommunicationSpi; 21 | import org.apache.ignite.spi.discovery.DiscoverySpi; 22 | import org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi; 23 | import org.apache.ignite.spi.discovery.tcp.ipfinder.multicast.TcpDiscoveryMulticastIpFinder; 24 | import org.apache.ignite.spi.discovery.tcp.ipfinder.vm.TcpDiscoveryVmIpFinder; 25 | import org.apache.ignite.spi.metric.MetricExporterSpi; 26 | import org.apache.ignite.ssl.SslContextFactory; 27 | 28 | import javax.cache.configuration.Factory; 29 | import javax.cache.expiry.*; 30 | import javax.net.ssl.KeyManager; 31 | import javax.net.ssl.SSLContext; 32 | import javax.net.ssl.TrustManager; 33 | import java.io.BufferedReader; 34 | import java.io.IOException; 35 | import java.io.InputStream; 36 | import java.io.InputStreamReader; 37 | import java.net.URL; 38 | import java.security.KeyManagementException; 39 | import java.security.NoSuchAlgorithmException; 40 | import java.security.SecureRandom; 41 | import java.util.ArrayList; 42 | import java.util.Arrays; 43 | import java.util.List; 44 | import java.util.Optional; 45 | import java.util.concurrent.TimeUnit; 46 | import java.util.stream.Collectors; 47 | 48 | import static org.apache.ignite.configuration.DataStorageConfiguration.DFLT_DATA_REG_DEFAULT_NAME; 49 | import static org.apache.ignite.spi.discovery.tcp.TcpDiscoverySpi.*; 50 | import static org.apache.ignite.spi.discovery.tcp.ipfinder.multicast.TcpDiscoveryMulticastIpFinder.*; 51 | import static org.apache.ignite.ssl.SslContextFactory.getDisabledTrustManager; 52 | 53 | public class ConfigHelper { 54 | 55 | private ConfigHelper() { 56 | //private 57 | } 58 | 59 | public static IgniteConfiguration loadConfiguration(URL config) { 60 | try { 61 | return F.first(IgnitionEx.loadConfigurations(config).get1()); 62 | } catch (IgniteCheckedException e) { 63 | throw new VertxException(e); 64 | } 65 | } 66 | 67 | public static IgniteConfiguration lookupXmlConfiguration(Class clazz, String... files) { 68 | InputStream is = lookupFiles(clazz, files); 69 | try { 70 | return F.first(IgnitionEx.loadConfigurations(is).get1()); 71 | } catch (IgniteCheckedException | IllegalArgumentException e) { 72 | throw new VertxException(e); 73 | } 74 | } 75 | 76 | public static JsonObject lookupJsonConfiguration(Class clazz, String... files) { 77 | InputStream is = lookupFiles(clazz, files); 78 | try { 79 | return new JsonObject(readFromInputStream(is)); 80 | } catch (NullPointerException | DecodeException | IOException e) { 81 | throw new VertxException(e); 82 | } 83 | } 84 | 85 | public static InputStream lookupFiles(Class clazz, String... files) { 86 | ClassLoader ctxClsLoader = Thread.currentThread().getContextClassLoader(); 87 | InputStream is = null; 88 | for (String file : files) { 89 | if (ctxClsLoader != null) { 90 | is = ctxClsLoader.getResourceAsStream(file); 91 | } 92 | if (is == null) { 93 | is = clazz.getClassLoader().getResourceAsStream(file); 94 | } 95 | if (is != null) { 96 | break; 97 | } 98 | } 99 | return is; 100 | } 101 | 102 | private static String readFromInputStream(InputStream inputStream) throws IOException { 103 | StringBuilder resultStringBuilder = new StringBuilder(); 104 | try (BufferedReader br = new BufferedReader(new InputStreamReader(inputStream))) { 105 | String line; 106 | while ((line = br.readLine()) != null) { 107 | resultStringBuilder.append(line).append("\n"); 108 | } 109 | } 110 | return resultStringBuilder.toString(); 111 | } 112 | 113 | public static IgniteConfiguration toIgniteConfig(Vertx vertx, IgniteOptions options) { 114 | IgniteConfiguration configuration = new IgniteConfiguration(); 115 | 116 | configuration 117 | .setLocalHost(options.getLocalHost()) 118 | .setCommunicationSpi( 119 | new TcpCommunicationSpi() 120 | .setLocalPort(options.getLocalPort()) 121 | .setConnectionsPerNode(options.getConnectionsPerNode()) 122 | .setConnectTimeout(options.getConnectTimeout()) 123 | .setIdleConnectionTimeout(options.getIdleConnectionTimeout()) 124 | .setMaxConnectTimeout(options.getMaxConnectTimeout()) 125 | .setReconnectCount(options.getReconnectCount()) 126 | ) 127 | .setDiscoverySpi(toDiscoverySpiConfig(options.getDiscoverySpi())) 128 | .setMetricExporterSpi(toMetricExporterSpi(options.getMetricExporterSpi())) 129 | .setCacheConfiguration( 130 | options.getCacheConfiguration().stream() 131 | .map(ConfigHelper::toCacheConfiguration) 132 | .toArray(CacheConfiguration[]::new) 133 | ) 134 | .setMetricsLogFrequency(options.getMetricsLogFrequency()) 135 | .setMetricsUpdateFrequency(options.getMetricsUpdateFrequency()) 136 | .setClientFailureDetectionTimeout(options.getClientFailureDetectionTimeout()) 137 | .setMetricsHistorySize(options.getMetricsHistorySize()) 138 | .setMetricsExpireTime(options.getMetricsExpireTime()); 139 | 140 | if (options.getSslContextFactory() != null) { 141 | configuration.setSslContextFactory(toSslContextFactoryConfig(vertx, options.getSslContextFactory())); 142 | } 143 | 144 | configuration.setDataStorageConfiguration( 145 | new DataStorageConfiguration() 146 | .setPageSize(options.getPageSize()) 147 | .setDefaultDataRegionConfiguration( 148 | new DataRegionConfiguration() 149 | .setName(DFLT_DATA_REG_DEFAULT_NAME) 150 | .setInitialSize(options.getDefaultRegionInitialSize()) 151 | .setMaxSize(Math.max(options.getDefaultRegionMaxSize(), options.getDefaultRegionInitialSize())) 152 | .setMetricsEnabled(options.isDefaultRegionMetricsEnabled()) 153 | ) 154 | ); 155 | 156 | return configuration; 157 | } 158 | 159 | public static Factory toSslContextFactoryConfig(Vertx vertx, IgniteSslOptions options) { 160 | if (options.getKeyStoreFilePath() == null || options.getKeyStoreFilePath().isEmpty()) { 161 | return createSslFactory(vertx, options); 162 | } 163 | return createIgniteSslFactory(options); 164 | } 165 | 166 | @Deprecated 167 | private static Factory createIgniteSslFactory(IgniteSslOptions options) { 168 | SslContextFactory sslContextFactory = new SslContextFactory(); 169 | sslContextFactory.setProtocol(options.getProtocol()); 170 | sslContextFactory.setKeyAlgorithm(options.getKeyAlgorithm()); 171 | sslContextFactory.setKeyStoreType(options.getKeyStoreType()); 172 | sslContextFactory.setKeyStoreFilePath(options.getKeyStoreFilePath()); 173 | if (options.getKeyStorePassword() != null) { 174 | sslContextFactory.setKeyStorePassword(options.getKeyStorePassword().toCharArray()); 175 | } 176 | sslContextFactory.setTrustStoreType(options.getTrustStoreType()); 177 | sslContextFactory.setTrustStoreFilePath(options.getTrustStoreFilePath()); 178 | if (options.getTrustStorePassword() != null) { 179 | sslContextFactory.setTrustStorePassword(options.getTrustStorePassword().toCharArray()); 180 | } 181 | if (options.isTrustAll()) { 182 | sslContextFactory.setTrustManagers(getDisabledTrustManager()); 183 | } 184 | return sslContextFactory; 185 | } 186 | 187 | private static Factory createSslFactory(Vertx vertx, IgniteSslOptions options) { 188 | final SecureRandom random = new SecureRandom(); 189 | final List keyManagers = new ArrayList<>(); 190 | final List trustManagers = new ArrayList<>(); 191 | try { 192 | keyManagers.addAll(toKeyManagers(vertx, options.getPemKeyCertOptions())); 193 | trustManagers.addAll(toTrustManagers(vertx, options.getPemTrustOptions())); 194 | keyManagers.addAll(toKeyManagers(vertx, options.getPfxKeyCertOptions())); 195 | trustManagers.addAll(toTrustManagers(vertx, options.getPfxTrustOptions())); 196 | keyManagers.addAll(toKeyManagers(vertx, options.getJksKeyCertOptions())); 197 | trustManagers.addAll(toTrustManagers(vertx, options.getPfxTrustOptions())); 198 | } catch (Exception e) { 199 | throw new IgniteException(e); 200 | } 201 | if (keyManagers.isEmpty()) { 202 | return null; 203 | } 204 | if (options.isTrustAll()) { 205 | trustManagers.clear(); 206 | trustManagers.add(getDisabledTrustManager()); 207 | } 208 | final KeyManager[] keyManagerArray = keyManagers.toArray(new KeyManager[0]); 209 | final TrustManager[] trustManagerArray = trustManagers.toArray(new TrustManager[0]); 210 | return () -> { 211 | try { 212 | SSLContext sslContext = SSLContext.getInstance(options.getProtocol()); 213 | sslContext.init(keyManagerArray, trustManagerArray, random); 214 | return sslContext; 215 | } catch (NoSuchAlgorithmException | KeyManagementException e) { 216 | throw new IgniteException(e); 217 | } 218 | }; 219 | } 220 | 221 | private static List toKeyManagers(Vertx vertx, KeyCertOptions keyCertOptions) throws Exception { 222 | if (keyCertOptions != null) { 223 | return Arrays.asList(keyCertOptions.getKeyManagerFactory(vertx).getKeyManagers()); 224 | } 225 | return new ArrayList<>(); 226 | } 227 | 228 | private static List toTrustManagers(Vertx vertx, TrustOptions trustOptions) throws Exception { 229 | if (trustOptions != null) { 230 | return Arrays.asList(trustOptions.getTrustManagerFactory(vertx).getTrustManagers()); 231 | } 232 | return new ArrayList<>(); 233 | } 234 | 235 | private static DiscoverySpi toDiscoverySpiConfig(IgniteDiscoveryOptions options) { 236 | if (options.getCustomSpi() != null) { 237 | return options.getCustomSpi(); 238 | } 239 | JsonObject properties = options.getProperties(); 240 | switch (options.getType()) { 241 | case "TcpDiscoveryVmIpFinder": 242 | return new TcpDiscoverySpi() 243 | .setJoinTimeout(properties.getLong("joinTimeout", DFLT_JOIN_TIMEOUT)) 244 | .setLocalAddress(properties.getString("localAddress", null)) 245 | .setLocalPort(properties.getInteger("localPort", DFLT_PORT)) 246 | .setLocalPortRange(properties.getInteger("localPortRange", DFLT_PORT_RANGE)) 247 | .setIpFinder(new TcpDiscoveryVmIpFinder() 248 | .setAddresses(properties.getJsonArray("addresses", new JsonArray()).stream() 249 | .map(Object::toString) 250 | .collect(Collectors.toList()) 251 | ) 252 | ); 253 | case "TcpDiscoveryMulticastIpFinder": 254 | return new TcpDiscoverySpi() 255 | .setJoinTimeout(properties.getLong("joinTimeout", DFLT_JOIN_TIMEOUT)) 256 | .setLocalAddress(properties.getString("localAddress", null)) 257 | .setLocalPort(properties.getInteger("localPort", DFLT_PORT)) 258 | .setLocalPortRange(properties.getInteger("localPortRange", DFLT_PORT_RANGE)) 259 | .setIpFinder(new TcpDiscoveryMulticastIpFinder() 260 | .setAddressRequestAttempts(properties.getInteger("addressRequestAttempts", DFLT_ADDR_REQ_ATTEMPTS)) 261 | .setLocalAddress(properties.getString("localAddress", null)) 262 | .setMulticastGroup(properties.getString("multicastGroup", DFLT_MCAST_GROUP)) 263 | .setMulticastPort(properties.getInteger("multicastPort", DFLT_MCAST_PORT)) 264 | .setResponseWaitTime(properties.getInteger("responseWaitTime", DFLT_RES_WAIT_TIME)) 265 | .setTimeToLive(properties.getInteger("timeToLive", -1)) 266 | .setAddresses(properties.getJsonArray("addresses", new JsonArray()).stream() 267 | .map(Object::toString) 268 | .collect(Collectors.toList()) 269 | ) 270 | ); 271 | default: 272 | throw new VertxException("not discovery spi found"); 273 | } 274 | } 275 | 276 | private static MetricExporterSpi[] toMetricExporterSpi(IgniteMetricExporterOptions options) { 277 | return Optional.ofNullable(options) 278 | .map(IgniteMetricExporterOptions::getCustomSpi) 279 | .map(spi -> new MetricExporterSpi[]{spi}) 280 | .orElse(new MetricExporterSpi[0]); 281 | } 282 | 283 | private static CacheConfiguration toCacheConfiguration(IgniteCacheOptions options) { 284 | CacheConfiguration cfg = new CacheConfiguration<>() 285 | .setName(options.getName()) 286 | .setCacheMode(CacheMode.valueOf(options.getCacheMode())) 287 | .setBackups(options.getBackups()) 288 | .setReadFromBackup(options.isReadFromBackup()) 289 | .setAtomicityMode(CacheAtomicityMode.valueOf(options.getAtomicityMode())) 290 | .setWriteSynchronizationMode(CacheWriteSynchronizationMode.valueOf(options.getWriteSynchronizationMode())) 291 | .setCopyOnRead(options.isCopyOnRead()) 292 | .setEagerTtl(options.isEagerTtl()) 293 | .setEncryptionEnabled(options.isEncryptionEnabled()) 294 | .setGroupName(options.getGroupName()) 295 | .setInvalidate(options.isInvalidate()) 296 | .setMaxConcurrentAsyncOperations(options.getMaxConcurrentAsyncOperations()) 297 | .setOnheapCacheEnabled(options.isOnheapCacheEnabled()) 298 | .setPartitionLossPolicy(PartitionLossPolicy.valueOf(options.getPartitionLossPolicy())) 299 | .setRebalanceMode(CacheRebalanceMode.valueOf(options.getRebalanceMode())) 300 | .setRebalanceOrder(options.getRebalanceOrder()) 301 | .setRebalanceDelay(options.getRebalanceDelay()) 302 | .setMaxQueryIteratorsCount(options.getMaxQueryInteratorsCount()) 303 | .setEventsDisabled(options.isEventsDisabled()) 304 | .setStatisticsEnabled(options.isMetricsEnabled()); 305 | if (options.getExpiryPolicy() != null) { 306 | Duration duration = new Duration(TimeUnit.MILLISECONDS, options.getExpiryPolicy().getLong("duration")); 307 | Factory factory; 308 | switch (options.getExpiryPolicy().getString("type", "created")) { 309 | case "accessed": 310 | factory = AccessedExpiryPolicy.factoryOf(duration); 311 | break; 312 | case "modified": 313 | factory = ModifiedExpiryPolicy.factoryOf(duration); 314 | break; 315 | case "touched": 316 | factory = TouchedExpiryPolicy.factoryOf(duration); 317 | break; 318 | case "created": 319 | default: 320 | factory = CreatedExpiryPolicy.factoryOf(duration); 321 | } 322 | cfg.setExpiryPolicyFactory(factory); 323 | } 324 | return cfg; 325 | } 326 | } 327 | -------------------------------------------------------------------------------- /src/main/resources/META-INF/services/io.vertx.core.spi.VertxServiceProvider: -------------------------------------------------------------------------------- 1 | io.vertx.spi.cluster.ignite.IgniteClusterManager -------------------------------------------------------------------------------- /src/main/resources/default-ignite.json: -------------------------------------------------------------------------------- 1 | { 2 | "cacheConfiguration": [ 3 | { 4 | "name": "__vertx.*", 5 | "cacheMode": "REPLICATED", 6 | "atomicityMode": "ATOMIC", 7 | "writeSynchronizationMode": "FULL_SYNC" 8 | }, { 9 | "name": "*", 10 | "cacheMode": "PARTITIONED", 11 | "backups": 1, 12 | "readFromBackup": false, 13 | "atomicityMode": "ATOMIC", 14 | "writeSynchronizationMode": "FULL_SYNC" 15 | } 16 | ], 17 | "metricsLogFrequency": 0, 18 | "shutdownOnSegmentation": true 19 | } 20 | -------------------------------------------------------------------------------- /src/test/java/io/vertx/Lifecycle.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Red Hat, Inc. 3 | * 4 | * Red Hat licenses this file to you under the Apache License, version 2.0 5 | * (the "License"); you may not use this file except in compliance with the 6 | * License. You may obtain a copy of the License at: 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | package io.vertx; 17 | 18 | import io.vertx.core.Vertx; 19 | import io.vertx.core.internal.logging.Logger; 20 | import io.vertx.core.internal.logging.LoggerFactory; 21 | import org.apache.ignite.Ignite; 22 | import org.apache.ignite.internal.IgniteEx; 23 | import org.apache.ignite.internal.binary.BinaryEnumCache; 24 | import org.apache.ignite.internal.util.GridClassLoaderCache; 25 | import org.apache.ignite.internal.util.IgniteUtils; 26 | import org.apache.ignite.internal.util.typedef.G; 27 | import org.apache.ignite.internal.util.typedef.internal.U; 28 | import org.apache.ignite.marshaller.MarshallerExclusions; 29 | 30 | import java.util.ArrayList; 31 | import java.util.Collection; 32 | import java.util.List; 33 | import java.util.UUID; 34 | import java.util.concurrent.CountDownLatch; 35 | import java.util.concurrent.TimeUnit; 36 | 37 | import static org.junit.Assert.assertTrue; 38 | 39 | /** 40 | * @author Thomas Segismont 41 | * @author Lukas Prettenthaler 42 | */ 43 | public class Lifecycle { 44 | private static final Logger log = LoggerFactory.getLogger(Lifecycle.class); 45 | 46 | public static void close(List clustered) throws Exception { 47 | CountDownLatch latch = new CountDownLatch(clustered.size()); 48 | for (Vertx clusteredVertx : clustered) { 49 | Thread.sleep(500L); 50 | clusteredVertx.close().onComplete(ar -> { 51 | if (ar.failed()) { 52 | log.error("Failed to shutdown vert.x", ar.cause()); 53 | } 54 | latch.countDown(); 55 | }); 56 | } 57 | assertTrue(latch.await(180, TimeUnit.SECONDS)); 58 | 59 | Thread.sleep(200L); 60 | 61 | Collection list = new ArrayList<>(G.allGrids()); 62 | 63 | for (Ignite g : list) { 64 | stopGrid(g.name()); 65 | } 66 | 67 | List nodes = G.allGrids(); 68 | 69 | assert nodes.isEmpty() : nodes; 70 | 71 | GridClassLoaderCache.clear(); 72 | U.clearClassCache(); 73 | MarshallerExclusions.clearCache(); 74 | BinaryEnumCache.clear(); 75 | } 76 | 77 | private static void stopGrid(String igniteInstanceName) { 78 | try { 79 | IgniteEx ignite = (IgniteEx) G.ignite(igniteInstanceName); 80 | 81 | assert ignite != null : "Ignite returned null grid for name: " + igniteInstanceName; 82 | 83 | UUID id = ignite.context().localNodeId(); 84 | log.info(">>> Stopping grid [name=" + ignite.name() + ", id=" + id + ']'); 85 | IgniteUtils.setCurrentIgniteName(igniteInstanceName); 86 | 87 | try { 88 | G.stop(igniteInstanceName, true); 89 | } finally { 90 | IgniteUtils.setCurrentIgniteName(null); 91 | } 92 | } catch (IllegalStateException ignored) { 93 | // Ignore error if grid already stopped. 94 | } catch (Throwable e) { 95 | log.error("Failed to stop grid [igniteInstanceName=" + igniteInstanceName + ']', e); 96 | } 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /src/test/java/io/vertx/LoggingTestWatcher.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Red Hat, Inc. 3 | * 4 | * Red Hat licenses this file to you under the Apache License, version 2.0 5 | * (the "License"); you may not use this file except in compliance with the 6 | * License. You may obtain a copy of the License at: 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | package io.vertx; 18 | 19 | import org.junit.rules.TestWatcher; 20 | import org.junit.runner.Description; 21 | 22 | /** 23 | * @author Thomas Segismont 24 | */ 25 | public class LoggingTestWatcher extends TestWatcher { 26 | 27 | @Override 28 | protected void starting(Description description) { 29 | System.out.printf("Running %s#%s %s", description.getClassName(), description.getMethodName(), System.getProperty("line.separator")); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/test/java/io/vertx/core/IgniteComplexHATest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 The original author or authors 3 | * --------------------------------- 4 | * 5 | * All rights reserved. This program and the accompanying materials 6 | * are made available under the terms of the Eclipse Public License v1.0 7 | * and Apache License v2.0 which accompanies this distribution. 8 | * 9 | * The Eclipse Public License is available at 10 | * http://www.eclipse.org/legal/epl-v10.html 11 | * 12 | * The Apache License v2.0 is available at 13 | * http://www.opensource.org/licenses/apache2.0.php 14 | * 15 | * You may elect to redistribute this code under either of these licenses. 16 | */ 17 | 18 | package io.vertx.core; 19 | 20 | import io.vertx.Lifecycle; 21 | import io.vertx.LoggingTestWatcher; 22 | import io.vertx.core.spi.cluster.ClusterManager; 23 | import io.vertx.spi.cluster.ignite.IgniteClusterManager; 24 | import org.junit.Rule; 25 | import org.junit.rules.TemporaryFolder; 26 | 27 | import java.util.List; 28 | 29 | import static java.util.concurrent.TimeUnit.MILLISECONDS; 30 | 31 | /** 32 | * @author Andrey Gura 33 | */ 34 | public class IgniteComplexHATest extends io.vertx.tests.ha.ComplexHATest { 35 | 36 | @Rule 37 | public LoggingTestWatcher watchman = new LoggingTestWatcher(); 38 | 39 | @Rule 40 | public TemporaryFolder temporaryFolder = new TemporaryFolder(); 41 | 42 | @Override 43 | public void setUp() throws Exception { 44 | System.setProperty("IGNITE_HOME", temporaryFolder.newFolder().getAbsolutePath()); 45 | super.setUp(); 46 | } 47 | 48 | @Override 49 | protected Future clusteredVertx(VertxOptions options) { 50 | try { 51 | MILLISECONDS.sleep(1000L); 52 | } catch (InterruptedException e) { 53 | throw new RuntimeException(e); 54 | } 55 | return super.clusteredVertx(options); 56 | } 57 | 58 | @Override 59 | protected ClusterManager getClusterManager() { 60 | return new IgniteClusterManager(); 61 | } 62 | 63 | @Override 64 | protected void close(List clustered) throws Exception { 65 | Lifecycle.close(clustered); 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /src/test/java/io/vertx/core/IgniteHATest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 The original author or authors 3 | * --------------------------------- 4 | * 5 | * All rights reserved. This program and the accompanying materials 6 | * are made available under the terms of the Eclipse Public License v1.0 7 | * and Apache License v2.0 which accompanies this distribution. 8 | * 9 | * The Eclipse Public License is available at 10 | * http://www.eclipse.org/legal/epl-v10.html 11 | * 12 | * The Apache License v2.0 is available at 13 | * http://www.opensource.org/licenses/apache2.0.php 14 | * 15 | * You may elect to redistribute this code under either of these licenses. 16 | */ 17 | 18 | package io.vertx.core; 19 | 20 | import io.vertx.Lifecycle; 21 | import io.vertx.LoggingTestWatcher; 22 | import io.vertx.core.spi.cluster.ClusterManager; 23 | import io.vertx.spi.cluster.ignite.IgniteClusterManager; 24 | import org.junit.Rule; 25 | import org.junit.rules.TemporaryFolder; 26 | 27 | import java.util.List; 28 | 29 | /** 30 | * @author Andrey Gura 31 | */ 32 | public class IgniteHATest extends io.vertx.tests.ha.HATest { 33 | 34 | @Rule 35 | public LoggingTestWatcher watchman = new LoggingTestWatcher(); 36 | 37 | @Rule 38 | public TemporaryFolder temporaryFolder = new TemporaryFolder(); 39 | 40 | @Override 41 | public void setUp() throws Exception { 42 | System.setProperty("IGNITE_HOME", temporaryFolder.newFolder().getAbsolutePath()); 43 | super.setUp(); 44 | } 45 | 46 | @Override 47 | protected ClusterManager getClusterManager() { 48 | return new IgniteClusterManager(); 49 | } 50 | 51 | @Override 52 | protected void close(List clustered) throws Exception { 53 | Lifecycle.close(clustered); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/test/java/io/vertx/core/eventbus/IgniteClusteredEventbusTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 The original author or authors 3 | * --------------------------------- 4 | * 5 | * All rights reserved. This program and the accompanying materials 6 | * are made available under the terms of the Eclipse Public License v1.0 7 | * and Apache License v2.0 which accompanies this distribution. 8 | * 9 | * The Eclipse Public License is available at 10 | * http://www.eclipse.org/legal/epl-v10.html 11 | * 12 | * The Apache License v2.0 is available at 13 | * http://www.opensource.org/licenses/apache2.0.php 14 | * 15 | * You may elect to redistribute this code under either of these licenses. 16 | */ 17 | 18 | package io.vertx.core.eventbus; 19 | 20 | import io.vertx.Lifecycle; 21 | import io.vertx.LoggingTestWatcher; 22 | import io.vertx.core.Vertx; 23 | import io.vertx.core.spi.cluster.*; 24 | import io.vertx.spi.cluster.ignite.IgniteClusterManager; 25 | import org.junit.Rule; 26 | import org.junit.rules.TemporaryFolder; 27 | 28 | import java.util.List; 29 | 30 | /** 31 | * @author Andrey Gura 32 | */ 33 | public class IgniteClusteredEventbusTest extends io.vertx.tests.eventbus.ClusteredEventBusTest { 34 | 35 | @Rule 36 | public LoggingTestWatcher watchman = new LoggingTestWatcher(); 37 | 38 | @Rule 39 | public TemporaryFolder temporaryFolder = new TemporaryFolder(); 40 | 41 | @Override 42 | public void setUp() throws Exception { 43 | System.setProperty("IGNITE_HOME", temporaryFolder.newFolder().getAbsolutePath()); 44 | super.setUp(); 45 | } 46 | 47 | @Override 48 | protected ClusterManager getClusterManager() { 49 | return new IgniteClusterManager(); 50 | } 51 | 52 | @Override 53 | protected void close(List clustered) throws Exception { 54 | Lifecycle.close(clustered); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/test/java/io/vertx/core/eventbus/IgniteFaultToleranceTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2022 Red Hat, Inc. 3 | * 4 | * Red Hat licenses this file to you under the Apache License, version 2.0 5 | * (the "License"); you may not use this file except in compliance with the 6 | * License. You may obtain a copy of the License at: 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | package io.vertx.core.eventbus; 17 | 18 | import io.vertx.Lifecycle; 19 | import io.vertx.core.Vertx; 20 | import io.vertx.core.spi.cluster.ClusterManager; 21 | import io.vertx.spi.cluster.ignite.IgniteClusterManager; 22 | 23 | import java.util.Arrays; 24 | import java.util.List; 25 | 26 | import static java.util.concurrent.TimeUnit.MILLISECONDS; 27 | 28 | /** 29 | * @author Andrey Gura 30 | */ 31 | public class IgniteFaultToleranceTest extends io.vertx.tests.eventbus.FaultToleranceTest { 32 | 33 | @Override 34 | protected ClusterManager getClusterManager() { 35 | return new IgniteClusterManager(); 36 | } 37 | 38 | @Override 39 | protected List getExternalNodeSystemProperties() { 40 | try { 41 | // is java 9+ 42 | Class.forName("java.lang.module.ModuleFinder"); 43 | return Arrays.asList( 44 | "-Dvertx.logger-delegate-factory-class-name=io.vertx.core.logging.SLF4JLogDelegateFactory", 45 | "-Djava.net.preferIPv4Stack=true", 46 | "--add-opens=java.base/java.nio=ALL-UNNAMED", 47 | "--add-opens=java.base/java.util=ALL-UNNAMED", 48 | "--add-opens=java.base/java.lang.invoke=ALL-UNNAMED", 49 | "--add-opens=java.base/java.lang=ALL-UNNAMED" 50 | ); 51 | } catch(ClassNotFoundException e) { 52 | return Arrays.asList( 53 | "-Dvertx.logger-delegate-factory-class-name=io.vertx.core.logging.SLF4JLogDelegateFactory", 54 | "-Djava.net.preferIPv4Stack=true" 55 | ); 56 | } 57 | } 58 | 59 | @Override 60 | protected void afterNodeStarted(int i, Process process) throws Exception { 61 | super.afterNodeStarted(i, process); 62 | MILLISECONDS.sleep(500L); 63 | } 64 | 65 | @Override 66 | protected void afterNodesKilled() throws Exception { 67 | super.afterNodesKilled(); 68 | // Additional wait to make sure all nodes noticed the shutdowns 69 | Thread.sleep(10_000); 70 | } 71 | 72 | @Override 73 | protected void close(List clustered) throws Exception { 74 | Lifecycle.close(clustered); 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /src/test/java/io/vertx/core/eventbus/IgniteNodeInfoTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2020 The original author or authors 3 | * --------------------------------- 4 | * 5 | * All rights reserved. This program and the accompanying materials 6 | * are made available under the terms of the Eclipse Public License v1.0 7 | * and Apache License v2.0 which accompanies this distribution. 8 | * 9 | * The Eclipse Public License is available at 10 | * http://www.eclipse.org/legal/epl-v10.html 11 | * 12 | * The Apache License v2.0 is available at 13 | * http://www.opensource.org/licenses/apache2.0.php 14 | * 15 | * You may elect to redistribute this code under either of these licenses. 16 | */ 17 | 18 | package io.vertx.core.eventbus; 19 | 20 | import io.vertx.Lifecycle; 21 | import io.vertx.LoggingTestWatcher; 22 | import io.vertx.core.Vertx; 23 | import io.vertx.core.spi.cluster.ClusterManager; 24 | import io.vertx.spi.cluster.ignite.IgniteClusterManager; 25 | import org.junit.Rule; 26 | import org.junit.rules.TemporaryFolder; 27 | 28 | import java.util.List; 29 | 30 | /** 31 | * @author Thomas Segismont 32 | */ 33 | public class IgniteNodeInfoTest extends io.vertx.tests.eventbus.NodeInfoTest { 34 | 35 | @Rule 36 | public LoggingTestWatcher watchman = new LoggingTestWatcher(); 37 | 38 | @Rule 39 | public TemporaryFolder temporaryFolder = new TemporaryFolder(); 40 | 41 | @Override 42 | public void setUp() throws Exception { 43 | System.setProperty("IGNITE_HOME", temporaryFolder.newFolder().getAbsolutePath()); 44 | super.setUp(); 45 | } 46 | 47 | @Override 48 | protected ClusterManager getClusterManager() { 49 | return new IgniteClusterManager(); 50 | } 51 | 52 | @Override 53 | protected void close(List clustered) throws Exception { 54 | Lifecycle.close(clustered); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/test/java/io/vertx/core/shareddata/IgniteClusteredAsyncMapTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 The original author or authors 3 | * --------------------------------- 4 | * 5 | * All rights reserved. This program and the accompanying materials 6 | * are made available under the terms of the Eclipse Public License v1.0 7 | * and Apache License v2.0 which accompanies this distribution. 8 | * 9 | * The Eclipse Public License is available at 10 | * http://www.eclipse.org/legal/epl-v10.html 11 | * 12 | * The Apache License v2.0 is available at 13 | * http://www.opensource.org/licenses/apache2.0.php 14 | * 15 | * You may elect to redistribute this code under either of these licenses. 16 | */ 17 | 18 | package io.vertx.core.shareddata; 19 | 20 | import io.vertx.Lifecycle; 21 | import io.vertx.LoggingTestWatcher; 22 | import io.vertx.core.Vertx; 23 | import io.vertx.core.spi.cluster.ClusterManager; 24 | import io.vertx.spi.cluster.ignite.IgniteClusterManager; 25 | import org.junit.Rule; 26 | import org.junit.rules.TemporaryFolder; 27 | 28 | import java.util.List; 29 | 30 | /** 31 | * @author Andrey Gura 32 | */ 33 | public class IgniteClusteredAsyncMapTest extends io.vertx.tests.shareddata.ClusteredAsyncMapTest { 34 | 35 | @Rule 36 | public LoggingTestWatcher watchman = new LoggingTestWatcher(); 37 | 38 | @Rule 39 | public TemporaryFolder temporaryFolder = new TemporaryFolder(); 40 | 41 | @Override 42 | public void setUp() throws Exception { 43 | System.setProperty("IGNITE_HOME", temporaryFolder.newFolder().getAbsolutePath()); 44 | super.setUp(); 45 | } 46 | 47 | @Override 48 | protected ClusterManager getClusterManager() { 49 | return new IgniteClusterManager(); 50 | } 51 | 52 | @Override 53 | protected void close(List clustered) throws Exception { 54 | Lifecycle.close(clustered); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/test/java/io/vertx/core/shareddata/IgniteClusteredAsynchronousLockTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 The original author or authors 3 | * --------------------------------- 4 | * 5 | * All rights reserved. This program and the accompanying materials 6 | * are made available under the terms of the Eclipse Public License v1.0 7 | * and Apache License v2.0 which accompanies this distribution. 8 | * 9 | * The Eclipse Public License is available at 10 | * http://www.eclipse.org/legal/epl-v10.html 11 | * 12 | * The Apache License v2.0 is available at 13 | * http://www.opensource.org/licenses/apache2.0.php 14 | * 15 | * You may elect to redistribute this code under either of these licenses. 16 | */ 17 | 18 | package io.vertx.core.shareddata; 19 | 20 | import io.vertx.Lifecycle; 21 | import io.vertx.LoggingTestWatcher; 22 | import io.vertx.core.Vertx; 23 | import io.vertx.core.spi.cluster.ClusterManager; 24 | import io.vertx.spi.cluster.ignite.IgniteClusterManager; 25 | import org.junit.Rule; 26 | import org.junit.Test; 27 | import org.junit.rules.TemporaryFolder; 28 | 29 | import java.util.List; 30 | 31 | /** 32 | * @author Andrey Gura 33 | */ 34 | public class IgniteClusteredAsynchronousLockTest extends io.vertx.tests.shareddata.ClusteredAsynchronousLockTest { 35 | 36 | @Rule 37 | public LoggingTestWatcher watchman = new LoggingTestWatcher(); 38 | 39 | @Rule 40 | public TemporaryFolder temporaryFolder = new TemporaryFolder(); 41 | 42 | @Override 43 | public void setUp() throws Exception { 44 | System.setProperty("IGNITE_HOME", temporaryFolder.newFolder().getAbsolutePath()); 45 | super.setUp(); 46 | } 47 | 48 | @Override 49 | protected ClusterManager getClusterManager() { 50 | return new IgniteClusterManager(); 51 | } 52 | 53 | @Test 54 | @Override 55 | public void testLockReleasedForClosedNode() throws Exception { 56 | super.testLockReleasedForClosedNode(); 57 | } 58 | 59 | @Test 60 | @Override 61 | public void testLockReleasedForKilledNode() throws Exception { 62 | super.testLockReleasedForKilledNode(); 63 | } 64 | 65 | @Override 66 | protected void close(List clustered) throws Exception { 67 | Lifecycle.close(clustered); 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/test/java/io/vertx/core/shareddata/IgniteClusteredSharedCounterTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 The original author or authors 3 | * --------------------------------- 4 | * 5 | * All rights reserved. This program and the accompanying materials 6 | * are made available under the terms of the Eclipse Public License v1.0 7 | * and Apache License v2.0 which accompanies this distribution. 8 | * 9 | * The Eclipse Public License is available at 10 | * http://www.eclipse.org/legal/epl-v10.html 11 | * 12 | * The Apache License v2.0 is available at 13 | * http://www.opensource.org/licenses/apache2.0.php 14 | * 15 | * You may elect to redistribute this code under either of these licenses. 16 | */ 17 | 18 | package io.vertx.core.shareddata; 19 | 20 | import io.vertx.Lifecycle; 21 | import io.vertx.LoggingTestWatcher; 22 | import io.vertx.core.Vertx; 23 | import io.vertx.core.spi.cluster.ClusterManager; 24 | import io.vertx.spi.cluster.ignite.IgniteClusterManager; 25 | import org.junit.Rule; 26 | import org.junit.rules.TemporaryFolder; 27 | 28 | import java.util.List; 29 | 30 | /** 31 | * @author Andrey Gura 32 | */ 33 | public class IgniteClusteredSharedCounterTest extends io.vertx.tests.shareddata.ClusteredSharedCounterTest { 34 | 35 | @Rule 36 | public LoggingTestWatcher watchman = new LoggingTestWatcher(); 37 | 38 | @Rule 39 | public TemporaryFolder temporaryFolder = new TemporaryFolder(); 40 | 41 | @Override 42 | public void setUp() throws Exception { 43 | System.setProperty("IGNITE_HOME", temporaryFolder.newFolder().getAbsolutePath()); 44 | super.setUp(); 45 | } 46 | 47 | @Override 48 | protected ClusterManager getClusterManager() { 49 | return new IgniteClusterManager(); 50 | } 51 | 52 | @Override 53 | protected void close(List clustered) throws Exception { 54 | Lifecycle.close(clustered); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/test/java/io/vertx/ext/web/sstore/IgniteClusteredSessionHandlerTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Red Hat, Inc. 3 | * 4 | * Red Hat licenses this file to you under the Apache License, version 2.0 5 | * (the "License"); you may not use this file except in compliance with the 6 | * License. You may obtain a copy of the License at: 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | package io.vertx.ext.web.sstore; 18 | 19 | import io.vertx.Lifecycle; 20 | import io.vertx.LoggingTestWatcher; 21 | import io.vertx.core.Vertx; 22 | import io.vertx.core.spi.cluster.ClusterManager; 23 | import io.vertx.ext.web.it.sstore.ClusteredSessionHandlerTest; 24 | import io.vertx.spi.cluster.ignite.IgniteClusterManager; 25 | import org.junit.Rule; 26 | import org.junit.rules.TemporaryFolder; 27 | 28 | import java.util.List; 29 | 30 | /** 31 | * @author Thomas Segismont 32 | */ 33 | public class IgniteClusteredSessionHandlerTest extends ClusteredSessionHandlerTest { 34 | 35 | @Rule 36 | public LoggingTestWatcher watchman = new LoggingTestWatcher(); 37 | 38 | @Rule 39 | public TemporaryFolder temporaryFolder = new TemporaryFolder(); 40 | 41 | @Override 42 | public void setUp() throws Exception { 43 | System.setProperty("IGNITE_HOME", temporaryFolder.newFolder().getAbsolutePath()); 44 | super.setUp(); 45 | } 46 | 47 | @Override 48 | protected ClusterManager getClusterManager() { 49 | return new IgniteClusterManager(); 50 | } 51 | 52 | @Override 53 | protected void close(List clustered) throws Exception { 54 | Lifecycle.close(clustered); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /src/test/java/io/vertx/it/core/ServiceProviderTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2018 Red Hat, Inc. 3 | * 4 | * Red Hat licenses this file to you under the Apache License, version 2.0 5 | * (the "License"); you may not use this file except in compliance with the 6 | * License. You may obtain a copy of the License at: 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | package io.vertx.it.core; 18 | 19 | import io.vertx.core.Vertx; 20 | import io.vertx.core.VertxOptions; 21 | import io.vertx.core.internal.VertxInternal; 22 | import io.vertx.spi.cluster.ignite.IgniteClusterManager; 23 | import org.junit.Test; 24 | 25 | import java.util.concurrent.CompletableFuture; 26 | import java.util.concurrent.TimeUnit; 27 | 28 | import static org.junit.Assert.assertTrue; 29 | 30 | public class ServiceProviderTest { 31 | 32 | @Test 33 | public void testDiscovery() throws Exception { 34 | CompletableFuture result = new CompletableFuture<>(); 35 | Vertx v1 = Vertx.clusteredVertx(new VertxOptions()).toCompletionStage().toCompletableFuture().get(30, TimeUnit.SECONDS); 36 | Vertx v2 = Vertx.clusteredVertx(new VertxOptions()).toCompletionStage().toCompletableFuture().get(30, TimeUnit.SECONDS); 37 | assertTrue(((VertxInternal) v1).clusterManager() instanceof IgniteClusterManager); 38 | assertTrue(((VertxInternal) v2).clusterManager() instanceof IgniteClusterManager); 39 | v1.eventBus().consumer("the-address", msg -> { 40 | if ("ping".equals(msg.body())) { 41 | result.complete(null); 42 | } else { 43 | result.completeExceptionally(new Exception()); 44 | } 45 | }).completion().onComplete(ar -> { 46 | if (ar.succeeded()) { 47 | v2.eventBus().send("the-address", "ping"); 48 | } else { 49 | result.completeExceptionally(ar.cause()); 50 | } 51 | }); 52 | result.get(30, TimeUnit.SECONDS); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/test/java/io/vertx/servicediscovery/impl/IgniteDiscoveryImplClusteredTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Red Hat, Inc. 3 | * 4 | * Red Hat licenses this file to you under the Apache License, version 2.0 5 | * (the "License"); you may not use this file except in compliance with the 6 | * License. You may obtain a copy of the License at: 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | package io.vertx.servicediscovery.impl; 17 | 18 | import io.vertx.LoggingTestWatcher; 19 | import io.vertx.core.Vertx; 20 | import io.vertx.core.VertxOptions; 21 | import io.vertx.servicediscovery.ServiceDiscoveryOptions; 22 | import io.vertx.spi.cluster.ignite.IgniteClusterManager; 23 | import org.junit.Before; 24 | import org.junit.Rule; 25 | import org.junit.rules.TemporaryFolder; 26 | 27 | import static com.jayway.awaitility.Awaitility.await; 28 | 29 | /** 30 | * @author Thomas Segismont 31 | * @author Lukas Prettenthaler 32 | */ 33 | public class IgniteDiscoveryImplClusteredTest extends DiscoveryImplTestBase { 34 | 35 | @Rule 36 | public LoggingTestWatcher watchman = new LoggingTestWatcher(); 37 | 38 | @Rule 39 | public TemporaryFolder temporaryFolder = new TemporaryFolder(); 40 | 41 | @Before 42 | public void setUp() throws Exception { 43 | System.setProperty("IGNITE_HOME", temporaryFolder.newFolder().getAbsolutePath()); 44 | Vertx.builder().withClusterManager(new IgniteClusterManager()).buildClustered().onComplete(ar -> { 45 | vertx = ar.result(); 46 | }); 47 | await().until(() -> vertx != null); 48 | discovery = new DiscoveryImpl(vertx, new ServiceDiscoveryOptions()); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/test/java/io/vertx/spi/cluster/ignite/impl/ThrottlingTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2021 Red Hat, Inc. 3 | * 4 | * Red Hat licenses this file to you under the Apache License, version 2.0 5 | * (the "License"); you may not use this file except in compliance with the 6 | * License. You may obtain a copy of the License at: 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations 14 | * under the License. 15 | */ 16 | 17 | package io.vertx.spi.cluster.ignite.impl; 18 | 19 | import io.vertx.core.Promise; 20 | import io.vertx.core.internal.VertxInternal; 21 | import io.vertx.test.core.VertxTestBase; 22 | import org.junit.Test; 23 | 24 | import java.util.Collections; 25 | import java.util.LinkedList; 26 | import java.util.List; 27 | import java.util.concurrent.*; 28 | 29 | import static java.util.concurrent.TimeUnit.*; 30 | 31 | public class ThrottlingTest extends VertxTestBase { 32 | 33 | int threadCount = 4; 34 | ExecutorService executorService; 35 | 36 | @Override 37 | public void setUp() throws Exception { 38 | super.setUp(); 39 | executorService = Executors.newFixedThreadPool(threadCount); 40 | } 41 | 42 | @Test 43 | public void testInterval() throws Exception { 44 | int duration = 5; 45 | String[] addresses = {"foo", "bar", "baz", "qux"}; 46 | 47 | ConcurrentMap> events = new ConcurrentHashMap<>(addresses.length); 48 | Throttling throttling = new Throttling((VertxInternal) vertx, address -> { 49 | events.compute(address, (k, v) -> { 50 | if (v == null) { 51 | v = Collections.synchronizedList(new LinkedList<>()); 52 | } 53 | v.add(System.nanoTime()); 54 | return v; 55 | }); 56 | Promise promise = Promise.promise(); 57 | vertx.setTimer(1, l -> promise.complete()); 58 | return promise.future(); 59 | }); 60 | 61 | CountDownLatch latch = new CountDownLatch(threadCount); 62 | long start = System.nanoTime(); 63 | for (int i = 0; i < threadCount; i++) { 64 | executorService.submit(() -> { 65 | try { 66 | do { 67 | randomSleep(); 68 | throttling.onEvent(addresses[ThreadLocalRandom.current().nextInt(addresses.length)]); 69 | } while (SECONDS.convert(System.nanoTime() - start, NANOSECONDS) < duration); 70 | } finally { 71 | latch.countDown(); 72 | } 73 | }); 74 | } 75 | latch.await(); 76 | 77 | assertWaitUntil(() -> { 78 | if (events.size() != addresses.length) { 79 | return false; 80 | } 81 | for (List nanoTimes : events.values()) { 82 | // must synchronize on synchronizedList traversal 83 | synchronized (nanoTimes) { 84 | Long previous = null; 85 | for (Long nanoTime : nanoTimes) { 86 | if (previous != null) { 87 | if (MILLISECONDS.convert(nanoTime - previous, NANOSECONDS) < 20) { 88 | return false; 89 | } 90 | } 91 | previous = nanoTime; 92 | } 93 | } 94 | } 95 | return true; 96 | }, 1000); 97 | } 98 | 99 | private void randomSleep() { 100 | try { 101 | MILLISECONDS.sleep(ThreadLocalRandom.current().nextLong(5)); 102 | } catch (InterruptedException e) { 103 | Thread.currentThread().interrupt(); 104 | } 105 | } 106 | 107 | @Override 108 | protected void tearDown() throws Exception { 109 | executorService.shutdown(); 110 | assertTrue(executorService.awaitTermination(5, SECONDS)); 111 | super.tearDown(); 112 | } 113 | } 114 | -------------------------------------------------------------------------------- /src/test/java/io/vertx/spi/cluster/ignite/util/ClasspathHelperTest.java: -------------------------------------------------------------------------------- 1 | package io.vertx.spi.cluster.ignite.util; 2 | 3 | import io.vertx.core.VertxException; 4 | import io.vertx.core.json.JsonObject; 5 | import org.apache.ignite.configuration.IgniteConfiguration; 6 | import org.junit.Test; 7 | 8 | import static org.junit.Assert.assertFalse; 9 | import static org.junit.Assert.assertNotNull; 10 | 11 | public class ClasspathHelperTest { 12 | @Test 13 | public void loadXml() { 14 | IgniteConfiguration config = ConfigHelper.lookupXmlConfiguration(this.getClass(), "ignite-test.xml"); 15 | assertNotNull(config); 16 | } 17 | 18 | @Test(expected = VertxException.class) 19 | public void loadNotExistingXml() { 20 | ConfigHelper.lookupXmlConfiguration(this.getClass(), "does-not-exist.xml"); 21 | } 22 | 23 | @Test 24 | public void loadJson() { 25 | JsonObject config = ConfigHelper.lookupJsonConfiguration(this.getClass(), "ignite.json"); 26 | assertNotNull(config); 27 | assertFalse(config.isEmpty()); 28 | } 29 | 30 | @Test(expected = VertxException.class) 31 | public void loadNotExistingJson() { 32 | ConfigHelper.lookupJsonConfiguration(this.getClass(), "does-not-exist.json"); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/test/resources/ca.p12: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vert-x3/vertx-ignite/10f20e474695a6e40bfef75d4cf5f1ffd64bf259/src/test/resources/ca.p12 -------------------------------------------------------------------------------- /src/test/resources/ca.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIICuTCCAaGgAwIBAgIBATANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdSb290 3 | IENBMB4XDTE4MDUyNjExMzY1MFoXDTI4MDUyMzExMzY1MFowFDESMBAGA1UEAxMJ 4 | bG9jYWxob3N0MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApxQ0vO4D 5 | YwlkftKPLncaVLGchDC+mABbHCVsoMkffQEZ3HzmM2YmAtlQPJ3KpCPlFE0AR3yN 6 | SfhGSwAX6ZMurSpXI0K06+WoXWO/zAX1YvpWOikwiBiv5a1qak555zCcoQv5M2Tv 7 | q8krCq6Iu6MME8E4wAKzYunYA4DysKcFj+lZpmKL0ui5Dubm+KxYsA0zafPve3FS 8 | MGt49FMwWJCD8315b92ia6uTq5mTPOqlfNOGHDOevYOq+7A4PL/Peuk4nIQJn32n 9 | YiwBcl2M7r5jRFAORWriGecCmMEpxBtD2ep9RkbV+mhg+c6/N2TicsjKqUzlOEWH 10 | BMXIzJQJQg+OewIDAQABoxgwFjAUBgNVHREEDTALgglsb2NhbGhvc3QwDQYJKoZI 11 | hvcNAQELBQADggEBAJ9pVuaNvgR3RcNOKnV11OgXN/VsNM4d2plT+bI6FNeme+YX 12 | 6Yu9A2WQmVXf/xuMch2W9OoXlJPq1Q707uy6P+3quUmiWCeWvl+efgRFs8G4BR/E 13 | XsVDE0Ovu8HP/FDn12tY4t/FxKMitkV5mqP4H3QWCAui4UJPbTHcCe9wXTuo1aqu 14 | 1liIIpe//iyhKUpE7atrnt3MpkU0spTWZXj6zRuaDoQ2C//rHLuf6YiFiNHfj5+9 15 | 4UV8v4cHELSn+DqEfzErqUCvj1buSNygjpgtT0jedsMOprm5V5vPArJdjogEt14W 16 | sL3xtm+/3XM2nZBvIclmEoVhiXIUtMArjaFmeQA= 17 | -----END CERTIFICATE----- 18 | -------------------------------------------------------------------------------- /src/test/resources/ignite-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 21 | 22 | 23 | 24 | 25 | 127.0.0.1:47500..47549 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | -------------------------------------------------------------------------------- /src/test/resources/ignite.json: -------------------------------------------------------------------------------- 1 | { 2 | "localHost": "127.0.0.1", 3 | "discoverySpi": { 4 | "type": "TcpDiscoveryVmIpFinder", 5 | "properties": { 6 | "joinTimeout": 10000, 7 | "addresses": ["127.0.0.1:47500..47549"] 8 | } 9 | }, 10 | "cacheConfiguration": [ 11 | { 12 | "name": "__vertx.*", 13 | "cacheMode": "REPLICATED", 14 | "atomicityMode": "ATOMIC", 15 | "writeSynchronizationMode": "FULL_SYNC" 16 | }, { 17 | "name": "*", 18 | "cacheMode": "PARTITIONED", 19 | "backups": 1, 20 | "readFromBackup": false, 21 | "atomicityMode": "ATOMIC", 22 | "writeSynchronizationMode": "FULL_SYNC" 23 | } 24 | ], 25 | "defaultRegionInitialSize": 20971520, 26 | "defaultRegionMaxSize": 41943040, 27 | "metricsLogFrequency": 0, 28 | "shutdownOnSegmentation": false, 29 | "delayAfterStart": 500 30 | } 31 | -------------------------------------------------------------------------------- /src/test/resources/logback-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 19 | 20 | 21 | %d [%thread] %-5level %logger{36} - %msg%n 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /src/test/resources/server-cert.pem: -------------------------------------------------------------------------------- 1 | Bag Attributes 2 | friendlyName: test-store 3 | localKeyID: 54 69 6D 65 20 31 35 32 37 33 33 34 36 31 30 30 31 31 4 | subject=/CN=localhost 5 | issuer=/CN=localhost 6 | -----BEGIN CERTIFICATE----- 7 | MIICxzCCAa+gAwIBAgIEWM3JmDANBgkqhkiG9w0BAQsFADAUMRIwEAYDVQQDEwls 8 | b2NhbGhvc3QwHhcNMTgwNTI2MTEzNjQ5WhcNMjEwNTI1MTEzNjQ5WjAUMRIwEAYD 9 | VQQDEwlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCn 10 | FDS87gNjCWR+0o8udxpUsZyEML6YAFscJWygyR99ARncfOYzZiYC2VA8ncqkI+UU 11 | TQBHfI1J+EZLABfpky6tKlcjQrTr5ahdY7/MBfVi+lY6KTCIGK/lrWpqTnnnMJyh 12 | C/kzZO+rySsKroi7owwTwTjAArNi6dgDgPKwpwWP6VmmYovS6LkO5ub4rFiwDTNp 13 | 8+97cVIwa3j0UzBYkIPzfXlv3aJrq5OrmZM86qV804YcM569g6r7sDg8v8966Tic 14 | hAmffadiLAFyXYzuvmNEUA5FauIZ5wKYwSnEG0PZ6n1GRtX6aGD5zr83ZOJyyMqp 15 | TOU4RYcExcjMlAlCD457AgMBAAGjITAfMB0GA1UdDgQWBBTwWmMGjEm0IpuRlVpd 16 | Rm7ol7d34jANBgkqhkiG9w0BAQsFAAOCAQEAl6r+9heUbjssFvMXfLiOl3PCBCFn 17 | a765gKdjlw2HZTBaZ79ay5FooYTqMvQa1j8NRQyfkGupM7QaBU02O3Y7gkMn3Ton 18 | QsaZtZRXUDUWGeIyXwMIbjLM3YUhm3Fk+RfIiLEf/yphaJffT9Uf2Ykht8oawfjh 19 | e/5aPg/7TN93Au3ChNKSht190a4CNC1MWlih8bHbmj6yHUIqgAwoQOxcoFziPFUd 20 | YUJ5rZy3DrLX9fxGV59JksivGcfWGWbFWt9NPTB29yKo5rnVvdGBMBQpNUrly9Xa 21 | 00SX2aDISJJg3Qdhm8oqGNeKRij//Lf7yYX08fnTS4sg6C7R+RSEWod7bg== 22 | -----END CERTIFICATE----- 23 | -------------------------------------------------------------------------------- /src/test/resources/server-key.pem: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCnFDS87gNjCWR+ 3 | 0o8udxpUsZyEML6YAFscJWygyR99ARncfOYzZiYC2VA8ncqkI+UUTQBHfI1J+EZL 4 | ABfpky6tKlcjQrTr5ahdY7/MBfVi+lY6KTCIGK/lrWpqTnnnMJyhC/kzZO+rySsK 5 | roi7owwTwTjAArNi6dgDgPKwpwWP6VmmYovS6LkO5ub4rFiwDTNp8+97cVIwa3j0 6 | UzBYkIPzfXlv3aJrq5OrmZM86qV804YcM569g6r7sDg8v8966TichAmffadiLAFy 7 | XYzuvmNEUA5FauIZ5wKYwSnEG0PZ6n1GRtX6aGD5zr83ZOJyyMqpTOU4RYcExcjM 8 | lAlCD457AgMBAAECggEAfHvck0uO8HImEyvUjF0nHCU9JWygBOZ2+7CSj/Vp5Zw1 9 | ZYcViQQ5m/PICXHTcppf6tE4PQr6xjsaPHU0W85Sf6jFRbtEy2HQIMzaMSvbWcSF 10 | DE52H2CtZaXgXJZd0zfv6zndkUJKJCb9T7ccnxjrPajAHKemejMaw/mGWMIIreCN 11 | ib0FgziK1EYZ++KNxx04wp6ctQwrPHi6W6BrwEiGOUjOXWBnvzeZTiz0bKtBG5JY 12 | xShy2kFnCJqKpIOH9019r0pLf8+2Eu9TxNqliFn+UWjk0xZn9CFzxPHK6aW7n4E5 13 | o74aYPn9XE0pa9VzKxKJ7p1W40LUju1h+XpnQok0iQKBgQDWuIZ6bsN0odRmUWFx 14 | WlKNKtJqx+unqV03y8H/nprWIM6yNJnw7VMbH6xHEpb7QXOhLSpAEKOAQfw5MtWK 15 | kKWjisJec6emJvAAdB0VtrY33AkJS94yNNPywqurfl+x1mYuE6J8US/R+TOg5Qn4 16 | F+qlNKpmt6BShOIBmXqYQChhPQKBgQDHMvzzChheqXQsn0dfLRz9Lu3D3j2yaMtk 17 | 6DvsyA0EaJmcFnC3vVtYr/bo3nMcxEmdqnhlcKaCrahMXUI+8cZGSCvngTFRqwYy 18 | 30EZGbMbaitAnejhmqam7RC9IY8wUttRYQViEe2MXRy2CZdYAqTI83ovWrG8fPxN 19 | 7Jj/8nM6FwKBgQCrswamJKhbPYURBIZ9FBLrG5EDHjbM7VvDYEYTWArMq5NdYT6w 20 | L7bC+8LRWoYtCJukCO++Jw/3YcyFGKc1lJE/g5gF20n2TTChzDftwxtW87auHmLh 21 | lujdONn52qY/GQjAU6cc7fblWvbz8/LS1p0l2kVgufmTwvrO+KHV2YfwqQKBgB+c 22 | V8e5smRTP7xVCl5wKkmDSPfsLJ5DQwOgVuIcXPR2JOpAJWMDCZvpUKVjp6DJBWWf 23 | x7tRRRs3s51qrziN5YkBqvXx6oGrQjCQfSQej+2py3NVm78xa4DR3fYlfTON8n/X 24 | haMqdSfxHr1EiF/PC5dYC+u32LywmNlE0oLLVr3BAoGAEgkH6CJ4BdHv5QGsFD2q 25 | 6fH2rbapgd5omAUiofHiLq53agIyRNOosmKr7M2EJS1qBofXJ5KfhxPaCBiF7cqu 26 | PKxAxzCCVQGof4QoGUzdqK7j4BvoacfzpJqQaB3VbzPCxVNiu1eP1VFZKzin6NxW 27 | wfV4e3iSObVFDPOCMS+suC4= 28 | -----END PRIVATE KEY----- 29 | -------------------------------------------------------------------------------- /src/test/resources/server-keystore.p12: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vert-x3/vertx-ignite/10f20e474695a6e40bfef75d4cf5f1ffd64bf259/src/test/resources/server-keystore.p12 -------------------------------------------------------------------------------- /src/test/resources/server.jks: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vert-x3/vertx-ignite/10f20e474695a6e40bfef75d4cf5f1ffd64bf259/src/test/resources/server.jks --------------------------------------------------------------------------------