├── .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.md
├── pom.xml
├── stack-depchain
└── pom.xml
├── stack-docs
├── docs.xml
├── html.xml
├── kotlin.md
├── pom.xml
└── src
│ └── main
│ └── asciidoc
│ └── index.adoc
└── stack-manager
├── pom.xml
└── src
├── main
├── descriptor
│ └── vertx-stack-full.json
├── java
│ └── io
│ │ └── vertx
│ │ └── stack
│ │ ├── command
│ │ ├── ResolveCommand.java
│ │ ├── ResolveCommandFactory.java
│ │ └── package-info.java
│ │ ├── model
│ │ ├── Artifact.java
│ │ ├── Dependency.java
│ │ ├── DependencyConflictException.java
│ │ ├── Stack.java
│ │ ├── StackResolution.java
│ │ └── StackResolutionOptions.java
│ │ ├── resolver
│ │ ├── ResolutionOptions.java
│ │ ├── Resolver.java
│ │ ├── ResolverImpl.java
│ │ └── ResolverOptions.java
│ │ └── utils
│ │ ├── Actions.java
│ │ ├── Cache.java
│ │ ├── Filtering.java
│ │ └── Home.java
└── resources
│ └── META-INF
│ └── services
│ └── io.vertx.core.spi.launcher.CommandFactory
└── test
├── java
└── io
│ └── vertx
│ └── stack
│ ├── DescriptorTest.java
│ ├── StackResolutionTest.java
│ ├── VertxStacksTest.java
│ ├── resolver
│ └── ResolverTest.java
│ └── utils
│ ├── CacheTest.java
│ ├── FileUtils.java
│ ├── FilteringTest.java
│ ├── FluentMap.java
│ ├── LocalArtifact.java
│ ├── LocalDependency.java
│ ├── LocalRepoBuilder.java
│ └── PomUtils.java
└── resources
└── stacks
├── core-with-system-variable.json
├── core-with-variable.json
├── core.json
├── vertx-core-only.json
└── vertx-web-stack.json
/.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-stack (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-stack (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-stack (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 | uses: ./.github/workflows/ci.yml
16 | with:
17 | branch: ${{ inputs.branch }}
18 | jdk: ${{ matrix.jdk }}
19 | os: ${{ matrix.os }}
20 | secrets: inherit
21 | Deploy:
22 | if: ${{ github.repository_owner == 'vert-x3' && (github.event_name == 'push' || github.event_name == 'schedule') }}
23 | needs: CI
24 | uses: ./.github/workflows/deploy.yml
25 | with:
26 | branch: ${{ inputs.branch }}
27 | jdk: 11
28 | secrets: inherit
29 |
--------------------------------------------------------------------------------
/.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: joschi/setup-jdk@v2
25 | with:
26 | java-version: ${{ inputs.jdk }}
27 | - name: Run tests
28 | run: mvn -q clean verify -B
29 |
--------------------------------------------------------------------------------
/.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 | .vscode
4 | .idea
5 | .classpath
6 | .project
7 | .settings
8 | .yardoc
9 | .yardopts
10 | build
11 | target
12 | out
13 | *.iml
14 | *.ipr
15 | *.iws
16 | test-output
17 | Scratch.java
18 | ScratchTest.java
19 | test-results
20 | test-tmp
21 | *.class
22 | src/gen
23 | src/main/groovy/io/vertx/groovy/core/**/*.groovy
24 | src/test/groovy/io/vertx/groovy/codegen/**/*.groovy
25 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "{}"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright {yyyy} {name of copyright owner}
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | vertx-stack
2 | ========
3 |
4 | [](https://github.com/vert-x3/vertx-stack/actions/workflows/ci-5.x.yml)
5 | [](https://github.com/vert-x3/vertx-stack/actions/workflows/ci-4.x.yml)
6 |
7 | The Vert.x stack : Vert.x + the endorsed modules
8 |
9 | ### Maven
10 |
11 | This project provides pre-configured Maven poms for using in your projects, allowing you to consume the Vert.x stack
12 | easily.
13 |
14 | #### Dependency chain (_Maven depchain_)
15 |
16 | This artifact `io.vertx:stack-depchain` is a POM projects can import to get the dependencies it needs for running
17 | the base stack:
18 |
19 | ~~~~
20 |
21 | io.vertx
22 | vertx-stack-depchain
23 | 3.5.1
24 | pom
25 |
26 | ~~~~
27 |
28 | #### Bills of Materials (Maven _BOM_)
29 |
30 | A [_BOM_](http://maven.apache.org/guides/introduction/introduction-to-dependency-mechanism.html) is a also a POM you
31 | can import in your project. It will not add dependencies to your POM, instead it will set the correct versions to use.
32 | Therefore it should be used with explicit dependencies:
33 |
34 | ~~~~
35 |
36 |
37 |
38 | io.vertx
39 | vertx-stack-depchain
40 | 3.5.1
41 | pom
42 | import
43 |
44 |
45 |
46 |
47 |
48 |
49 | io.vertx
50 | vertx-core
51 |
52 | ...
53 |
54 | ~~~~
55 |
56 | ### Adding a new module to the stack
57 |
58 | 1. Add it to [`vertx-dependencies`](https://github.com/vert-x3/vertx-dependencies) (open the project, add it to the `pom.xml`, install, commit and push)
59 | 2. Add it to `stack-depchain/pom.xml` (open the project, add the dependency, without the version (inherited from
60 | vertx-dependencies))
61 | 3. Add it in the stack manager:
62 | * Open `./stack-manager/src/main/descriptor/vertx-stack-full.json`
63 | * Add the dependency. If the dependency must be embedded in the _full_ distribution, set `included` to `true`. Don't forget to use the `\${version}`.
64 | 4. Add it to the doc distribution:
65 | * Open `./stack-docs/pom.xml`
66 | * Add the `docs` dependency (the using `docs` and `zip`)
67 | * Add the `source` dependency (the `sources`)
68 | * Add the _copy_ instruction for the ant execution:
69 | ```
70 |
71 |
72 |
73 | ```
74 | * Save the `pom.xml` file
75 | * Build (`mvn clean install` from the root).
76 | 5. Make it polyglot (unless the module is not polyglot, e.g. a cluster manager)
77 | * Kotlin: in [`vertx-lang-kotlin`](https://github.com/vert-x3/vertx-lang-kotlin), edit `vertx-lang-kotlin/pom.xml`
78 | * Add an `optional` dependency to the POM
79 | * Update the list in the `maven-dependency-plugin` config
80 | * RxJava3: in [`vertx-rx`](https://github.com/vert-x3/vertx-rx), edit `rx-java3/pom.xml`
81 | * Add an `optional` dependency to the POM
82 | * Update the list in the `maven-dependency-plugin` config
83 | * RxJava2: in [`vertx-rx`](https://github.com/vert-x3/vertx-rx), edit `rx-java2/pom.xml`
84 | * Add an `optional` dependency to the POM
85 | * Update the list in the `maven-dependency-plugin` config
86 | 6. Add it to the website in [`vertx-web-site`](https://github.com/vertx-web-site/vertx-web-site.github.io):
87 | * Edit the docs summary page `docs/metadata/.jsx`, use `Tech Preview` label
88 | 7. Add it to the starter website in [`vertx-starter`](https://github.com/vert-x3/vertx-starter/):
89 | * Edit the stack definition file `src/main/resources/starter.json`
90 | * Add the module details in one of the categories (web, data, ...etc)
91 | * Exclude the module from versions that did not have it (`exclusions`)
92 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 |
8 | io.vertx
9 | vertx5-parent
10 | 12
11 |
12 |
13 | vertx-stack
14 | 5.1.0-SNAPSHOT
15 |
16 | Vert.x Stack - Project
17 | pom
18 |
19 |
20 |
21 | The Apache Software License, Version 2.0
22 | http://www.apache.org/licenses/LICENSE-2.0.txt
23 | repo
24 |
25 |
26 | Eclipse Public License - v 1.0
27 | http://www.eclipse.org/legal/epl-v10.html
28 | repo
29 |
30 |
31 |
32 |
33 |
34 |
35 | io.vertx
36 | vertx-dependencies
37 | ${project.version}
38 | pom
39 | import
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 | maven-assembly-plugin
49 | 2.4.1
50 |
51 |
52 |
53 |
54 |
55 |
56 | stack-depchain
57 | stack-manager
58 | stack-docs
59 |
60 |
61 |
62 |
63 |
64 | sonatype-oss-release
65 |
66 |
67 |
68 | org.apache.maven.plugins
69 | maven-enforcer-plugin
70 |
71 |
72 | enforce-no-snapshots
73 |
74 | enforce
75 |
76 |
77 |
78 |
79 | No Snapshots Allowed during a release!
80 |
81 | io.vertx:*
82 |
83 |
84 |
85 | true
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
--------------------------------------------------------------------------------
/stack-depchain/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 |
8 | io.vertx
9 | vertx-stack
10 | 5.1.0-SNAPSHOT
11 | ../pom.xml
12 |
13 |
14 | vertx-stack-depchain
15 | 5.1.0-SNAPSHOT
16 |
17 | Vert.x Stack - Dependency Chain
18 | pom
19 |
20 |
21 |
22 | io.vertx
23 | vertx-core
24 |
25 |
26 | io.vertx
27 | vertx-launcher-legacy-cli
28 |
29 |
30 | io.vertx
31 | vertx-launcher-application
32 |
33 |
34 | io.vertx
35 | vertx-lang-groovy
36 |
37 |
38 | io.vertx
39 | vertx-service-proxy
40 |
41 |
42 | io.vertx
43 | vertx-hazelcast
44 |
45 |
46 | io.vertx
47 | vertx-zookeeper
48 |
49 |
50 | io.vertx
51 | vertx-dropwizard-metrics
52 |
53 |
54 | io.vertx
55 | vertx-micrometer-metrics
56 |
57 |
58 | io.vertx
59 | vertx-zipkin
60 |
61 |
62 | io.vertx
63 | vertx-opentracing
64 |
65 |
66 | io.vertx
67 | vertx-opentelemetry
68 |
69 |
70 | io.vertx
71 | vertx-openapi
72 |
73 |
74 | io.vertx
75 | vertx-reactive-streams
76 |
77 |
78 | io.vertx
79 | vertx-rx-java2
80 |
81 |
82 | io.vertx
83 | vertx-rx-java3
84 |
85 |
86 | io.vertx
87 | vertx-consul-client
88 |
89 |
90 | io.vertx
91 | vertx-cassandra-client
92 |
93 |
94 | io.vertx
95 | vertx-mongo-client
96 |
97 |
98 | io.vertx
99 | vertx-jdbc-client
100 |
101 |
102 | io.vertx
103 | vertx-auth-common
104 |
105 |
106 | io.vertx
107 | vertx-auth-htdigest
108 |
109 |
110 | io.vertx
111 | vertx-auth-htpasswd
112 |
113 |
114 | io.vertx
115 | vertx-auth-jwt
116 |
117 |
118 | io.vertx
119 | vertx-auth-oauth2
120 |
121 |
122 | io.vertx
123 | vertx-auth-mongo
124 |
125 |
126 | io.vertx
127 | vertx-auth-properties
128 |
129 |
130 | io.vertx
131 | vertx-auth-ldap
132 |
133 |
134 | io.vertx
135 | vertx-auth-webauthn4j
136 |
137 |
138 | io.vertx
139 | vertx-auth-sql-client
140 |
141 |
142 | io.vertx
143 | vertx-auth-otp
144 |
145 |
146 | io.vertx
147 | vertx-auth-abac
148 |
149 |
150 | io.vertx
151 | vertx-web
152 |
153 |
154 | io.vertx
155 | vertx-web-common
156 |
157 |
158 | io.vertx
159 | vertx-web-client
160 |
161 |
162 | io.vertx
163 | vertx-web-api-service
164 |
165 |
166 | io.vertx
167 | vertx-web-openapi-router
168 |
169 |
170 | io.vertx
171 | vertx-web-sstore-cookie
172 |
173 |
174 | io.vertx
175 | vertx-web-sstore-redis
176 |
177 |
178 | io.vertx
179 | vertx-web-sstore-infinispan
180 |
181 |
182 | io.vertx
183 | vertx-web-templ-thymeleaf
184 | shaded
185 |
186 |
187 | io.vertx
188 | vertx-web-templ-handlebars
189 | shaded
190 |
191 |
192 | io.vertx
193 | vertx-web-templ-pug
194 | shaded
195 |
196 |
197 | io.vertx
198 | vertx-web-templ-mvel
199 | shaded
200 |
201 |
202 | io.vertx
203 | vertx-web-templ-pebble
204 | shaded
205 |
206 |
207 | io.vertx
208 | vertx-web-templ-freemarker
209 | shaded
210 |
211 |
212 | io.vertx
213 | vertx-web-templ-rocker
214 | shaded
215 |
216 |
217 | io.vertx
218 | vertx-web-templ-httl
219 | shaded
220 |
221 |
222 | io.vertx
223 | vertx-web-graphql
224 |
225 |
226 | io.vertx
227 | vertx-web-proxy
228 |
229 |
230 | io.vertx
231 | vertx-web-validation
232 |
233 |
234 | io.vertx
235 | vertx-sockjs-service-proxy
236 |
237 |
238 | io.vertx
239 | vertx-unit
240 | test
241 |
242 |
243 | io.vertx
244 | vertx-junit5
245 | test
246 |
247 |
248 | io.vertx
249 | vertx-junit5-rx-java2
250 | test
251 |
252 |
253 | io.vertx
254 | vertx-junit5-rx-java3
255 | test
256 |
257 |
258 | io.vertx
259 | vertx-mail-client
260 |
261 |
262 | io.vertx
263 | vertx-redis-client
264 |
265 |
266 | io.vertx
267 | vertx-shell
268 |
269 |
270 | io.vertx
271 | vertx-stomp
272 |
273 |
274 | io.vertx
275 | vertx-infinispan
276 |
277 |
278 | io.vertx
279 | vertx-bridge-common
280 |
281 |
282 | io.vertx
283 | vertx-tcp-eventbus-bridge
284 |
285 |
286 | io.vertx
287 | vertx-sql-client
288 |
289 |
290 | io.vertx
291 | vertx-pg-client
292 |
293 |
294 | io.vertx
295 | vertx-mysql-client
296 |
297 |
298 | io.vertx
299 | vertx-db2-client
300 |
301 |
302 | io.vertx
303 | vertx-mssql-client
304 |
305 |
306 | io.vertx
307 | vertx-oracle-client
308 |
309 |
310 | io.vertx
311 | vertx-sql-client-templates
312 |
313 |
314 | io.vertx
315 | vertx-camel-bridge
316 |
317 |
318 | io.vertx
319 | vertx-ignite
320 |
321 |
322 | io.vertx
323 | vertx-rabbitmq-client
324 |
325 |
326 | io.vertx
327 | vertx-service-discovery
328 |
329 |
330 | io.vertx
331 | vertx-circuit-breaker
332 |
333 |
334 | io.vertx
335 | vertx-service-discovery-bridge-kubernetes
336 |
337 |
338 | io.vertx
339 | vertx-service-discovery-bridge-docker-links
340 |
341 |
342 | io.vertx
343 | vertx-service-discovery-bridge-docker
344 |
345 |
346 | io.vertx
347 | vertx-service-discovery-backend-redis
348 |
349 |
350 | io.vertx
351 | vertx-service-discovery-bridge-consul
352 |
353 |
354 | io.vertx
355 | vertx-service-discovery-bridge-zookeeper
356 |
357 |
358 | io.vertx
359 | vertx-config
360 |
361 |
362 | io.vertx
363 | vertx-config-git
364 |
365 |
366 | io.vertx
367 | vertx-config-hocon
368 |
369 |
370 | io.vertx
371 | vertx-config-kubernetes-configmap
372 |
373 |
374 | io.vertx
375 | vertx-config-redis
376 |
377 |
378 | io.vertx
379 | vertx-config-spring-config-server
380 |
381 |
382 | io.vertx
383 | vertx-config-yaml
384 |
385 |
386 | io.vertx
387 | vertx-config-zookeeper
388 |
389 |
390 | io.vertx
391 | vertx-grpc
392 |
393 |
394 |
395 | io.vertx
396 | vertx-proton
397 |
398 |
399 | io.vertx
400 | vertx-amqp-client
401 |
402 |
403 | io.vertx
404 | vertx-kafka-client
405 |
406 |
407 | io.vertx
408 | vertx-json-schema
409 |
410 |
411 | io.vertx
412 | vertx-health-check
413 |
414 |
415 | io.vertx
416 | vertx-mqtt
417 |
418 |
419 | io.vertx
420 | vertx-http-proxy
421 |
422 |
423 | io.vertx
424 | vertx-uri-template
425 |
426 |
427 | io.vertx
428 | vertx-grpc-common
429 |
430 |
431 | io.vertx
432 | vertx-grpc-client
433 |
434 |
435 | io.vertx
436 | vertx-grpc-server
437 |
438 |
439 | io.vertx
440 | vertx-grpcio-common
441 |
442 |
443 | io.vertx
444 | vertx-grpcio-client
445 |
446 |
447 | io.vertx
448 | vertx-grpcio-server
449 |
450 |
451 | io.vertx
452 | vertx-grpc-reflection
453 |
454 |
455 | io.vertx
456 | vertx-grpc-health
457 |
458 |
459 | io.vertx
460 | vertx-grpc-transcoding
461 |
462 |
463 | io.vertx
464 | vertx-service-resolver
465 |
466 |
467 |
468 |
469 |
--------------------------------------------------------------------------------
/stack-docs/docs.xml:
--------------------------------------------------------------------------------
1 |
4 | docs
5 |
6 | zip
7 |
8 | false
9 |
10 |
11 | ${project.build.directory}/docs
12 | /
13 |
14 |
15 |
--------------------------------------------------------------------------------
/stack-docs/html.xml:
--------------------------------------------------------------------------------
1 |
4 | html
5 |
6 | zip
7 |
8 | false
9 |
10 |
11 | ${project.build.directory}/html
12 | /
13 |
14 |
15 |
--------------------------------------------------------------------------------
/stack-docs/kotlin.md:
--------------------------------------------------------------------------------
1 | # Module vertx
2 |
3 | Vert.x for Kotlin API documentation.
4 |
--------------------------------------------------------------------------------
/stack-docs/src/main/asciidoc/index.adoc:
--------------------------------------------------------------------------------
1 |
2 |
3 | == Documentation
4 |
5 | === Java
6 |
7 | - link:vertx-core/java/index.html[Core]
8 | - link:vertx-launcher-application/java/index.html[Application Launcher]
9 | - link:vertx-web/java/index.html[Web]
10 | - link:vertx-web-client/java/index.html[Web client]
11 | - link:vertx-web-api-contract/java/index.html[Web API contracts]
12 | - link:vertx-web-api-service/java/index.html[Web API service]
13 | - link:vertx-web-graphql/java/index.html[Web GraphQL]
14 | - link:vertx-http-proxy/java/index.html[HTTP proxy]
15 | - link:vertx-jdbc-client/java/index.html[JDBC client]
16 | - link:vertx-mongo-client/java/index.html[Mongo client]
17 | - link:vertx-redis-client/java/index.html[Redis client]
18 | - link:vertx-rx/java2/index.html[RxJava2]
19 | - link:vertx-rx/java3/index.html[RxJava3]
20 | - link:vertx-reactive-streams/java/index.html[Reactive streams]
21 | - link:vertx-service-resolver/java/index.html[Service resolver]
22 | - link:vertx-service-discovery/java/index.html[Service discovery]
23 | - link:vertx-circuit-breaker/java/index.html[Circuit breaker]
24 | - link:vertx-config/java/index.html[Config]
25 | - link:vertx-mqtt/java/index.html[MQTT]
26 | - link:vertx-pg-client/java/index.html[PostgreSQL client]
27 | - link:vertx-mssql-client/java/index.html[MS SQL client]
28 | - link:vertx-auth-common/java/index.html[Auth common]
29 | - link:vertx-auth-jwt/java/index.html[JWT auth]
30 | - link:vertx-auth-mongo/java/index.html[Auth MongoDB]
31 | - link:vertx-auth-oauth2/java/index.html[OAuth2]
32 | - link:vertx-auth-htdigest/java/index.html[.htdigest Auth]
33 | - link:vertx-mail-client/java/index.html[Mail client]
34 | - link:vertx-stomp/java/index.html[STOMP]
35 | - link:vertx-consul-client/java/index.html[Consul client]
36 | - link:vertx-cassandra-client/java/index.html[Cassandra client]
37 | - link:vertx-rabbitmq-client/java/index.html[RabbitMQ client]
38 | - link:vertx-kafka-client/java/index.html[Kafka client]
39 | - link:vertx-amqp-bridge/java/index.html[AMQP bridge]
40 | - link:vertx-amqp-client/java/index.html[AMQP client]
41 | - link:vertx-tcp-eventbus-bridge/java/index.html[TCP Eventbus bridge]
42 | - link:vertx-camel-bridge/java/index.html[Camel bridge]
43 | - link:vertx-dropwizard-metrics/java/index.html[Dropwizard metrics]
44 | - link:vertx-micrometer-metrics/java/index.html[Micrometer metrics]
45 | - link:vertx-zipkin/java/index.html[Zipkin]
46 | - link:vertx-opentracing/java/index.html[Opentracing]
47 | - link:vertx-opentelemetry/java/index.html[Opentelemetry]
48 | - link:vertx-health-check/java/index.html[Health check]
49 | - link:vertx-shell/java/index.html[Shell]
50 | - link:vertx-unit/java/index.html[Vert.x unit]
51 | - link:vertx-junit5/java/index.html[Vert.x JUnit 5]
52 | - link:vertx-hazelcast/java/index.html[Hazelcast]
53 | - link:vertx-infinispan/java/index.html[Infinispan]
54 | - link:vertx-ignite/java/index.html[Ignite]
55 | - link:vertx-zookeeper/java/index.html[Apache Zookeeper]
56 | - link:vertx-service-proxy/java/index.html[Service proxies]
57 | - link:vertx-sockjs-service-proxy/java/index.html[SockJS service proxies]
58 | - link:vertx-grpc/java/index.html[gRPC]
59 |
60 | === Kotlin
61 |
62 | - link:vertx-lang-kotlin-coroutines/kotlin/index.html[Kotlin coroutines]
63 |
--------------------------------------------------------------------------------
/stack-manager/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
17 |
18 |
21 | 4.0.0
22 |
23 |
24 | io.vertx
25 | vertx-stack
26 | 5.1.0-SNAPSHOT
27 |
28 |
29 | vertx-stack-manager
30 | Vert.x Stack - Stack Manager
31 |
32 |
33 | 1.1.0
34 | ${project.version}
35 | vert.x-${project.version}
36 |
37 |
38 |
39 |
40 |
41 |
42 | commons-logging
43 | commons-logging
44 | 1.2
45 |
46 |
47 | io.vertx
48 | vertx-core
49 |
50 |
51 | io.vertx
52 | vertx-launcher-legacy-cli
53 |
54 |
55 | com.fasterxml.jackson.core
56 | jackson-databind
57 |
58 |
59 | com.fasterxml.jackson.core
60 | jackson-annotations
61 |
62 |
63 | org.apache.maven
64 | maven-aether-provider
65 | 3.3.9
66 |
67 |
68 | org.eclipse.sisu
69 | org.eclipse.sisu.plexus
70 |
71 |
72 | org.codehaus.plexus
73 | plexus-component-annotations
74 |
75 |
76 |
77 |
78 | org.eclipse.aether
79 | aether-api
80 | ${aether.version}
81 |
82 |
83 | org.eclipse.aether
84 | aether-connector-basic
85 | ${aether.version}
86 |
87 |
88 | org.eclipse.aether
89 | aether-transport-file
90 | ${aether.version}
91 |
92 |
93 | org.eclipse.aether
94 | aether-transport-http
95 | ${aether.version}
96 |
97 |
98 | org.slf4j
99 | slf4j-api
100 |
101 |
102 | org.slf4j
103 | jcl-over-slf4j
104 |
105 |
106 |
107 |
108 | org.eclipse.aether
109 | aether-spi
110 | ${aether.version}
111 |
112 |
113 | org.eclipse.aether
114 | aether-impl
115 | ${aether.version}
116 |
117 |
118 | org.eclipse.aether
119 | aether-util
120 | ${aether.version}
121 |
122 |
123 |
124 | com.google.guava
125 | guava
126 | 30.1.1-jre
127 |
128 |
129 | com.jayway.awaitility
130 | awaitility
131 | 1.7.0
132 | test
133 |
134 |
135 |
136 | org.assertj
137 | assertj-core
138 | 3.3.0
139 | test
140 |
141 |
142 | junit
143 | junit
144 | 4.13.1
145 | test
146 |
147 |
148 |
149 |
150 |
151 |
152 | maven-resources-plugin
153 |
154 |
155 | copy-resources
156 | process-resources
157 |
158 | copy-resources
159 |
160 |
161 | \
162 | ${basedir}/target/vertx-stack
163 |
164 |
165 | src/main/descriptor
166 | true
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 | org.apache.maven.plugins
178 | maven-surefire-plugin
179 |
180 |
181 | ${vertx.snapshotRepository}
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
--------------------------------------------------------------------------------
/stack-manager/src/main/descriptor/vertx-stack-full.json:
--------------------------------------------------------------------------------
1 | //
2 | // vert.x stack descriptor
3 | //
4 | // To add a dependency:
5 | // - if the dependency is already listed, just set `included` to `true`
6 | // - if not, add the dependency using the Maven coordinates, and set `included` to `true`
7 | //
8 | // You can also set `exclusions` and whether or not the dependency need to resolve its transitive dependencies.
9 | //
10 | // Then launch the resolution process with: vertx resolve --dir=lib --stack=./vertx-vertx.json
11 | //
12 | // To remove a dependency:
13 | // - either remove the dependency declaration or just toggled the `included` value. Then launch the resolution process.
14 | //
15 | {
16 | "variables": {
17 | "vertx.version": "${vertx.version}",
18 | "tcnative.version": "2.0.29.Final"
19 | },
20 | "dependencies": [
21 | {
22 | "groupId": "io.vertx",
23 | "artifactId": "vertx-core",
24 | "version": "\${vertx.version}",
25 | "included": true
26 | },
27 | {
28 | "groupId": "io.vertx",
29 | "artifactId": "vertx-launcher-application",
30 | "version": "\${vertx.version}",
31 | "included": true
32 | },
33 | {
34 | "groupId": "io.netty",
35 | "artifactId": "netty-tcnative-boringssl-static",
36 | "version": "\${tcnative.version}",
37 | "included": true
38 | },
39 | {
40 | "groupId": "io.vertx",
41 | "artifactId": "vertx-hazelcast",
42 | "version": "\${vertx.version}",
43 | "included": true
44 | },
45 | {
46 | "groupId": "io.vertx",
47 | "artifactId": "vertx-lang-groovy",
48 | "version": "\${vertx.version}",
49 | "included": true
50 | },
51 | {
52 | "groupId": "io.vertx",
53 | "artifactId": "vertx-lang-kotlin",
54 | "version": "\${vertx.version}",
55 | "included": true
56 | },
57 | {
58 | "groupId": "io.vertx",
59 | "artifactId": "vertx-lang-kotlin-coroutines",
60 | "version": "\${vertx.version}",
61 | "included": true
62 | },
63 | {
64 | "groupId": "io.vertx",
65 | "artifactId": "vertx-service-proxy",
66 | "version": "\${vertx.version}",
67 | "included": true
68 | },
69 | {
70 | "groupId": "io.vertx",
71 | "artifactId": "vertx-dropwizard-metrics",
72 | "version": "\${vertx.version}",
73 | "included": true
74 | },
75 | {
76 | "groupId": "io.vertx",
77 | "artifactId": "vertx-micrometer-metrics",
78 | "version": "\${vertx.version}",
79 | "included": false
80 | },
81 | {
82 | "groupId": "io.vertx",
83 | "artifactId": "vertx-auth-common",
84 | "version": "\${vertx.version}",
85 | "included": true
86 | },
87 | {
88 | "groupId": "io.vertx",
89 | "artifactId": "vertx-auth-jwt",
90 | "version": "\${vertx.version}",
91 | "included": true
92 | },
93 | {
94 | "groupId": "io.vertx",
95 | "artifactId": "vertx-auth-oauth2",
96 | "version": "\${vertx.version}",
97 | "included": true
98 | },
99 | {
100 | "groupId": "io.vertx",
101 | "artifactId": "vertx-auth-webauthn4j",
102 | "version": "\${vertx.version}",
103 | "included": true
104 | },
105 | {
106 | "groupId": "io.vertx",
107 | "artifactId": "vertx-auth-otp",
108 | "version": "\${vertx.version}",
109 | "included": true
110 | },
111 | {
112 | "groupId": "io.vertx",
113 | "artifactId": "vertx-auth-abac",
114 | "version": "\${vertx.version}",
115 | "included": true
116 | },
117 | {
118 | "groupId": "io.vertx",
119 | "artifactId": "vertx-jdbc-client",
120 | "version": "\${vertx.version}",
121 | "included": true
122 | },
123 | {
124 | "groupId": "io.vertx",
125 | "artifactId": "vertx-consul-client",
126 | "version": "\${vertx.version}",
127 | "included": true
128 | },
129 | {
130 | "groupId": "io.vertx",
131 | "artifactId": "vertx-mongo-client",
132 | "version": "\${vertx.version}",
133 | "included": true
134 | },
135 | {
136 | "groupId": "io.vertx",
137 | "artifactId": "vertx-reactive-streams",
138 | "version": "\${vertx.version}",
139 | "included": true
140 | },
141 | {
142 | "groupId": "io.vertx",
143 | "artifactId": "vertx-redis-client",
144 | "version": "\${vertx.version}",
145 | "included": true
146 | },
147 | {
148 | "groupId": "io.vertx",
149 | "artifactId": "vertx-unit",
150 | "version": "\${vertx.version}",
151 | "included": true
152 | },
153 | {
154 | "groupId": "io.vertx",
155 | "artifactId": "vertx-junit5",
156 | "version": "\${vertx.version}",
157 | "included": true
158 | },
159 | {
160 | "groupId": "io.vertx",
161 | "artifactId": "vertx-junit5-rx-java2",
162 | "version": "\${vertx.version}",
163 | "included": true
164 | },
165 | {
166 | "groupId": "io.vertx",
167 | "artifactId": "vertx-web",
168 | "version": "\${vertx.version}",
169 | "included": true
170 | },
171 | {
172 | "groupId": "io.vertx",
173 | "artifactId": "vertx-web-client",
174 | "version": "\${vertx.version}",
175 | "included": true
176 | },
177 | {
178 | "groupId": "io.vertx",
179 | "artifactId": "vertx-web-templ-handlebars",
180 | "version": "\${vertx.version}",
181 | "classifier": "shaded",
182 | "transitive": false,
183 | "included": true
184 | },
185 | {
186 | "groupId": "io.vertx",
187 | "artifactId": "vertx-web-templ-pug",
188 | "version": "\${vertx.version}",
189 | "classifier": "shaded",
190 | "transitive": false,
191 | "included": true
192 | },
193 | {
194 | "groupId": "io.vertx",
195 | "artifactId": "vertx-web-templ-mvel",
196 | "version": "\${vertx.version}",
197 | "classifier": "shaded",
198 | "transitive": false,
199 | "included": true
200 | },
201 | {
202 | "groupId": "io.vertx",
203 | "artifactId": "vertx-web-templ-thymeleaf",
204 | "version": "\${vertx.version}",
205 | "classifier": "shaded",
206 | "transitive": false,
207 | "included": true
208 | },
209 | {
210 | "groupId": "io.vertx",
211 | "artifactId": "vertx-sockjs-service-proxy",
212 | "version": "\${vertx.version}",
213 | "included": false
214 | },
215 | {
216 | "groupId": "io.vertx",
217 | "artifactId": "vertx-mail-client",
218 | "version": "\${vertx.version}",
219 | "included": true
220 | },
221 | {
222 | "groupId": "io.vertx",
223 | "artifactId": "vertx-stomp",
224 | "version": "\${vertx.version}",
225 | "included": true
226 | },
227 | {
228 | "groupId": "io.vertx",
229 | "artifactId": "vertx-shell",
230 | "version": "\${vertx.version}",
231 | "included": false
232 | },
233 | {
234 | "groupId": "io.vertx",
235 | "artifactId": "vertx-tcp-eventbus-bridge",
236 | "version": "\${vertx.version}",
237 | "included": true
238 | },
239 | {
240 | "groupId": "io.vertx",
241 | "artifactId": "vertx-infinispan",
242 | "version": "\${vertx.version}",
243 | "included": false
244 | },
245 | {
246 | "groupId": "io.vertx",
247 | "artifactId": "vertx-hazelcast",
248 | "version": "\${vertx.version}",
249 | "included": false
250 | },
251 | {
252 | "groupId": "io.vertx",
253 | "artifactId": "vertx-camel-bridge",
254 | "version": "\${vertx.version}",
255 | "included": false
256 | },
257 | {
258 | "groupId": "io.vertx",
259 | "artifactId": "vertx-service-discovery",
260 | "version": "\${vertx.version}",
261 | "included": true
262 | },
263 | {
264 | "groupId": "io.vertx",
265 | "artifactId": "vertx-service-discovery-bridge-kubernetes",
266 | "version": "\${vertx.version}",
267 | "included": false
268 | },
269 | {
270 | "groupId": "io.vertx",
271 | "artifactId": "vertx-service-discovery-bridge-docker",
272 | "version": "\${vertx.version}",
273 | "included": false
274 | },
275 | {
276 | "groupId": "io.vertx",
277 | "artifactId": "vertx-service-discovery-bridge-docker-links",
278 | "version": "\${vertx.version}",
279 | "included": false
280 | },
281 | {
282 | "groupId": "io.vertx",
283 | "artifactId": "vertx-service-discovery-bridge-consul",
284 | "version": "\${vertx.version}",
285 | "included": false
286 | },
287 | {
288 | "groupId": "io.vertx",
289 | "artifactId": "vertx-service-discovery-backend-redis",
290 | "version": "\${vertx.version}",
291 | "included": false
292 | },
293 | {
294 | "groupId": "io.vertx",
295 | "artifactId": "vertx-config",
296 | "version": "\${vertx.version}",
297 | "included": true
298 | },
299 | {
300 | "groupId": "io.vertx",
301 | "artifactId": "vertx-config-git",
302 | "version": "\${vertx.version}",
303 | "included": false
304 | },
305 | {
306 | "groupId": "io.vertx",
307 | "artifactId": "vertx-config-hocon",
308 | "version": "\${vertx.version}",
309 | "included": false
310 | },
311 | {
312 | "groupId": "io.vertx",
313 | "artifactId": "vertx-config-kubernetes-configmap",
314 | "version": "\${vertx.version}",
315 | "included": false
316 | },
317 | {
318 | "groupId": "io.vertx",
319 | "artifactId": "vertx-config-redis",
320 | "version": "\${vertx.version}",
321 | "included": false
322 | },
323 | {
324 | "groupId": "io.vertx",
325 | "artifactId": "vertx-config-spring-config-server",
326 | "version": "\${vertx.version}",
327 | "included": false
328 | },
329 | {
330 | "groupId": "io.vertx",
331 | "artifactId": "vertx-config-vault",
332 | "version": "\${vertx.version}",
333 | "included": false
334 | },
335 | {
336 | "groupId": "io.vertx",
337 | "artifactId": "vertx-config-consul",
338 | "version": "\${vertx.version}",
339 | "included": false
340 | },
341 | {
342 | "groupId": "io.vertx",
343 | "artifactId": "vertx-config-yaml",
344 | "version": "\${vertx.version}",
345 | "included": false
346 | },
347 | {
348 | "groupId": "io.vertx",
349 | "artifactId": "vertx-config-zookeeper",
350 | "version": "\${vertx.version}",
351 | "included": false
352 | },
353 | {
354 | "groupId": "io.vertx",
355 | "artifactId": "vertx-circuit-breaker",
356 | "version": "\${vertx.version}",
357 | "included": true
358 | },
359 | {
360 | "groupId": "io.vertx",
361 | "artifactId": "vertx-rabbitmq-client",
362 | "version": "\${vertx.version}",
363 | "included": true
364 | },
365 | {
366 | "groupId": "io.vertx",
367 | "artifactId": "vertx-kafka-client",
368 | "version": "\${vertx.version}",
369 | "included": false
370 | },
371 | {
372 | "groupId": "io.vertx",
373 | "artifactId": "vertx-consul-client",
374 | "version": "\${vertx.version}",
375 | "included": false
376 | },
377 | {
378 | "groupId": "io.vertx",
379 | "artifactId": "vertx-mqtt",
380 | "version": "\${vertx.version}",
381 | "included": false
382 | },
383 | {
384 | "groupId": "io.vertx",
385 | "artifactId": "vertx-grpc-common",
386 | "version": "\${vertx.version}",
387 | "included": false
388 | },
389 | {
390 | "groupId": "io.vertx",
391 | "artifactId": "vertx-grpc-client",
392 | "version": "\${vertx.version}",
393 | "included": false
394 | },
395 | {
396 | "groupId": "io.vertx",
397 | "artifactId": "vertx-grpc-server",
398 | "version": "\${vertx.version}",
399 | "included": false
400 | },
401 | {
402 | "groupId": "io.vertx",
403 | "artifactId": "vertx-json-schema",
404 | "version": "\${vertx.version}",
405 | "included": false
406 | },
407 | {
408 | "groupId": "io.vertx",
409 | "artifactId": "vertx-openapi",
410 | "version": "\${vertx.version}",
411 | "included": false
412 | },
413 | {
414 | "groupId": "io.vertx",
415 | "artifactId": "vertx-web-openapi-router",
416 | "version": "\${vertx.version}",
417 | "included": false
418 | }
419 | ]
420 | }
421 |
--------------------------------------------------------------------------------
/stack-manager/src/main/java/io/vertx/stack/command/ResolveCommand.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2011-2015 The original author or authors
3 | * ------------------------------------------------------
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the Eclipse Public License v1.0
6 | * and Apache License v2.0 which accompanies this distribution.
7 | *
8 | * The Eclipse Public License is available at
9 | * http://www.eclipse.org/legal/epl-v10.html
10 | *
11 | * The Apache License v2.0 is available at
12 | * http://www.opensource.org/licenses/apache2.0.php
13 | *
14 | * You may elect to redistribute this code under either of these licenses.
15 | */
16 |
17 | package io.vertx.stack.command;
18 |
19 | import io.vertx.core.cli.CLI;
20 | import io.vertx.core.cli.CLIException;
21 | import io.vertx.core.cli.CommandLine;
22 | import io.vertx.core.cli.annotations.*;
23 | import io.vertx.core.spi.launcher.DefaultCommand;
24 | import io.vertx.core.spi.launcher.ExecutionContext;
25 | import io.vertx.stack.model.Stack;
26 | import io.vertx.stack.model.StackResolution;
27 | import io.vertx.stack.model.StackResolutionOptions;
28 | import io.vertx.stack.utils.Home;
29 |
30 | import java.io.File;
31 | import java.util.Arrays;
32 | import java.util.List;
33 |
34 | /**
35 | * The resolve command.
36 | *
37 | * The resolve command maintains the files contained in the `lib` directory of a vert.x stack based on a stack
38 | * descriptor.
39 | *
40 | * @author Clement Escoffier
41 | */
42 | @Name("resolve")
43 | @Summary("Resolve the vert.x stack according to the content the stack description.")
44 | @Description("Synchronize the content of a vert.x distribution based on the description given in a 'json' file. From " +
45 | "the 'VERTX_HOME' directory, launch it with: 'bin/vertx resolve'.")
46 | public class ResolveCommand extends DefaultCommand {
47 |
48 | private String directory;
49 | private String descriptor;
50 | private boolean failOnConflict;
51 | private String localRepository;
52 | private List remoteRepositories;
53 | private String httpProxy;
54 | private String httpsProxy;
55 | private boolean disableCache;
56 | private boolean disableCacheForSnapshots;
57 | private File cacheFile;
58 |
59 | @Option(longName = "dir")
60 | @Description("The directory containing the artifacts composing the stack. Defaults to the '$VERTX_HOME/lib' " +
61 | "directory, if $VERTX_HOME is set, './lib' otherwise.")
62 | public void setDirectory(String file) {
63 | this.directory = file;
64 | }
65 |
66 | @Argument(index = 0, required = false, argName = "stack-descriptor")
67 | @DefaultValue("vertx-stack.json")
68 | @Description("The path to the stack descriptor. Defaults to '$VERTX_HOME/vertx-stack.json', if $VERTX_HOME is set, " +
69 | "'./vertx-stack.json' otherwise.")
70 | public void setStackDescriptor(String file) {
71 | this.descriptor = file;
72 | }
73 |
74 | @Option(longName = "fail-on-conflict", flag = true)
75 | @DefaultValue("false")
76 | @Description("Set whether or not the resolver should fail or conflict or just log a warning. Disabled by default.")
77 | public void setFailOnConflict(boolean fail) {
78 | this.failOnConflict = fail;
79 | }
80 |
81 | @Option(longName = "local-repo")
82 | @Description("Set the path to the local Maven repository. Defaults to '~/.m2/repository'.")
83 | public void setLocalRepository(String localRepository) {
84 | this.localRepository = localRepository;
85 | }
86 |
87 | @Option(longName = "remote-repo", acceptMultipleValues = true)
88 | @Description("Set the path to a remote Maven repository. Can be set multiple times.")
89 | public void setRemoteRepositories(List remoteRepositories) {
90 | this.remoteRepositories = remoteRepositories;
91 | }
92 |
93 | @Option(longName = "http-proxy")
94 | @Description("Set the HTTP proxy address if any.")
95 | public void setHttpProxy(String p) {
96 | this.httpProxy = p;
97 | }
98 |
99 | @Option(longName = "https-proxy")
100 | @Description("Set the HTTPS proxy address if any.")
101 | public void setHttpsProxy(String p) {
102 | this.httpsProxy = p;
103 | }
104 |
105 | @Option(longName = "no-cache", flag = true)
106 | @Description("Disable the resolver cache")
107 | public void setDisableCache(boolean disableCache) {
108 | this.disableCache = disableCache;
109 | }
110 |
111 | @Option(longName = "no-cache-for-snapshots", flag = true)
112 | @Description("Disable the caching of snapshot resolution")
113 | public void setDisableCacheForSnapshots(boolean disableCache) {
114 | this.disableCacheForSnapshots = disableCache;
115 | }
116 |
117 | @Option(longName = "cache-file")
118 | @Hidden
119 | public void setCacheLocation(File cache) {
120 | this.cacheFile = cache;
121 | }
122 |
123 | /**
124 | * Executes the command.
125 | * @throws CLIException if something bad happened during the execution.
126 | */
127 | @Override
128 | public void run() throws CLIException {
129 | File descriptorFile = new File(descriptor);
130 | if (! descriptorFile.isFile()) {
131 | // Try with vert.x home
132 | if (Home.getVertxHome() != null) {
133 | descriptorFile = new File(Home.getVertxHome(), descriptor);
134 | }
135 | }
136 |
137 | if (! descriptorFile.isFile()) {
138 | String message = "Cannot find the stack descriptor. Have been tried: \n\t - ./" + descriptorFile;
139 | if (Home.getVertxHome() != null) {
140 | message += "\n\t - " + descriptorFile.getAbsolutePath();
141 | }
142 | throw new CLIException(message);
143 | }
144 |
145 | File lib;
146 | if (directory == null) {
147 | if (Home.getVertxHome() != null) {
148 | lib = new File(Home.getVertxHome(), "lib");
149 | } else {
150 | lib = new File("lib");
151 | }
152 | } else {
153 | lib = new File(directory);
154 | }
155 |
156 | out().println("lib directory set to: " + lib.getAbsolutePath());
157 |
158 | Stack stack = Stack.fromDescriptor(descriptorFile);
159 | StackResolutionOptions options = new StackResolutionOptions()
160 | .setFailOnConflicts(failOnConflict)
161 | .setCacheDisabled(disableCache)
162 | .setCacheDisabledForSnapshots(disableCacheForSnapshots)
163 | .setCacheFile(cacheFile);
164 |
165 | if (localRepository != null) {
166 | options.setLocalRepository(localRepository);
167 | }
168 |
169 | if (remoteRepositories != null) {
170 | options.setRemoteRepositories(remoteRepositories);
171 | }
172 |
173 | options.setHttpProxy(httpProxy);
174 | options.setHttpsProxy(httpsProxy);
175 |
176 | StackResolution resolution = new StackResolution(stack, lib, options);
177 | resolution.resolve();
178 | }
179 |
180 | }
181 |
--------------------------------------------------------------------------------
/stack-manager/src/main/java/io/vertx/stack/command/ResolveCommandFactory.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2011-2015 The original author or authors
3 | * ------------------------------------------------------
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the Eclipse Public License v1.0
6 | * and Apache License v2.0 which accompanies this distribution.
7 | *
8 | * The Eclipse Public License is available at
9 | * http://www.eclipse.org/legal/epl-v10.html
10 | *
11 | * The Apache License v2.0 is available at
12 | * http://www.opensource.org/licenses/apache2.0.php
13 | *
14 | * You may elect to redistribute this code under either of these licenses.
15 | */
16 |
17 | package io.vertx.stack.command;
18 |
19 | import io.vertx.core.spi.launcher.DefaultCommandFactory;
20 |
21 | /**
22 | * The {@link ResolveCommand} factory.
23 | *
24 | * @author Clement Escoffier
25 | */
26 | public class ResolveCommandFactory extends DefaultCommandFactory {
27 |
28 | public ResolveCommandFactory() {
29 | super(ResolveCommand.class);
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/stack-manager/src/main/java/io/vertx/stack/command/package-info.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2011-2015 The original author or authors
3 | * ------------------------------------------------------
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the Eclipse Public License v1.0
6 | * and Apache License v2.0 which accompanies this distribution.
7 | *
8 | * The Eclipse Public License is available at
9 | * http://www.eclipse.org/legal/epl-v10.html
10 | *
11 | * The Apache License v2.0 is available at
12 | * http://www.opensource.org/licenses/apache2.0.php
13 | *
14 | * You may elect to redistribute this code under either of these licenses.
15 | */
16 |
17 | package io.vertx.stack.command;
18 |
--------------------------------------------------------------------------------
/stack-manager/src/main/java/io/vertx/stack/model/Artifact.java:
--------------------------------------------------------------------------------
1 | package io.vertx.stack.model;
2 |
3 | import org.eclipse.aether.artifact.AbstractArtifact;
4 |
5 | import java.io.File;
6 | import java.util.HashMap;
7 | import java.util.Map;
8 | import java.util.Objects;
9 | import java.util.regex.Matcher;
10 | import java.util.regex.Pattern;
11 |
12 | public class Artifact extends AbstractArtifact {
13 |
14 | private final String groupId;
15 | private final String artifactId;
16 | private final String version;
17 | private final String classifier;
18 | private final String extension;
19 | private final File file;
20 | private final Map properties;
21 | private final Artifact via;
22 | private static final Pattern coordinatesPattern =
23 | Pattern.compile("([^: ]+):([^: ]+)(:([^: ]*)(:([^: ]+))?)?:([^: ]+)");
24 |
25 | public Artifact(String coordinates) {
26 | this(coordinates, null);
27 | }
28 |
29 | public Artifact(String groupId, String artifactId, String classifier, String extension, String version, Artifact via) {
30 | this(groupId + ":" + artifactId + ":" + extension + ":" + classifier + ":" + version, via);
31 | }
32 |
33 | public Artifact(String groupId, String artifactId, String extension, String version, Artifact via) {
34 | this(groupId + ":" + artifactId + ":" + extension + ":" + version, via);
35 | }
36 |
37 | public Artifact(org.eclipse.aether.artifact.Artifact fromArtifact, Artifact via) {
38 | this(coordinates(fromArtifact), via, fromArtifact.getFile(), fromArtifact.getProperties());
39 | }
40 |
41 | public Artifact(String coordinates, Artifact viaArtifact) {
42 | this(coordinates, viaArtifact, null, new HashMap<>());
43 | }
44 |
45 | private Artifact(String coordinates, Artifact viaArtifact, File artifactFile, Map props) {
46 | Matcher m = coordinatesPattern.matcher(coordinates);
47 |
48 | if (!m.matches()) {
49 | throw new IllegalArgumentException("Bad artifact coordinates " + coordinates
50 | + ", expected format is :[:[:]]:");
51 | }
52 |
53 | groupId = m.group(1);
54 | artifactId = m.group(2);
55 | extension = defaultIfEmpty(m.group(4), "jar");
56 | classifier = defaultIfEmpty(m.group(6), "");
57 | version = m.group(7);
58 | file = artifactFile;
59 | properties = copyProperties(props);
60 | via = viaArtifact;
61 | }
62 |
63 | private String defaultIfEmpty(String value, String defaultValue) {
64 | if (value == null || value.trim().isEmpty()) {
65 | return defaultValue;
66 | } else {
67 | return value;
68 | }
69 | }
70 |
71 | @Override
72 | public String getGroupId() {
73 | return groupId;
74 | }
75 |
76 | @Override
77 | public String getArtifactId() {
78 | return artifactId;
79 | }
80 |
81 | @Override
82 | public String getVersion() {
83 | return version;
84 | }
85 |
86 | @Override
87 | public String getClassifier() {
88 | return classifier;
89 | }
90 |
91 | @Override
92 | public String getExtension() {
93 | return extension;
94 | }
95 |
96 | @Override
97 | public Artifact setFile(File file) {
98 | if (Objects.equals(this.file, file)) {
99 | return this;
100 | } else {
101 | return new Artifact(coordinates(this), via, file, properties);
102 | }
103 | }
104 |
105 | @Override
106 | public File getFile() {
107 | return file;
108 | }
109 |
110 | @Override
111 | public Map getProperties() {
112 | return properties;
113 | }
114 |
115 | @Override
116 | public Artifact setProperties(Map properties) {
117 | if (Objects.equals(this.properties, properties)) {
118 | return this;
119 | } else {
120 | return new Artifact(coordinates(this), via, file, copyProperties(properties));
121 | }
122 | }
123 |
124 | public Artifact getVia() {
125 | return via;
126 | }
127 |
128 | public String getCoordinates() {
129 | return coordinates(this);
130 | }
131 |
132 | @Override
133 | public boolean equals(Object o) {
134 | if (this == o) return true;
135 | if (o == null || getClass() != o.getClass()) return false;
136 | if (!super.equals(o)) return false;
137 | Artifact artifact = (Artifact) o;
138 | return Objects.equals(groupId, artifact.groupId)
139 | && Objects.equals(artifactId, artifact.artifactId)
140 | && Objects.equals(version, artifact.version)
141 | && Objects.equals(classifier, artifact.classifier)
142 | && Objects.equals(extension, artifact.extension)
143 | && Objects.equals(file, artifact.file)
144 | && Objects.equals(properties, artifact.properties)
145 | && Objects.equals(via, artifact.via);
146 | }
147 |
148 | @Override
149 | public int hashCode() {
150 | return Objects.hash(super.hashCode(), groupId, artifactId, version, classifier, extension, file, properties, via);
151 | }
152 |
153 | private static String coordinates(org.eclipse.aether.artifact.Artifact artifact) {
154 | // :[:[:]]:
155 | return artifact.getGroupId() + ":" + artifact.getArtifactId()
156 | + ":" + artifact.getExtension()
157 | + (artifact.getClassifier().isEmpty() ? "" : ":" + artifact.getClassifier())
158 | + ":" + artifact.getVersion();
159 | }
160 | }
161 |
--------------------------------------------------------------------------------
/stack-manager/src/main/java/io/vertx/stack/model/Dependency.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2011-2015 The original author or authors
3 | * ------------------------------------------------------
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the Eclipse Public License v1.0
6 | * and Apache License v2.0 which accompanies this distribution.
7 | *
8 | * The Eclipse Public License is available at
9 | * http://www.eclipse.org/legal/epl-v10.html
10 | *
11 | * The Apache License v2.0 is available at
12 | * http://www.opensource.org/licenses/apache2.0.php
13 | *
14 | * You may elect to redistribute this code under either of these licenses.
15 | */
16 |
17 | package io.vertx.stack.model;
18 |
19 | import com.fasterxml.jackson.annotation.JsonIgnore;
20 | import io.vertx.stack.resolver.ResolutionOptions;
21 | import org.apache.maven.model.Exclusion;
22 |
23 | /**
24 | * Represents a dependency. The stack describes a set of dependencies resolved as Maven dependencies. Each dependency
25 | * can be included or excluded and can instruct whether the resolution need to bring the transitive dependencies too.
26 | *
27 | * Be aware the dependencies cannot be set as "optional', as optionality do not make sense when we deploy the artifact.
28 | *
29 | * @author Clement Escoffier
30 | */
31 | public class Dependency extends org.apache.maven.model.Dependency {
32 |
33 | private boolean included = true;
34 |
35 | private boolean transitive = true;
36 |
37 | /**
38 | * Creates a new {@link Dependency}.
39 | *
40 | * @param groupId the groupId
41 | * @param artifactId the artifactId
42 | * @param version the version
43 | */
44 | public Dependency(String groupId, String artifactId, String version) {
45 | this();
46 | setGroupId(groupId);
47 | setArtifactId(artifactId);
48 | setVersion(version);
49 | }
50 |
51 | /**
52 | * Creates a new {@link Dependency}.
53 | *
54 | * @param groupId the groupId
55 | * @param artifactId the artifactId
56 | * @param version the version
57 | * @param type the type / extension / packaging
58 | */
59 | public Dependency(String groupId, String artifactId, String version, String type) {
60 | this(groupId, artifactId, version);
61 | setType(type);
62 | }
63 |
64 | /**
65 | * Creates a new {@link Dependency}.
66 | *
67 | * The type is set to "jar" by default.
68 | */
69 | public Dependency() {
70 | setType("jar");
71 | }
72 |
73 | /**
74 | * @return {@code true} if the dependency is included, {@code false} otherwise.
75 | */
76 | public boolean isIncluded() {
77 | return included;
78 | }
79 |
80 | /**
81 | * Sets whether or not the dependency is included. Included by default.
82 | *
83 | * @return the current {@link Dependency} instance.
84 | */
85 | public Dependency setIncluded(boolean included) {
86 | this.included = included;
87 | return this;
88 | }
89 |
90 | /**
91 | * @return {@code true} if the dependency must be resolved with its transitive dependencies.
92 | */
93 | public boolean isTransitive() {
94 | return transitive;
95 | }
96 |
97 | /**
98 | * Sets whether or not the dependency resolution also resolves the transitive dependencies. Transitive dependencies
99 | * are resolved by default.
100 | *
101 | * @return the current {@link Dependency} instance.
102 | */
103 | public Dependency setTransitive(boolean transitive) {
104 | this.transitive = transitive;
105 | return this;
106 | }
107 |
108 | /**
109 | * Creates the {@link ResolutionOptions} object for the dependency.
110 | *
111 | * @return the {@link ResolutionOptions} instructing the dependency resolution.
112 | */
113 | public ResolutionOptions getResolutionOptions() {
114 | ResolutionOptions options = new ResolutionOptions();
115 | options.setWithTransitive(transitive);
116 | for (Exclusion exclusion : getExclusions()) {
117 | options.addExclusion(exclusion.getGroupId() + ":" + exclusion.getArtifactId());
118 | }
119 |
120 | return options;
121 | }
122 |
123 | /**
124 | * @return the Maven GACV string.
125 | */
126 | public String getGACV() {
127 | return getManagementKey() + ":" + getVersion();
128 | }
129 |
130 | /**
131 | * Not supported property, as the concept of 'optional' does not make sense when building a stack.
132 | *
133 | * @param optional ignored
134 | */
135 | @Override
136 | @JsonIgnore
137 | public void setOptional(boolean optional) {
138 | throw new UnsupportedOperationException("You cannot add an optional dependency to a stack - optional does not " +
139 | "make sense in this case");
140 | }
141 | }
142 |
--------------------------------------------------------------------------------
/stack-manager/src/main/java/io/vertx/stack/model/DependencyConflictException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2011-2015 The original author or authors
3 | * ------------------------------------------------------
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the Eclipse Public License v1.0
6 | * and Apache License v2.0 which accompanies this distribution.
7 | *
8 | * The Eclipse Public License is available at
9 | * http://www.eclipse.org/legal/epl-v10.html
10 | *
11 | * The Apache License v2.0 is available at
12 | * http://www.opensource.org/licenses/apache2.0.php
13 | *
14 | * You may elect to redistribute this code under either of these licenses.
15 | */
16 |
17 | package io.vertx.stack.model;
18 |
19 | import org.apache.commons.lang3.StringUtils;
20 |
21 | import java.util.ArrayList;
22 | import java.util.List;
23 | import java.util.concurrent.atomic.AtomicInteger;
24 |
25 | /**
26 | * Thrown when a conflict is detected between two dependencies.
27 | *
28 | * @author Clement Escoffier
29 | */
30 | public class DependencyConflictException extends RuntimeException {
31 |
32 | private final String artifact;
33 | private final String version;
34 | private final List trace;
35 | private final String conflictingDependency;
36 | private final Artifact conflictingArtifact;
37 |
38 | /**
39 | * Creates a {@link DependencyConflictException}.
40 | *
41 | * @param artifact the artifact
42 | * @param version the current version
43 | * @param conflictingDependency the conflicting dependency
44 | * @param conflictingArtifact the conflicting {@link Artifact}
45 | */
46 | public DependencyConflictException(String artifact, String version, List trace, String conflictingDependency, Artifact conflictingArtifact) {
47 | this.artifact = artifact;
48 | this.version = version;
49 | this.trace = trace;
50 | this.conflictingDependency = conflictingDependency;
51 | this.conflictingArtifact = conflictingArtifact;
52 | }
53 |
54 | /**
55 | * Returns the detail message string of this throwable.
56 | *
57 | * @return the detail message string of this {@code Throwable} instance
58 | * (which may be {@code null}).
59 | */
60 | @Override
61 | public String getMessage() {
62 |
63 | return "Conflict detected for artifact " + artifact + " - version " + version + " was already selected" +
64 | " by " + trace +
65 | " while " + conflictingDependency + " depends on version " + conflictingArtifact.getVersion() +
66 | " - see the following chain:\n" +
67 | renderArtifactChain(conflictingArtifact, new ArrayList<>());
68 | }
69 |
70 | private String renderArtifactChain(Artifact fromArtifact, List acc) {
71 | if (fromArtifact.getVia() == null) {
72 | StringBuilder resultBuilder = new StringBuilder(fromArtifact.getCoordinates());
73 | AtomicInteger level = new AtomicInteger(0);
74 | acc.forEach(coords -> {
75 | String indent = StringUtils.repeat('\t', level.incrementAndGet());
76 | resultBuilder.append("\n")
77 | .append(indent).append("\\-- ").append(coords);
78 | });
79 | return resultBuilder.toString();
80 | } else {
81 | acc.add(0, fromArtifact.getCoordinates());
82 | return renderArtifactChain(fromArtifact.getVia(), acc);
83 | }
84 | }
85 |
86 | }
87 |
--------------------------------------------------------------------------------
/stack-manager/src/main/java/io/vertx/stack/model/Stack.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2011-2015 The original author or authors
3 | * ------------------------------------------------------
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the Eclipse Public License v1.0
6 | * and Apache License v2.0 which accompanies this distribution.
7 | *
8 | * The Eclipse Public License is available at
9 | * http://www.eclipse.org/legal/epl-v10.html
10 | *
11 | * The Apache License v2.0 is available at
12 | * http://www.opensource.org/licenses/apache2.0.php
13 | *
14 | * You may elect to redistribute this code under either of these licenses.
15 | */
16 |
17 | package io.vertx.stack.model;
18 |
19 | import com.fasterxml.jackson.core.JsonParser;
20 | import com.fasterxml.jackson.databind.ObjectMapper;
21 | import io.vertx.stack.utils.Filtering;
22 |
23 | import java.io.File;
24 | import java.io.IOException;
25 | import java.util.ArrayList;
26 | import java.util.LinkedHashMap;
27 | import java.util.List;
28 | import java.util.Map;
29 | import java.util.stream.Stream;
30 |
31 | /**
32 | * Represents a stack. A stack is composed by a set of dependencies and variables.
33 | *
34 | * @author Clement Escoffier
35 | */
36 | public class Stack {
37 |
38 | private List dependencies = new ArrayList<>();
39 |
40 | private Map variables = new LinkedHashMap<>();
41 |
42 | /**
43 | * Adds a new variables or updates the value of an existing one.
44 | *
45 | * @param key the variable name
46 | * @param value the value
47 | * @return the current {@link Stack} instance
48 | */
49 | public Stack addVariable(String key, String value) {
50 | variables.put(key, value);
51 | return this;
52 | }
53 |
54 | /**
55 | * Removes a variable.
56 | *
57 | * @param key the variable name
58 | * @return the current {@link Stack} instance
59 | */
60 | public Stack removeVariable(String key) {
61 | variables.remove(key);
62 | return this;
63 | }
64 |
65 | /**
66 | * Adds a dependency.
67 | *
68 | * @param dependency the dependency
69 | * @return the current {@link Stack} instance
70 | */
71 | public Stack addDependency(Dependency dependency) {
72 | dependencies.add(dependency);
73 | return this;
74 | }
75 |
76 | /**
77 | * Removes a dependency.
78 | *
79 | * @param dependency the dependency
80 | * @return the current {@link Stack} instance
81 | */
82 | public Stack removeDependency(Dependency dependency) {
83 | dependencies.remove(dependency);
84 | return this;
85 | }
86 |
87 | /**
88 | * Gets the variables.
89 | *
90 | * @return the variables, empty if none.
91 | */
92 | public Map getVariables() {
93 | return variables;
94 | }
95 |
96 | /**
97 | * Apply filtering on the set of dependencies.
98 | */
99 | public void applyFiltering() {
100 | // Compute the final set of properties.
101 | // First the properties, Then the system properties, so you can override a value using -D.
102 | Map properties = new LinkedHashMap<>();
103 | properties.putAll(variables);
104 | properties.putAll((Map) System.getProperties());
105 |
106 | dependencies.stream().forEach(dependency -> {
107 | dependency.setGroupId(Filtering.filter(dependency.getGroupId(), properties));
108 | dependency.setArtifactId(Filtering.filter(dependency.getArtifactId(), properties));
109 | dependency.setVersion(Filtering.filter(dependency.getVersion(), properties));
110 | dependency.setClassifier(Filtering.filter(dependency.getClassifier(), properties));
111 | dependency.setType(Filtering.filter(dependency.getType(), properties));
112 | });
113 | }
114 |
115 | /**
116 | * Gets the dependencies, empty if none.
117 | *
118 | * @return the dependencies
119 | */
120 | public Stream getDependencies() {
121 | return dependencies.stream();
122 | }
123 |
124 | /**
125 | * Reads a stack descriptor.
126 | *
127 | * @param descriptor the descriptor, must be a valid YAML file.
128 | * @return the created stack
129 | */
130 | public static Stack fromDescriptor(File descriptor) {
131 | ObjectMapper mapper = new ObjectMapper();
132 | mapper = mapper
133 | .enable(JsonParser.Feature.ALLOW_COMMENTS)
134 | .enable(JsonParser.Feature.ALLOW_UNQUOTED_FIELD_NAMES)
135 | .enable(JsonParser.Feature.ALLOW_SINGLE_QUOTES)
136 | .enable(JsonParser.Feature.STRICT_DUPLICATE_DETECTION);
137 | try {
138 | return mapper.readValue(descriptor, Stack.class);
139 | } catch (IOException e) {
140 | throw new IllegalArgumentException("Cannot load stack from " + descriptor.getAbsolutePath(), e);
141 | }
142 | }
143 | }
144 |
--------------------------------------------------------------------------------
/stack-manager/src/main/java/io/vertx/stack/model/StackResolution.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2011-2015 The original author or authors
3 | * ------------------------------------------------------
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the Eclipse Public License v1.0
6 | * and Apache License v2.0 which accompanies this distribution.
7 | *
8 | * The Eclipse Public License is available at
9 | * http://www.eclipse.org/legal/epl-v10.html
10 | *
11 | * The Apache License v2.0 is available at
12 | * http://www.opensource.org/licenses/apache2.0.php
13 | *
14 | * You may elect to redistribute this code under either of these licenses.
15 | */
16 |
17 | package io.vertx.stack.model;
18 |
19 | import io.vertx.core.internal.logging.Logger;
20 | import io.vertx.core.internal.logging.LoggerFactory;
21 | import io.vertx.stack.resolver.Resolver;
22 | import io.vertx.stack.utils.Actions;
23 | import io.vertx.stack.utils.Cache;
24 | import org.eclipse.aether.artifact.Artifact;
25 |
26 | import java.io.File;
27 | import java.nio.file.Path;
28 | import java.util.*;
29 | import java.util.function.Predicate;
30 | import java.util.stream.Collectors;
31 |
32 | /**
33 | * Object responsible for resolving a stack. This object is stateful, and must be used only for a single resolution.
34 | *
35 | * @author Clement Escoffier
36 | */
37 | public class StackResolution {
38 |
39 | private final static Logger LOGGER = LoggerFactory.getLogger("Stack Resolution");
40 |
41 | private final File directory;
42 | private final Stack stack;
43 |
44 | private final Map selectedVersions = new LinkedHashMap<>();
45 | private final Map selectedArtifacts = new LinkedHashMap<>();
46 |
47 | /**
48 | * Map keeping a trace from who has resolved which version. It imrpvoes the reporting when a conflict has been
49 | * detected.
50 | */
51 | private final Map> traces = new LinkedHashMap<>();
52 |
53 | private final StackResolutionOptions options;
54 | private Resolver resolver;
55 |
56 | private final Cache cache;
57 |
58 | /**
59 | * Creates an instance of {@link StackResolution}.
60 | *
61 | * @param stack the stack
62 | * @param directory the output directory, created if not existing
63 | * @param options the stack resolution options
64 | */
65 | public StackResolution(Stack stack, File directory, StackResolutionOptions options) {
66 | Objects.requireNonNull(stack);
67 | Objects.requireNonNull(options);
68 | Objects.requireNonNull(directory);
69 | this.stack = stack;
70 | this.options = options;
71 | this.directory = directory;
72 | this.cache = new Cache(options.isCacheDisabled(), options.isCacheDisabledForSnapshots(), options.getCacheFile());
73 | }
74 |
75 | /**
76 | * Resolves the stack.
77 | *
78 | * @return the map artifact's management key - file composing the stack
79 | */
80 | public Map resolve() {
81 | traces.clear();
82 | selectedVersions.clear();
83 | init();
84 | stack.getDependencies().forEach(this::resolve);
85 | List chain = computeChainOfActions();
86 |
87 | chain.forEach(Actions.Action::execute);
88 |
89 | Map resolved = new LinkedHashMap<>();
90 | for (ResolvedArtifact artifact : selectedArtifacts.values()) {
91 | Path source = artifact.artifact.getFile().toPath();
92 | Path output = directory.toPath().resolve(source.getFileName());
93 | resolved.put(artifact.artifact.toString(), output.toFile());
94 | }
95 |
96 | return resolved;
97 | }
98 |
99 | public Map resolve(Predicate validator) {
100 | traces.clear();
101 | selectedVersions.clear();
102 | init();
103 | stack.getDependencies().forEach(this::resolve);
104 | List chain = computeChainOfActions();
105 |
106 | chain.forEach(Actions.Action::execute);
107 |
108 | Map resolved = new LinkedHashMap<>();
109 | for (ResolvedArtifact artifact : selectedArtifacts.values()) {
110 | String gav = artifact.artifact.toString();
111 | if (!validator.test(gav)) {
112 | throw new IllegalStateException("Invalid artifact " + gav + ", used by " + artifact.getUsages());
113 | }
114 | Path source = artifact.artifact.getFile().toPath();
115 | Path output = directory.toPath().resolve(source.getFileName());
116 | resolved.put(gav, output.toFile());
117 | }
118 |
119 | return resolved;
120 | }
121 |
122 | private void init() {
123 | if (!directory.isDirectory()) {
124 | LOGGER.info("Creating directory " + directory.getAbsolutePath());
125 | boolean mkdirs = directory.mkdirs();
126 | LOGGER.debug("Directory created: " + mkdirs);
127 | }
128 | stack.applyFiltering();
129 | stack.getDependencies().filter(Dependency::isIncluded).forEach(
130 | dependency -> selectedVersions.put(dependency.getManagementKey(), dependency.getVersion()));
131 | resolver = Resolver.create(options);
132 | }
133 |
134 | private List computeChainOfActions() {
135 | File[] files = directory.listFiles((dir, name) -> name.endsWith(".jar"));
136 | if (files == null) {
137 | throw new IllegalStateException("Unable to read from the file system");
138 | }
139 |
140 | Map marks = new HashMap<>();
141 | for (File file : files) {
142 | marks.put(file.getName(), false);
143 | }
144 |
145 | List chain = new ArrayList<>();
146 |
147 | selectedArtifacts.forEach((key, artifact) -> {
148 | String fileName = artifact.getArtifact().getFile().getName();
149 |
150 | if (marks.containsKey(fileName)) {
151 | // Mark the file.
152 | marks.put(fileName, true);
153 | chain.add(Actions.skip(artifact.getArtifact()));
154 | } else {
155 | chain.add(Actions.copy(artifact.getArtifact(), directory));
156 | }
157 | });
158 |
159 | // Schedule the deletion of all non-marked file.
160 | marks.forEach((fileName, mark) -> {
161 | if (!mark && !fileName.startsWith("vertx-stack-manager-")) { // Do not delete me
162 | chain.add(Actions.remove(new File(directory, fileName)));
163 | }
164 | });
165 |
166 | return chain;
167 | }
168 |
169 | private void resolve(Dependency dependency) {
170 | List list;
171 | if (dependency.isIncluded()) {
172 | list = cache.get(dependency.getGACV(), dependency.getResolutionOptions());
173 | // artifacts = cache.get(dependency.getGACV(), dependency.getResolutionOptions());
174 | if (list == null || list.isEmpty()) {
175 | // list = resolver.resolve(dependency.getGACV(), dependency.getResolutionOptions());
176 | list = resolver.resolve(dependency.getGACV(), dependency.getResolutionOptions());
177 | cache.put(dependency.getGACV(), dependency.getResolutionOptions(), list);
178 | cache.writeCacheOnFile();
179 | } else {
180 | LOGGER.info("Dependency " + dependency + " loaded from cache");
181 | }
182 | } else {
183 | return;
184 | }
185 |
186 | if (list == null || list.isEmpty()) {
187 | throw new IllegalArgumentException("Cannot resolve " + dependency);
188 | }
189 |
190 | LOGGER.debug("Artifacts resolved for " + dependency.getGACV() + " : "
191 | + list.stream().map(Object::toString).collect(Collectors.toList()));
192 |
193 | list.forEach(artifact -> {
194 | String gaec = getManagementKey(artifact);
195 | String version = selectedVersions.get(gaec);
196 | if (version == null || version.equalsIgnoreCase(artifact.getBaseVersion())) {
197 | selectedVersions.put(gaec, artifact.getBaseVersion());
198 | keepATrace(dependency, artifact);
199 | } else {
200 | List trace = traces.get(gaec + ":" + version);
201 | if (options.isFailOnConflicts()) {
202 | throw new DependencyConflictException(gaec, version, trace, dependency.getGACV(), artifact);
203 | }
204 | }
205 | addSelectedArtifact(dependency, artifact, version);
206 | });
207 | }
208 |
209 | /**
210 | * Keep a trace of the resolution.
211 | *
212 | * @param dependency the dependency having triggered the resolution
213 | * @param artifact the resolved artifact
214 | */
215 | private void keepATrace(Dependency dependency, Artifact artifact) {
216 | String traceId = getManagementKey(artifact) + ":" + artifact.getBaseVersion();
217 | List deps = traces.computeIfAbsent(traceId, k -> new ArrayList<>());
218 | deps.add(dependency.getGACV());
219 | }
220 |
221 | private void addSelectedArtifact(Dependency dependency, Artifact artifact, String version) {
222 | String key = getManagementKey(artifact);
223 | ResolvedArtifact resolved = selectedArtifacts.get(key);
224 | if (resolved != null) {
225 | resolved.addUsage(getManagementKey(dependency));
226 | } else {
227 | selectedArtifacts.put(key,
228 | new ResolvedArtifact().addUsage(getManagementKey(dependency))
229 | .setSelectedVersion(version).setArtifact(artifact));
230 | }
231 | }
232 |
233 | private String getManagementKey(Artifact artifact) {
234 | return artifact.getGroupId()
235 | + ":" + artifact.getArtifactId()
236 | + ":" + artifact.getExtension()
237 | + (artifact.getClassifier() != null && !artifact.getClassifier().isEmpty()
238 | ? ":" + artifact.getClassifier() : "");
239 | }
240 |
241 | private String getManagementKey(Dependency dependency) {
242 | return dependency.getManagementKey();
243 | }
244 |
245 | /**
246 | * Represents a resolved artifact.
247 | */
248 | public static class ResolvedArtifact {
249 | private Artifact artifact;
250 | private String selectedVersion;
251 | private final Set usages = new LinkedHashSet<>();
252 |
253 | public Artifact getArtifact() {
254 | return artifact;
255 | }
256 |
257 | public ResolvedArtifact setArtifact(Artifact artifact) {
258 | this.artifact = artifact;
259 | return this;
260 | }
261 |
262 | @SuppressWarnings("unused")
263 | public String getSelectedVersion() {
264 | return selectedVersion;
265 | }
266 |
267 | public ResolvedArtifact setSelectedVersion(String selectedVersion) {
268 | this.selectedVersion = selectedVersion;
269 | return this;
270 | }
271 |
272 | public ResolvedArtifact addUsage(String key) {
273 | usages.add(key);
274 | return this;
275 | }
276 |
277 | @SuppressWarnings("unused")
278 | public Set getUsages() {
279 | return usages;
280 | }
281 | }
282 |
283 | }
284 |
--------------------------------------------------------------------------------
/stack-manager/src/main/java/io/vertx/stack/model/StackResolutionOptions.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2011-2015 The original author or authors
3 | * ------------------------------------------------------
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the Eclipse Public License v1.0
6 | * and Apache License v2.0 which accompanies this distribution.
7 | *
8 | * The Eclipse Public License is available at
9 | * http://www.eclipse.org/legal/epl-v10.html
10 | *
11 | * The Apache License v2.0 is available at
12 | * http://www.opensource.org/licenses/apache2.0.php
13 | *
14 | * You may elect to redistribute this code under either of these licenses.
15 | */
16 |
17 | package io.vertx.stack.model;
18 |
19 | import io.vertx.stack.resolver.ResolverOptions;
20 |
21 | import java.io.File;
22 | import java.util.List;
23 |
24 | /**
25 | * The options configuring the stack resolution.
26 | *
27 | * @author Clement Escoffier
28 | */
29 | public class StackResolutionOptions extends ResolverOptions {
30 |
31 | private boolean failOnConflicts;
32 |
33 | private boolean cacheDisabled;
34 |
35 | private boolean cacheDisabledForSnapshots;
36 |
37 | private File cacheFile;
38 |
39 | /**
40 | * @return whether or not the resolution fails on conflicts or just prints a warning.
41 | */
42 | public boolean isFailOnConflicts() {
43 | return failOnConflicts;
44 | }
45 |
46 | /**
47 | * Sets whether or not the resolution should fail on conflicts.
48 | *
49 | * @param failOnConflicts whether or not the resolution fails on conflicts.
50 | * @return the current {@link StackResolutionOptions} instance
51 | */
52 | public StackResolutionOptions setFailOnConflicts(boolean failOnConflicts) {
53 | this.failOnConflicts = failOnConflicts;
54 | return this;
55 | }
56 |
57 | @Override
58 | public StackResolutionOptions setHttpProxy(String httpProxy) {
59 | super.setHttpProxy(httpProxy);
60 | return this;
61 | }
62 |
63 | @Override
64 | public StackResolutionOptions setHttpsProxy(String httpsProxy) {
65 | super.setHttpsProxy(httpsProxy);
66 | return this;
67 | }
68 |
69 | @Override
70 | public StackResolutionOptions setLocalRepository(String localRepository) {
71 | super.setLocalRepository(localRepository);
72 | return this;
73 | }
74 |
75 | @Override
76 | public StackResolutionOptions setRemoteRepositories(List remoteRepositories) {
77 | super.setRemoteRepositories(remoteRepositories);
78 | return this;
79 | }
80 |
81 | /**
82 | * @return whether or not the cache is disabled.
83 | */
84 | public boolean isCacheDisabled() {
85 | return cacheDisabled;
86 | }
87 |
88 | /**
89 | * Sets whether or not the cache is disabled.
90 | *
91 | * @param cacheDisabled {@code true} to disable the cache, {@code false} to enable it (default)
92 | * @return the current {@link StackResolutionOptions} instance
93 | */
94 | public StackResolutionOptions setCacheDisabled(boolean cacheDisabled) {
95 | this.cacheDisabled = cacheDisabled;
96 | return this;
97 | }
98 |
99 | /**
100 | * @return whether or not the cache is disabled for snapshots
101 | */
102 | public boolean isCacheDisabledForSnapshots() {
103 | return cacheDisabledForSnapshots;
104 | }
105 |
106 | /**
107 | * Sets whether or not the cache is disabled for snapshot.
108 | *
109 | * @param cacheDisabledForSnapshots {@code true} to disable the cache for snapshot, {@code false} to enable it
110 | * (default)
111 | * @return the current {@link StackResolutionOptions} instance
112 | */
113 | public StackResolutionOptions setCacheDisabledForSnapshots(boolean cacheDisabledForSnapshots) {
114 | this.cacheDisabledForSnapshots = cacheDisabledForSnapshots;
115 | return this;
116 | }
117 |
118 | /**
119 | * @return the location of the cache file is set.
120 | */
121 | public File getCacheFile() {
122 | return cacheFile;
123 | }
124 |
125 | /**
126 | * Sets the cache file location (json file).
127 | *
128 | * @param cacheFile the cache file
129 | * @return the current {@link StackResolutionOptions} instance
130 | */
131 | public StackResolutionOptions setCacheFile(File cacheFile) {
132 | this.cacheFile = cacheFile;
133 | return this;
134 | }
135 | }
136 |
--------------------------------------------------------------------------------
/stack-manager/src/main/java/io/vertx/stack/resolver/ResolutionOptions.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2011-2015 The original author or authors
3 | * ------------------------------------------------------
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the Eclipse Public License v1.0
6 | * and Apache License v2.0 which accompanies this distribution.
7 | *
8 | * The Eclipse Public License is available at
9 | * http://www.eclipse.org/legal/epl-v10.html
10 | *
11 | * The Apache License v2.0 is available at
12 | * http://www.opensource.org/licenses/apache2.0.php
13 | *
14 | * You may elect to redistribute this code under either of these licenses.
15 | */
16 |
17 | package io.vertx.stack.resolver;
18 |
19 | import java.util.*;
20 |
21 | /**
22 | * Options configuring the resolution of a single dependency.
23 | *
24 | * @author Clement Escoffier
25 | */
26 | public class ResolutionOptions {
27 |
28 | private boolean withTransitive = true;
29 | private List exclusions = new ArrayList<>();
30 |
31 | /**
32 | * @return whether or not the resolution should also resolve the transitive dependencies.
33 | */
34 | public boolean isWithTransitive() {
35 | return withTransitive;
36 | }
37 |
38 | /**
39 | * Sets whether or not the resolution of the dependency should include the transitive dependencies.
40 | *
41 | * @param withTransitive whether or not the resolution should also resolve the transitive dependencies, {@code
42 | * true} by default.
43 | * @return the current {@link ResolutionOptions} instance
44 | */
45 | public ResolutionOptions setWithTransitive(boolean withTransitive) {
46 | this.withTransitive = withTransitive;
47 | return this;
48 | }
49 |
50 | /**
51 | * Adds an exclusion. The excluded dependencies and its children would not be resolved. The exclusion is given
52 | * under the following form: {@code groupId:artifactId}.
53 | *
54 | * @param exclusion the exclusion to add
55 | * @return the current {@link ResolutionOptions} instance
56 | */
57 | public ResolutionOptions addExclusion(String exclusion) {
58 | exclusions.add(exclusion);
59 | return this;
60 | }
61 |
62 | /**
63 | * Removes an exclusion.
64 | *
65 | * @param exclusion the exlusion to remove
66 | * @return the current {@link ResolutionOptions} instance
67 | * @see #addExclusion(String)
68 | */
69 | public ResolutionOptions removeExclusion(String exclusion) {
70 | exclusions.remove(exclusion);
71 | return this;
72 | }
73 |
74 | /**
75 | * @return the list of exclusions, empty if none.
76 | */
77 | public List getExclusions() {
78 | return exclusions;
79 | }
80 |
81 | @Override
82 | public boolean equals(Object o) {
83 | if (this == o) return true;
84 | if (o == null || getClass() != o.getClass()) return false;
85 |
86 | ResolutionOptions that = (ResolutionOptions) o;
87 |
88 | if (isWithTransitive() != that.isWithTransitive()) return false;
89 |
90 | Set set1 = new HashSet<>();
91 | set1.addAll(that.getExclusions());
92 | Set set2 = new HashSet<>();
93 | set2.addAll(getExclusions());
94 | return set1.equals(set2);
95 | }
96 |
97 | @Override
98 | public int hashCode() {
99 | int result = (isWithTransitive() ? 1 : 0);
100 | result = 31 * result + getExclusions().hashCode();
101 | return result;
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/stack-manager/src/main/java/io/vertx/stack/resolver/Resolver.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2011-2015 The original author or authors
3 | * ------------------------------------------------------
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the Eclipse Public License v1.0
6 | * and Apache License v2.0 which accompanies this distribution.
7 | *
8 | * The Eclipse Public License is available at
9 | * http://www.eclipse.org/legal/epl-v10.html
10 | *
11 | * The Apache License v2.0 is available at
12 | * http://www.opensource.org/licenses/apache2.0.php
13 | *
14 | * You may elect to redistribute this code under either of these licenses.
15 | */
16 |
17 | package io.vertx.stack.resolver;
18 |
19 |
20 | import io.vertx.stack.model.Artifact;
21 |
22 | import java.util.List;
23 |
24 | /**
25 | * Interface implemented by resolver. Resolvers are responsible for the resolution of the dependencies.
26 | *
27 | * @author Clement Escoffier
28 | */
29 | public interface Resolver {
30 |
31 | /**
32 | * Resolves a dependency.
33 | *
34 | * @param dependency the dependency, using the GACV form.
35 | * @param options the resolution options
36 | * @return the list of resolved artifacts. The list contains a single element if the transitive dependencies are
37 | * not resolved. The first artifact of the list if the artifact for the given dependency.
38 | */
39 | List resolve(String dependency, ResolutionOptions options);
40 |
41 | /**
42 | * Creates a {@link Resolver} using the default implementation and default options.
43 | *
44 | * @return the created {@link Resolver}.
45 | */
46 | static Resolver create() {
47 | return new ResolverImpl(new ResolverOptions());
48 | }
49 |
50 | /**
51 | * Creates a {@link Resolver} using the default implementation and the given options.
52 | *
53 | * @param options the resolver options
54 | * @return the created {@link Resolver}.
55 | */
56 | static Resolver create(ResolverOptions options) {
57 | return new ResolverImpl(options);
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/stack-manager/src/main/java/io/vertx/stack/resolver/ResolverImpl.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2011-2015 The original author or authors
3 | * ------------------------------------------------------
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the Eclipse Public License v1.0
6 | * and Apache License v2.0 which accompanies this distribution.
7 | *
8 | * The Eclipse Public License is available at
9 | * http://www.eclipse.org/legal/epl-v10.html
10 | *
11 | * The Apache License v2.0 is available at
12 | * http://www.opensource.org/licenses/apache2.0.php
13 | *
14 | * You may elect to redistribute this code under either of these licenses.
15 | */
16 |
17 | package io.vertx.stack.resolver;
18 |
19 |
20 | import io.vertx.core.internal.logging.Logger;
21 | import io.vertx.core.internal.logging.LoggerFactory;
22 | import io.vertx.stack.model.Artifact;
23 | import org.apache.maven.repository.internal.MavenRepositorySystemUtils;
24 | import org.eclipse.aether.DefaultRepositorySystemSession;
25 | import org.eclipse.aether.RepositorySystem;
26 | import org.eclipse.aether.RepositorySystemSession;
27 | import org.eclipse.aether.collection.CollectRequest;
28 | import org.eclipse.aether.connector.basic.BasicRepositoryConnectorFactory;
29 | import org.eclipse.aether.graph.Dependency;
30 | import org.eclipse.aether.graph.DependencyFilter;
31 | import org.eclipse.aether.graph.DependencyNode;
32 | import org.eclipse.aether.graph.Exclusion;
33 | import org.eclipse.aether.impl.DefaultServiceLocator;
34 | import org.eclipse.aether.repository.*;
35 | import org.eclipse.aether.resolution.DependencyRequest;
36 | import org.eclipse.aether.resolution.DependencyResolutionException;
37 | import org.eclipse.aether.resolution.DependencyResult;
38 | import org.eclipse.aether.spi.connector.RepositoryConnectorFactory;
39 | import org.eclipse.aether.spi.connector.transport.TransporterFactory;
40 | import org.eclipse.aether.transport.file.FileTransporterFactory;
41 | import org.eclipse.aether.transport.http.HttpTransporterFactory;
42 | import org.eclipse.aether.util.artifact.JavaScopes;
43 | import org.eclipse.aether.util.filter.DependencyFilterUtils;
44 | import org.eclipse.aether.util.repository.AuthenticationBuilder;
45 |
46 | import java.net.MalformedURLException;
47 | import java.net.URL;
48 | import java.util.ArrayList;
49 | import java.util.Collection;
50 | import java.util.List;
51 | import java.util.stream.Collectors;
52 | import java.util.stream.Stream;
53 |
54 | /**
55 | * An implementation of {@link Resolver} based on Aether.
56 | *
57 | * @author Clement Escoffier
58 | */
59 | public class ResolverImpl implements Resolver {
60 |
61 | private final static Logger LOGGER = LoggerFactory.getLogger("vertx-stack-resolver");
62 |
63 | public static final String REMOTE_SNAPSHOT_POLICY_SYS_PROP = "vertx.maven.remoteSnapshotPolicy";
64 |
65 | private final RepositorySystem system;
66 | private final LocalRepository localRepo;
67 | private final List remotes = new ArrayList<>();
68 |
69 | /**
70 | * Creates a new instance of {@link ResolverImpl} with the given options.
71 | *
72 | * @param options the options
73 | */
74 | public ResolverImpl(ResolverOptions options) {
75 | String localMavenRepo = options.getLocalRepository();
76 | List remoteMavenRepos = options.getRemoteRepositories();
77 | String httpProxy = options.getHttpProxy();
78 | String httpsProxy = options.getHttpsProxy();
79 |
80 | DefaultServiceLocator locator = getDefaultServiceLocator();
81 |
82 | system = locator.getService(RepositorySystem.class);
83 | localRepo = new LocalRepository(localMavenRepo);
84 | Proxy proxy = getHttpProxy(httpProxy);
85 | Proxy secureProxy = getHttpsProxy(httpsProxy);
86 |
87 | configureRemoteRepositories(remoteMavenRepos, proxy, secureProxy);
88 | }
89 |
90 | private Proxy getHttpsProxy(String httpsProxy) {
91 | Proxy secureProxy = null;
92 | if (httpsProxy != null) {
93 | URL url = url(httpsProxy);
94 | Authentication authentication = extractAuth(url);
95 | secureProxy = new Proxy("https", url.getHost(), url.getPort(), authentication);
96 | }
97 | return secureProxy;
98 | }
99 |
100 | private Proxy getHttpProxy(String httpProxy) {
101 | Proxy proxy = null;
102 | if (httpProxy != null) {
103 | URL url = url(httpProxy);
104 | Authentication authentication = extractAuth(url);
105 | proxy = new Proxy("http", url.getHost(), url.getPort(), authentication);
106 | }
107 | return proxy;
108 | }
109 |
110 | private void configureRemoteRepositories(List remoteMavenRepos, Proxy proxy, Proxy secureProxy) {
111 | int count = 0;
112 | for (String remote : remoteMavenRepos) {
113 | URL url = url(remote);
114 | Authentication auth = extractAuth(url);
115 | if (auth != null) {
116 | url = url(url.getProtocol(), url.getHost(), url.getPort(), url.getFile());
117 | }
118 | RemoteRepository.Builder builder = new RemoteRepository.Builder("repo" + (count++), "default", url.toString());
119 | if (auth != null) {
120 | builder.setAuthentication(auth);
121 | }
122 | switch (url.getProtocol()) {
123 | case "http":
124 | if (proxy != null) {
125 | builder.setProxy(proxy);
126 | }
127 | break;
128 | case "https":
129 | if (secureProxy != null) {
130 | builder.setProxy(secureProxy);
131 | }
132 | break;
133 | }
134 | customizeRemoteRepoBuilder(builder);
135 | RemoteRepository remoteRepo = builder.build();
136 | remotes.add(remoteRepo);
137 | }
138 | }
139 |
140 | private static DefaultServiceLocator getDefaultServiceLocator() {
141 | DefaultServiceLocator locator = MavenRepositorySystemUtils.newServiceLocator();
142 | locator.addService(RepositoryConnectorFactory.class, BasicRepositoryConnectorFactory.class);
143 | locator.addService(TransporterFactory.class, FileTransporterFactory.class);
144 | locator.addService(TransporterFactory.class, HttpTransporterFactory.class);
145 | locator.setErrorHandler(new DefaultServiceLocator.ErrorHandler() {
146 | @Override
147 | public void serviceCreationFailed(Class> type, Class> impl, Throwable exception) {
148 | LOGGER.error("Service creation failure: " + exception.getMessage(), exception);
149 | }
150 | });
151 | return locator;
152 | }
153 |
154 | private URL url(String u) {
155 | try {
156 | return new URL(u);
157 | } catch (MalformedURLException e) {
158 | LOGGER.error("Cannot create url from " + u, e);
159 | throw new IllegalArgumentException("Invalid url " + u);
160 | }
161 | }
162 |
163 | private URL url(String protocol, String host, int port, String file) {
164 | try {
165 | return new URL(protocol, host, port, file);
166 | } catch (MalformedURLException e) {
167 | final String url = "{protocol:" + protocol + ", host:" + host + ", port:" + port + ", file:" + file + "}";
168 | LOGGER.error("Cannot create url from " + url, e);
169 | throw new IllegalArgumentException("Invalid url " + url);
170 | }
171 | }
172 |
173 | /**
174 | * Resolve the given artifact.
175 | *
176 | * @param artifact the artifact
177 | * @param withTransitive whether the transitive dependencies needs to be resolved too
178 | * @param exclusions the list of exclusions
179 | * @return the list of resolved artifacts
180 | */
181 | private DependencyNode resolve(Artifact artifact, boolean withTransitive, List exclusions) {
182 | CollectRequest collectRequest = collectRequest(artifact, exclusions, remotes);
183 | DependencyRequest dependencyRequest = new DependencyRequest(collectRequest, dependencyFilter());
184 | RepositorySystemSession session = session(system, localRepo);
185 | try {
186 | DependencyResult dependencyResult = system.resolveDependencies(session, dependencyRequest);
187 | DependencyNode root = dependencyResult.getRoot();
188 | if (withTransitive) {
189 | return root;
190 | } else {
191 | root.setChildren(new ArrayList<>());
192 | return root;
193 | }
194 | } catch (DependencyResolutionException e) {
195 | throw new IllegalArgumentException("Cannot resolve artifact " + artifact.toString() +
196 | " in maven repositories: " + e.getMessage());
197 | }
198 | }
199 |
200 | protected void customizeRemoteRepoBuilder(RemoteRepository.Builder builder) {
201 | String updatePolicy = System.getProperty(REMOTE_SNAPSHOT_POLICY_SYS_PROP);
202 | if (updatePolicy != null && !updatePolicy.isEmpty()) {
203 | builder.setSnapshotPolicy(new RepositoryPolicy(true, updatePolicy, RepositoryPolicy.CHECKSUM_POLICY_WARN));
204 | }
205 | }
206 |
207 | private static Authentication extractAuth(URL url) {
208 | String userInfo = url.getUserInfo();
209 | if (userInfo != null) {
210 | AuthenticationBuilder authBuilder = new AuthenticationBuilder();
211 | int sep = userInfo.indexOf(':');
212 | if (sep != -1) {
213 | authBuilder.addUsername(userInfo.substring(0, sep));
214 | authBuilder.addPassword(userInfo.substring(sep + 1));
215 | } else {
216 | authBuilder.addUsername(userInfo);
217 | }
218 | return authBuilder.build();
219 | }
220 | return null;
221 | }
222 |
223 | private static RepositorySystemSession session(RepositorySystem system, LocalRepository localRepo) {
224 | DefaultRepositorySystemSession session = MavenRepositorySystemUtils.newSession();
225 | session.setLocalRepositoryManager(system.newLocalRepositoryManager(session, localRepo));
226 | return session;
227 | }
228 |
229 | private static CollectRequest collectRequest(Artifact artifact, List exclusions, List remotes) {
230 | CollectRequest collectRequest = new CollectRequest();
231 | Dependency root = new Dependency(artifact, JavaScopes.COMPILE)
232 | .setExclusions(
233 | exclusions.stream()
234 | .map(e -> {
235 | // Exclusion are structured as groupId:artifactId.
236 | String[] segments = e.split(":");
237 | if (segments.length != 2) {
238 | throw new IllegalStateException("Invalid exclusion format: " + e + " - exclusion are " +
239 | "structured as follows: groupId:artifactId");
240 | }
241 | return new Exclusion(segments[0], segments[1], null, null);
242 | })
243 | .collect(Collectors.toList()));
244 | collectRequest.setRoot(root);
245 | collectRequest.setRepositories(remotes);
246 | return collectRequest;
247 | }
248 |
249 | private static DependencyFilter dependencyFilter() {
250 | return
251 | DependencyFilterUtils.andFilter(
252 | DependencyFilterUtils.classpathFilter(
253 | JavaScopes.COMPILE
254 | ),
255 | // Remove optionals and dependencies of optionals
256 | (dependencyNode, list) -> {
257 | for (DependencyNode parent : list) {
258 | if (parent.getDependency().isOptional()) {
259 | return false;
260 | }
261 | }
262 |
263 | return !dependencyNode.getDependency().isOptional();
264 | },
265 |
266 | // Remove excluded dependencies
267 | (dependencyNode, list) -> {
268 | // Build the list of exclusion, traverse the tree.
269 | Collection ex = new ArrayList<>();
270 | for (DependencyNode parent : list) {
271 | ex.addAll(parent.getDependency().getExclusions());
272 | }
273 |
274 | for (Exclusion e : ex) {
275 | // Check the the passed artifact is excluded
276 | if (e.getArtifactId().equals(dependencyNode.getArtifact().getArtifactId())
277 | && e.getGroupId().equals(dependencyNode.getArtifact().getGroupId())) {
278 | return false;
279 | }
280 |
281 | // Check if a parent artifact is excluded
282 | for (DependencyNode parent : list) {
283 | if (e.getArtifactId().equals(parent.getArtifact().getArtifactId())
284 | && e.getGroupId().equals(parent.getArtifact().getGroupId())) {
285 | return false;
286 | }
287 | }
288 | }
289 | return true;
290 | },
291 |
292 | // Remove provided dependencies and transitive dependencies of provided dependencies
293 | (dependencyNode, list) -> {
294 | for (DependencyNode parent : list) {
295 | if (!parent.getDependency().getScope().equalsIgnoreCase("compile")) {
296 | return false;
297 | }
298 | }
299 | return dependencyNode.getDependency().getScope().equalsIgnoreCase("compile");
300 | }
301 | );
302 | }
303 |
304 | @Override
305 | public List resolve(String gacv, ResolutionOptions options) {
306 | DependencyNode root = resolve(new Artifact(gacv), options.isWithTransitive(), options.getExclusions());
307 | List exclusions = Stream.concat(Stream.of(root), root.getChildren().stream())
308 | .map(DependencyNode::getDependency)
309 | .flatMap(dependency -> dependency.getExclusions().stream())
310 | .collect(Collectors.toList());
311 | Artifact rootArtifact = new Artifact(root.getArtifact(), null);
312 | return Stream
313 | .concat(Stream.of(rootArtifact), toArtifacts(root, rootArtifact, exclusions))
314 | .collect(Collectors.toList());
315 | }
316 |
317 | private Stream toArtifacts(DependencyNode dependencyNode, Artifact rootArtifact, List exclusions) {
318 | return dependencyNode.getChildren().stream()
319 | // remove optional dependencies
320 | .filter(childNode -> !childNode.getDependency().isOptional())
321 | // remove excluded dependencies
322 | .filter(childNode -> exclusions.stream().noneMatch(exclusion ->
323 | exclusion.getGroupId().equals(childNode.getArtifact().getGroupId())
324 | && exclusion.getArtifactId().equals(childNode.getArtifact().getArtifactId())))
325 | // remove provided dependencies and transitive dependencies of provided dependencies
326 | .filter(childNode -> childNode.getDependency().getScope().equalsIgnoreCase("compile"))
327 | .flatMap(childNode -> {
328 | Artifact childArtifact = new Artifact(childNode.getArtifact(), rootArtifact);
329 | return Stream.concat(Stream.of(childArtifact), toArtifacts(childNode, childArtifact, exclusions));
330 | });
331 | }
332 |
333 | }
334 |
335 |
--------------------------------------------------------------------------------
/stack-manager/src/main/java/io/vertx/stack/resolver/ResolverOptions.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2011-2015 The original author or authors
3 | * ------------------------------------------------------
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the Eclipse Public License v1.0
6 | * and Apache License v2.0 which accompanies this distribution.
7 | *
8 | * The Eclipse Public License is available at
9 | * http://www.eclipse.org/legal/epl-v10.html
10 | *
11 | * The Apache License v2.0 is available at
12 | * http://www.opensource.org/licenses/apache2.0.php
13 | *
14 | * You may elect to redistribute this code under either of these licenses.
15 | */
16 |
17 | package io.vertx.stack.resolver;
18 |
19 | import java.util.ArrayList;
20 | import java.util.Arrays;
21 | import java.util.List;
22 |
23 | /**
24 | * Options to configure the resolver.
25 | *
26 | * @author Clement Escoffier
27 | */
28 | public class ResolverOptions {
29 |
30 | public static final String LOCAL_REPO_SYS_PROP = "vertx.maven.localRepo";
31 | public static final String REMOTE_REPOS_SYS_PROP = "vertx.maven.remoteRepos";
32 | public static final String HTTP_PROXY_SYS_PROP = "vertx.maven.httpProxy";
33 | public static final String HTTPS_PROXY_SYS_PROP = "vertx.maven.httpsProxy";
34 |
35 | private static final String USER_HOME = System.getProperty("user.home");
36 | private static final String FILE_SEP = System.getProperty("file.separator");
37 | private static final String DEFAULT_MAVEN_LOCAL = USER_HOME + FILE_SEP + ".m2" + FILE_SEP + "repository";
38 | private static final String SNAPSHOT_REPO = System.getProperty("vertx.snapshotRepository");
39 | private static final String DEFAULT_MAVEN_REMOTES =
40 | "https://repo1.maven.org/maven2/ " + SNAPSHOT_REPO;
41 |
42 | private String localRepository = System.getProperty(LOCAL_REPO_SYS_PROP, DEFAULT_MAVEN_LOCAL);
43 |
44 | private List remoteRepositories =
45 | new ArrayList<>(Arrays.asList(System.getProperty(REMOTE_REPOS_SYS_PROP, DEFAULT_MAVEN_REMOTES).split(" ")));
46 |
47 | private String httpProxy = System.getProperty(HTTP_PROXY_SYS_PROP);
48 | private String httpsProxy = System.getProperty(HTTPS_PROXY_SYS_PROP);
49 |
50 | /**
51 | * @return the configured proxy address for HTTP request, {@code null} if none.
52 | */
53 | public String getHttpProxy() {
54 | return httpProxy;
55 | }
56 |
57 | /**
58 | * Sets the address of the proxy used for HTTP requests.
59 | *
60 | * @param httpProxy the proxy address
61 | * @return the current {@link ResolverOptions} instance
62 | */
63 | public ResolverOptions setHttpProxy(String httpProxy) {
64 | this.httpProxy = httpProxy;
65 | return this;
66 | }
67 |
68 | /**
69 | * @return the configured proxy address for HTTPS request, {@code null} if none.
70 | */
71 | public String getHttpsProxy() {
72 | return httpsProxy;
73 | }
74 |
75 | /**
76 | * Sets the address of the proxy used for HTTPS requests.
77 | *
78 | * @param httpsProxy the proxy address
79 | * @return the current {@link ResolverOptions} instance
80 | */
81 | public ResolverOptions setHttpsProxy(String httpsProxy) {
82 | this.httpsProxy = httpsProxy;
83 | return this;
84 | }
85 |
86 | /**
87 | * @return the path of the local repository. By default it's ~/.m2/repository.
88 | */
89 | public String getLocalRepository() {
90 | return localRepository;
91 | }
92 |
93 | /**
94 | * Sets the path to the local Maven repository. By default it's ~/.m2/repository.
95 | *
96 | * @param localRepository the local repository
97 | * @return the current {@link ResolverOptions} instance
98 | */
99 | public ResolverOptions setLocalRepository(String localRepository) {
100 | this.localRepository = localRepository;
101 | return this;
102 | }
103 |
104 | /**
105 | * @return the list of remove repositories.
106 | */
107 | public List getRemoteRepositories() {
108 | if (remoteRepositories == null || remoteRepositories.isEmpty()) {
109 | String remoteString = System.getProperty(REMOTE_REPOS_SYS_PROP, DEFAULT_MAVEN_REMOTES);
110 | // They are space-delimited (space is illegal char in urls)
111 | remoteRepositories = Arrays.asList(remoteString.split(" "));
112 | }
113 | return remoteRepositories;
114 | }
115 |
116 | /**
117 | * Sets the list of remote repositories used by the resolver. The repository must use the Maven 2 repository
118 | * layout. If you don't want to resolved from remote locations, set it to an empty list. By default it resolves
119 | * from Maven central and Sonatype OSS Snapshots.
120 | *
121 | * @param remoteRepositories the list of remote repositories
122 | * @return the current {@link ResolverOptions} instance
123 | */
124 | public ResolverOptions setRemoteRepositories(List remoteRepositories) {
125 | this.remoteRepositories = remoteRepositories;
126 | return this;
127 | }
128 | }
129 |
--------------------------------------------------------------------------------
/stack-manager/src/main/java/io/vertx/stack/utils/Actions.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2011-2015 The original author or authors
3 | * ------------------------------------------------------
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the Eclipse Public License v1.0
6 | * and Apache License v2.0 which accompanies this distribution.
7 | *
8 | * The Eclipse Public License is available at
9 | * http://www.eclipse.org/legal/epl-v10.html
10 | *
11 | * The Apache License v2.0 is available at
12 | * http://www.opensource.org/licenses/apache2.0.php
13 | *
14 | * You may elect to redistribute this code under either of these licenses.
15 | */
16 |
17 | package io.vertx.stack.utils;
18 |
19 | import io.vertx.core.internal.logging.LoggerFactory;
20 | import org.eclipse.aether.artifact.Artifact;
21 |
22 | import java.io.File;
23 | import java.io.IOException;
24 | import java.nio.file.Files;
25 | import java.nio.file.Path;
26 |
27 | /**
28 | * Common {@link Action} implementation.
29 | *
30 | * @author Clement Escoffier
31 | */
32 | public class Actions {
33 |
34 | /**
35 | * Wraps an action that is applied when the resolution is completed.
36 | */
37 | public interface Action {
38 |
39 | /**
40 | * Executes the action.
41 | * Actions may throw a runtime exception if something bad happened when the action is executed.
42 | */
43 | void execute();
44 | }
45 |
46 | private final static io.vertx.core.internal.logging.Logger LOGGER = LoggerFactory.getLogger("Stack Resolver");
47 |
48 | /**
49 | * Action to copy an artifact to a directory.
50 | *
51 | * @param artifact the artifact
52 | * @param directory the directory
53 | * @return the created {@link Action}
54 | */
55 | public static Action copy(Artifact artifact, File directory) {
56 | return () -> {
57 | Path source = artifact.getFile().toPath();
58 | Path output = directory.toPath().resolve(source.getFileName());
59 | LOGGER.info("Copying " + source.getFileName());
60 | try {
61 | Files.copy(source, output);
62 | } catch (IOException e) {
63 | throw new RuntimeException(e);
64 | }
65 | };
66 | }
67 |
68 | /**
69 | * Action denoting that nothing needs to be done for the given artifact.
70 | *
71 | * @param artifact the artifact
72 | * @return the created {@link Action}
73 | */
74 | public static Action skip(Artifact artifact) {
75 | return () -> LOGGER.info("Skipping " + artifact.toString());
76 | }
77 |
78 | /**
79 | * Action removing a file.
80 | *
81 | * @param file the file to be removed
82 | * @return the created {@link Action}
83 | */
84 | public static Action remove(File file) {
85 | return () -> {
86 | if (file.isFile()) {
87 | LOGGER.info("Deleting " + file.getName());
88 | file.delete();
89 | }
90 | };
91 | }
92 |
93 | }
94 |
--------------------------------------------------------------------------------
/stack-manager/src/main/java/io/vertx/stack/utils/Cache.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2011-2015 The original author or authors
3 | * ------------------------------------------------------
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the Eclipse Public License v1.0
6 | * and Apache License v2.0 which accompanies this distribution.
7 | *
8 | * The Eclipse Public License is available at
9 | * http://www.eclipse.org/legal/epl-v10.html
10 | *
11 | * The Apache License v2.0 is available at
12 | * http://www.opensource.org/licenses/apache2.0.php
13 | *
14 | * You may elect to redistribute this code under either of these licenses.
15 | */
16 |
17 | package io.vertx.stack.utils;
18 |
19 | import com.fasterxml.jackson.core.JsonParser;
20 | import com.fasterxml.jackson.databind.*;
21 | import com.fasterxml.jackson.databind.module.SimpleModule;
22 | import io.vertx.core.internal.logging.Logger;
23 | import io.vertx.core.internal.logging.LoggerFactory;
24 | import io.vertx.stack.model.Artifact;
25 | import io.vertx.stack.resolver.ResolutionOptions;
26 |
27 | import java.io.File;
28 | import java.io.IOException;
29 | import java.util.ArrayList;
30 | import java.util.List;
31 | import java.util.Optional;
32 |
33 | /**
34 | * A cache storing the resolution result.
35 | *
36 | * @author Clement Escoffier
37 | */
38 | public class Cache {
39 | private final static Logger LOGGER = LoggerFactory.getLogger("stack-manager-cache");
40 |
41 | // We don't use the MAPPEr from vert.x because it requires some tuning.
42 | private static final ObjectMapper MAPPER = new ObjectMapper().registerModule(
43 | new SimpleModule("artifact-module").addDeserializer(Artifact.class, new JsonDeserializer() {
44 | @Override
45 | public Artifact deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
46 | JsonNode node = p.getCodec().readTree(p);
47 | return fromJsonNode(node);
48 | }
49 |
50 | private Artifact fromJsonNode(JsonNode node) {
51 | JsonNode viaNode = node.get("via");
52 | Artifact via;
53 | if (viaNode == null || viaNode.asText().equalsIgnoreCase("null")) {
54 | via = null;
55 | } else {
56 | via = fromJsonNode(viaNode);
57 | }
58 |
59 | Artifact artifact;
60 | if (!node.get("classifier").asText().isEmpty()) {
61 | artifact = new Artifact(node.get("groupId").asText(), node.get("artifactId").asText(),
62 | node.get("classifier").asText(), node.get("extension").asText(), node.get("version").asText(), via);
63 | } else {
64 | artifact = new Artifact(node.get("groupId").asText(), node.get("artifactId").asText(),
65 | node.get("extension").asText(), node.get("version").asText(), via);
66 | }
67 | return artifact.setFile(new File(node.get("file").asText()));
68 | }
69 | }));
70 |
71 | private final boolean disabled;
72 | private final boolean disabledForSnapshot;
73 |
74 | List cache = new ArrayList<>();
75 | private File cacheFile;
76 |
77 |
78 | public Cache(boolean disabled, boolean disabledForSnapshot, File cacheFile) {
79 | this.disabled = disabled;
80 | this.disabledForSnapshot = disabledForSnapshot;
81 | this.cacheFile = cacheFile;
82 |
83 | // Load cache.
84 | if (this.cacheFile == null && Home.getVertxHome() != null) {
85 | this.cacheFile = new File(Home.getVertxHome(), ".stack-manager-cache.json");
86 | LOGGER.info("Set resolver cache to " + this.cacheFile.getAbsolutePath());
87 | }
88 |
89 | if (this.cacheFile != null && !this.cacheFile.isFile()) {
90 | this.cacheFile.getParentFile().mkdirs();
91 | }
92 |
93 | if (!disabled && this.cacheFile != null && this.cacheFile.isFile()) {
94 | LOGGER.info("Loading resolver cache from " + this.cacheFile.getAbsolutePath());
95 | JavaType type = MAPPER.getTypeFactory().
96 | constructCollectionType(List.class, CacheEntry.class);
97 | try {
98 | cache.addAll(MAPPER.readValue(this.cacheFile, type));
99 | } catch (IOException e) {
100 | LOGGER.error("Cannot read the cache entries from " + this.cacheFile.getAbsolutePath() + ": " + e.getMessage());
101 | }
102 | }
103 | }
104 |
105 | public void writeCacheOnFile() {
106 | if (disabled) {
107 | return;
108 | }
109 | if (cacheFile != null) {
110 | try {
111 | MAPPER.writer().writeValue(cacheFile, cache);
112 | } catch (IOException e) {
113 | LOGGER.error("Cannot write the cache entries to " + cacheFile.getAbsolutePath() + ": " + e.getMessage());
114 | }
115 | }
116 | }
117 |
118 | public List get(String gacv, ResolutionOptions resolutionOptions) {
119 | if (disabled) {
120 | return null;
121 | }
122 |
123 | if (disabledForSnapshot && gacv.contains("SNAPSHOT")) {
124 | return null;
125 | }
126 |
127 | Optional entry = find(gacv, resolutionOptions);
128 | if (entry.isPresent()) {
129 | if (isValid(entry.get())) {
130 | return entry.get().getArtifacts();
131 | } else {
132 | // cleanup required
133 | cache.remove(entry.get());
134 | return null;
135 | }
136 | }
137 | return null;
138 | }
139 |
140 | private boolean isValid(CacheEntry entry) {
141 | // If valid check two aspects:
142 | // All artifact files must be existing and non empty
143 | // If the dependency is a snapshot, it must check the insertion date.
144 | if (entry.getArtifacts().isEmpty()) {
145 | return false;
146 | }
147 |
148 | if (entry.getArtifacts().stream().anyMatch(artifact -> !artifact.getFile().isFile())) {
149 | return false;
150 | }
151 |
152 | if (entry.gacv.contains("SNAPSHOT")) {
153 | long now = System.currentTimeMillis();
154 | long insertion = entry.getInsertionTime();
155 | return now - insertion < 24 * 60 * 60 * 1000; // 24 hours of 60 minutes composed by 60 seconds.
156 | }
157 | return true;
158 | }
159 |
160 |
161 | public void put(String gacv, ResolutionOptions resolutionOptions, List list) {
162 | if (disabled) {
163 | return;
164 | }
165 |
166 | if (disabledForSnapshot && gacv.contains("SNAPSHOT")) {
167 | return;
168 | }
169 |
170 | Optional entry = find(gacv, resolutionOptions);
171 | if (entry.isPresent()) {
172 | CacheEntry cached = entry.get();
173 | cached.setInsertionTime(System.currentTimeMillis()).setArtifacts(list);
174 | } else {
175 | CacheEntry cached = new CacheEntry();
176 | cached.setArtifacts(list)
177 | .setGacv(gacv)
178 | .setOptions(resolutionOptions)
179 | .setInsertionTime(System.currentTimeMillis());
180 | cache.add(cached);
181 | }
182 | }
183 |
184 | public Optional find(String gacv, ResolutionOptions options) {
185 | return cache.stream().filter(entry -> entry.gacv.equals(gacv)
186 | && entry.options.equals(options)).findFirst();
187 | }
188 |
189 | public int size() {
190 | return cache.size();
191 | }
192 |
193 | public static class CacheEntry {
194 | String gacv;
195 | ResolutionOptions options;
196 | List artifacts = new ArrayList<>();
197 |
198 | long insertionTime;
199 |
200 | public CacheEntry() {
201 | }
202 |
203 | public List getArtifacts() {
204 | return artifacts;
205 | }
206 |
207 | public CacheEntry setArtifacts(List artifacts) {
208 | this.artifacts = artifacts;
209 | return this;
210 | }
211 |
212 | public String getGacv() {
213 | return gacv;
214 | }
215 |
216 | public CacheEntry setGacv(String gacv) {
217 | this.gacv = gacv;
218 | return this;
219 | }
220 |
221 | public long getInsertionTime() {
222 | return insertionTime;
223 | }
224 |
225 | public CacheEntry setInsertionTime(long insertionTime) {
226 | this.insertionTime = insertionTime;
227 | return this;
228 | }
229 |
230 | public ResolutionOptions getOptions() {
231 | return options;
232 | }
233 |
234 | public CacheEntry setOptions(ResolutionOptions options) {
235 | this.options = options;
236 | return this;
237 | }
238 | }
239 | }
240 |
--------------------------------------------------------------------------------
/stack-manager/src/main/java/io/vertx/stack/utils/Filtering.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2011-2015 The original author or authors
3 | * ------------------------------------------------------
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the Eclipse Public License v1.0
6 | * and Apache License v2.0 which accompanies this distribution.
7 | *
8 | * The Eclipse Public License is available at
9 | * http://www.eclipse.org/legal/epl-v10.html
10 | *
11 | * The Apache License v2.0 is available at
12 | * http://www.opensource.org/licenses/apache2.0.php
13 | *
14 | * You may elect to redistribute this code under either of these licenses.
15 | */
16 |
17 | package io.vertx.stack.utils;
18 |
19 | import java.util.Map;
20 |
21 | /**
22 | * Utility class to handle Maven-like filtering.
23 | *
24 | * @author Clement Escoffier
25 | */
26 | public class Filtering {
27 |
28 | private Filtering() {
29 | // Avoid direct instantiation
30 | }
31 |
32 | /**
33 | * Filters the given input using the given set of variables.
34 | *
35 | * @param input the input
36 | * @param variables the variables
37 | * @return the modified input
38 | */
39 | public static String filter(String input, Map variables) {
40 | if (variables.isEmpty()) {
41 | return input;
42 | }
43 |
44 | if (input == null || input.isEmpty()) {
45 | return input;
46 | }
47 |
48 | String current = input;
49 | String last = input;
50 | while (current.contains("${") && current.contains("}")) {
51 |
52 | // Replace all variables
53 | for (Map.Entry entry : variables.entrySet()) {
54 | current = current.replace("${" + entry.getKey() + "}", entry.getValue());
55 | }
56 |
57 | // If we didn't change anything, just leave.
58 | if (last.equals(current)) {
59 | return current;
60 | }
61 |
62 | last = current;
63 | }
64 |
65 | return current;
66 | }
67 |
68 | }
69 |
--------------------------------------------------------------------------------
/stack-manager/src/main/java/io/vertx/stack/utils/Home.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2011-2015 The original author or authors
3 | * ------------------------------------------------------
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the Eclipse Public License v1.0
6 | * and Apache License v2.0 which accompanies this distribution.
7 | *
8 | * The Eclipse Public License is available at
9 | * http://www.eclipse.org/legal/epl-v10.html
10 | *
11 | * The Apache License v2.0 is available at
12 | * http://www.opensource.org/licenses/apache2.0.php
13 | *
14 | * You may elect to redistribute this code under either of these licenses.
15 | */
16 |
17 | package io.vertx.stack.utils;
18 |
19 | import java.io.File;
20 |
21 | /**
22 | * Helper method to find vert.x home.
23 | *
24 | * @author Clement Escoffier
25 | */
26 | public class Home {
27 |
28 | /**
29 | * Try to find the home of vert.x using the `VERTX_HOME` env variable or the `vertx.home` system property.
30 | *
31 | * @return the found directory, {@code null} if not set.
32 | */
33 | public static File getVertxHome() {
34 | // System property ?
35 | String home = System.getProperty("vertx.home");
36 | if (home != null) {
37 | return new File(home);
38 | }
39 | // Environment variable
40 | home = System.getenv("VERTX_HOME");
41 | if (home != null) {
42 | return new File(home);
43 | }
44 | return null;
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/stack-manager/src/main/resources/META-INF/services/io.vertx.core.spi.launcher.CommandFactory:
--------------------------------------------------------------------------------
1 | io.vertx.stack.command.ResolveCommandFactory
--------------------------------------------------------------------------------
/stack-manager/src/test/java/io/vertx/stack/DescriptorTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2011-2015 The original author or authors
3 | * ------------------------------------------------------
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the Eclipse Public License v1.0
6 | * and Apache License v2.0 which accompanies this distribution.
7 | *
8 | * The Eclipse Public License is available at
9 | * http://www.eclipse.org/legal/epl-v10.html
10 | *
11 | * The Apache License v2.0 is available at
12 | * http://www.opensource.org/licenses/apache2.0.php
13 | *
14 | * You may elect to redistribute this code under either of these licenses.
15 | */
16 |
17 | package io.vertx.stack;
18 |
19 | import com.jayway.awaitility.Awaitility;
20 | import io.vertx.core.Launcher;
21 | import io.vertx.core.impl.launcher.VertxCommandLauncher;
22 | import io.vertx.core.spi.launcher.ExecutionContext;
23 | import io.vertx.stack.command.ResolveCommand;
24 | import io.vertx.stack.utils.FileUtils;
25 | import org.junit.Before;
26 | import org.junit.Test;
27 |
28 | import java.io.File;
29 | import java.util.ArrayList;
30 | import java.util.List;
31 | import java.util.concurrent.TimeUnit;
32 |
33 | import static org.assertj.core.api.Assertions.assertThat;
34 |
35 | /**
36 | * @author Clement Escoffier
37 | */
38 | public class DescriptorTest {
39 |
40 | private File root = new File("target/stack");
41 |
42 | @Before
43 | public void setUp() {
44 | FileUtils.delete(root);
45 | Awaitility.await().atMost(10, TimeUnit.SECONDS).until(() -> !root.exists());
46 | }
47 |
48 | @Test
49 | public void testResolutionOfCore() {
50 | ResolveCommand cmd = new ResolveCommand();
51 | cmd.setFailOnConflict(false);
52 | cmd.setDirectory(root.getAbsolutePath());
53 | cmd.setStackDescriptor(new File("src/test/resources/stacks/core.json").getAbsolutePath());
54 | cmd.setUp(new ExecutionContext(cmd, new VertxCommandLauncher(), null));
55 | cmd.run();
56 | assertThat(new File(root, "vertx-core-3.1.0.jar")).isFile();
57 | }
58 |
59 | @Test
60 | public void testResolutionOfCoreWithVariable() {
61 | ResolveCommand cmd = new ResolveCommand();
62 | cmd.setFailOnConflict(false);
63 | cmd.setDirectory(root.getAbsolutePath());
64 | cmd.setStackDescriptor(new File("src/test/resources/stacks/core-with-variable.json").getAbsolutePath());
65 | cmd.setUp(new ExecutionContext(cmd, new VertxCommandLauncher(), null));
66 | cmd.run();
67 | assertThat(new File(root, "vertx-core-3.1.0.jar")).isFile();
68 | }
69 |
70 | @Test
71 | public void testResolutionOfCoreUsingSystemVariable() {
72 | List args = new ArrayList<>();
73 | args.add("resolve");
74 | args.add("--dir=" + root.getAbsolutePath());
75 | args.add("-Dvertx.version=3.1.0");
76 | args.add(new File("src/test/resources/stacks/core-with-system-variable.json").getAbsolutePath());
77 | Launcher.main(args.toArray(new String[args.size()]));
78 |
79 | assertThat(new File(root, "vertx-core-3.1.0.jar")).isFile();
80 | }
81 |
82 | @Test
83 | public void testResolutionWithDefaultDescriptor() {
84 | File defaultStack = new File("vertx-stack.json");
85 | FileUtils.copyFile(new File("src/test/resources/stacks/core-with-system-variable.json"),
86 | defaultStack);
87 |
88 | List args = new ArrayList<>();
89 | args.add("resolve");
90 | args.add("--dir=" + root.getAbsolutePath());
91 | args.add("-Dvertx.version=3.1.0");
92 | Launcher.main(args.toArray(new String[args.size()]));
93 |
94 | assertThat(new File(root, "vertx-core-3.1.0.jar")).isFile();
95 | defaultStack.delete();
96 | }
97 |
98 | @Test
99 | public void testResolutionWithDefaultDescriptorInVertxHome() {
100 | File home = new File("target/home");
101 | home.mkdirs();
102 | System.setProperty("vertx.home", home.getAbsolutePath());
103 |
104 | FileUtils.copyFile(new File("src/test/resources/stacks/core-with-system-variable.json"),
105 | new File(home, "vertx-stack.json"));
106 |
107 | List args = new ArrayList<>();
108 | args.add("resolve");
109 | args.add("-Dvertx.version=3.1.0");
110 | Launcher.main(args.toArray(new String[args.size()]));
111 |
112 | assertThat(new File(home, "lib/vertx-core-3.1.0.jar")).isFile();
113 | System.clearProperty("vertx.home");
114 | }
115 |
116 |
117 | }
118 |
--------------------------------------------------------------------------------
/stack-manager/src/test/java/io/vertx/stack/StackResolutionTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2011-2015 The original author or authors
3 | * ------------------------------------------------------
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the Eclipse Public License v1.0
6 | * and Apache License v2.0 which accompanies this distribution.
7 | *
8 | * The Eclipse Public License is available at
9 | * http://www.eclipse.org/legal/epl-v10.html
10 | *
11 | * The Apache License v2.0 is available at
12 | * http://www.opensource.org/licenses/apache2.0.php
13 | *
14 | * You may elect to redistribute this code under either of these licenses.
15 | */
16 |
17 | package io.vertx.stack;
18 |
19 | import com.jayway.awaitility.Awaitility;
20 | import io.vertx.stack.model.*;
21 | import io.vertx.stack.utils.FileUtils;
22 | import io.vertx.stack.utils.LocalArtifact;
23 | import io.vertx.stack.utils.LocalDependency;
24 | import io.vertx.stack.utils.LocalRepoBuilder;
25 | import org.apache.maven.model.Exclusion;
26 | import org.junit.After;
27 | import org.junit.Before;
28 | import org.junit.Test;
29 |
30 | import java.io.File;
31 | import java.util.Map;
32 | import java.util.concurrent.TimeUnit;
33 |
34 | import static org.assertj.core.api.Assertions.*;
35 |
36 | /**
37 | * @author Clement Escoffier
38 | */
39 | public class StackResolutionTest {
40 |
41 | private final File root = new File("target/stack");
42 |
43 | private final static StackResolutionOptions STRICT = new StackResolutionOptions().setFailOnConflicts(true);
44 |
45 | @Before
46 | public void setUp() {
47 | FileUtils.delete(root);
48 | Awaitility.await().atMost(10, TimeUnit.SECONDS).until(() -> !root.exists());
49 | }
50 |
51 | @After
52 | public void tearDown() {
53 | System.clearProperty("vertx.version");
54 | }
55 |
56 | @Test
57 | public void testTheResolutionOfAVerySmallStack() {
58 | Stack stack = new Stack().addDependency(new Dependency("io.vertx", "vertx-core", "3.1.0"));
59 | StackResolution resolution = new StackResolution(stack, root, STRICT);
60 | Map map = resolution.resolve();
61 | assertThat(map).containsKey("io.vertx:vertx-core:jar:3.1.0");
62 | }
63 |
64 | @Test
65 | public void testTheResolutionOfAVerySmallStackWithFiltering() {
66 | Stack stack = new Stack().addDependency(new Dependency("io.vertx", "vertx-core", "${vertx.version}"))
67 | .addVariable("vertx.version", "3.1.0");
68 | StackResolution resolution = new StackResolution(stack, root, STRICT);
69 | Map map = resolution.resolve();
70 | assertThat(map).containsKey("io.vertx:vertx-core:jar:3.1.0");
71 | }
72 |
73 | @Test
74 | public void testTheResolutionOfVertxCoreWithoutTransitive() {
75 | Stack stack = new Stack().addDependency(new Dependency("io.vertx", "vertx-core", "3.1.0").setTransitive(false));
76 | StackResolution resolution = new StackResolution(stack, root, STRICT);
77 | Map map = resolution.resolve();
78 | assertThat(map).containsKeys("io.vertx:vertx-core:jar:3.1.0").hasSize(1);
79 | }
80 |
81 | @Test
82 | public void testNoConflictWhenADependencyIsDeclaredTwice() {
83 | Dependency dependency = new Dependency("io.vertx", "vertx-core", "3.1.0");
84 | Stack stack = new Stack()
85 | .addDependency(dependency)
86 | .addDependency(new Dependency("com.fasterxml.jackson.core", "jackson-databind", "2.6.1"));
87 |
88 | StackResolution resolution = new StackResolution(stack, root, STRICT);
89 | Map map = resolution.resolve();
90 | assertThat(map).containsKey("io.vertx:vertx-core:jar:3.1.0");
91 | assertThat(map).containsKey("com.fasterxml.jackson.core:jackson-databind:jar:2.6.1");
92 | }
93 |
94 | @Test(expected = DependencyConflictException.class)
95 | public void testConflictOnDependencyVersionMismatch() {
96 | Dependency dependency = new Dependency("io.vertx", "vertx-core", "3.1.0");
97 | Stack stack = new Stack()
98 | .addDependency(dependency)
99 | .addDependency(new Dependency("com.fasterxml.jackson.core", "jackson-databind", "2.4.1.3"));
100 |
101 | StackResolution resolution = new StackResolution(stack, root, STRICT);
102 | resolution.resolve();
103 | }
104 |
105 | @Test
106 | public void testConflictManagementUsingExclusions() {
107 | Dependency dependency = new Dependency("io.vertx", "vertx-core", "3.1.0");
108 | Exclusion exclusion1 = new Exclusion();
109 | exclusion1.setGroupId("com.fasterxml.jackson.core");
110 | exclusion1.setArtifactId("jackson-databind");
111 | Exclusion exclusion2 = new Exclusion();
112 | exclusion2.setGroupId("com.fasterxml.jackson.core");
113 | exclusion2.setArtifactId("jackson-core");
114 | dependency.addExclusion(exclusion1);
115 | dependency.addExclusion(exclusion2);
116 | Stack stack = new Stack()
117 | .addDependency(dependency)
118 | // Not the version used by vert.x
119 | .addDependency(new Dependency("com.fasterxml.jackson.core", "jackson-databind", "2.4.1.3"));
120 | StackResolution resolution = new StackResolution(stack, root, STRICT);
121 | resolution.resolve();
122 | Map map = resolution.resolve();
123 | assertThat(map).containsKey("io.vertx:vertx-core:jar:3.1.0");
124 | assertThat(map).containsKey("com.fasterxml.jackson.core:jackson-databind:jar:2.4.1.3");
125 | }
126 |
127 | @Test
128 | public void testModificationOfStack() {
129 | Stack stack = new Stack()
130 | .addDependency(new Dependency("io.vertx", "vertx-core", "3.1.0"))
131 | .addDependency(new Dependency("io.vertx", "vertx-stomp", "3.1.0").setIncluded(false));
132 |
133 | StackResolution resolution = new StackResolution(stack, root, STRICT);
134 | Map resolved = resolution.resolve();
135 | assertThat(resolved).doesNotContainKeys("io.vertx:vertx-stomp:jar:3.1.0");
136 | int numberOfArtifacts = root.listFiles().length;
137 |
138 | // include stomp
139 | stack = new Stack()
140 | .addDependency(new Dependency("io.vertx", "vertx-core", "3.1.0"))
141 | .addDependency(new Dependency("io.vertx", "vertx-stomp", "3.1.0").setIncluded(true));
142 | resolution = new StackResolution(stack, root, STRICT);
143 | resolved = resolution.resolve();
144 | assertThat(resolved).containsKey("io.vertx:vertx-stomp:jar:3.1.0");
145 |
146 | // remove stomp
147 | stack = new Stack()
148 | .addDependency(new Dependency("io.vertx", "vertx-core", "3.1.0"))
149 | .addDependency(new Dependency("io.vertx", "vertx-stomp", "3.1.0").setIncluded(false));
150 |
151 | resolution = new StackResolution(stack, root, STRICT);
152 | resolved = resolution.resolve();
153 | assertThat(resolved).doesNotContainKeys("io.vertx:vertx-stomp:jar:3.1.0");
154 | int numberOfArtifacts2 = root.listFiles().length;
155 | assertThat(numberOfArtifacts).isEqualTo(numberOfArtifacts2);
156 | }
157 |
158 | @Test(expected = IllegalArgumentException.class)
159 | public void testTheResolutionWhenAnArtifactIsMissing() {
160 | Stack stack = new Stack()
161 | .addDependency(new Dependency("io.vertx", "vertx-core", "3.1.0"))
162 | .addDependency(new Dependency("io.vertx", "vertx-missing", "3.1.0"));
163 | StackResolution resolution = new StackResolution(stack, root, STRICT);
164 | resolution.resolve();
165 | }
166 |
167 | @Test(expected = IllegalArgumentException.class)
168 | public void testTheResolutionWhenATransitiveDependencyIsMissing() {
169 | File local = new File("target/test-repos/incomplete");
170 | new LocalRepoBuilder(local).addArtifact(new LocalArtifact("org.acme", "acme", "1.0").generateMainArtifact()
171 | .addDependency(new LocalDependency("org.acme", "acme-missing", "1.0"))).build();
172 | Stack stack = new Stack()
173 | .addDependency(new Dependency("io.vertx", "vertx-core", "3.1.0"))
174 | .addDependency(new Dependency("org.acme", "acme", "1.0", "txt"));
175 | StackResolutionOptions options = new StackResolutionOptions().setFailOnConflicts(true)
176 | .setLocalRepository(local.getAbsolutePath())
177 | .setCacheDisabled(true);
178 | StackResolution resolution = new StackResolution(stack, root, options);
179 | resolution.resolve();
180 | }
181 |
182 | @Test
183 | public void testTheResolutionWhenATransitiveDependencyIsMissingButExcluded() {
184 | File local = new File("target/test-repos/incomplete");
185 | new LocalRepoBuilder(local).addArtifact(new LocalArtifact("org.acme", "acme", "1.0").generateMainArtifact()
186 | .addDependency(new LocalDependency("org.acme", "acme-missing", "1.0"))).build();
187 |
188 | Exclusion exclusion = new Exclusion();
189 | exclusion.setArtifactId("acme-missing");
190 | exclusion.setGroupId("org.acme");
191 |
192 | Dependency dependency = new Dependency("org.acme", "acme", "1.0", "txt");
193 | dependency.addExclusion(exclusion);
194 |
195 | Stack stack = new Stack()
196 | .addDependency(new Dependency("io.vertx", "vertx-core", "3.1.0"))
197 | .addDependency(dependency);
198 | StackResolutionOptions options = new StackResolutionOptions().setFailOnConflicts(true)
199 | .setLocalRepository(local.getAbsolutePath());
200 | StackResolution resolution = new StackResolution(stack, root, options);
201 | Map map = resolution.resolve();
202 | assertThat(map).containsKey("io.vertx:vertx-core:jar:3.1.0");
203 | assertThat(map).containsKey("org.acme:acme:txt:1.0");
204 | }
205 |
206 | @Test
207 | public void testTheResolutionWhenATransitiveDependencyIsMissingButOptional() {
208 | File local = new File("target/test-repos/incomplete");
209 | new LocalRepoBuilder(local).addArtifact(new LocalArtifact("org.acme", "acme", "1.0").generateMainArtifact()
210 | .addDependency(new LocalDependency("org.acme", "acme-missing", "1.0").optional(true))).build();
211 |
212 | Exclusion exclusion = new Exclusion();
213 | exclusion.setArtifactId("acme-missing");
214 | exclusion.setGroupId("org.acme");
215 |
216 | Dependency dependency = new Dependency("org.acme", "acme", "1.0", "txt");
217 | Stack stack = new Stack()
218 | .addDependency(new Dependency("io.vertx", "vertx-core", "3.1.0"))
219 | .addDependency(dependency);
220 | StackResolutionOptions options = new StackResolutionOptions().setFailOnConflicts(true)
221 | .setLocalRepository(local.getAbsolutePath());
222 | StackResolution resolution = new StackResolution(stack, root, options);
223 | Map map = resolution.resolve();
224 | assertThat(map).containsKey("io.vertx:vertx-core:jar:3.1.0");
225 | assertThat(map).containsKey("org.acme:acme:txt:1.0");
226 | }
227 |
228 | @Test
229 | public void testModificationOfStackIntroducingConflict() {
230 | Stack stack = new Stack()
231 | .addDependency(new Dependency("io.vertx", "vertx-core", "3.1.0"))
232 | .addDependency(new Dependency("io.vertx", "vertx-stomp", "3.1.0").setIncluded(false))
233 | .addDependency(new Dependency("io.vertx", "vertx-core", "3.0.0").setIncluded(false));
234 |
235 | StackResolution resolution = new StackResolution(stack, root, STRICT);
236 | Map resolved = resolution.resolve();
237 | assertThat(resolved).doesNotContainKeys("io.vertx:vertx-core:jar:3.0.0");
238 |
239 | stack = new Stack()
240 | .addDependency(new Dependency("io.vertx", "vertx-core", "3.1.0"))
241 | .addDependency(new Dependency("io.vertx", "vertx-stomp", "3.1.0").setIncluded(true))
242 | .addDependency(new Dependency("io.vertx", "vertx-core", "3.0.0").setIncluded(true));
243 | resolution = new StackResolution(stack, root, STRICT);
244 | try {
245 | resolved = resolution.resolve();
246 | fail("Conflict expected");
247 | } catch (DependencyConflictException e) {
248 | // OK
249 | }
250 |
251 | assertThat(resolved).containsKey("io.vertx:vertx-core:jar:3.1.0");
252 | assertThat(resolved).doesNotContainKeys("io.vertx:vertx-core:jar:3.0.0");
253 | assertThat(resolved).doesNotContainKeys("io.vertx:vertx-stomp:jar:3.1.0");
254 | }
255 |
256 | @Test
257 | public void testTheResolutionWhenATransitiveDependencyConflicts() {
258 | // This stack introduces a dependency conflict:
259 | // vertx-web-templ-pug:4.4.8 depends transitively on a newer version of org.jetbrains:annotations
260 | // than vertx-lang-kotlin:4.4.8
261 | Stack stack = new Stack()
262 | .addDependency(new Dependency("io.vertx", "vertx-web-templ-pug", "4.4.8"))
263 | .addDependency(new Dependency("io.vertx", "vertx-lang-kotlin", "4.4.8"));
264 |
265 | StackResolution resolution = new StackResolution(stack, root, STRICT);
266 |
267 | assertThatThrownBy(resolution::resolve)
268 | .isInstanceOf(DependencyConflictException.class)
269 | .hasMessage("Conflict detected for artifact org.jetbrains:annotations:jar - " +
270 | "version 15.0 was already selected by [io.vertx:vertx-web-templ-pug:jar:4.4.8] " +
271 | "while io.vertx:vertx-lang-kotlin:jar:4.4.8 depends on version 13.0" +
272 | " - see the following chain:\n" +
273 | "io.vertx:vertx-lang-kotlin:jar:4.4.8\n" +
274 | "\t\\-- org.jetbrains.kotlin:kotlin-stdlib-jdk8:jar:1.7.21\n" +
275 | "\t\t\\-- org.jetbrains.kotlin:kotlin-stdlib:jar:1.7.21\n" +
276 | "\t\t\t\\-- org.jetbrains:annotations:jar:13.0");
277 | }
278 | }
279 |
--------------------------------------------------------------------------------
/stack-manager/src/test/java/io/vertx/stack/VertxStacksTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2011-2015 The original author or authors
3 | * ------------------------------------------------------
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the Eclipse Public License v1.0
6 | * and Apache License v2.0 which accompanies this distribution.
7 | *
8 | * The Eclipse Public License is available at
9 | * http://www.eclipse.org/legal/epl-v10.html
10 | *
11 | * The Apache License v2.0 is available at
12 | * http://www.opensource.org/licenses/apache2.0.php
13 | *
14 | * You may elect to redistribute this code under either of these licenses.
15 | */
16 |
17 | package io.vertx.stack;
18 |
19 | import com.jayway.awaitility.Awaitility;
20 | import io.vertx.core.impl.launcher.commands.VersionCommand;
21 | import io.vertx.stack.model.Dependency;
22 | import io.vertx.stack.model.Stack;
23 | import io.vertx.stack.model.StackResolution;
24 | import io.vertx.stack.model.StackResolutionOptions;
25 | import io.vertx.stack.utils.FileUtils;
26 | import org.junit.After;
27 | import org.junit.Before;
28 | import org.junit.Test;
29 |
30 | import java.io.File;
31 | import java.util.Arrays;
32 | import java.util.List;
33 | import java.util.Map;
34 | import java.util.Set;
35 | import java.util.concurrent.TimeUnit;
36 |
37 | import static org.assertj.core.api.Assertions.assertThat;
38 | import static org.assertj.core.api.Assertions.fail;
39 |
40 | /**
41 | * @author Clement Escoffier
42 | */
43 | public class VertxStacksTest {
44 |
45 | private static final List BASE = Arrays.asList(
46 | "io.vertx:vertx-dropwizard-metrics:jar",
47 | "io.vertx:vertx-reactive-streams:jar",
48 | "io.vertx:vertx-rx-java2:jar"
49 | );
50 |
51 |
52 | private File root = new File("target/stack");
53 |
54 | @Before
55 | public void setUp() {
56 | FileUtils.delete(root);
57 | Awaitility.await().atMost(10, TimeUnit.SECONDS).until(() -> !root.exists());
58 | String vertxVersion = new VersionCommand().getVersion();
59 | assertThat(vertxVersion).isNotEmpty();
60 | System.setProperty("vertx.version", vertxVersion);
61 | }
62 |
63 | @After
64 | public void tearDown() {
65 | System.clearProperty("vertx.version");
66 | }
67 |
68 | /**
69 | * This tests checks that all our dependencies converge to the same version.
70 | */
71 | @Test
72 | public void testConvergence() {
73 | // Prepare the stack - use full stack, include everything
74 | Stack stack = Stack.fromDescriptor(new File("target/vertx-stack/vertx-stack-full.json"));
75 | // Stack stack = new Stack().addDependency(new Dependency("io.vertx", "vertx-core", "5.0.0-SNAPSHOT"));
76 | stack.getDependencies()
77 | .forEach(d -> d.setIncluded(true));
78 |
79 | StackResolution resolution = new StackResolution(stack, root,
80 | new StackResolutionOptions().setFailOnConflicts(true).setCacheDisabled(true));
81 | Map resolved = resolution.resolve(gav -> {
82 | // Check we don't have loggers in the distrib
83 | return !gav.startsWith("log4j:log4j") && !gav.startsWith("org.apache.logging.log4j:");
84 | });
85 | assertThat(resolved).isNotEmpty();
86 | }
87 |
88 | @Test
89 | public void testTheResolutionOfTheWebStack() {
90 | Stack stack = Stack.fromDescriptor(new File("src/test/resources/stacks/vertx-web-stack.json"));
91 |
92 | StackResolution resolution = new StackResolution(stack, root,
93 | new StackResolutionOptions().setFailOnConflicts(true));
94 | Map resolved = resolution.resolve();
95 | assertThat(resolved).isNotEmpty();
96 | }
97 |
98 | @Test
99 | public void testTheCoreWithoutNettyBufferStack() {
100 | Stack stack = Stack.fromDescriptor(new File("src/test/resources/stacks/vertx-core-only.json"));
101 |
102 | StackResolution resolution = new StackResolution(stack, root,
103 | new StackResolutionOptions().setFailOnConflicts(true));
104 | Map resolved = resolution.resolve();
105 | assertThat(resolved).isNotEmpty().doesNotContainKey("io.netty:netty-buffer");
106 | }
107 |
108 | private void setUpBaseStack(Stack stack) {
109 | stack.getDependencies()
110 | .filter(dependency -> wasPartOfTheBaseStack(dependency.getManagementKey()))
111 | .forEach(dependency -> dependency.setIncluded(true));
112 | }
113 |
114 | private void tearDownBaseStack(Stack stack) {
115 | stack.getDependencies()
116 | .filter(dependency -> wasPartOfTheBaseStack(dependency.getManagementKey()))
117 | .forEach(dependency -> dependency.setIncluded(false));
118 | }
119 |
120 | private boolean wasPartOfTheBaseStack(String gacv) {
121 | return BASE.contains(gacv);
122 | }
123 |
124 | private VertxStacksTest hasKeysStartingBy(Map files, String k) {
125 | if (!containsKeyStartingByPrefix(files.keySet(), k)) {
126 | fail("Expected to have a key starting with '" + k + "' in " + files.keySet());
127 | return this;
128 | }
129 | return this;
130 | }
131 |
132 | private VertxStacksTest doNotHaveKeysStartingBy(Map files, String k) {
133 | if (containsKeyStartingByPrefix(files.keySet(), k)) {
134 | fail("Expected to not have a key starting with '" + k + "' in " + files.keySet());
135 | return this;
136 | }
137 | return this;
138 | }
139 |
140 | private VertxStacksTest ensureThatAllFilesExist(Map files) {
141 | for (File f : files.values()) {
142 | assertThat(f).isFile();
143 | }
144 | return this;
145 | }
146 |
147 | private boolean containsKeyStartingByPrefix(Set keys, String prefix) {
148 | for (String k : keys) {
149 | if (k.startsWith(prefix)) {
150 | return true;
151 | }
152 | }
153 | return false;
154 | }
155 |
156 | }
157 |
--------------------------------------------------------------------------------
/stack-manager/src/test/java/io/vertx/stack/utils/CacheTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2011-2015 The original author or authors
3 | * ------------------------------------------------------
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the Eclipse Public License v1.0
6 | * and Apache License v2.0 which accompanies this distribution.
7 | *
8 | * The Eclipse Public License is available at
9 | * http://www.eclipse.org/legal/epl-v10.html
10 | *
11 | * The Apache License v2.0 is available at
12 | * http://www.opensource.org/licenses/apache2.0.php
13 | *
14 | * You may elect to redistribute this code under either of these licenses.
15 | */
16 |
17 | package io.vertx.stack.utils;
18 |
19 | import io.vertx.stack.model.Artifact;
20 | import io.vertx.stack.resolver.ResolutionOptions;
21 | import org.junit.Before;
22 | import org.junit.Test;
23 |
24 | import java.io.File;
25 | import java.io.IOException;
26 | import java.nio.file.Files;
27 | import java.util.Arrays;
28 | import java.util.Collections;
29 | import java.util.List;
30 | import java.util.Optional;
31 |
32 | import static org.assertj.core.api.Assertions.assertThat;
33 |
34 | /**
35 | * @author Clement Escoffier
36 | */
37 | public class CacheTest {
38 |
39 | private Cache cache;
40 | private File cacheFile;
41 |
42 | static File TEMP_FILE;
43 |
44 | static {
45 | try {
46 | TEMP_FILE = File.createTempFile("acme", ".jar");
47 | } catch (IOException e) {
48 | throw new IllegalStateException(e);
49 | }
50 | }
51 |
52 | @Before
53 | public void setUp() throws IOException {
54 | cacheFile = new File("target/test-cache/cache.json");
55 | if (cacheFile.isFile()) {
56 | Files.delete(cacheFile.toPath());
57 | }
58 |
59 | cache = new Cache(false, false, cacheFile);
60 | }
61 |
62 | @Test
63 | public void testCachingOfReleaseAndUpdate() {
64 | String gacv = "org.acme:acme:jar:1.0";
65 | ResolutionOptions options = new ResolutionOptions();
66 | List list = cache.get(gacv, options);
67 | assertThat(list).isNull();
68 |
69 | Artifact artifact = new Artifact("org.acme:acme:jar:1.0").setFile(TEMP_FILE);
70 | Artifact artifact2 = new Artifact("org.acme:acme-dep:jar:1.0").setFile(TEMP_FILE);
71 |
72 | cache.put(gacv, options, Collections.singletonList(artifact));
73 | list = cache.get(gacv, options);
74 | assertThat(list).hasSize(1);
75 |
76 | cache.put(gacv, options, Collections.singletonList(artifact));
77 | list = cache.get(gacv, options);
78 | assertThat(list).hasSize(1);
79 |
80 | cache.put(gacv, options, Arrays.asList(artifact, artifact2));
81 | list = cache.get(gacv, options);
82 | assertThat(list).hasSize(2);
83 | }
84 |
85 | @Test
86 | public void testCachingOfSnapshotAndUpdate() {
87 | String gacv = "org.acme:acme:jar:1.0-SNAPSHOT";
88 | ResolutionOptions options = new ResolutionOptions();
89 | List list = cache.get(gacv, options);
90 | assertThat(list).isNull();
91 |
92 | Artifact artifact = new Artifact("org.acme:acme:jar:1.0-SNAPSHOT").setFile(TEMP_FILE);
93 | Artifact artifact2 = new Artifact("org.acme:acme-dep:jar:1.0-SNAPSHOT").setFile(TEMP_FILE);
94 |
95 | cache.put(gacv, options, Collections.singletonList(artifact));
96 | list = cache.get(gacv, options);
97 | assertThat(list).hasSize(1);
98 |
99 | cache.put(gacv, options, Collections.singletonList(artifact));
100 | list = cache.get(gacv, options);
101 | assertThat(list).hasSize(1);
102 |
103 | cache.put(gacv, options, Arrays.asList(artifact, artifact2));
104 | list = cache.get(gacv, options);
105 | assertThat(list).hasSize(2);
106 | }
107 |
108 |
109 | @Test
110 | public void testDisabledCache() throws IOException {
111 | String gacv = "org.acme:acme:jar:1.0";
112 | cache = new Cache(true, false, cacheFile);
113 | ResolutionOptions options = new ResolutionOptions();
114 | List list = cache.get(gacv, options);
115 | assertThat(list).isNull();
116 |
117 | File file = File.createTempFile("acme", ".jar");
118 | Artifact artifact = new Artifact("org.acme:acme:jar:1.0").setFile(file);
119 |
120 | cache.put(gacv, options, Collections.singletonList(artifact));
121 | list = cache.get(gacv, options);
122 | assertThat(list).isNull();
123 | }
124 |
125 | @Test
126 | public void testCacheDisabledForSnapshots() {
127 | String gacv = "org.acme:acme:jar:1.0-SNAPSHOT";
128 | cache = new Cache(false, true, cacheFile);
129 | ResolutionOptions options = new ResolutionOptions();
130 | List list = cache.get(gacv, options);
131 | assertThat(list).isNull();
132 |
133 | Artifact artifact = new Artifact("org.acme:acme:jar:1.0-SNAPSHOT").setFile(TEMP_FILE);
134 |
135 | cache.put(gacv, options, Collections.singletonList(artifact));
136 | list = cache.get(gacv, options);
137 | assertThat(list).isNull();
138 | }
139 |
140 | @Test
141 | public void testWithInvalidArtifact() {
142 | String gacv = "org.acme:acme:jar:1.0";
143 | ResolutionOptions options = new ResolutionOptions();
144 | List list = cache.get(gacv, options);
145 | assertThat(list).isNull();
146 |
147 | Artifact artifact = new Artifact("org.acme:acme:jar:1.0").setFile(new File("does not exist.jar"));
148 |
149 | cache.put(gacv, options, Collections.singletonList(artifact));
150 | list = cache.get(gacv, options);
151 | assertThat(list).isNull();
152 | }
153 |
154 | @Test
155 | public void testWithEmptyResolution() {
156 | String gacv = "org.acme:acme:jar:1.0";
157 | ResolutionOptions options = new ResolutionOptions();
158 | List list = cache.get(gacv, options);
159 | assertThat(list).isNull();
160 | cache.put(gacv, options, Collections.emptyList());
161 | list = cache.get(gacv, options);
162 | assertThat(list).isNull();
163 | }
164 |
165 | @Test
166 | public void testCacheReloading() {
167 | String gacv = "org.acme:acme:jar:1.0";
168 | ResolutionOptions options = new ResolutionOptions();
169 | List list = cache.get(gacv, options);
170 | assertThat(list).isNull();
171 |
172 | Artifact artifact = new Artifact("org.acme:acme:jar:1.0").setFile(TEMP_FILE);
173 |
174 | cache.put(gacv, options, Collections.singletonList(artifact));
175 | list = cache.get(gacv, options);
176 | assertThat(list).hasSize(1);
177 | cache.writeCacheOnFile();
178 |
179 | cache = new Cache(false, false, cacheFile);
180 |
181 | list = cache.get(gacv, options);
182 | assertThat(list).hasSize(1);
183 | }
184 |
185 | @Test
186 | public void testSnapshotEviction() {
187 | String gacv = "org.acme:acme:jar:1.0-SNAPSHOT";
188 | ResolutionOptions options = new ResolutionOptions();
189 | List list = cache.get(gacv, options);
190 | assertThat(list).isNull();
191 |
192 | Artifact artifact = new Artifact("org.acme:acme:jar:1.0-SNAPSHOT").setFile(TEMP_FILE);
193 |
194 | cache.put(gacv, options, Collections.singletonList(artifact));
195 | list = cache.get(gacv, options);
196 | assertThat(list).hasSize(1);
197 |
198 | Optional entry = cache.find(gacv, options);
199 | assertThat(entry).isPresent();
200 | entry.get().setInsertionTime(System.currentTimeMillis() - 25 * 60 * 60 * 1000);
201 |
202 | list = cache.get(gacv, options);
203 | assertThat(list).isNull();
204 | }
205 |
206 | @Test
207 | public void testNonSnapshotEviction() {
208 | String gacv = "org.acme:acme:jar:1.0-SNAPSHOT";
209 | ResolutionOptions options = new ResolutionOptions();
210 | List list = cache.get(gacv, options);
211 | assertThat(list).isNull();
212 |
213 | Artifact artifact = new Artifact("org.acme:acme:jar:1.0-SNAPSHOT").setFile(TEMP_FILE);
214 |
215 | cache.put(gacv, options, Collections.singletonList(artifact));
216 | list = cache.get(gacv, options);
217 | assertThat(list).hasSize(1);
218 |
219 | Optional entry = cache.find(gacv, options);
220 | assertThat(entry).isPresent();
221 | entry.get().setInsertionTime(System.currentTimeMillis() - 22 * 60 * 60 * 1000);
222 |
223 | list = cache.get(gacv, options);
224 | assertThat(list).hasSize(1);
225 | }
226 |
227 | @Test
228 | public void testCachingUsingDifferentResolutionOption() {
229 | String gacv = "org.acme:acme:jar:1.0";
230 | ResolutionOptions options = new ResolutionOptions();
231 | List list = cache.get(gacv, options);
232 | assertThat(list).isNull();
233 |
234 | Artifact artifact = new Artifact("org.acme:acme:jar:1.0").setFile(TEMP_FILE);
235 |
236 | cache.put(gacv, options, Collections.singletonList(artifact));
237 | list = cache.get(gacv, options);
238 | assertThat(list).hasSize(1);
239 |
240 | options = new ResolutionOptions().setWithTransitive(false);
241 | list = cache.get(gacv, options);
242 | assertThat(list).isNull();
243 |
244 | cache.put(gacv, options, Collections.singletonList(artifact));
245 | list = cache.get(gacv, options);
246 | assertThat(list).hasSize(1);
247 | assertThat(cache.size()).isEqualTo(2);
248 |
249 | options = new ResolutionOptions().setWithTransitive(true).addExclusion("org.acme:transitive");
250 | list = cache.get(gacv, options);
251 | assertThat(list).isNull();
252 |
253 | cache.put(gacv, options, Collections.singletonList(artifact));
254 | list = cache.get(gacv, options);
255 | assertThat(list).hasSize(1);
256 | assertThat(cache.size()).isEqualTo(3);
257 | }
258 |
259 | @Test
260 | public void testDeserializationOfViaArtifact() {
261 | ResolutionOptions resolutionOptions = new ResolutionOptions();
262 | Artifact root = new Artifact("org.acme:acme:jar:1.0").setFile(TEMP_FILE);
263 | String gacv = "org.acme:transitive:jar:1.1";
264 | Artifact transitive = new Artifact(gacv, root).setFile(TEMP_FILE);
265 | cache.put(gacv, resolutionOptions, Collections.singletonList(transitive));
266 | cache.writeCacheOnFile();
267 |
268 | cache = new Cache(false, false, cacheFile);
269 | List deserialized = cache.get(gacv, resolutionOptions);
270 | assertThat(deserialized).hasSize(1);
271 | assertThat(deserialized.get(0).getVia()).isEqualTo(root);
272 | }
273 |
274 | }
275 |
--------------------------------------------------------------------------------
/stack-manager/src/test/java/io/vertx/stack/utils/FileUtils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2011-2015 The original author or authors
3 | * ------------------------------------------------------
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the Eclipse Public License v1.0
6 | * and Apache License v2.0 which accompanies this distribution.
7 | *
8 | * The Eclipse Public License is available at
9 | * http://www.eclipse.org/legal/epl-v10.html
10 | *
11 | * The Apache License v2.0 is available at
12 | * http://www.opensource.org/licenses/apache2.0.php
13 | *
14 | * You may elect to redistribute this code under either of these licenses.
15 | */
16 |
17 | package io.vertx.stack.utils;
18 |
19 | import java.io.File;
20 | import java.io.IOException;
21 | import java.nio.file.*;
22 | import java.nio.file.attribute.BasicFileAttributes;
23 |
24 | /**
25 | * @author Clement Escoffier
26 | */
27 | public class FileUtils {
28 |
29 | public static void write(File file, String content) {
30 | try {
31 | Files.write(file.toPath(), content.getBytes());
32 | } catch (IOException ex) {
33 | throw new RuntimeException(ex);
34 | }
35 | }
36 |
37 | public static void deleteQuietly(File file) {
38 | try {
39 | Files.deleteIfExists(file.toPath());
40 | } catch (Exception e) {
41 | // Ignore it.
42 | }
43 | }
44 |
45 | public static void copyFile(File source, File target) {
46 | Path s = source.toPath();
47 | Path t = target.toPath();
48 | try {
49 | Files.copy(s, t, StandardCopyOption.REPLACE_EXISTING);
50 | } catch (IOException e) {
51 | throw new RuntimeException(e);
52 | }
53 | }
54 |
55 | public static String getExtension(File file) {
56 | int index = file.getName().lastIndexOf(".");
57 | if (index == -1) {
58 | return "";
59 | } else {
60 | return file.getName().substring(index + 1);
61 | }
62 | }
63 |
64 | public static void delete(File file) {
65 | if (file.isFile()) {
66 | deleteQuietly(file);
67 | } else if (file.isDirectory()) {
68 | Path directory = file.toPath();
69 | try {
70 | Files.walkFileTree(directory, new SimpleFileVisitor() {
71 | @Override
72 | public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
73 | Files.delete(file);
74 | return FileVisitResult.CONTINUE;
75 | }
76 |
77 | @Override
78 | public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
79 | Files.delete(dir);
80 | return FileVisitResult.CONTINUE;
81 | }
82 | });
83 | } catch (IOException e) {
84 | throw new IllegalStateException(e);
85 | }
86 | }
87 | }
88 |
89 | }
90 |
--------------------------------------------------------------------------------
/stack-manager/src/test/java/io/vertx/stack/utils/FilteringTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2011-2015 The original author or authors
3 | * ------------------------------------------------------
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the Eclipse Public License v1.0
6 | * and Apache License v2.0 which accompanies this distribution.
7 | *
8 | * The Eclipse Public License is available at
9 | * http://www.eclipse.org/legal/epl-v10.html
10 | *
11 | * The Apache License v2.0 is available at
12 | * http://www.opensource.org/licenses/apache2.0.php
13 | *
14 | * You may elect to redistribute this code under either of these licenses.
15 | */
16 |
17 | package io.vertx.stack.utils;
18 |
19 | import org.junit.Test;
20 |
21 | import java.util.Collections;
22 |
23 | import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat;
24 |
25 |
26 | /**
27 | * @author Clement Escoffier
28 | */
29 | public class FilteringTest {
30 |
31 | @Test
32 | public void testFilteringWithoutVariables() {
33 | String out = Filtering.filter("hello", Collections.emptyMap());
34 | assertThat(out).isEqualTo("hello");
35 | }
36 |
37 | @Test
38 | public void testFilteringWithoutPlaceholders() {
39 | String out = Filtering.filter("hello", new FluentMap<>().add("key", "value"));
40 | assertThat(out).isEqualTo("hello");
41 | }
42 |
43 | @Test
44 | public void testFilteringWithNonMatchingVariables() {
45 | String out = Filtering.filter("hello ${nope}", new FluentMap<>().add("key", "value"));
46 | assertThat(out).isEqualTo("hello ${nope}");
47 | }
48 |
49 | @Test
50 | public void testFilteringWithReplacement() {
51 | String out = Filtering.filter("hello ${world}", new FluentMap<>().add("world", "vert.x"));
52 | assertThat(out).isEqualTo("hello vert.x");
53 | }
54 |
55 | @Test
56 | public void testFilteringWithPartialReplacement() {
57 | String out = Filtering.filter("hello ${world} ${period}", new FluentMap<>().add("world", "vert.x"));
58 | assertThat(out).isEqualTo("hello vert.x ${period}");
59 | }
60 |
61 | @Test
62 | public void testFilteringWithNestedReplacement() {
63 | String out = Filtering.filter("hello ${world} ${period}", new FluentMap<>()
64 | .add("name", "vert.x")
65 | .add("world", "${name}"));
66 | assertThat(out).isEqualTo("hello vert.x ${period}");
67 | }
68 |
69 | @Test
70 | public void testFilteringWithUnfinishedVariables() {
71 | String out = Filtering.filter("hello ${world} ${per ", new FluentMap<>()
72 | .add("name", "vert.x")
73 | .add("world", "${name}"));
74 | assertThat(out).isEqualTo("hello vert.x ${per ");
75 | }
76 |
77 | }
--------------------------------------------------------------------------------
/stack-manager/src/test/java/io/vertx/stack/utils/FluentMap.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2011-2015 The original author or authors
3 | * ------------------------------------------------------
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the Eclipse Public License v1.0
6 | * and Apache License v2.0 which accompanies this distribution.
7 | *
8 | * The Eclipse Public License is available at
9 | * http://www.eclipse.org/legal/epl-v10.html
10 | *
11 | * The Apache License v2.0 is available at
12 | * http://www.opensource.org/licenses/apache2.0.php
13 | *
14 | * You may elect to redistribute this code under either of these licenses.
15 | */
16 |
17 | package io.vertx.stack.utils;
18 |
19 | import java.util.LinkedHashMap;
20 |
21 | /**
22 | * @author Clement Escoffier
23 | */
24 | public class FluentMap extends LinkedHashMap {
25 |
26 | public FluentMap add(K k, V v) {
27 | put(k, v);
28 | return this;
29 | }
30 |
31 | }
32 |
--------------------------------------------------------------------------------
/stack-manager/src/test/java/io/vertx/stack/utils/LocalArtifact.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2011-2015 The original author or authors
3 | * ------------------------------------------------------
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the Eclipse Public License v1.0
6 | * and Apache License v2.0 which accompanies this distribution.
7 | *
8 | * The Eclipse Public License is available at
9 | * http://www.eclipse.org/legal/epl-v10.html
10 | *
11 | * The Apache License v2.0 is available at
12 | * http://www.opensource.org/licenses/apache2.0.php
13 | *
14 | * You may elect to redistribute this code under either of these licenses.
15 | */
16 |
17 | package io.vertx.stack.utils;
18 |
19 | import java.io.File;
20 | import java.io.IOException;
21 | import java.util.*;
22 |
23 | /**
24 | * @author Clement Escoffier
25 | */
26 | public class LocalArtifact {
27 |
28 | public static final String MAIN_ARTIFACT_CLASSIFIER = "MAIN";
29 | private final String groupId;
30 | private final String artifactId;
31 | private final String version;
32 | private String packaging;
33 | private Map files = new HashMap<>();
34 | private LocalArtifact parent;
35 | private List dependencies = new ArrayList<>();
36 | private List dependencyManagement = new ArrayList<>();
37 | private Map properties = new LinkedHashMap<>();
38 | private boolean inheritGroupId;
39 | private boolean inheritVersion;
40 |
41 | public LocalArtifact(String groupId, String artifactId, String version) {
42 | Objects.requireNonNull(groupId);
43 | Objects.requireNonNull(artifactId);
44 | Objects.requireNonNull(version);
45 | this.groupId = groupId;
46 | this.artifactId = artifactId;
47 | this.version = version;
48 | }
49 |
50 | public LocalArtifact inheritGroupId() {
51 | this.inheritGroupId = true;
52 | return this;
53 | }
54 |
55 | public LocalArtifact inheritVersion() {
56 | this.inheritVersion = true;
57 | return this;
58 | }
59 |
60 | public LocalArtifact packaging(String type) {
61 | this.packaging = type;
62 | return this;
63 | }
64 |
65 | public LocalArtifact file(File file) {
66 | this.files.put(MAIN_ARTIFACT_CLASSIFIER, file);
67 | return this;
68 | }
69 |
70 | public LocalArtifact file(File file, String classifier) {
71 | this.files.put(classifier, file);
72 | return this;
73 | }
74 |
75 | public LocalArtifact parent(LocalArtifact parent) {
76 | this.parent = parent;
77 | return this;
78 | }
79 |
80 | public LocalArtifact parent(String groupId, String artifactId, String version) {
81 | this.parent = new LocalArtifact(groupId, artifactId, version);
82 | return this;
83 | }
84 |
85 | public LocalArtifact addDependency(LocalDependency dependency) {
86 | dependencies.add(dependency);
87 | return this;
88 | }
89 |
90 | public LocalArtifact addDependencyToDependencyManagement(LocalDependency dependency) {
91 | dependencyManagement.add(dependency);
92 | return this;
93 | }
94 |
95 | public LocalArtifact addProperty(String key, String value) {
96 | properties.put(key, value);
97 | return this;
98 | }
99 |
100 | public File getArtifactDirectory(File root) {
101 | return new File(root, groupId.replace(".", File.separator) + File.separator + artifactId
102 | + File.separator + version);
103 | }
104 |
105 | public File getPomFile(File root) {
106 | return new File(getArtifactDirectory(root), artifactId + "-" + version + ".pom");
107 | }
108 |
109 | public File getFile(File root) {
110 | String ext = FileUtils.getExtension(files.get(MAIN_ARTIFACT_CLASSIFIER));
111 | return new File(getArtifactDirectory(root), artifactId + "-" + version + "." + ext);
112 | }
113 |
114 | public File getFile(String classifier, File root) {
115 | String ext = FileUtils.getExtension(files.get(classifier));
116 | return new File(getArtifactDirectory(root), artifactId + "-" + version + "-" + classifier + "." + ext);
117 | }
118 |
119 | public String toPom() {
120 | StringBuilder builder = new StringBuilder();
121 | line(builder, 0, "");
125 |
126 | line(builder, 1, "4.0.0");
127 |
128 | // Coordinates
129 | if (!inheritGroupId) {
130 | line(builder, 1, "" + groupId + "");
131 | }
132 | line(builder, 1, "" + artifactId + "");
133 | if (!inheritVersion) {
134 | line(builder, 1, "" + version + "");
135 | }
136 |
137 | // Parent if any
138 | if (parent != null) {
139 | line(builder, 1, "");
140 | line(builder, 2, "" + parent.groupId + "");
141 | line(builder, 2, "" + parent.artifactId + "");
142 | line(builder, 2, "" + parent.version + "");
143 | line(builder, 1, "");
144 | }
145 |
146 | if (packaging != null) {
147 | line(builder, 1, "" + packaging + "");
148 | }
149 |
150 | if (!properties.isEmpty()) {
151 | line(builder, 1, "");
152 | properties.forEach((k, v) -> line(builder, 2, "<" + k + ">" + v + "" + k + ">"));
153 | line(builder, 1, "");
154 | }
155 |
156 | if (!dependencyManagement.isEmpty()) {
157 | line(builder, 1, "");
158 | dependencyManagement.stream().forEach(dep -> builder.append(dep.toDependency(2)));
159 | line(builder, 1, "");
160 | }
161 |
162 | if (!dependencies.isEmpty()) {
163 | line(builder, 1, "");
164 | dependencies.stream().forEach(dep -> builder.append(dep.toDependency(2)));
165 | line(builder, 1, "");
166 | }
167 |
168 | line(builder, 0, "");
169 | return builder.toString();
170 | }
171 |
172 | private void line(StringBuilder builder, int indent, String line) {
173 | builder.append(PomUtils.indentation(indent)).append(line).append("\n");
174 | }
175 |
176 | public Map getFiles() {
177 | return files;
178 | }
179 |
180 | public String gav() {
181 | return groupId + ":" + artifactId + ":" + version;
182 | }
183 |
184 | public LocalArtifact generateMainArtifact() {
185 | try {
186 | File tmp = File.createTempFile("local-artifact-" + artifactId, ".txt");
187 | FileUtils.write(tmp, gav());
188 | return file(tmp).packaging("txt");
189 | } catch (IOException e) {
190 | throw new IllegalStateException(e);
191 | }
192 | }
193 | }
194 |
--------------------------------------------------------------------------------
/stack-manager/src/test/java/io/vertx/stack/utils/LocalDependency.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2011-2015 The original author or authors
3 | * ------------------------------------------------------
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the Eclipse Public License v1.0
6 | * and Apache License v2.0 which accompanies this distribution.
7 | *
8 | * The Eclipse Public License is available at
9 | * http://www.eclipse.org/legal/epl-v10.html
10 | *
11 | * The Apache License v2.0 is available at
12 | * http://www.opensource.org/licenses/apache2.0.php
13 | *
14 | * You may elect to redistribute this code under either of these licenses.
15 | */
16 |
17 | package io.vertx.stack.utils;
18 |
19 | import java.util.ArrayList;
20 | import java.util.List;
21 | import java.util.Objects;
22 |
23 | /**
24 | * @author Clement Escoffier
25 | */
26 | public class LocalDependency {
27 |
28 | private final String groupId;
29 | private final String artifactId;
30 | private final String version;
31 | private String type;
32 | private List exclusions = new ArrayList<>();
33 |
34 | private String scope = "compile";
35 | private boolean optional = false;
36 | private String classifier;
37 |
38 | public LocalDependency(String groupId, String artifactId, String version) {
39 | this.groupId = groupId;
40 | this.artifactId = artifactId;
41 | Objects.requireNonNull(groupId);
42 | Objects.requireNonNull(artifactId);
43 | this.version = version;
44 | }
45 |
46 | public LocalDependency(String groupId, String artifactId) {
47 | this(groupId, artifactId, null);
48 | }
49 |
50 | public LocalDependency type(String type) {
51 | this.type = type;
52 | return this;
53 | }
54 |
55 | public LocalDependency classifier(String c) {
56 | this.classifier = c;
57 | return this;
58 | }
59 |
60 | public LocalDependency optional(boolean opt) {
61 | this.optional = opt;
62 | return this;
63 | }
64 |
65 | public LocalDependency scope(String scope) {
66 | this.scope = scope;
67 | return this;
68 | }
69 |
70 | public LocalDependency addExclusion(String groupId, String artifactId) {
71 | this.exclusions.add(new Exclusion(groupId, artifactId));
72 | return this;
73 | }
74 |
75 | private class Exclusion {
76 |
77 | private final String groupId;
78 | private final String artifactId;
79 |
80 | public Exclusion(String groupId, String artifactId) {
81 | this.groupId = groupId;
82 | this.artifactId = artifactId;
83 | }
84 | }
85 |
86 | public String toDependency(int indent) {
87 | StringBuilder builder = new StringBuilder();
88 | builder.append(PomUtils.indentation(indent)).append("\n");
89 | builder.append(PomUtils.indentation(indent + 1)).append("").append(groupId).append("\n");
90 | builder.append(PomUtils.indentation(indent + 1)).append("").append(artifactId).append("\n");
91 | if (version != null) {
92 | builder.append(PomUtils.indentation(indent + 1)).append("").append(version).append("\n");
93 | }
94 | if (optional) {
95 | builder.append(PomUtils.indentation(indent + 1)).append("true\n");
96 | }
97 | if (type != null) {
98 | builder.append(PomUtils.indentation(indent + 1)).append("").append(type).append("\n");
99 | }
100 | if (scope != null) {
101 | builder.append(PomUtils.indentation(indent + 1)).append("").append(scope).append("\n");
102 | }
103 | if (classifier != null) {
104 | builder.append(PomUtils.indentation(indent + 1)).append("").append(classifier).append("\n");
105 | }
106 | if (! exclusions.isEmpty()) {
107 | builder.append(PomUtils.indentation(indent + 1)).append("\n");
108 | for (Exclusion exclusion : exclusions) {
109 | builder.append(PomUtils.indentation(indent + 2)).append("\n");
110 | builder.append(PomUtils.indentation(indent + 3)).append("").append(exclusion.groupId).append("\n");
111 | builder.append(PomUtils.indentation(indent + 3)).append("").append(exclusion.artifactId).append("\n");
112 | builder.append(PomUtils.indentation(indent + 2)).append("\n");
113 | }
114 | builder.append(PomUtils.indentation(indent + 1)).append("\n");
115 | }
116 | builder.append(PomUtils.indentation(indent)).append("\n");
117 | return builder.toString();
118 | }
119 | }
120 |
--------------------------------------------------------------------------------
/stack-manager/src/test/java/io/vertx/stack/utils/LocalRepoBuilder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2011-2015 The original author or authors
3 | * ------------------------------------------------------
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the Eclipse Public License v1.0
6 | * and Apache License v2.0 which accompanies this distribution.
7 | *
8 | * The Eclipse Public License is available at
9 | * http://www.eclipse.org/legal/epl-v10.html
10 | *
11 | * The Apache License v2.0 is available at
12 | * http://www.opensource.org/licenses/apache2.0.php
13 | *
14 | * You may elect to redistribute this code under either of these licenses.
15 | */
16 |
17 | package io.vertx.stack.utils;
18 |
19 | import io.vertx.core.internal.logging.Logger;
20 | import io.vertx.core.internal.logging.LoggerFactory;
21 |
22 | import java.io.File;
23 | import java.util.ArrayList;
24 | import java.util.List;
25 | import java.util.Map;
26 |
27 | /**
28 | * @author Clement Escoffier
29 | */
30 | public class LocalRepoBuilder {
31 |
32 | private final static Logger LOGGER = LoggerFactory.getLogger(LocalRepoBuilder.class.getName());
33 |
34 | private final File output;
35 | private List artifacts = new ArrayList<>();
36 |
37 | public LocalRepoBuilder(File output) {
38 | this.output = output;
39 | }
40 |
41 | public LocalRepoBuilder addArtifact(LocalArtifact artifact) {
42 | this.artifacts.add(artifact);
43 | return this;
44 | }
45 |
46 | public void build() {
47 | build(true);
48 | }
49 |
50 | public void build(boolean clean) {
51 | if (output.isDirectory() && clean) {
52 | LOGGER.info("Deleting " + output.getAbsolutePath());
53 | FileUtils.deleteQuietly(output);
54 | output.mkdirs();
55 | }
56 |
57 | // Install all artifacts
58 | artifacts.stream().forEach(artifact -> {
59 | File directory = artifact.getArtifactDirectory(output);
60 | directory.mkdirs();
61 |
62 | // Copy pom
63 | File pom = artifact.getPomFile(output);
64 | FileUtils.write(pom, artifact.toPom());
65 |
66 | // Copy files
67 | for (Map.Entry entry : artifact.getFiles().entrySet()) {
68 | if (entry.getKey().equals(LocalArtifact.MAIN_ARTIFACT_CLASSIFIER)) {
69 | FileUtils.copyFile(entry.getValue(), artifact.getFile(output));
70 | } else {
71 | FileUtils.copyFile(entry.getValue(), artifact.getFile(entry.getKey(), output));
72 | }
73 | }
74 |
75 | LOGGER.info("The artifact " + artifact.gav() + " has been installed in the local repository");
76 | });
77 | }
78 |
79 |
80 | }
81 |
--------------------------------------------------------------------------------
/stack-manager/src/test/java/io/vertx/stack/utils/PomUtils.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2011-2015 The original author or authors
3 | * ------------------------------------------------------
4 | * All rights reserved. This program and the accompanying materials
5 | * are made available under the terms of the Eclipse Public License v1.0
6 | * and Apache License v2.0 which accompanies this distribution.
7 | *
8 | * The Eclipse Public License is available at
9 | * http://www.eclipse.org/legal/epl-v10.html
10 | *
11 | * The Apache License v2.0 is available at
12 | * http://www.opensource.org/licenses/apache2.0.php
13 | *
14 | * You may elect to redistribute this code under either of these licenses.
15 | */
16 |
17 | package io.vertx.stack.utils;
18 |
19 | /**
20 | * @author Clement Escoffier
21 | */
22 | public class PomUtils {
23 |
24 | public static String indentation(int numberOfIndent) {
25 | StringBuilder builder = new StringBuilder();
26 | for (int i = 0; i < numberOfIndent; i++) {
27 | builder.append("\t");
28 | }
29 | return builder.toString();
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/stack-manager/src/test/resources/stacks/core-with-system-variable.json:
--------------------------------------------------------------------------------
1 | {
2 | "dependencies": [
3 | {
4 | "groupId": "io.vertx",
5 | "artifactId": "vertx-core",
6 | "version": "${vertx.version}",
7 | "included" : true
8 | }
9 | ]
10 | }
--------------------------------------------------------------------------------
/stack-manager/src/test/resources/stacks/core-with-variable.json:
--------------------------------------------------------------------------------
1 | {
2 | "variables": {
3 | "vertx.version": "3.1.0"
4 | },
5 | "dependencies": [
6 | {
7 | "groupId": "io.vertx",
8 | "artifactId": "vertx-core",
9 | "version": "${vertx.version}",
10 | "included": true
11 | }
12 | ]
13 | }
--------------------------------------------------------------------------------
/stack-manager/src/test/resources/stacks/core.json:
--------------------------------------------------------------------------------
1 | {
2 | "dependencies": [
3 | {
4 | "groupId": "io.vertx",
5 | "artifactId": "vertx-core",
6 | "version": "3.1.0",
7 | "included" : true
8 | }
9 | ]
10 | }
11 |
--------------------------------------------------------------------------------
/stack-manager/src/test/resources/stacks/vertx-core-only.json:
--------------------------------------------------------------------------------
1 | {
2 | "dependencies": [
3 | {
4 | "groupId": "io.vertx",
5 | "artifactId": "vertx-core",
6 | "version": "3.1.0",
7 | "included" : true,
8 | "exclusions": [
9 | {
10 | "groupId": "io.netty",
11 | "artifactId": "netty-buffer"
12 | }
13 | ]
14 | }
15 | ]
16 | }
17 |
--------------------------------------------------------------------------------
/stack-manager/src/test/resources/stacks/vertx-web-stack.json:
--------------------------------------------------------------------------------
1 | {
2 | "dependencies": [
3 | {
4 | "groupId": "io.vertx",
5 | "artifactId": "vertx-core",
6 | "version": "${vertx.version}",
7 | "included": true
8 | },
9 | {
10 | "groupId": "io.vertx",
11 | "artifactId": "vertx-hazelcast",
12 | "version": "${vertx.version}",
13 | "included": true
14 | },
15 | {
16 | "groupId": "io.vertx",
17 | "artifactId": "vertx-lang-groovy",
18 | "version": "${vertx.version}",
19 | "included": true
20 | },
21 | {
22 | "groupId": "io.vertx",
23 | "artifactId": "vertx-service-proxy",
24 | "version": "${vertx.version}",
25 | "included": true
26 | },
27 | {
28 | "groupId": "io.vertx",
29 | "artifactId": "vertx-http-service-factory",
30 | "version": "${vertx.version}",
31 | "included": false
32 | },
33 | {
34 | "groupId": "io.vertx",
35 | "artifactId": "vertx-dropwizard-metrics",
36 | "version": "${vertx.version}",
37 | "included": false
38 | },
39 | {
40 | "groupId": "io.vertx",
41 | "artifactId": "vertx-maven-service-factory",
42 | "version": "${vertx.version}",
43 | "included": false
44 | },
45 | {
46 | "groupId": "io.vertx",
47 | "artifactId": "vertx-reactive-streams",
48 | "version": "${vertx.version}",
49 | "included": false
50 | },
51 | {
52 | "groupId": "io.vertx",
53 | "artifactId": "vertx-service-factory",
54 | "version": "${vertx.version}",
55 | "included": false
56 | },
57 | {
58 | "groupId": "io.vertx",
59 | "artifactId": "vertx-auth-common",
60 | "version": "${vertx.version}",
61 | "included": false
62 | },
63 | {
64 | "groupId": "io.vertx",
65 | "artifactId": "vertx-auth-jwt",
66 | "version": "${vertx.version}",
67 | "included": false
68 | },
69 | {
70 | "groupId": "io.vertx",
71 | "artifactId": "vertx-jdbc-client",
72 | "version": "${vertx.version}",
73 | "included": false
74 | },
75 | {
76 | "groupId": "io.vertx",
77 | "artifactId": "vertx-consul-client",
78 | "version": "${vertx.version}",
79 | "included": false
80 | },
81 | {
82 | "groupId": "io.vertx",
83 | "artifactId": "vertx-mongo-client",
84 | "version": "${vertx.version}",
85 | "included": false
86 | },
87 | {
88 | "groupId": "io.vertx",
89 | "artifactId": "vertx-reactive-streams",
90 | "version": "${vertx.version}",
91 | "included": false
92 | },
93 | {
94 | "groupId": "io.vertx",
95 | "artifactId": "vertx-redis-client",
96 | "version": "${vertx.version}",
97 | "included": false
98 | },
99 | {
100 | "groupId": "io.vertx",
101 | "artifactId": "vertx-unit",
102 | "version": "${vertx.version}",
103 | "included": false
104 | },
105 | {
106 | "groupId": "io.vertx",
107 | "artifactId": "vertx-web",
108 | "version": "${vertx.version}",
109 | "included": true
110 | },
111 | {
112 | "groupId": "io.vertx",
113 | "artifactId": "vertx-web-templ-handlebars",
114 | "version": "${vertx.version}",
115 | "classifier": "shaded",
116 | "transitive": false,
117 | "included": true
118 | },
119 | {
120 | "groupId": "io.vertx",
121 | "artifactId": "vertx-web-templ-pug",
122 | "version": "${vertx.version}",
123 | "classifier": "shaded",
124 | "transitive": false,
125 | "included": true
126 | },
127 | {
128 | "groupId": "io.vertx",
129 | "artifactId": "vertx-web-templ-mvel",
130 | "version": "${vertx.version}",
131 | "classifier": "shaded",
132 | "transitive": false,
133 | "included": true
134 | },
135 | {
136 | "groupId": "io.vertx",
137 | "artifactId": "vertx-web-templ-thymeleaf",
138 | "version": "${vertx.version}",
139 | "classifier": "shaded",
140 | "transitive": false,
141 | "included": true
142 | },
143 | {
144 | "groupId": "io.vertx",
145 | "artifactId": "vertx-stomp",
146 | "version": "${vertx.version}",
147 | "included": false
148 | },
149 | {
150 | "groupId": "io.vertx",
151 | "artifactId": "vertx-shell",
152 | "version": "${vertx.version}",
153 | "included": false
154 | },
155 | {
156 | "groupId": "io.vertx",
157 | "artifactId": "vertx-sync",
158 | "version": "${vertx.version}",
159 | "included": false
160 | }
161 | ]
162 | }
163 |
--------------------------------------------------------------------------------