merged in main from project spring-cloud-dataflow-apps-plugin
This commit is contained in:
29
spring-cloud-dataflow-apps-plugin/.gitignore
vendored
Normal file
29
spring-cloud-dataflow-apps-plugin/.gitignore
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
apps/
|
||||
/application.yml
|
||||
/application.properties
|
||||
asciidoctor.css
|
||||
*~
|
||||
.#*
|
||||
*#
|
||||
target/
|
||||
build/
|
||||
bin/
|
||||
_site/
|
||||
.classpath
|
||||
.project
|
||||
.settings
|
||||
.springBeans
|
||||
.DS_Store
|
||||
*.sw*
|
||||
*.iml
|
||||
*.ipr
|
||||
*.iws
|
||||
.idea/
|
||||
.factorypath
|
||||
spring-xd-samples/*/xd
|
||||
dump.rdb
|
||||
coverage-error.log
|
||||
.apt_generated
|
||||
aws.credentials.properties
|
||||
.vscode/
|
||||
|
||||
1
spring-cloud-dataflow-apps-plugin/.mvn/jvm.config
Normal file
1
spring-cloud-dataflow-apps-plugin/.mvn/jvm.config
Normal file
@@ -0,0 +1 @@
|
||||
-Xmx1024m -XX:CICompilerCount=1 -XX:TieredStopAtLevel=1 -Djava.security.egd=file:/dev/./urandom
|
||||
1
spring-cloud-dataflow-apps-plugin/.mvn/maven.config
Normal file
1
spring-cloud-dataflow-apps-plugin/.mvn/maven.config
Normal file
@@ -0,0 +1 @@
|
||||
-DaltSnapshotDeploymentRepository=repo.spring.io::default::https://repo.spring.io/libs-snapshot-local -P spring
|
||||
117
spring-cloud-dataflow-apps-plugin/.mvn/wrapper/MavenWrapperDownloader.java
vendored
Normal file
117
spring-cloud-dataflow-apps-plugin/.mvn/wrapper/MavenWrapperDownloader.java
vendored
Normal file
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Copyright 2007-present the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
import java.net.*;
|
||||
import java.io.*;
|
||||
import java.nio.channels.*;
|
||||
import java.util.Properties;
|
||||
|
||||
public class MavenWrapperDownloader {
|
||||
|
||||
private static final String WRAPPER_VERSION = "0.5.6";
|
||||
/**
|
||||
* Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided.
|
||||
*/
|
||||
private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/"
|
||||
+ WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar";
|
||||
|
||||
/**
|
||||
* Path to the maven-wrapper.properties file, which might contain a downloadUrl property to
|
||||
* use instead of the default one.
|
||||
*/
|
||||
private static final String MAVEN_WRAPPER_PROPERTIES_PATH =
|
||||
".mvn/wrapper/maven-wrapper.properties";
|
||||
|
||||
/**
|
||||
* Path where the maven-wrapper.jar will be saved to.
|
||||
*/
|
||||
private static final String MAVEN_WRAPPER_JAR_PATH =
|
||||
".mvn/wrapper/maven-wrapper.jar";
|
||||
|
||||
/**
|
||||
* Name of the property which should be used to override the default download url for the wrapper.
|
||||
*/
|
||||
private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl";
|
||||
|
||||
public static void main(String args[]) {
|
||||
System.out.println("- Downloader started");
|
||||
File baseDirectory = new File(args[0]);
|
||||
System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath());
|
||||
|
||||
// If the maven-wrapper.properties exists, read it and check if it contains a custom
|
||||
// wrapperUrl parameter.
|
||||
File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH);
|
||||
String url = DEFAULT_DOWNLOAD_URL;
|
||||
if(mavenWrapperPropertyFile.exists()) {
|
||||
FileInputStream mavenWrapperPropertyFileInputStream = null;
|
||||
try {
|
||||
mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile);
|
||||
Properties mavenWrapperProperties = new Properties();
|
||||
mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream);
|
||||
url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url);
|
||||
} catch (IOException e) {
|
||||
System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'");
|
||||
} finally {
|
||||
try {
|
||||
if(mavenWrapperPropertyFileInputStream != null) {
|
||||
mavenWrapperPropertyFileInputStream.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// Ignore ...
|
||||
}
|
||||
}
|
||||
}
|
||||
System.out.println("- Downloading from: " + url);
|
||||
|
||||
File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH);
|
||||
if(!outputFile.getParentFile().exists()) {
|
||||
if(!outputFile.getParentFile().mkdirs()) {
|
||||
System.out.println(
|
||||
"- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'");
|
||||
}
|
||||
}
|
||||
System.out.println("- Downloading to: " + outputFile.getAbsolutePath());
|
||||
try {
|
||||
downloadFileFromURL(url, outputFile);
|
||||
System.out.println("Done");
|
||||
System.exit(0);
|
||||
} catch (Throwable e) {
|
||||
System.out.println("- Error downloading");
|
||||
e.printStackTrace();
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
private static void downloadFileFromURL(String urlString, File destination) throws Exception {
|
||||
if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) {
|
||||
String username = System.getenv("MVNW_USERNAME");
|
||||
char[] password = System.getenv("MVNW_PASSWORD").toCharArray();
|
||||
Authenticator.setDefault(new Authenticator() {
|
||||
@Override
|
||||
protected PasswordAuthentication getPasswordAuthentication() {
|
||||
return new PasswordAuthentication(username, password);
|
||||
}
|
||||
});
|
||||
}
|
||||
URL website = new URL(urlString);
|
||||
ReadableByteChannel rbc;
|
||||
rbc = Channels.newChannel(website.openStream());
|
||||
FileOutputStream fos = new FileOutputStream(destination);
|
||||
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
|
||||
fos.close();
|
||||
rbc.close();
|
||||
}
|
||||
|
||||
}
|
||||
BIN
spring-cloud-dataflow-apps-plugin/.mvn/wrapper/maven-wrapper.jar
vendored
Normal file
BIN
spring-cloud-dataflow-apps-plugin/.mvn/wrapper/maven-wrapper.jar
vendored
Normal file
Binary file not shown.
2
spring-cloud-dataflow-apps-plugin/.mvn/wrapper/maven-wrapper.properties
vendored
Normal file
2
spring-cloud-dataflow-apps-plugin/.mvn/wrapper/maven-wrapper.properties
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip
|
||||
wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar
|
||||
201
spring-cloud-dataflow-apps-plugin/LICENSE
Normal file
201
spring-cloud-dataflow-apps-plugin/LICENSE
Normal file
@@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
https://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "{}"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright {yyyy} {name of copyright owner}
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
@@ -0,0 +1,17 @@
|
||||
^\Q/*\E$
|
||||
^\Q * Copyright \E20\d\d\-20\d\d\Q the original author or authors.\E$
|
||||
^\Q *\E$
|
||||
^\Q * Licensed under the Apache License, Version 2.0 (the "License");\E$
|
||||
^\Q * you may not use this file except in compliance with the License.\E$
|
||||
^\Q * You may obtain a copy of the License at\E$
|
||||
^\Q *\E$
|
||||
^\Q * https://www.apache.org/licenses/LICENSE-2.0\E$
|
||||
^\Q *\E$
|
||||
^\Q * Unless required by applicable law or agreed to in writing, software\E$
|
||||
^\Q * distributed under the License is distributed on an "AS IS" BASIS,\E$
|
||||
^\Q * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\E$
|
||||
^\Q * See the License for the specific language governing permissions and\E$
|
||||
^\Q * limitations under the License.\E$
|
||||
^\Q */\E$
|
||||
^$
|
||||
^.*$
|
||||
@@ -0,0 +1,20 @@
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE suppressions PUBLIC
|
||||
"-//Puppy Crawl//DTD Suppressions 1.1//EN"
|
||||
"https://www.puppycrawl.com/dtds/suppressions_1_1.dtd">
|
||||
<suppressions>
|
||||
<suppress files="(.*EmbeddedEngine\.java)" checks="[a-zA-Z0-9]*"/>
|
||||
<suppress files="(.*Class\.java)" checks="[a-zA-Z0-9]*"/>
|
||||
<suppress files="[\\/]src[\\/]main[\\/](protos)[\\/]"
|
||||
checks="(Javadoc*|HideUtility*)"/>
|
||||
<suppress files=".*sample.*" checks="(Javadoc*|HideUtility*)"/>
|
||||
<suppress files=".*example.*" checks="(Javadoc*|HideUtility*)"/>
|
||||
<suppress files=".*integration-tests.*" checks="(Javadoc*|HideUtility*)"/>
|
||||
<suppress files="(.*MavenXmlWriter\.java)" checks="Javadoc*"/>
|
||||
<suppress files="(.*Tests\.java|.*Tests\.groovy)" checks="Javadoc*"/>
|
||||
<suppress files=".*src.test.java.*" checks="Javadoc*"/>
|
||||
<suppress files="generated-sources" checks="[a-zA-Z0-9]*"/>
|
||||
<suppress files=".*target.*" checks="[a-zA-Z0-9]*"/>
|
||||
<suppress files=".*build.*" checks="[a-zA-Z0-9]*"/>
|
||||
<suppress files=".*protos" checks="[a-zA-Z0-9]*"/>
|
||||
</suppressions>
|
||||
196
spring-cloud-dataflow-apps-plugin/etc/checkstyle/checkstyle.xml
Normal file
196
spring-cloud-dataflow-apps-plugin/etc/checkstyle/checkstyle.xml
Normal file
@@ -0,0 +1,196 @@
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE module PUBLIC
|
||||
"-//Puppy Crawl//DTD Check Configuration 1.3//EN"
|
||||
"https://www.puppycrawl.com/dtds/configuration_1_3.dtd">
|
||||
<module name="com.puppycrawl.tools.checkstyle.Checker">
|
||||
|
||||
<module name="SuppressionFilter">
|
||||
<property name="file" value="${checkstyle.suppressions.file}"/>
|
||||
<property name="optional" value="true"/>
|
||||
</module>
|
||||
|
||||
<module name="SuppressionFilter">
|
||||
<property name="file" value="${checkstyle.additional.suppressions.file}"/>
|
||||
<property name="optional" value="true"/>
|
||||
</module>
|
||||
|
||||
<!-- TAKEN FROM SPRING BOOT -->
|
||||
<!-- Root Checks -->
|
||||
<module name="com.puppycrawl.tools.checkstyle.checks.header.RegexpHeaderCheck">
|
||||
<property name="headerFile" value="${checkstyle.header.file}"/>
|
||||
<property name="fileExtensions" value="java,groovy"/>
|
||||
</module>
|
||||
<module name="com.puppycrawl.tools.checkstyle.checks.NewlineAtEndOfFileCheck">
|
||||
<property name="lineSeparator" value="lf"/>
|
||||
</module>
|
||||
|
||||
<!-- TreeWalker Checks -->
|
||||
<module name="com.puppycrawl.tools.checkstyle.TreeWalker">
|
||||
<property name="tabWidth" value="1"/>
|
||||
|
||||
<!-- Spring Cloud ones -->
|
||||
<!-- <module name="LineLength">
|
||||
<property name="max" value="120"/>
|
||||
</module> -->
|
||||
|
||||
<module name="com.puppycrawl.tools.checkstyle.checks.imports.IllegalImportCheck">
|
||||
<property name="illegalPkgs" value="com.google.common"/>
|
||||
</module>
|
||||
|
||||
<module name="SuppressionCommentFilter">
|
||||
<property name="offCommentFormat" value="@checkstyle:off"/>
|
||||
<property name="onCommentFormat" value="@checkstyle:on"/>
|
||||
</module>
|
||||
|
||||
<!-- TAKEN FROM SPRING BOOT -->
|
||||
<!-- Annotations -->
|
||||
<module name="com.puppycrawl.tools.checkstyle.checks.annotation.AnnotationUseStyleCheck">
|
||||
<property name="elementStyle" value="compact"/>
|
||||
</module>
|
||||
<module name="com.puppycrawl.tools.checkstyle.checks.annotation.MissingOverrideCheck"/>
|
||||
<module name="com.puppycrawl.tools.checkstyle.checks.annotation.PackageAnnotationCheck"/>
|
||||
<module name="com.puppycrawl.tools.checkstyle.checks.annotation.AnnotationLocationCheck">
|
||||
<property name="allowSamelineSingleParameterlessAnnotation"
|
||||
value="false"/>
|
||||
</module>
|
||||
|
||||
<!-- Block Checks -->
|
||||
<module name="com.puppycrawl.tools.checkstyle.checks.blocks.EmptyBlockCheck">
|
||||
<property name="option" value="text"/>
|
||||
</module>
|
||||
<module name="com.puppycrawl.tools.checkstyle.checks.blocks.LeftCurlyCheck"/>
|
||||
<module name="com.puppycrawl.tools.checkstyle.checks.blocks.RightCurlyCheck">
|
||||
<property name="option" value="alone"/>
|
||||
</module>
|
||||
<module name="com.puppycrawl.tools.checkstyle.checks.blocks.NeedBracesCheck"/>
|
||||
<module name="com.puppycrawl.tools.checkstyle.checks.blocks.AvoidNestedBlocksCheck"/>
|
||||
|
||||
<!-- Class Design -->
|
||||
<module name="com.puppycrawl.tools.checkstyle.checks.design.FinalClassCheck"/>
|
||||
<module name="com.puppycrawl.tools.checkstyle.checks.design.InterfaceIsTypeCheck"/>
|
||||
<module name="com.puppycrawl.tools.checkstyle.checks.design.HideUtilityClassConstructorCheck"/>
|
||||
<module name="com.puppycrawl.tools.checkstyle.checks.design.MutableExceptionCheck"/>
|
||||
<module name="com.puppycrawl.tools.checkstyle.checks.design.InnerTypeLastCheck"/>
|
||||
<!--<module name="com.puppycrawl.tools.checkstyle.checks.design.OneTopLevelClassCheck" />-->
|
||||
|
||||
<!-- Coding -->
|
||||
<module name="com.puppycrawl.tools.checkstyle.checks.coding.CovariantEqualsCheck"/>
|
||||
<module name="com.puppycrawl.tools.checkstyle.checks.coding.EmptyStatementCheck"/>
|
||||
<module name="com.puppycrawl.tools.checkstyle.checks.coding.EqualsHashCodeCheck"/>
|
||||
<module name="com.puppycrawl.tools.checkstyle.checks.coding.InnerAssignmentCheck"/>
|
||||
<module name="com.puppycrawl.tools.checkstyle.checks.coding.SimplifyBooleanExpressionCheck"/>
|
||||
<module name="com.puppycrawl.tools.checkstyle.checks.coding.SimplifyBooleanReturnCheck"/>
|
||||
<module name="com.puppycrawl.tools.checkstyle.checks.coding.StringLiteralEqualityCheck"/>
|
||||
<module name="com.puppycrawl.tools.checkstyle.checks.coding.NestedForDepthCheck">
|
||||
<property name="max" value="3"/>
|
||||
</module>
|
||||
<module name="com.puppycrawl.tools.checkstyle.checks.coding.NestedIfDepthCheck">
|
||||
<property name="max" value="3"/>
|
||||
</module>
|
||||
<module name="com.puppycrawl.tools.checkstyle.checks.coding.NestedTryDepthCheck">
|
||||
<property name="max" value="3"/>
|
||||
</module>
|
||||
<module name="com.puppycrawl.tools.checkstyle.checks.coding.MultipleVariableDeclarationsCheck"/>
|
||||
<!--<module name="com.puppycrawl.tools.checkstyle.checks.coding.RequireThisCheck">
|
||||
<property name="checkMethods" value="false" />
|
||||
<property name="validateOnlyOverlapping" value="false" />
|
||||
</module>-->
|
||||
<module name="com.puppycrawl.tools.checkstyle.checks.coding.OneStatementPerLineCheck"/>
|
||||
|
||||
<!-- Imports -->
|
||||
<module name="com.puppycrawl.tools.checkstyle.checks.imports.AvoidStarImportCheck"/>
|
||||
<!--<module name="com.puppycrawl.tools.checkstyle.checks.imports.AvoidStaticImportCheck">-->
|
||||
<!--<property name="excludes"-->
|
||||
<!--value="io.restassured.RestAssured.*, org.assertj.core.api.Assertions.*, org.assertj.core.api.Assumptions.*, org.awaitility.Awaitility.*, org.junit.Assert.*, org.junit.Assume.*, org.junit.internal.matchers.ThrowableMessageMatcher.*, org.junit.jupiter.api.Assertions.*, org.hamcrest.CoreMatchers.*, org.hamcrest.Matchers.*, org.springframework.boot.configurationprocessor.ConfigurationMetadataMatchers.*, org.springframework.boot.configurationprocessor.TestCompiler.*, org.springframework.boot.test.autoconfigure.AutoConfigurationImportedCondition.*, org.mockito.Mockito.*, org.mockito.BDDMockito.*, org.mockito.ArgumentMatchers.*, org.mockito.Matchers.*, org.springframework.restdocs.headers.HeaderDocumentation.*, org.springframework.restdocs.hypermedia.HypermediaDocumentation.*, org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.*, org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.*, org.springframework.restdocs.operation.preprocess.Preprocessors.*, org.springframework.restdocs.payload.PayloadDocumentation.*, org.springframework.restdocs.request.RequestDocumentation.*, org.springframework.restdocs.restassured3.operation.preprocess.RestAssuredPreprocessors.*, org.springframework.restdocs.restassured3.RestAssuredRestDocumentation.*, org.springframework.restdocs.snippet.Attributes.*, org.springframework.restdocs.webtestclient.WebTestClientRestDocumentation.*, org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*, org.springframework.test.web.servlet.result.MockMvcResultMatchers.*, org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestBuilders.*, org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.*, org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.*, org.springframework.hateoas.mvc.ControllerLinkBuilder.linkTo, org.springframework.test.web.client.ExpectedCount.*, org.springframework.test.web.client.match.MockRestRequestMatchers.*, org.springframework.test.web.client.response.MockRestResponseCreators.*, org.springframework.test.web.servlet.result.MockMvcResultHandlers.*, org.springframework.web.reactive.function.BodyInserters.*, org.springframework.web.reactive.function.server.RequestPredicates.*, org.springframework.web.reactive.function.server.RouterFunctions.*, org.springframework.test.web.servlet.setup.MockMvcBuilders.*" />-->
|
||||
<!--</module>-->
|
||||
<module name="com.puppycrawl.tools.checkstyle.checks.imports.IllegalImportCheck"/>
|
||||
<module name="com.puppycrawl.tools.checkstyle.checks.imports.RedundantImportCheck"/>
|
||||
<module name="com.puppycrawl.tools.checkstyle.checks.imports.UnusedImportsCheck">
|
||||
<property name="processJavadoc" value="true"/>
|
||||
</module>
|
||||
<module name="com.puppycrawl.tools.checkstyle.checks.imports.ImportOrderCheck">
|
||||
<property name="groups" value="java,/^javax?\./,*,org.springframework"/>
|
||||
<property name="ordered" value="true"/>
|
||||
<property name="separated" value="true"/>
|
||||
<property name="option" value="bottom"/>
|
||||
<property name="sortStaticImportsAlphabetically" value="true"/>
|
||||
</module>
|
||||
|
||||
<!-- Javadoc Comments -->
|
||||
<module name="com.puppycrawl.tools.checkstyle.checks.javadoc.JavadocTypeCheck">
|
||||
<property name="scope" value="public"/>
|
||||
<property name="excludeScope" value="package"/>
|
||||
<property name="authorFormat" value=".+\s.+"/>
|
||||
</module>
|
||||
<module name="com.puppycrawl.tools.checkstyle.checks.javadoc.JavadocVariableCheck">
|
||||
<property name="scope" value="public"/>
|
||||
</module>
|
||||
<module name="com.puppycrawl.tools.checkstyle.checks.javadoc.JavadocStyleCheck"/>
|
||||
<module name="com.puppycrawl.tools.checkstyle.checks.javadoc.NonEmptyAtclauseDescriptionCheck"/>
|
||||
<module name="com.puppycrawl.tools.checkstyle.checks.javadoc.JavadocTagContinuationIndentationCheck">
|
||||
<property name="offset" value="0"/>
|
||||
</module>
|
||||
<module name="com.puppycrawl.tools.checkstyle.checks.javadoc.AtclauseOrderCheck">
|
||||
<property name="target" value="CLASS_DEF, INTERFACE_DEF, ENUM_DEF"/>
|
||||
<property name="tagOrder"
|
||||
value="@param, @author, @since, @see, @version, @serial, @deprecated"/>
|
||||
</module>
|
||||
<module name="com.puppycrawl.tools.checkstyle.checks.javadoc.AtclauseOrderCheck">
|
||||
<property name="target" value="METHOD_DEF, CTOR_DEF, VARIABLE_DEF"/>
|
||||
<property name="tagOrder"
|
||||
value="@param, @return, @throws, @since, @deprecated, @see"/>
|
||||
</module>
|
||||
|
||||
<!-- Miscellaneous -->
|
||||
<module name="com.puppycrawl.tools.checkstyle.checks.indentation.CommentsIndentationCheck">
|
||||
<property name="tokens" value="BLOCK_COMMENT_BEGIN"/>
|
||||
</module>
|
||||
<module name="com.puppycrawl.tools.checkstyle.checks.UpperEllCheck"/>
|
||||
<module name="com.puppycrawl.tools.checkstyle.checks.ArrayTypeStyleCheck"/>
|
||||
<module name="com.puppycrawl.tools.checkstyle.checks.OuterTypeFilenameCheck"/>
|
||||
|
||||
<!-- Modifiers -->
|
||||
<module name="com.puppycrawl.tools.checkstyle.checks.modifier.RedundantModifierCheck"/>
|
||||
|
||||
<!-- Regexp -->
|
||||
<module name="com.puppycrawl.tools.checkstyle.checks.regexp.RegexpSinglelineJavaCheck">
|
||||
<property name="format" value="^\t* +\t*\S"/>
|
||||
<property name="message"
|
||||
value="Line has leading space characters; indentation should be performed with tabs only."/>
|
||||
<property name="ignoreComments" value="true"/>
|
||||
</module>
|
||||
<!--<module name="com.puppycrawl.tools.checkstyle.checks.regexp.RegexpSinglelineJavaCheck">
|
||||
<property name="maximum" value="0"/>
|
||||
<property name="format" value="org\.mockito\.Mockito\.(when|doThrow|doAnswer)" />
|
||||
<property name="message"
|
||||
value="Please use BDDMockito imports." />
|
||||
<property name="ignoreComments" value="true" />
|
||||
</module>-->
|
||||
<module name="com.puppycrawl.tools.checkstyle.checks.regexp.RegexpSinglelineJavaCheck">
|
||||
<property name="maximum" value="0"/>
|
||||
<property name="format"
|
||||
value="org\.junit\.(Assert|jupiter\.api\.Assertions)\.assert"/>
|
||||
<property name="message"
|
||||
value="Please use AssertJ imports."/>
|
||||
<property name="ignoreComments" value="true"/>
|
||||
</module>
|
||||
<module name="com.puppycrawl.tools.checkstyle.checks.regexp.RegexpCheck">
|
||||
<property name="format" value="[ \t]+$"/>
|
||||
<property name="illegalPattern" value="true"/>
|
||||
<property name="message" value="Trailing whitespace"/>
|
||||
</module>
|
||||
|
||||
<!-- Whitespace -->
|
||||
<module name="com.puppycrawl.tools.checkstyle.checks.whitespace.GenericWhitespaceCheck"/>
|
||||
<module name="com.puppycrawl.tools.checkstyle.checks.whitespace.MethodParamPadCheck"/>
|
||||
<module name="com.puppycrawl.tools.checkstyle.checks.whitespace.NoWhitespaceAfterCheck">
|
||||
<property name="tokens"
|
||||
value="BNOT, DEC, DOT, INC, LNOT, UNARY_MINUS, UNARY_PLUS, ARRAY_DECLARATOR"/>
|
||||
</module>
|
||||
<module name="com.puppycrawl.tools.checkstyle.checks.whitespace.NoWhitespaceBeforeCheck"/>
|
||||
<module name="com.puppycrawl.tools.checkstyle.checks.whitespace.ParenPadCheck"/>
|
||||
<module name="com.puppycrawl.tools.checkstyle.checks.whitespace.TypecastParenPadCheck"/>
|
||||
<module name="com.puppycrawl.tools.checkstyle.checks.whitespace.WhitespaceAfterCheck"/>
|
||||
<module name="com.puppycrawl.tools.checkstyle.checks.whitespace.WhitespaceAroundCheck"/>
|
||||
</module>
|
||||
</module>
|
||||
@@ -0,0 +1,29 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
~ Copyright 2002-2019 the original author or authors.
|
||||
~
|
||||
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||
~ you may not use this file except in compliance with the License.
|
||||
~ You may obtain a copy of the License at
|
||||
~
|
||||
~ https://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing, software
|
||||
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
~ See the License for the specific language governing permissions and
|
||||
~ limitations under the License.
|
||||
-->
|
||||
|
||||
<!DOCTYPE module PUBLIC "-//Puppy Crawl//DTD Check Configuration 1.3//EN"
|
||||
"https://www.puppycrawl.com/dtds/configuration_1_3.dtd">
|
||||
<module name="Checker">
|
||||
|
||||
<!-- Configure checker to use UTF-8 encoding -->
|
||||
<property name="charset" value="UTF-8"/>
|
||||
<!-- Configure checker to run on files with these extensions -->
|
||||
<property name="fileExtensions" value=""/>
|
||||
<!-- For detailed checkstyle configuration, see https://github.com/spring-io/nohttp/tree/master/nohttp-checkstyle -->
|
||||
<!--<module name="io.spring.nohttp.checkstyle.check.NoHttpCheck">
|
||||
</module>-->
|
||||
</module>
|
||||
310
spring-cloud-dataflow-apps-plugin/mvnw
vendored
Executable file
310
spring-cloud-dataflow-apps-plugin/mvnw
vendored
Executable file
@@ -0,0 +1,310 @@
|
||||
#!/bin/sh
|
||||
# ----------------------------------------------------------------------------
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# Maven Start Up Batch script
|
||||
#
|
||||
# Required ENV vars:
|
||||
# ------------------
|
||||
# JAVA_HOME - location of a JDK home dir
|
||||
#
|
||||
# Optional ENV vars
|
||||
# -----------------
|
||||
# M2_HOME - location of maven2's installed home dir
|
||||
# MAVEN_OPTS - parameters passed to the Java VM when running Maven
|
||||
# e.g. to debug Maven itself, use
|
||||
# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
|
||||
# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
if [ -z "$MAVEN_SKIP_RC" ] ; then
|
||||
|
||||
if [ -f /etc/mavenrc ] ; then
|
||||
. /etc/mavenrc
|
||||
fi
|
||||
|
||||
if [ -f "$HOME/.mavenrc" ] ; then
|
||||
. "$HOME/.mavenrc"
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
# OS specific support. $var _must_ be set to either true or false.
|
||||
cygwin=false;
|
||||
darwin=false;
|
||||
mingw=false
|
||||
case "`uname`" in
|
||||
CYGWIN*) cygwin=true ;;
|
||||
MINGW*) mingw=true;;
|
||||
Darwin*) darwin=true
|
||||
# Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
|
||||
# See https://developer.apple.com/library/mac/qa/qa1170/_index.html
|
||||
if [ -z "$JAVA_HOME" ]; then
|
||||
if [ -x "/usr/libexec/java_home" ]; then
|
||||
export JAVA_HOME="`/usr/libexec/java_home`"
|
||||
else
|
||||
export JAVA_HOME="/Library/Java/Home"
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -z "$JAVA_HOME" ] ; then
|
||||
if [ -r /etc/gentoo-release ] ; then
|
||||
JAVA_HOME=`java-config --jre-home`
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$M2_HOME" ] ; then
|
||||
## resolve links - $0 may be a link to maven's home
|
||||
PRG="$0"
|
||||
|
||||
# need this for relative symlinks
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG="`dirname "$PRG"`/$link"
|
||||
fi
|
||||
done
|
||||
|
||||
saveddir=`pwd`
|
||||
|
||||
M2_HOME=`dirname "$PRG"`/..
|
||||
|
||||
# make it fully qualified
|
||||
M2_HOME=`cd "$M2_HOME" && pwd`
|
||||
|
||||
cd "$saveddir"
|
||||
# echo Using m2 at $M2_HOME
|
||||
fi
|
||||
|
||||
# For Cygwin, ensure paths are in UNIX format before anything is touched
|
||||
if $cygwin ; then
|
||||
[ -n "$M2_HOME" ] &&
|
||||
M2_HOME=`cygpath --unix "$M2_HOME"`
|
||||
[ -n "$JAVA_HOME" ] &&
|
||||
JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
|
||||
[ -n "$CLASSPATH" ] &&
|
||||
CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
|
||||
fi
|
||||
|
||||
# For Mingw, ensure paths are in UNIX format before anything is touched
|
||||
if $mingw ; then
|
||||
[ -n "$M2_HOME" ] &&
|
||||
M2_HOME="`(cd "$M2_HOME"; pwd)`"
|
||||
[ -n "$JAVA_HOME" ] &&
|
||||
JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
|
||||
fi
|
||||
|
||||
if [ -z "$JAVA_HOME" ]; then
|
||||
javaExecutable="`which javac`"
|
||||
if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
|
||||
# readlink(1) is not available as standard on Solaris 10.
|
||||
readLink=`which readlink`
|
||||
if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
|
||||
if $darwin ; then
|
||||
javaHome="`dirname \"$javaExecutable\"`"
|
||||
javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
|
||||
else
|
||||
javaExecutable="`readlink -f \"$javaExecutable\"`"
|
||||
fi
|
||||
javaHome="`dirname \"$javaExecutable\"`"
|
||||
javaHome=`expr "$javaHome" : '\(.*\)/bin'`
|
||||
JAVA_HOME="$javaHome"
|
||||
export JAVA_HOME
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$JAVACMD" ] ; then
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
else
|
||||
JAVACMD="`which java`"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
echo "Error: JAVA_HOME is not defined correctly." >&2
|
||||
echo " We cannot execute $JAVACMD" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$JAVA_HOME" ] ; then
|
||||
echo "Warning: JAVA_HOME environment variable is not set."
|
||||
fi
|
||||
|
||||
CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
|
||||
|
||||
# traverses directory structure from process work directory to filesystem root
|
||||
# first directory with .mvn subdirectory is considered project base directory
|
||||
find_maven_basedir() {
|
||||
|
||||
if [ -z "$1" ]
|
||||
then
|
||||
echo "Path not specified to find_maven_basedir"
|
||||
return 1
|
||||
fi
|
||||
|
||||
basedir="$1"
|
||||
wdir="$1"
|
||||
while [ "$wdir" != '/' ] ; do
|
||||
if [ -d "$wdir"/.mvn ] ; then
|
||||
basedir=$wdir
|
||||
break
|
||||
fi
|
||||
# workaround for JBEAP-8937 (on Solaris 10/Sparc)
|
||||
if [ -d "${wdir}" ]; then
|
||||
wdir=`cd "$wdir/.."; pwd`
|
||||
fi
|
||||
# end of workaround
|
||||
done
|
||||
echo "${basedir}"
|
||||
}
|
||||
|
||||
# concatenates all lines of a file
|
||||
concat_lines() {
|
||||
if [ -f "$1" ]; then
|
||||
echo "$(tr -s '\n' ' ' < "$1")"
|
||||
fi
|
||||
}
|
||||
|
||||
BASE_DIR=`find_maven_basedir "$(pwd)"`
|
||||
if [ -z "$BASE_DIR" ]; then
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
##########################################################################################
|
||||
# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
|
||||
# This allows using the maven wrapper in projects that prohibit checking in binary data.
|
||||
##########################################################################################
|
||||
if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Found .mvn/wrapper/maven-wrapper.jar"
|
||||
fi
|
||||
else
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
|
||||
fi
|
||||
if [ -n "$MVNW_REPOURL" ]; then
|
||||
jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
|
||||
else
|
||||
jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
|
||||
fi
|
||||
while IFS="=" read key value; do
|
||||
case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
|
||||
esac
|
||||
done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Downloading from: $jarUrl"
|
||||
fi
|
||||
wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
|
||||
if $cygwin; then
|
||||
wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"`
|
||||
fi
|
||||
|
||||
if command -v wget > /dev/null; then
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Found wget ... using wget"
|
||||
fi
|
||||
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
|
||||
wget "$jarUrl" -O "$wrapperJarPath"
|
||||
else
|
||||
wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath"
|
||||
fi
|
||||
elif command -v curl > /dev/null; then
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Found curl ... using curl"
|
||||
fi
|
||||
if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then
|
||||
curl -o "$wrapperJarPath" "$jarUrl" -f
|
||||
else
|
||||
curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f
|
||||
fi
|
||||
|
||||
else
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo "Falling back to using Java to download"
|
||||
fi
|
||||
javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
|
||||
# For Cygwin, switch paths to Windows format before running javac
|
||||
if $cygwin; then
|
||||
javaClass=`cygpath --path --windows "$javaClass"`
|
||||
fi
|
||||
if [ -e "$javaClass" ]; then
|
||||
if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo " - Compiling MavenWrapperDownloader.java ..."
|
||||
fi
|
||||
# Compiling the Java class
|
||||
("$JAVA_HOME/bin/javac" "$javaClass")
|
||||
fi
|
||||
if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
|
||||
# Running the downloader
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo " - Running MavenWrapperDownloader.java ..."
|
||||
fi
|
||||
("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
##########################################################################################
|
||||
# End of extension
|
||||
##########################################################################################
|
||||
|
||||
export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
|
||||
if [ "$MVNW_VERBOSE" = true ]; then
|
||||
echo $MAVEN_PROJECTBASEDIR
|
||||
fi
|
||||
MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
|
||||
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin; then
|
||||
[ -n "$M2_HOME" ] &&
|
||||
M2_HOME=`cygpath --path --windows "$M2_HOME"`
|
||||
[ -n "$JAVA_HOME" ] &&
|
||||
JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
|
||||
[ -n "$CLASSPATH" ] &&
|
||||
CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
|
||||
[ -n "$MAVEN_PROJECTBASEDIR" ] &&
|
||||
MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
|
||||
fi
|
||||
|
||||
# Provide a "standardized" way to retrieve the CLI args that will
|
||||
# work with both Windows and non-Windows executions.
|
||||
MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
|
||||
export MAVEN_CMD_LINE_ARGS
|
||||
|
||||
WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
|
||||
|
||||
exec "$JAVACMD" \
|
||||
$MAVEN_OPTS \
|
||||
-classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
|
||||
"-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
|
||||
${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
|
||||
182
spring-cloud-dataflow-apps-plugin/mvnw.cmd
vendored
Normal file
182
spring-cloud-dataflow-apps-plugin/mvnw.cmd
vendored
Normal file
@@ -0,0 +1,182 @@
|
||||
@REM ----------------------------------------------------------------------------
|
||||
@REM Licensed to the Apache Software Foundation (ASF) under one
|
||||
@REM or more contributor license agreements. See the NOTICE file
|
||||
@REM distributed with this work for additional information
|
||||
@REM regarding copyright ownership. The ASF licenses this file
|
||||
@REM to you under the Apache License, Version 2.0 (the
|
||||
@REM "License"); you may not use this file except in compliance
|
||||
@REM with the License. You may obtain a copy of the License at
|
||||
@REM
|
||||
@REM http://www.apache.org/licenses/LICENSE-2.0
|
||||
@REM
|
||||
@REM Unless required by applicable law or agreed to in writing,
|
||||
@REM software distributed under the License is distributed on an
|
||||
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
@REM KIND, either express or implied. See the License for the
|
||||
@REM specific language governing permissions and limitations
|
||||
@REM under the License.
|
||||
@REM ----------------------------------------------------------------------------
|
||||
|
||||
@REM ----------------------------------------------------------------------------
|
||||
@REM Maven Start Up Batch script
|
||||
@REM
|
||||
@REM Required ENV vars:
|
||||
@REM JAVA_HOME - location of a JDK home dir
|
||||
@REM
|
||||
@REM Optional ENV vars
|
||||
@REM M2_HOME - location of maven2's installed home dir
|
||||
@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
|
||||
@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending
|
||||
@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
|
||||
@REM e.g. to debug Maven itself, use
|
||||
@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
|
||||
@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
|
||||
@REM ----------------------------------------------------------------------------
|
||||
|
||||
@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
|
||||
@echo off
|
||||
@REM set title of command window
|
||||
title %0
|
||||
@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on'
|
||||
@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
|
||||
|
||||
@REM set %HOME% to equivalent of $HOME
|
||||
if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
|
||||
|
||||
@REM Execute a user defined script before this one
|
||||
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
|
||||
@REM check for pre script, once with legacy .bat ending and once with .cmd ending
|
||||
if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
|
||||
if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
|
||||
:skipRcPre
|
||||
|
||||
@setlocal
|
||||
|
||||
set ERROR_CODE=0
|
||||
|
||||
@REM To isolate internal variables from possible post scripts, we use another setlocal
|
||||
@setlocal
|
||||
|
||||
@REM ==== START VALIDATION ====
|
||||
if not "%JAVA_HOME%" == "" goto OkJHome
|
||||
|
||||
echo.
|
||||
echo Error: JAVA_HOME not found in your environment. >&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the >&2
|
||||
echo location of your Java installation. >&2
|
||||
echo.
|
||||
goto error
|
||||
|
||||
:OkJHome
|
||||
if exist "%JAVA_HOME%\bin\java.exe" goto init
|
||||
|
||||
echo.
|
||||
echo Error: JAVA_HOME is set to an invalid directory. >&2
|
||||
echo JAVA_HOME = "%JAVA_HOME%" >&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the >&2
|
||||
echo location of your Java installation. >&2
|
||||
echo.
|
||||
goto error
|
||||
|
||||
@REM ==== END VALIDATION ====
|
||||
|
||||
:init
|
||||
|
||||
@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
|
||||
@REM Fallback to current working directory if not found.
|
||||
|
||||
set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
|
||||
IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
|
||||
|
||||
set EXEC_DIR=%CD%
|
||||
set WDIR=%EXEC_DIR%
|
||||
:findBaseDir
|
||||
IF EXIST "%WDIR%"\.mvn goto baseDirFound
|
||||
cd ..
|
||||
IF "%WDIR%"=="%CD%" goto baseDirNotFound
|
||||
set WDIR=%CD%
|
||||
goto findBaseDir
|
||||
|
||||
:baseDirFound
|
||||
set MAVEN_PROJECTBASEDIR=%WDIR%
|
||||
cd "%EXEC_DIR%"
|
||||
goto endDetectBaseDir
|
||||
|
||||
:baseDirNotFound
|
||||
set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
|
||||
cd "%EXEC_DIR%"
|
||||
|
||||
:endDetectBaseDir
|
||||
|
||||
IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
|
||||
|
||||
@setlocal EnableExtensions EnableDelayedExpansion
|
||||
for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
|
||||
@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
|
||||
|
||||
:endReadAdditionalConfig
|
||||
|
||||
SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
|
||||
set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
|
||||
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
|
||||
|
||||
set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
|
||||
|
||||
FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO (
|
||||
IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
|
||||
)
|
||||
|
||||
@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
|
||||
@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
|
||||
if exist %WRAPPER_JAR% (
|
||||
if "%MVNW_VERBOSE%" == "true" (
|
||||
echo Found %WRAPPER_JAR%
|
||||
)
|
||||
) else (
|
||||
if not "%MVNW_REPOURL%" == "" (
|
||||
SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar"
|
||||
)
|
||||
if "%MVNW_VERBOSE%" == "true" (
|
||||
echo Couldn't find %WRAPPER_JAR%, downloading it ...
|
||||
echo Downloading from: %DOWNLOAD_URL%
|
||||
)
|
||||
|
||||
powershell -Command "&{"^
|
||||
"$webclient = new-object System.Net.WebClient;"^
|
||||
"if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^
|
||||
"$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^
|
||||
"}"^
|
||||
"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^
|
||||
"}"
|
||||
if "%MVNW_VERBOSE%" == "true" (
|
||||
echo Finished downloading %WRAPPER_JAR%
|
||||
)
|
||||
)
|
||||
@REM End of extension
|
||||
|
||||
@REM Provide a "standardized" way to retrieve the CLI args that will
|
||||
@REM work with both Windows and non-Windows executions.
|
||||
set MAVEN_CMD_LINE_ARGS=%*
|
||||
|
||||
%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
|
||||
if ERRORLEVEL 1 goto error
|
||||
goto end
|
||||
|
||||
:error
|
||||
set ERROR_CODE=1
|
||||
|
||||
:end
|
||||
@endlocal & set ERROR_CODE=%ERROR_CODE%
|
||||
|
||||
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
|
||||
@REM check for post script, once with legacy .bat ending and once with .cmd ending
|
||||
if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
|
||||
if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
|
||||
:skipRcPost
|
||||
|
||||
@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
|
||||
if "%MAVEN_BATCH_PAUSE%" == "on" pause
|
||||
|
||||
if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
|
||||
|
||||
exit /B %ERROR_CODE%
|
||||
289
spring-cloud-dataflow-apps-plugin/pom.xml
Normal file
289
spring-cloud-dataflow-apps-plugin/pom.xml
Normal file
@@ -0,0 +1,289 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-dataflow-apps-plugin-parent</artifactId>
|
||||
<version>1.0.8-SNAPSHOT</version>
|
||||
<name>spring-cloud-dataflow-apps-plugin-parent</name>
|
||||
<description>Spring Cloud Dataflow Apps Plugin Parent</description>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<properties>
|
||||
<java.version>17</java.version>
|
||||
<maven-javadoc-plugin.version>3.1.1</maven-javadoc-plugin.version>
|
||||
<maven-source-plugin.version>3.2.1</maven-source-plugin.version>
|
||||
<maven-surefire-plugin.version>2.22.2</maven-surefire-plugin.version>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
|
||||
<maven.compiler.source>${java.version}</maven.compiler.source>
|
||||
<maven.compiler.target>${java.version}</maven.compiler.target>
|
||||
<maven-source-plugin.version>3.0.1</maven-source-plugin.version>
|
||||
<maven-checkstyle-plugin.version>3.1.0</maven-checkstyle-plugin.version>
|
||||
<disable.checks>false</disable.checks>
|
||||
<maven-checkstyle-plugin.failsOnError>true</maven-checkstyle-plugin.failsOnError>
|
||||
<maven-checkstyle-plugin.failOnViolation>true</maven-checkstyle-plugin.failOnViolation>
|
||||
<maven-checkstyle-plugin.includeTestSourceDirectory>true</maven-checkstyle-plugin.includeTestSourceDirectory>
|
||||
<puppycrawl-tools-checkstyle.version>8.29</puppycrawl-tools-checkstyle.version>
|
||||
<checkstyle.location>https://raw.githubusercontent.com/spring-cloud/spring-cloud-dataflow-apps-plugin/master/etc/checkstyle</checkstyle.location>
|
||||
<checkstyle.suppressions.file>
|
||||
${checkstyle.location}/checkstyle-suppressions.xml
|
||||
</checkstyle.suppressions.file>
|
||||
<checkstyle.nohttp.file>
|
||||
${checkstyle.location}/nohttp-checkstyle.xml
|
||||
</checkstyle.nohttp.file>
|
||||
<checkstyle.additional.suppressions.file>
|
||||
${checkstyle.location}/checkstyle-suppressions.xml
|
||||
</checkstyle.additional.suppressions.file>
|
||||
<nohttp-checkstyle.version>0.0.2.RELEASE</nohttp-checkstyle.version>
|
||||
<disable.nohttp.checks>true</disable.nohttp.checks>
|
||||
<spring-javaformat-checkstyle.version>0.0.7</spring-javaformat-checkstyle.version>
|
||||
</properties>
|
||||
|
||||
<modules>
|
||||
<module>spring-cloud-dataflow-apps-generator-plugin</module>
|
||||
<module>spring-cloud-dataflow-apps-metadata-plugin</module>
|
||||
<module>spring-cloud-dataflow-apps-docs-plugin</module>
|
||||
</modules>
|
||||
<url>https://github.com/spring-cloud/spring-cloud-dataflow-apps-plugin</url>
|
||||
<developers>
|
||||
<developer>
|
||||
<id>scdf-apps-plugin-developers</id>
|
||||
<name>SCDF Apps Plugin Developers</name>
|
||||
<email>chackos at vmware com</email>
|
||||
<organization>VMware</organization>
|
||||
<organizationUrl>https://www.spring.io</organizationUrl>
|
||||
<roles>
|
||||
<role>lead</role>
|
||||
</roles>
|
||||
</developer>
|
||||
</developers>
|
||||
|
||||
<licenses>
|
||||
<license>
|
||||
<name>Apache License, Version 2.0</name>
|
||||
<url>http://www.apache.org/licenses/LICENSE-2.0</url>
|
||||
<comments>Copyright 2014-2020 the original author or authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied.
|
||||
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.</comments>
|
||||
</license>
|
||||
</licenses>
|
||||
<scm>
|
||||
<connection>scm:git:git://github.com/spring-cloud/spring-cloud-dataflow-apps-plugin.git</connection>
|
||||
<developerConnection>scm:git:ssh://git@github.com/spring-cloud/spring-cloud-dataflow-apps-plugin.git</developerConnection>
|
||||
<url>https://github.com/spring-cloud/spring-cloud-dataflow-apps-plugin</url>
|
||||
</scm>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<version>${maven-javadoc-plugin.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>javadoc</id>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<quiet>true</quiet>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-source-plugin</artifactId>
|
||||
<version>${maven-source-plugin.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>attach-sources</id>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>${maven-surefire-plugin.version}</version>
|
||||
<configuration>
|
||||
<includes>
|
||||
<include>**/*Tests.java</include>
|
||||
<include>**/*Test.java</include>
|
||||
</includes>
|
||||
<excludes>
|
||||
<exclude>**/Abstract*.java</exclude>
|
||||
</excludes>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-checkstyle-plugin</artifactId>
|
||||
<version>${maven-checkstyle-plugin.version}</version>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.puppycrawl.tools</groupId>
|
||||
<artifactId>checkstyle</artifactId>
|
||||
<version>${puppycrawl-tools-checkstyle.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.spring.javaformat</groupId>
|
||||
<artifactId>spring-javaformat-checkstyle</artifactId>
|
||||
<version>${spring-javaformat-checkstyle.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.spring.nohttp</groupId>
|
||||
<artifactId>nohttp-checkstyle</artifactId>
|
||||
<version>${nohttp-checkstyle.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>checkstyle-validation</id>
|
||||
<phase>validate</phase>
|
||||
<inherited>true</inherited>
|
||||
<configuration>
|
||||
<skip>${disable.checks}</skip>
|
||||
<configLocation>${checkstyle.location}/checkstyle.xml</configLocation>
|
||||
<headerLocation>${checkstyle.location}/checkstyle-header.txt</headerLocation>
|
||||
<propertyExpansion>
|
||||
checkstyle.build.directory=${project.build.directory}
|
||||
checkstyle.suppressions.file=${checkstyle.suppressions.file}
|
||||
checkstyle.additional.suppressions.file=${checkstyle.additional.suppressions.file}
|
||||
</propertyExpansion>
|
||||
<consoleOutput>true</consoleOutput>
|
||||
<includeTestSourceDirectory>
|
||||
${maven-checkstyle-plugin.includeTestSourceDirectory}
|
||||
</includeTestSourceDirectory>
|
||||
<failsOnError>${maven-checkstyle-plugin.failsOnError}
|
||||
</failsOnError>
|
||||
<failOnViolation>
|
||||
${maven-checkstyle-plugin.failOnViolation}
|
||||
</failOnViolation>
|
||||
</configuration>
|
||||
<goals>
|
||||
<goal>check</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>no-http-checkstyle-validation</id>
|
||||
<phase>validate</phase>
|
||||
<inherited>true</inherited>
|
||||
<configuration>
|
||||
<skip>${disable.nohttp.checks}</skip>
|
||||
<configLocation>${checkstyle.nohttp.file}</configLocation>
|
||||
<includes>**/*</includes>
|
||||
<excludes>**/.idea/**/*,**/.git/**/*,**/target/**/*,**/*.log</excludes>
|
||||
<sourceDirectories>./</sourceDirectories>
|
||||
</configuration>
|
||||
<goals>
|
||||
<goal>check</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<distributionManagement>
|
||||
<repository>
|
||||
<id>repo.spring.io</id>
|
||||
<name>Spring Release Repository</name>
|
||||
<url>https://repo.spring.io/libs-release-local</url>
|
||||
</repository>
|
||||
<snapshotRepository>
|
||||
<id>repo.spring.io</id>
|
||||
<name>Spring Snapshot Repository</name>
|
||||
<url>https://repo.spring.io/libs-snapshot-local</url>
|
||||
</snapshotRepository>
|
||||
</distributionManagement>
|
||||
<repositories>
|
||||
<repository>
|
||||
<id>spring-milestones</id>
|
||||
<name>Spring Milestones</name>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<id>spring-snapshots</id>
|
||||
<name>Spring Snapshots</name>
|
||||
<url>https://repo.spring.io/snapshot</url>
|
||||
<snapshots>
|
||||
<enabled>true</enabled>
|
||||
</snapshots>
|
||||
</repository>
|
||||
</repositories>
|
||||
<pluginRepositories>
|
||||
<pluginRepository>
|
||||
<id>spring-milestones</id>
|
||||
<name>Spring Milestones</name>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
</pluginRepository>
|
||||
<pluginRepository>
|
||||
<id>spring-snapshots</id>
|
||||
<name>Spring Snapshots</name>
|
||||
<url>https://repo.spring.io/snapshot</url>
|
||||
<snapshots>
|
||||
<enabled>true</enabled>
|
||||
</snapshots>
|
||||
</pluginRepository>
|
||||
</pluginRepositories>
|
||||
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>milestone</id>
|
||||
<distributionManagement>
|
||||
<repository>
|
||||
<id>repo.spring.io</id>
|
||||
<name>Spring Milestone Repository</name>
|
||||
<url>https://repo.spring.io/libs-milestone-local</url>
|
||||
</repository>
|
||||
</distributionManagement>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>central</id>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-gpg-plugin</artifactId>
|
||||
<version>1.6</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>sign-artifacts</id>
|
||||
<phase>verify</phase>
|
||||
<goals>
|
||||
<goal>sign</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<distributionManagement>
|
||||
<repository>
|
||||
<id>sonatype-nexus-staging</id>
|
||||
<name>Nexus Release Repository</name>
|
||||
<url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
|
||||
</repository>
|
||||
<snapshotRepository>
|
||||
<id>sonatype-nexus-snapshots</id>
|
||||
<name>Sonatype Nexus Snapshots</name>
|
||||
<url>https://oss.sonatype.org/content/repositories/snapshots/</url>
|
||||
</snapshotRepository>
|
||||
</distributionManagement>
|
||||
</profile>
|
||||
</profiles>
|
||||
</project>
|
||||
@@ -0,0 +1,44 @@
|
||||
= Spring Cloud Stream & Task Maven Documentation Plugin
|
||||
|
||||
Maven plugin for generating documentation for Spring Cloud stream and task app starters.
|
||||
|
||||
Assuming a Spring Cloud Stream / Task app (or app starter) has
|
||||
specified selected configuration properties to be visible (i.e., providing src/main/resources/META-INF/dataflow-configuration-metadata.properties),
|
||||
this plugin will help automate the documentation of such properties.
|
||||
https://docs.spring.io/spring-cloud-dataflow/docs/1.1.0.M2/reference/html/spring-cloud-dataflow-register-apps.html#spring-cloud-dataflow-stream-app-whitelisting[whitelisted]
|
||||
some configuration properties, this plugin will help automate the documentation of such properties.
|
||||
|
||||
== Usage
|
||||
|
||||
To use this plugin, simply add the following markers to your project `README.adoc` file:
|
||||
|
||||
```
|
||||
//tag::configuration-properties[]
|
||||
//end::configuration-properties[]
|
||||
```
|
||||
|
||||
|
||||
Then, configure this plugin for your app project (either directly or through a parent POM):
|
||||
```
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.cloud.stream.app.plugin</groupId>
|
||||
<artifactId>spring-cloud-stream-app-documentation-maven-plugin</artifactId>
|
||||
<version>1.0.0.BUILD-SNAPSHOT</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>generate-documentation</id>
|
||||
<phase>verify</phase>
|
||||
<goals>
|
||||
<goal>generate-documentation</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
```
|
||||
|
||||
Documentation for the visible properties shall appear on next build, which should be committed under VCS.
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-dataflow-apps-plugin-parent</artifactId>
|
||||
<version>1.0.8-SNAPSHOT</version>
|
||||
<relativePath>..</relativePath>
|
||||
</parent>
|
||||
|
||||
<artifactId>spring-cloud-dataflow-apps-docs-plugin</artifactId>
|
||||
<packaging>maven-plugin</packaging>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.maven</groupId>
|
||||
<artifactId>maven-plugin-api</artifactId>
|
||||
<version>3.5.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.maven</groupId>
|
||||
<artifactId>maven-core</artifactId>
|
||||
<version>3.5.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-dataflow-configuration-metadata</artifactId>
|
||||
<version>2.7.0</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.maven.plugin-tools</groupId>
|
||||
<artifactId>maven-plugin-annotations</artifactId>
|
||||
<version>3.4</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.12</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.assertj</groupId>
|
||||
<artifactId>assertj-core</artifactId>
|
||||
<version>3.15.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-plugin-plugin</artifactId>
|
||||
<version>3.5</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>spring</id>
|
||||
<repositories>
|
||||
<repository>
|
||||
<snapshots>
|
||||
<enabled>true</enabled>
|
||||
</snapshots>
|
||||
<id>spring-snapshots</id>
|
||||
<name>Spring Snapshots</name>
|
||||
<url>https://repo.spring.io/snapshot</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
<id>spring-milestones</id>
|
||||
<name>Spring Milestones</name>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
</profile>
|
||||
</profiles>
|
||||
</project>
|
||||
@@ -0,0 +1,424 @@
|
||||
/*
|
||||
* Copyright 2016-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.dataflow.app.plugin;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.function.Function;
|
||||
import java.util.jar.Manifest;
|
||||
|
||||
import org.apache.maven.artifact.Artifact;
|
||||
import org.apache.maven.artifact.DependencyResolutionRequiredException;
|
||||
import org.apache.maven.plugin.AbstractMojo;
|
||||
import org.apache.maven.plugin.MojoExecutionException;
|
||||
import org.apache.maven.plugins.annotations.Mojo;
|
||||
import org.apache.maven.plugins.annotations.Parameter;
|
||||
import org.apache.maven.plugins.annotations.ResolutionScope;
|
||||
import org.apache.maven.project.MavenProject;
|
||||
|
||||
import org.springframework.boot.configurationmetadata.ConfigurationMetadataProperty;
|
||||
import org.springframework.boot.loader.archive.Archive;
|
||||
import org.springframework.boot.loader.archive.ExplodedArchive;
|
||||
import org.springframework.boot.loader.archive.JarFileArchive;
|
||||
import org.springframework.cloud.dataflow.configuration.metadata.BootApplicationConfigurationMetadataResolver;
|
||||
import org.springframework.cloud.dataflow.configuration.metadata.BootClassLoaderFactory;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* A maven plugin that will scan an asciidoc file for special comment markers and replace
|
||||
* everything in between with a listing of visible configuration properties for a Spring
|
||||
* Cloud Stream/Task app. Applications with multiple properties prefixes are grouped by default.
|
||||
* This can be disabled by using {@code //tag::configuration-properties[group=false]}.
|
||||
*
|
||||
* @author Eric Bottard
|
||||
* @author David Turanski
|
||||
* @see <a href=
|
||||
* "https://dataflow.spring.io/docs/feature-guides/general/application-metadata/#whitelisting-properties">Whitelisting
|
||||
* Properties</a>
|
||||
*/
|
||||
@Mojo(name = "generate-documentation", requiresDependencyResolution = ResolutionScope.RUNTIME)
|
||||
public class ConfigurationMetadataDocumentationMojo extends AbstractMojo {
|
||||
|
||||
static final String CONFIGURATION_PROPERTIES_START_TAG = "//tag::configuration-properties[";
|
||||
|
||||
static final String CONFIGURATION_PROPERTIES_END_TAG = "//end::configuration-properties[]";
|
||||
|
||||
private BootApplicationConfigurationMetadataResolver metadataResolver = new BootApplicationConfigurationMetadataResolver(
|
||||
imageName -> null);
|
||||
|
||||
@Parameter(defaultValue = "${project}")
|
||||
private MavenProject mavenProject;
|
||||
|
||||
@Parameter(defaultValue = "false")
|
||||
private boolean failOnMissingDescription;
|
||||
|
||||
private boolean grouped = true;
|
||||
|
||||
public void execute() throws MojoExecutionException {
|
||||
|
||||
File readme = new File(mavenProject.getBasedir(), "README.adoc");
|
||||
if (!readme.exists()) {
|
||||
getLog().info(String.format("No README.adoc file found in %s, skipping", mavenProject.getBasedir()));
|
||||
return;
|
||||
}
|
||||
|
||||
Artifact artifact = mavenProject.getArtifact();
|
||||
if (artifact.getFile() == null) {
|
||||
getLog().info(String.format("Project in %s does not produce a build artifact, skipping",
|
||||
mavenProject.getBasedir()));
|
||||
return;
|
||||
}
|
||||
|
||||
File tmp = new File(readme.getPath() + ".tmp");
|
||||
try (PrintWriter out = new PrintWriter(tmp);
|
||||
BufferedReader reader = new BufferedReader(new FileReader(readme))) {
|
||||
|
||||
String line;
|
||||
do {
|
||||
line = reader.readLine();
|
||||
out.println(line);
|
||||
}
|
||||
while (line != null && !line.startsWith(CONFIGURATION_PROPERTIES_START_TAG));
|
||||
if (line == null) {
|
||||
getLog().info("No documentation section marker found");
|
||||
return;
|
||||
}
|
||||
|
||||
Map<String, String> startTagAttributes = startTagAttributes(line);
|
||||
|
||||
if ("false".equals(startTagAttributes.get("group"))) {
|
||||
grouped = false;
|
||||
}
|
||||
|
||||
ScatteredArchive archive = new ScatteredArchive(mavenProject);
|
||||
BootClassLoaderFactory bootClassLoaderFactory = new BootClassLoaderFactory(archive, null);
|
||||
try (URLClassLoader classLoader = bootClassLoaderFactory.createClassLoader()) {
|
||||
debug(classLoader);
|
||||
|
||||
List<ConfigurationMetadataProperty> properties = metadataResolver.listProperties(archive, false);
|
||||
Collections.sort(properties, Comparator.comparing(ConfigurationMetadataProperty::getId));
|
||||
|
||||
Map<String, List<ConfigurationMetadataProperty>> groupedProperties = groupProperties(properties);
|
||||
|
||||
grouped = grouped && groupedProperties.size() > 1;
|
||||
|
||||
if (grouped) {
|
||||
out.println("Properties grouped by prefix:\n");
|
||||
groupedProperties.forEach((group, props) -> {
|
||||
getLog().debug(" Documenting group " + group);
|
||||
out.println(asciidocForGroup(group));
|
||||
listProperties(props, out, classLoader, prop -> prop.getName());
|
||||
});
|
||||
|
||||
}
|
||||
else {
|
||||
listProperties(properties, out, classLoader, prop -> prop.getId());
|
||||
}
|
||||
do {
|
||||
line = reader.readLine();
|
||||
// drop lines
|
||||
}
|
||||
while (!line.startsWith(CONFIGURATION_PROPERTIES_END_TAG));
|
||||
|
||||
// Copy remaining lines, including //end::configuration-properties[]
|
||||
while (line != null) {
|
||||
out.println(line);
|
||||
line = reader.readLine();
|
||||
}
|
||||
getLog().info(String.format("Documented %d configuration properties", properties.size()));
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
tmp.delete();
|
||||
throw new MojoExecutionException("Error generating documentation", e);
|
||||
}
|
||||
|
||||
try {
|
||||
Files.move(tmp.toPath(), readme.toPath(), StandardCopyOption.REPLACE_EXISTING);
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new MojoExecutionException("Error moving tmp file to README.adoc", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void listProperties(List<ConfigurationMetadataProperty> properties, PrintWriter out,
|
||||
ClassLoader classLoader,
|
||||
Function<ConfigurationMetadataProperty, String> propertyValue) {
|
||||
for (ConfigurationMetadataProperty property : properties) {
|
||||
getLog().debug("Documenting " + property.getId());
|
||||
out.println(asciidocFor(property, classLoader, propertyValue));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private Map<String, List<ConfigurationMetadataProperty>> groupProperties(
|
||||
List<ConfigurationMetadataProperty> properties) {
|
||||
Map<String, List<ConfigurationMetadataProperty>> groupedProperties = new LinkedHashMap<>();
|
||||
properties.forEach(property -> {
|
||||
String group = group(property.getId());
|
||||
if (!groupedProperties.containsKey(group)) {
|
||||
groupedProperties.put(group, new LinkedList<>());
|
||||
}
|
||||
groupedProperties.get(group).add(property);
|
||||
});
|
||||
return groupedProperties;
|
||||
}
|
||||
|
||||
private String group(String id) {
|
||||
return id.lastIndexOf('.') > 0 ? id.substring(0, id.lastIndexOf('.')) : "";
|
||||
}
|
||||
|
||||
private void debug(ClassLoader classLoader) {
|
||||
if (classLoader instanceof URLClassLoader) {
|
||||
List<URL> urls = Arrays.asList(((URLClassLoader) classLoader).getURLs());
|
||||
getLog().debug("Classloader has the following URLs:\n" + urls.toString().replace(',', '\n'));
|
||||
}
|
||||
}
|
||||
|
||||
private String asciidocFor(ConfigurationMetadataProperty property, ClassLoader classLoader,
|
||||
Function<ConfigurationMetadataProperty, String> propertyValue) {
|
||||
return String.format("$$%s$$:: $$%s$$ *($$%s$$, default: `$$%s$$`%s)*",
|
||||
propertyValue.apply(property),
|
||||
niceDescription(property),
|
||||
niceType(property),
|
||||
niceDefault(property),
|
||||
maybeHints(property, classLoader));
|
||||
}
|
||||
|
||||
private String asciidocForGroup(String group) {
|
||||
return "\n=== " + group + "\n";
|
||||
}
|
||||
|
||||
private Map<String, String> startTagAttributes(String startTag) {
|
||||
String attrs = startTag.substring(startTag.indexOf('[') + 1, startTag.indexOf(']'));
|
||||
Set<String> set = StringUtils.commaDelimitedListToSet(attrs);
|
||||
Map<String, String> attributes = new LinkedHashMap<>();
|
||||
set.forEach(attr -> {
|
||||
String[] keyValue = attr.split("=");
|
||||
attributes.put(keyValue[0].trim(), keyValue.length == 2 ? keyValue[1].trim() : "");
|
||||
});
|
||||
return attributes;
|
||||
}
|
||||
|
||||
private String niceDescription(ConfigurationMetadataProperty property) {
|
||||
if (property.getDescription() == null) {
|
||||
if (failOnMissingDescription) {
|
||||
throw new RuntimeException("Missing description for property " + property.getId());
|
||||
}
|
||||
else {
|
||||
return "<documentation missing>";
|
||||
}
|
||||
}
|
||||
return property.getDescription();
|
||||
}
|
||||
|
||||
private CharSequence maybeHints(ConfigurationMetadataProperty property, ClassLoader classLoader) {
|
||||
String type = property.getType();
|
||||
if (type == null) {
|
||||
return "";
|
||||
}
|
||||
|
||||
type = type.replace('$', '.');
|
||||
if (ClassUtils.isPresent(type, classLoader)) {
|
||||
Class<?> clazz = ClassUtils.resolveClassName(type, classLoader);
|
||||
if (clazz.isEnum()) {
|
||||
return ", possible values: `" + StringUtils.arrayToDelimitedString(clazz.getEnumConstants(), "`,`")
|
||||
+ "`";
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
private String niceDefault(ConfigurationMetadataProperty property) {
|
||||
if (property.getDefaultValue() == null) {
|
||||
return "<none>";
|
||||
}
|
||||
else if ("".equals(property.getDefaultValue())) {
|
||||
return "<empty string>";
|
||||
}
|
||||
else {
|
||||
return stringify(property.getDefaultValue());
|
||||
}
|
||||
}
|
||||
|
||||
private String stringify(Object element) {
|
||||
Class<?> clazz = element.getClass();
|
||||
if (clazz == byte[].class) {
|
||||
return Arrays.toString((byte[]) element);
|
||||
}
|
||||
else if (clazz == short[].class) {
|
||||
return Arrays.toString((short[]) element);
|
||||
}
|
||||
else if (clazz == int[].class) {
|
||||
return Arrays.toString((int[]) element);
|
||||
}
|
||||
else if (clazz == long[].class) {
|
||||
return Arrays.toString((long[]) element);
|
||||
}
|
||||
else if (clazz == char[].class) {
|
||||
return Arrays.toString((char[]) element);
|
||||
}
|
||||
else if (clazz == float[].class) {
|
||||
return Arrays.toString((float[]) element);
|
||||
}
|
||||
else if (clazz == double[].class) {
|
||||
return Arrays.toString((double[]) element);
|
||||
}
|
||||
else if (clazz == boolean[].class) {
|
||||
return Arrays.toString((boolean[]) element);
|
||||
}
|
||||
else if (element instanceof Object[]) {
|
||||
return Arrays.deepToString((Object[]) element);
|
||||
}
|
||||
else {
|
||||
return element.toString();
|
||||
}
|
||||
}
|
||||
|
||||
private String niceType(ConfigurationMetadataProperty property) {
|
||||
String type = property.getType();
|
||||
if (type == null) {
|
||||
return "<unknown>";
|
||||
}
|
||||
return niceType(type);
|
||||
}
|
||||
|
||||
String niceType(String type) {
|
||||
List<String> parts = new ArrayList<>();
|
||||
int openBrackets = 0;
|
||||
int lastGenericPart = 0;
|
||||
for (int i = 0; i < type.length(); i++) {
|
||||
switch (type.charAt(i)) {
|
||||
case '<':
|
||||
if (openBrackets++ == 0) {
|
||||
parts.add(type.substring(0, i));
|
||||
lastGenericPart = i + 1;
|
||||
}
|
||||
break;
|
||||
case '>':
|
||||
if (--openBrackets == 0) {
|
||||
parts.add(type.substring(lastGenericPart, i));
|
||||
}
|
||||
break;
|
||||
case ',':
|
||||
if (openBrackets == 1) {
|
||||
parts.add(type.substring(lastGenericPart, i));
|
||||
lastGenericPart = i + 1;
|
||||
}
|
||||
break;
|
||||
case ' ':
|
||||
if (openBrackets == 1) {
|
||||
lastGenericPart++;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (parts.isEmpty()) {
|
||||
return unqualify(type); // simple type
|
||||
}
|
||||
else { // type with generics
|
||||
StringBuilder sb = new StringBuilder(unqualify(parts.get(0)));
|
||||
for (int i = 1; i < parts.size(); i++) {
|
||||
if (i == 1) {
|
||||
sb.append('<');
|
||||
}
|
||||
sb.append(unqualify(niceType(parts.get(i))));
|
||||
if (i == parts.size() - 1) {
|
||||
sb.append('>');
|
||||
}
|
||||
else {
|
||||
sb.append(", ");
|
||||
}
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
||||
private String unqualify(String type) {
|
||||
int lastDot = type.lastIndexOf('.');
|
||||
int lastDollar = type.lastIndexOf('$');
|
||||
return type.substring(Math.max(lastDot, lastDollar) + 1);
|
||||
}
|
||||
|
||||
/**
|
||||
* An adapter to boot {@link Archive} that satisfies just enough of the API to craft a
|
||||
* ClassLoader that "sees" all the properties that this Mojo tries to document.
|
||||
* @author Eric Bottard
|
||||
*/
|
||||
private static final class ScatteredArchive implements Archive {
|
||||
|
||||
private final MavenProject mavenProject;
|
||||
|
||||
private ScatteredArchive(MavenProject mavenProject) {
|
||||
|
||||
this.mavenProject = mavenProject;
|
||||
}
|
||||
|
||||
@Override
|
||||
public URL getUrl() throws MalformedURLException {
|
||||
return mavenProject.getArtifact().getFile().toURI().toURL();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Manifest getManifest() {
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Archive> getNestedArchives(EntryFilter ignored) throws IOException {
|
||||
try {
|
||||
List<Archive> archives = new ArrayList<>(mavenProject.getRuntimeClasspathElements().size());
|
||||
for (String dep : mavenProject.getRuntimeClasspathElements()) {
|
||||
File file = new File(dep);
|
||||
archives.add(file.isDirectory() ? new ExplodedArchive(file) : new JarFileArchive(file));
|
||||
}
|
||||
return archives;
|
||||
}
|
||||
catch (DependencyResolutionRequiredException e) {
|
||||
throw new IOException("Could not create boot archive", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<Entry> iterator() {
|
||||
// BootClassLoaderFactory.createClassLoader (which uses this iterator call) is not
|
||||
// actually
|
||||
// used here. Returning the simples thing that works.
|
||||
return Collections.emptyIterator();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2017-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.dataflow.app.plugin;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
public class ConfigurationMetadataDocumentationMojoTests {
|
||||
|
||||
@Test
|
||||
public void testJavaTypeBeautifier() {
|
||||
ConfigurationMetadataDocumentationMojo mojo = new ConfigurationMetadataDocumentationMojo();
|
||||
String s = mojo.niceType("java.lang.String");
|
||||
assertThat(s).isEqualTo("String");
|
||||
|
||||
s = mojo.niceType("java.lang.Class<?>");
|
||||
assertThat(s).isEqualTo("Class<?>");
|
||||
|
||||
s = mojo.niceType("java.util.Map$Entry<java.lang.String, java.util.Map<java.lang.Integer,java.util.List<java.lang.Long>>>");
|
||||
assertThat(s).isEqualTo("Entry<String, Map<Integer, List<Long>>>");
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,302 @@
|
||||
= spring-cloud-dataflow-apps-generator-plugin
|
||||
|
||||
Maven plugin for generating spring cloud stream applications: https://github.com/spring-cloud/stream-applications
|
||||
It generates a separate maven project for every configured binder.
|
||||
|
||||
Plugin `Application` section helps to configure the application project independently form the Binders that
|
||||
can be used. The `Binders` section helps to define the Binder specific configurations, that are merged to
|
||||
the `Application` configurations to generate the binder specific maven projects.
|
||||
|
||||
The `Global` section (e.g. `global.application` and `global.binders`) helps to define configurations sharable
|
||||
between many Applications and Binders.
|
||||
|
||||
As the following diagram illustrates, both the `Application` and the
|
||||
`Binder` allow configuring various application and maven properties:
|
||||
|
||||
image::src/main/resources/doc/MojoConfiguration.jpg[]
|
||||
|
||||
== Build
|
||||
|
||||
mvn clean package [Requires JDK 8]
|
||||
|
||||
== Sample Configuration for generating spring cloud stream apps
|
||||
|
||||
In the parent POM define the `Application` and `Binder` configurations common for all applications to be generated.
|
||||
Do this under the `pluginManagement` pom section and use the plugin's `global` configuration:
|
||||
|
||||
[source, xml]
|
||||
----
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-dataflow-apps-generator-plugin</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>app-gen</id>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>generate-app</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<generatedProjectHome>${basedir}/apps</generatedProjectHome>
|
||||
|
||||
<global>
|
||||
<application>
|
||||
|
||||
<bootVersion>${spring-boot.version}</bootVersion>
|
||||
|
||||
<containerImage>
|
||||
<enableMetadata>true</enableMetadata>
|
||||
</containerImage>
|
||||
|
||||
<metadata>
|
||||
<mavenPluginVersion>2.0.2.BUILD-SNAPSHOT</mavenPluginVersion>
|
||||
</metadata>
|
||||
|
||||
<maven>
|
||||
<dependencyManagement>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud.fn</groupId>
|
||||
<artifactId>function-dependencies</artifactId>
|
||||
<version>${java-functions.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-stream-dependencies</artifactId>
|
||||
<version>${spring-cloud-stream-dependencies.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-function-dependencies</artifactId>
|
||||
<version>${spring-cloud-function-dependencies.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-dependencies</artifactId>
|
||||
<version>${spring-cloud-dependencies.version}</version>
|
||||
</dependency>
|
||||
</dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud.stream.app</groupId>
|
||||
<artifactId>stream-applications-security-common</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud.stream.app</groupId>
|
||||
<artifactId>stream-applications-micrometer-common</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud.stream.app</groupId>
|
||||
<artifactId>stream-applications-postprocessor-common</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.micrometer</groupId>
|
||||
<artifactId>micrometer-registry-prometheus</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.micrometer.prometheus</groupId>
|
||||
<artifactId>prometheus-rsocket-spring</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.micrometer</groupId>
|
||||
<artifactId>micrometer-registry-wavefront</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.pivotal.cfenv</groupId>
|
||||
<artifactId>java-cfenv-boot</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-logging</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-security</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</maven>
|
||||
</application>
|
||||
<binders>
|
||||
<kafka>
|
||||
<maven>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-stream-binder-kafka</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</maven>
|
||||
</kafka>
|
||||
<rabbit>
|
||||
<maven>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-stream-binder-rabbit</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</maven>
|
||||
</rabbit>
|
||||
</binders>
|
||||
</global>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
----
|
||||
|
||||
Above global configurations will be reused by all children applications.
|
||||
|
||||
In addition, the child application can add application specific configurations, contributed to the inherited from
|
||||
to the global:
|
||||
|
||||
[source, xml]
|
||||
----
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-dataflow-apps-generator-plugin</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<configuration>
|
||||
<application>
|
||||
<name>syslog</name>
|
||||
<type>source</type>
|
||||
<version>${project.version}</version>
|
||||
<configClass>org.springframework.cloud.fn.supplier.syslog.SyslogSupplierConfiguration.class</configClass>
|
||||
|
||||
<maven>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud.fn</groupId>
|
||||
<artifactId>syslog-supplier</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud.stream.app</groupId>
|
||||
<artifactId>stream-applications-composite-function-support</artifactId>
|
||||
<version>${stream-apps-core.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</maven>
|
||||
</application>
|
||||
</configuration>
|
||||
</plugin>
|
||||
...
|
||||
</plugins>
|
||||
----
|
||||
|
||||
|
||||
== Configure Solace and Pubsub binders support
|
||||
|
||||
To generate applications for https://github.com/SolaceProducts/spring-cloud-stream-binder-solace[Solace] binders, extend your `binders` section with following configuration:
|
||||
|
||||
[source, xml]
|
||||
----
|
||||
<binders>
|
||||
....
|
||||
<solace>
|
||||
<maven>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.solace.spring.cloud</groupId>
|
||||
<artifactId>spring-cloud-starter-stream-solace</artifactId>
|
||||
<version>1.2.1</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</maven>
|
||||
</solace>
|
||||
....
|
||||
</binders>
|
||||
----
|
||||
|
||||
You can add it either to your application's POM or to the parent's `global` POM sections.
|
||||
|
||||
Similar to generate application for the https://github.com/spring-cloud/spring-cloud-gcp/tree/master/spring-cloud-gcp-pubsub-stream-binder[PubSub]
|
||||
binders and to your binders section configuration like this:
|
||||
|
||||
[source, xml]
|
||||
----
|
||||
<binders>
|
||||
...
|
||||
<pubsub>
|
||||
<maven>
|
||||
<dependencyManagement>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-gcp-dependencies</artifactId>
|
||||
<version>1.2.4.RELEASE</version>
|
||||
</dependency>
|
||||
</dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-gcp-pubsub-stream-binder</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</maven>
|
||||
</pubsub>
|
||||
...
|
||||
</binders>
|
||||
----
|
||||
|
||||
== Custom Spring Boot Maven Plugin Configuration
|
||||
|
||||
Spring Boot Maven plugin offers a number of customization options by specifying a configuration section in the plugin definition.
|
||||
For example, using the custom configuration, you can instruct the plugin to unpack a particular dependency.
|
||||
You would do that using Spring Boot Maven plugin as below.
|
||||
```
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<configuration>
|
||||
<requiresUnpack>
|
||||
<dependency>
|
||||
<groupId>org.python</groupId>
|
||||
<artifactId>jython-standalone</artifactId>
|
||||
</dependency>
|
||||
</requiresUnpack>
|
||||
</configuration>
|
||||
</plugin>
|
||||
```
|
||||
|
||||
When using the app generator plugin, you can ask the plugin to include this information when it generates the necessary XML snippets for adding the Spring Boot Maven plugin.
|
||||
Below is an example of doing so.
|
||||
```
|
||||
<plugin>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-dataflow-apps-generator-plugin</artifactId>
|
||||
<configuration>
|
||||
<application>
|
||||
...
|
||||
<bootPluginConfiguration>
|
||||
<![CDATA[
|
||||
<requiresUnpack>
|
||||
<dependency>
|
||||
<groupId>org.python</groupId>
|
||||
<artifactId>jython-standalone</artifactId>
|
||||
</dependency>
|
||||
</requiresUnpack>
|
||||
]]>
|
||||
</bootPluginConfiguration>
|
||||
...
|
||||
</application>
|
||||
</configuration>
|
||||
```
|
||||
|
||||
Pay attention to how the Spring Boot plugin configuration is wrapped inside a `CDATA` element.
|
||||
This is necessary for the app generator to properly parse this information.
|
||||
@@ -0,0 +1,166 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>spring-cloud-dataflow-apps-generator-plugin</artifactId>
|
||||
<packaging>maven-plugin</packaging>
|
||||
<name>spring-cloud-dataflow-apps-generator-plugin</name>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-dataflow-apps-plugin-parent</artifactId>
|
||||
<version>1.0.8-SNAPSHOT</version>
|
||||
<relativePath>..</relativePath>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<maven.version>3.9.2</maven.version>
|
||||
<maven.plugin.version>3.9.0</maven.plugin.version>
|
||||
<jmustache.version>1.15</jmustache.version>
|
||||
<spring.version>6.0.8</spring.version>
|
||||
<commons.io.version>2.12.0</commons.io.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.samskivert</groupId>
|
||||
<artifactId>jmustache</artifactId>
|
||||
<version>${jmustache.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-core</artifactId>
|
||||
<version>${spring.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>org.apache.maven</groupId>
|
||||
<artifactId>maven-plugin-api</artifactId>
|
||||
<scope>provided</scope>
|
||||
<version>${maven.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.maven</groupId>
|
||||
<artifactId>maven-core</artifactId>
|
||||
<version>${maven.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.maven.plugin-tools</groupId>
|
||||
<artifactId>maven-plugin-annotations</artifactId>
|
||||
<version>${maven.plugin.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>commons-io</groupId>
|
||||
<artifactId>commons-io</artifactId>
|
||||
<version>${commons.io.version}</version>
|
||||
</dependency>
|
||||
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.13</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.maven.plugin-testing</groupId>
|
||||
<artifactId>maven-plugin-testing-harness</artifactId>
|
||||
<version>3.3.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.maven</groupId>
|
||||
<artifactId>maven-compat</artifactId>
|
||||
<version>${maven.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.assertj</groupId>
|
||||
<artifactId>assertj-core</artifactId>
|
||||
<version>3.15.0</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-plugin-plugin</artifactId>
|
||||
<version>${maven.plugin.version}</version>
|
||||
<configuration>
|
||||
<goalPrefix>generate-app</goalPrefix>
|
||||
<skipErrorNoDescriptorsFound>true</skipErrorNoDescriptorsFound>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>mojo-descriptor</id>
|
||||
<goals>
|
||||
<goal>descriptor</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
<execution>
|
||||
<id>help-goal</id>
|
||||
<goals>
|
||||
<goal>helpmojo</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>run-its</id>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-invoker-plugin</artifactId>
|
||||
<version>3.2.1</version>
|
||||
<configuration>
|
||||
<debug>true</debug>
|
||||
<cloneProjectsTo>${project.build.directory}/it</cloneProjectsTo>
|
||||
<pomIncludes>
|
||||
<pomInclude>*/pom.xml</pomInclude>
|
||||
</pomIncludes>
|
||||
<postBuildHookScript>verify</postBuildHookScript>
|
||||
<localRepositoryPath>${project.build.directory}/local-repo</localRepositoryPath>
|
||||
<settingsFile>src/it/settings.xml</settingsFile>
|
||||
<goals>
|
||||
<goal>clean</goal>
|
||||
<goal>test-compile</goal>
|
||||
</goals>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>integration-test</id>
|
||||
<goals>
|
||||
<goal>install</goal>
|
||||
<goal>integration-test</goal>
|
||||
<goal>verify</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
</project>
|
||||
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
* Copyright 2020-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.dataflow.app.plugin;
|
||||
|
||||
import java.io.StringReader;
|
||||
import java.io.StringWriter;
|
||||
import java.io.Writer;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
import org.apache.maven.model.Plugin;
|
||||
import org.apache.maven.model.io.xpp3.MavenXpp3Writer;
|
||||
import org.codehaus.plexus.util.xml.Xpp3Dom;
|
||||
import org.codehaus.plexus.util.xml.Xpp3DomBuilder;
|
||||
import org.codehaus.plexus.util.xml.pull.MXSerializer;
|
||||
import org.codehaus.plexus.util.xml.pull.XmlSerializer;
|
||||
|
||||
/**
|
||||
* Uses the private MavenXpp3Writer write methods to convert Model elements into XML strings.
|
||||
*
|
||||
* @author Christian Tzolov
|
||||
*/
|
||||
public final class MavenXmlWriter {
|
||||
|
||||
private MavenXmlWriter() {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Serializes any instance of a e.g. org.apache.maven.model.XXXX class into XML text.
|
||||
* Via reflections calls the private MavenXpp3Writer#writeXXXX(XXXX, String, XmlSerializer) method.
|
||||
* As xml tag uses the lower case of the XXXX class name (e.g. xxxx).
|
||||
* <p>
|
||||
* If above name conventions don't hold or additional processing is required implement a dedicated overload method.
|
||||
* For example see {@link #toXml(Plugin)}
|
||||
*
|
||||
* @param element instance of a org.apache.maven.model.* class.
|
||||
* @param <T> element type.
|
||||
* @return XML text serialization of the element.
|
||||
*/
|
||||
public static <T> String toXml(T element) {
|
||||
String privateMethodName = "write" + element.getClass().getSimpleName();
|
||||
String xmlTagName = element.getClass().getSimpleName().toLowerCase();
|
||||
return write(serializer -> invokeMavenXppWriteMethod(element, privateMethodName, xmlTagName, serializer));
|
||||
}
|
||||
|
||||
/**
|
||||
* Serializes an {@link Plugin} instance into XML text, using reflection to invoke the private
|
||||
* MavenXpp3Writer#writePlugin(Plugin, String, XmlSerializer) method. The Plugin Configuration block (when present)
|
||||
* requires special handling to convert String values into Xpp3Dom object before writing.
|
||||
* <p>
|
||||
* For Plugin Configuration you must nest the configuration content into a CDATA block like shown here:
|
||||
* <pre>{@code
|
||||
* <additionalPlugins>
|
||||
* <plugin>
|
||||
* <groupId>com.google.cloud.tools</groupId>
|
||||
* <artifactId>jib-maven-plugin</artifactId>
|
||||
* <version>3.3.0</version>
|
||||
* <configuration>
|
||||
* <![CDATA[
|
||||
* <from><image>springcloud/baseimage:1.0.4</image></from>
|
||||
* <to>
|
||||
* <image>springcloudstream:${project.artifactId}</image>
|
||||
* <tags><tag>latest</tag></tags>
|
||||
* </to>
|
||||
* <container>
|
||||
* <format>Docker</format>
|
||||
* </container>
|
||||
* ]]>
|
||||
* </configuration>
|
||||
* </plugin>
|
||||
* </additionalPlugins>
|
||||
* }</pre>
|
||||
*
|
||||
* @param plugin Plugin instance to serialize.
|
||||
* @return POM/XML serialization of the plugin.
|
||||
*/
|
||||
public static String toXml(Plugin plugin) {
|
||||
try {
|
||||
Object configuration = plugin.getConfiguration();
|
||||
if (configuration != null && !(configuration instanceof Xpp3Dom)) {
|
||||
plugin.setConfiguration(Xpp3DomBuilder.build(new StringReader(
|
||||
"<configuration>" + configuration.toString() + "</configuration>")));
|
||||
}
|
||||
}
|
||||
catch (Exception ex) {
|
||||
throw new IllegalStateException("Issue creating config for additional plugin", ex);
|
||||
}
|
||||
|
||||
return write(serializer -> invokeMavenXppWriteMethod(
|
||||
plugin, "writePlugin", "plugin", serializer));
|
||||
}
|
||||
|
||||
/**
|
||||
* Template method that helps generating well-formed and valid XML segments. It uses the {@link XmlSerializer}
|
||||
* to create the create the XML structure and delegates to the #elementWriter callback to fill in the content.
|
||||
*
|
||||
* @param elementWriter Callback handler that contributes the XML content.
|
||||
* @return Returns well-formed XML element.
|
||||
*/
|
||||
public static String write(Consumer<XmlSerializer> elementWriter) {
|
||||
try {
|
||||
Writer writer = new StringWriter();
|
||||
|
||||
XmlSerializer serializer = new MXSerializer();
|
||||
serializer.setProperty("http://xmlpull.org/v1/doc/properties.html#serializer-indentation", " ");
|
||||
serializer.setProperty("http://xmlpull.org/v1/doc/properties.html#serializer-line-separator", "\n");
|
||||
serializer.setOutput(writer);
|
||||
|
||||
serializer.startDocument("UTF-8", null);
|
||||
elementWriter.accept(serializer);
|
||||
serializer.endDocument();
|
||||
|
||||
String result = writer.toString();
|
||||
return result.substring(result.indexOf('\n') + 1); // remove first line (e.g. remove the <?xml ... ?>)
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses the private MavenXpp3Writer methods to convert Model elements into XML strings.
|
||||
*
|
||||
* @param modelElementToWrite a parameterizable org.apache.maven.model.T instance to serialize.
|
||||
* @param <T> The actual org.apache.maven.model's class type.
|
||||
* @param writeMethodName Name of the private {@link MavenXpp3Writer} method to call.
|
||||
* @param xmlTagName Name for the XML tag to surround the serialized model instance.
|
||||
* @param serializer The XmlSerializer used to write the xml.
|
||||
*/
|
||||
public static <T> void invokeMavenXppWriteMethod(T modelElementToWrite, String writeMethodName,
|
||||
String xmlTagName, XmlSerializer serializer) {
|
||||
|
||||
try {
|
||||
MavenXpp3Writer pomWriter = new MavenXpp3Writer();
|
||||
Method method = pomWriter.getClass().getDeclaredMethod(
|
||||
writeMethodName, modelElementToWrite.getClass(), String.class, XmlSerializer.class);
|
||||
method.setAccessible(true); // allow invoking private method.
|
||||
method.invoke(pomWriter, modelElementToWrite, xmlTagName, serializer);
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Indent the input string by the provided indentation steps.
|
||||
* @param input String to indent.
|
||||
* @param indentation Number of indentation steps.
|
||||
* @return Returns the formatted string.
|
||||
*/
|
||||
public static String indent(String input, int indentation) {
|
||||
String indentPrefix = "\n" + IntStream.range(0, indentation).mapToObj(i -> " ").collect(Collectors.joining());
|
||||
String indentedInput = input.replace("\n", indentPrefix);
|
||||
return indentedInput.substring(0, indentedInput.lastIndexOf(indentPrefix)); // remove the last empty line.
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,780 @@
|
||||
/*
|
||||
* Copyright 2020-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.dataflow.app.plugin;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.Properties;
|
||||
import java.util.TreeMap;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.apache.commons.io.FileUtils;
|
||||
import org.apache.maven.model.Dependency;
|
||||
import org.apache.maven.model.Plugin;
|
||||
import org.apache.maven.model.Repository;
|
||||
import org.apache.maven.model.RepositoryBase;
|
||||
import org.apache.maven.plugin.AbstractMojo;
|
||||
import org.apache.maven.plugin.MojoExecutionException;
|
||||
import org.apache.maven.plugin.MojoFailureException;
|
||||
import org.apache.maven.plugins.annotations.Mojo;
|
||||
import org.apache.maven.plugins.annotations.Parameter;
|
||||
import org.apache.maven.project.MavenProject;
|
||||
|
||||
import org.springframework.cloud.dataflow.app.plugin.generator.AppDefinition;
|
||||
import org.springframework.cloud.dataflow.app.plugin.generator.BinderDefinition;
|
||||
import org.springframework.cloud.dataflow.app.plugin.generator.ProjectGenerator;
|
||||
import org.springframework.cloud.dataflow.app.plugin.generator.ProjectGeneratorProperties;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* @author Christian Tzolov
|
||||
* @author David Turanski
|
||||
* @author Soby Chacko
|
||||
*/
|
||||
@Mojo(name = "generate-app")
|
||||
public class SpringCloudStreamAppGeneratorMojo extends AbstractMojo {
|
||||
|
||||
private static final String DEPRECATED_WHITELIST_FILE_NAME = "dataflow-configuration-metadata-whitelist.properties";
|
||||
private static final String VISIBLE_PROPERTIES_FILE_NAME = "dataflow-configuration-metadata.properties";
|
||||
private static final String CONFIGURATION_PROPERTIES_CLASSES = "configuration-properties.classes";
|
||||
private static final String CONFIGURATION_PROPERTIES_NAMES = "configuration-properties.names";
|
||||
|
||||
@Parameter(defaultValue = "${project}", readonly = true, required = true)
|
||||
private MavenProject project;
|
||||
|
||||
@Parameter(defaultValue = "${project.resources[0].directory}", readonly = true, required = true)
|
||||
private File projectResourcesDir;
|
||||
|
||||
@Parameter(defaultValue = "./apps", required = true)
|
||||
private String generatedProjectHome;
|
||||
|
||||
@Parameter
|
||||
private Global global = new Global();
|
||||
|
||||
@Parameter(required = true)
|
||||
private Application application;
|
||||
|
||||
@Parameter
|
||||
private Map<String, Binder> binders = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public void execute() throws MojoFailureException, MojoExecutionException {
|
||||
|
||||
// ----------------------------------------------------------------------------------------------------------
|
||||
// Application Configuration
|
||||
// ----------------------------------------------------------------------------------------------------------
|
||||
|
||||
AppDefinition app = new AppDefinition();
|
||||
|
||||
String bootVersion = StringUtils.isEmpty(this.application.getBootVersion()) ?
|
||||
this.global.getApplication().getBootVersion() : this.application.getBootVersion();
|
||||
if (StringUtils.isEmpty(bootVersion)) {
|
||||
throw new MojoExecutionException("The application.bootVersion parameter is required!");
|
||||
}
|
||||
app.setSpringBootVersion(bootVersion);
|
||||
|
||||
String applicationName = StringUtils.isEmpty(this.application.getName()) ?
|
||||
this.global.getApplication().getName() : this.application.getName();
|
||||
if (StringUtils.isEmpty(applicationName)) {
|
||||
throw new MojoExecutionException("The application.name parameter is required!");
|
||||
}
|
||||
app.setName(applicationName);
|
||||
|
||||
AppDefinition.AppType applicationType = (this.application.getType() == null) ?
|
||||
this.global.getApplication().getType() : this.application.getType();
|
||||
if (applicationType == null) {
|
||||
throw new MojoExecutionException("The application.type parameter is required!");
|
||||
}
|
||||
app.setType(applicationType);
|
||||
|
||||
String applicationVersion = StringUtils.isEmpty(this.application.getVersion()) ?
|
||||
this.global.getApplication().getVersion() : this.application.getVersion();
|
||||
if (StringUtils.isEmpty(applicationVersion)) {
|
||||
throw new MojoExecutionException("The application.version parameter is required!");
|
||||
}
|
||||
app.setVersion(applicationVersion);
|
||||
|
||||
String applicationConfigClass = StringUtils.isEmpty(this.application.getConfigClass()) ?
|
||||
this.global.getApplication().getConfigClass() : this.application.getConfigClass();
|
||||
app.setConfigClass(applicationConfigClass); // TODO is applicationConfigClass a required parameter?
|
||||
|
||||
String applicationGroupId = StringUtils.isEmpty(this.application.getGroupId()) ?
|
||||
this.global.getApplication().getGroupId() : this.application.getGroupId();
|
||||
app.setGroupId(applicationGroupId); // optional parameter
|
||||
|
||||
String applicationFunctionDefinition = StringUtils.isEmpty(this.application.getFunctionDefinition()) ?
|
||||
this.global.getApplication().getFunctionDefinition() : this.application.getFunctionDefinition();
|
||||
app.setFunctionDefinition(applicationFunctionDefinition); //TODO is applicationFunctionDefinition required?
|
||||
|
||||
String metadataMavenPluginVersion = StringUtils.isEmpty(this.application.getMetadata().getMavenPluginVersion()) ?
|
||||
this.global.getApplication().getMetadata().getMavenPluginVersion() : this.application.getMetadata().getMavenPluginVersion();
|
||||
if (StringUtils.isEmpty(metadataMavenPluginVersion)) {
|
||||
throw new MojoExecutionException("The application.metadata.mavenPluginVersion parameter is required!");
|
||||
}
|
||||
app.getMetadata().setMavenPluginVersion(metadataMavenPluginVersion);
|
||||
|
||||
List<String> allSourceTypeFilters = new ArrayList<>(this.global.getApplication().getMetadata().getSourceTypeFilters());
|
||||
allSourceTypeFilters.addAll(this.application.getMetadata().getSourceTypeFilters());
|
||||
List<String> allNamedFilters = new ArrayList<>(this.global.getApplication().getMetadata().getNameFilters());
|
||||
allNamedFilters.addAll(this.application.getMetadata().getNameFilters());
|
||||
|
||||
this.populateVisiblePropertiesFromFile(allSourceTypeFilters, allNamedFilters);
|
||||
|
||||
if (!CollectionUtils.isEmpty(allSourceTypeFilters)) {
|
||||
app.getMetadata().setSourceTypeFilters(allSourceTypeFilters);
|
||||
}
|
||||
|
||||
if (!CollectionUtils.isEmpty(allNamedFilters)) {
|
||||
app.getMetadata().setNameFilters(allNamedFilters);
|
||||
}
|
||||
|
||||
// Application properties
|
||||
Map<String, String> allApplicationProperties = new TreeMap<>(this.global.getApplication().getProperties());
|
||||
allApplicationProperties.putAll(this.application.getProperties());
|
||||
app.setProperties(allApplicationProperties.entrySet().stream()
|
||||
.map(e -> e.getKey() + "=" + (StringUtils.hasText(e.getValue()) ?
|
||||
e.getValue().replaceAll("^\"|\"$", "") : ""))
|
||||
.collect(Collectors.toList()));
|
||||
|
||||
// Maven properties
|
||||
Map<String, String> allMavenProperties = new TreeMap<>(this.global.getApplication().getMaven().getProperties());
|
||||
allMavenProperties.putAll(this.application.getMaven().getProperties());
|
||||
app.getMaven().setProperties(allMavenProperties.entrySet().stream()
|
||||
.map(es -> "<" + es.getKey() + ">" + (StringUtils.hasText(es.getValue()) ?
|
||||
es.getValue().replaceAll("^\"|\"$", "") : "") + "</" + es.getKey() + ">")
|
||||
.collect(Collectors.toList()));
|
||||
|
||||
//Maven BOM. For DependencyManagement it is important to retain the exact definition order!
|
||||
// Override the global dependencies with matching app dependency definitions. Retain the definition order!
|
||||
List<Dependency> allDeps = this.global.getApplication().getMaven().getDependencyManagement().stream()
|
||||
.map(globalDep -> this.application.getMaven().getDependencyManagement().stream()
|
||||
.filter(d -> isSameArtifact(globalDep, d))
|
||||
.findFirst().orElse(globalDep))
|
||||
.collect(Collectors.toList());
|
||||
|
||||
// Add remaining app dependencies that have not be used for overriding. Retain the order!
|
||||
this.application.getMaven().getDependencyManagement()
|
||||
.forEach(appDep -> {
|
||||
if (allDeps.stream().noneMatch(d -> isSameArtifact(appDep, d))) {
|
||||
allDeps.add(appDep);
|
||||
}
|
||||
});
|
||||
|
||||
app.getMaven().setDependencyManagement(allDeps.stream()
|
||||
.filter(Objects::nonNull)
|
||||
.peek(dependency -> {
|
||||
dependency.setScope("import");
|
||||
dependency.setType("pom");
|
||||
})
|
||||
.map(MavenXmlWriter::toXml)
|
||||
.map(xml -> MavenXmlWriter.indent(xml, 12))
|
||||
.collect(Collectors.toList()));
|
||||
|
||||
//Maven Dependencies
|
||||
Map<String, Dependency> allDependenciesMap = this.global.getApplication().getMaven().getDependencies().stream()
|
||||
.collect(Collectors.toMap(d -> d.getGroupId() + ":" + d.getArtifactId(), d -> d));
|
||||
// Ensure that for dependencies with same maven coordinates that application definition overrides the global one.
|
||||
allDependenciesMap.putAll(this.application.getMaven().getDependencies().stream()
|
||||
.collect(Collectors.toMap(d -> d.getGroupId() + ":" + d.getArtifactId(), d -> d)));
|
||||
app.getMaven().setDependencies(allDependenciesMap.values().stream()
|
||||
.map(MavenXmlWriter::toXml)
|
||||
.map(xml -> MavenXmlWriter.indent(xml, 8))
|
||||
.collect(Collectors.toList()));
|
||||
|
||||
//Maven Plugins
|
||||
Map<String, Plugin> allPluginsMap = this.global.getApplication().getMaven().getPlugins().stream()
|
||||
.collect(Collectors.toMap(p -> p.getGroupId() + ":" + p.getArtifactId(), p -> p));
|
||||
// Ensure that for plugins with same maven coordinates that application definition overrides the global one.
|
||||
allPluginsMap.putAll(this.application.getMaven().getPlugins().stream()
|
||||
.collect(Collectors.toMap(p -> p.getGroupId() + ":" + p.getArtifactId(), p -> p)));
|
||||
app.getMaven().setPlugins(allPluginsMap.values().stream()
|
||||
.map(MavenXmlWriter::toXml)
|
||||
.map(d -> MavenXmlWriter.indent(d, 12))
|
||||
.collect(Collectors.toList()));
|
||||
|
||||
// Maven Repositories
|
||||
Map<String, Repository> allRepositoriesMap = this.global.getApplication().getMaven().getRepositories().stream()
|
||||
.collect(Collectors.toMap(RepositoryBase::getId, r -> r));
|
||||
// Ensure that for repos with same maven coordinates that application definition overrides the global one.
|
||||
allRepositoriesMap.putAll(this.application.getMaven().getRepositories().stream()
|
||||
.collect(Collectors.toMap(RepositoryBase::getId, r -> r)));
|
||||
app.getMaven().setRepositories(allRepositoriesMap.values().stream()
|
||||
.map(MavenXmlWriter::toXml)
|
||||
.map(d -> MavenXmlWriter.indent(d, 12))
|
||||
.collect(Collectors.toList()));
|
||||
|
||||
// Container Image configuration
|
||||
AppDefinition.ContainerImageFormat containerImageFormat = (this.application.getContainerImage().getFormat() != null) ?
|
||||
this.application.getContainerImage().getFormat() : this.global.getApplication().getContainerImage().getFormat();
|
||||
containerImageFormat = (containerImageFormat == null) ? AppDefinition.ContainerImageFormat.Docker : containerImageFormat;
|
||||
app.getContainerImage().setFormat(containerImageFormat);
|
||||
|
||||
// TODO how to choose between global an app metadata enabling?
|
||||
app.getContainerImage().setEnableMetadata(this.application.getContainerImage().isEnableMetadata());
|
||||
|
||||
if (StringUtils.hasText(this.application.getContainerImage().getOrgName())) {
|
||||
app.getContainerImage().setOrgName(this.application.getContainerImage().getOrgName());
|
||||
}
|
||||
else if (StringUtils.hasText(this.global.getApplication().getContainerImage().getOrgName())) {
|
||||
app.getContainerImage().setOrgName(this.global.getApplication().getContainerImage().getOrgName());
|
||||
}
|
||||
|
||||
app.getContainerImage().setTag(applicationVersion);
|
||||
|
||||
if (StringUtils.hasText(this.application.getContainerImage().getBaseImage())) {
|
||||
app.getContainerImage().setBaseImage(this.application.getContainerImage().getBaseImage());
|
||||
}
|
||||
else if (StringUtils.hasText(this.global.getApplication().getContainerImage().getBaseImage())) {
|
||||
app.getContainerImage().setBaseImage(this.global.getApplication().getContainerImage().getBaseImage());
|
||||
}
|
||||
|
||||
// Generator Properties
|
||||
ProjectGeneratorProperties generatorProperties = new ProjectGeneratorProperties();
|
||||
|
||||
// ----------------------------------------------------------------------------------------------------------
|
||||
// Binders Configuration
|
||||
// ----------------------------------------------------------------------------------------------------------
|
||||
|
||||
Map<String, Binder> allBinders = new HashMap<>(this.global.getBinders());
|
||||
// Note: The Application concrete Binder definitions will replace any global
|
||||
// Binder definitions with the same names. E.g. you can replace but not extend global binders configurations.
|
||||
allBinders.putAll(this.binders);
|
||||
|
||||
if (CollectionUtils.isEmpty(allBinders)) {
|
||||
throw new MojoExecutionException("At least one Binder configuration is required!");
|
||||
}
|
||||
|
||||
// Converts Mojo's Binder configurations into BinderDefinitions.
|
||||
List<BinderDefinition> bindersDefinitions = allBinders.entrySet().stream()
|
||||
.map(es -> {
|
||||
BinderDefinition bd = new BinderDefinition();
|
||||
bd.setName(es.getKey());
|
||||
bd.setProperties(es.getValue().getProperties());
|
||||
bd.getMaven().setProperties(es.getValue().getMaven().getProperties()
|
||||
.entrySet().stream()
|
||||
.map(pes -> "<" + pes.getKey() + ">" + pes.getValue() + "</" + pes.getKey() + ">")
|
||||
.collect(Collectors.toList()));
|
||||
bd.getMaven().setDependencies(
|
||||
es.getValue().getMaven().getDependencies().stream()
|
||||
.map(MavenXmlWriter::toXml)
|
||||
.map(xml -> MavenXmlWriter.indent(xml, 8))
|
||||
.collect(Collectors.toList()));
|
||||
bd.getMaven().setDependencyManagement(
|
||||
es.getValue().getMaven().getDependencyManagement().stream()
|
||||
.filter(Objects::nonNull)
|
||||
.peek(dependency -> {
|
||||
dependency.setScope("import");
|
||||
dependency.setType("pom");
|
||||
})
|
||||
.map(MavenXmlWriter::toXml)
|
||||
.map(xml -> MavenXmlWriter.indent(xml, 12))
|
||||
.collect(Collectors.toList()));
|
||||
bd.getMaven().setPlugins(
|
||||
es.getValue().getMaven().getPlugins().stream()
|
||||
.map(MavenXmlWriter::toXml)
|
||||
.map(d -> MavenXmlWriter.indent(d, 12))
|
||||
.collect(Collectors.toList()));
|
||||
bd.getMaven().setRepositories(es.getValue().getMaven().getRepositories().stream()
|
||||
.map(MavenXmlWriter::toXml)
|
||||
.map(d -> MavenXmlWriter.indent(d, 12))
|
||||
.collect(Collectors.toList()));
|
||||
|
||||
return bd;
|
||||
})
|
||||
.collect(Collectors.toList());
|
||||
|
||||
app.setBootPluginConfiguration(this.application.getBootPluginConfiguration());
|
||||
|
||||
// ----------------------------------------------------------------------------------------------------------
|
||||
// Project Generator
|
||||
// ----------------------------------------------------------------------------------------------------------
|
||||
|
||||
generatorProperties.setAppDefinition(app);
|
||||
generatorProperties.setBinderDefinitions(bindersDefinitions);
|
||||
generatorProperties.setOutputFolder(new File(this.generatedProjectHome));
|
||||
generatorProperties.setProjectResourcesDirectory(this.projectResourcesDir);
|
||||
|
||||
try {
|
||||
ProjectGenerator.getInstance().generate(generatorProperties);
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new MojoFailureException("Project generation failure", e);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isSameArtifact(Dependency dep1, Dependency dep2) {
|
||||
return dep1.getGroupId().equalsIgnoreCase(dep2.getGroupId())
|
||||
&& dep1.getArtifactId().equalsIgnoreCase(dep2.getArtifactId());
|
||||
}
|
||||
|
||||
/**
|
||||
* If the visible metadata properties files are provided in the source project, add theirs' type and name filters
|
||||
* to the existing visible configurations.
|
||||
*
|
||||
* @param sourceTypeFilters existing source type filters configured via the mojo parameter.
|
||||
* @param nameFilters existing name filters configured via the mojo parameter.
|
||||
*/
|
||||
private void populateVisiblePropertiesFromFile(List<String> sourceTypeFilters, List<String> nameFilters) {
|
||||
if (this.projectResourcesDir == null || !projectResourcesDir.exists()) {
|
||||
return;
|
||||
}
|
||||
Optional<Properties> optionalProperties =
|
||||
loadVisiblePropertiesFromResource(FileUtils.getFile(projectResourcesDir, "META-INF",
|
||||
VISIBLE_PROPERTIES_FILE_NAME));
|
||||
optionalProperties.ifPresent(properties -> {
|
||||
addToFilters(properties.getProperty(CONFIGURATION_PROPERTIES_CLASSES), sourceTypeFilters);
|
||||
addToFilters(properties.getProperty(CONFIGURATION_PROPERTIES_NAMES), nameFilters);
|
||||
});
|
||||
if (optionalProperties.isPresent()) {
|
||||
return;
|
||||
}
|
||||
|
||||
loadVisiblePropertiesFromResource(FileUtils.getFile(
|
||||
projectResourcesDir, "META-INF", DEPRECATED_WHITELIST_FILE_NAME))
|
||||
.ifPresent(properties -> {
|
||||
getLog().warn(DEPRECATED_WHITELIST_FILE_NAME + " is deprecated." +
|
||||
" Please use " + VISIBLE_PROPERTIES_FILE_NAME + " instead");
|
||||
addToFilters(properties.getProperty(CONFIGURATION_PROPERTIES_CLASSES), sourceTypeFilters);
|
||||
addToFilters(properties.getProperty(CONFIGURATION_PROPERTIES_NAMES), nameFilters);
|
||||
});
|
||||
}
|
||||
|
||||
private Optional<Properties> loadVisiblePropertiesFromResource(File visiblePropertiesFile) {
|
||||
if (visiblePropertiesFile.exists()) {
|
||||
Properties properties = new Properties();
|
||||
try (InputStream is = new FileInputStream(visiblePropertiesFile)) {
|
||||
properties.load(is);
|
||||
|
||||
}
|
||||
catch (Exception e) {
|
||||
return Optional.empty();
|
||||
}
|
||||
return Optional.of(properties);
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
private void addToFilters(String csvFilterProperties, List<String> filterList) {
|
||||
if (!StringUtils.isEmpty(csvFilterProperties)) {
|
||||
for (String filterProperty : csvFilterProperties.trim().split(",")) {
|
||||
if (StringUtils.hasText(filterProperty)) {
|
||||
if (!filterList.contains(filterProperty.trim())) {
|
||||
filterList.add(filterProperty.trim());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Section that allow to define Application and Binder configurations common across multiple applications
|
||||
* and binders.
|
||||
*/
|
||||
public static class Global {
|
||||
|
||||
private final Application application = new Application();
|
||||
|
||||
private final Map<String, Binder> binders = new HashMap<>();
|
||||
|
||||
public Application getApplication() {
|
||||
return application;
|
||||
}
|
||||
|
||||
public Map<String, Binder> getBinders() {
|
||||
return binders;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Allow defining the target application configuration, excluding the Binder specific configurations.
|
||||
*/
|
||||
public static class Application {
|
||||
|
||||
/**
|
||||
* Unique name of the application for the given type.
|
||||
* The generated binder specific, applications have names that combine this application name, type as well
|
||||
* as the name of the binder they are produced for.
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* Application type. Cloud be of type (source, processor, sink).
|
||||
*/
|
||||
private AppDefinition.AppType type;
|
||||
|
||||
/**
|
||||
* Version to be used for the generated application.
|
||||
*/
|
||||
private String version;
|
||||
|
||||
/**
|
||||
* The Spring Boot version the generated application is configured to inherit from.
|
||||
*/
|
||||
private String bootVersion;
|
||||
|
||||
/**
|
||||
* Spring configuration class used to instantiate the application.
|
||||
*/
|
||||
private String configClass;
|
||||
|
||||
/**
|
||||
* Group Id to use with the application.
|
||||
*/
|
||||
private String groupId = "org.springframework.cloud.stream.app";
|
||||
|
||||
/**
|
||||
* The Spring Cloud Function definition. Could be a composition definition as well.
|
||||
*/
|
||||
private String functionDefinition;
|
||||
|
||||
/**
|
||||
* Custom application properties to contribute to the generated application.properties file.
|
||||
*/
|
||||
private Map<String, String> properties = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Parameters used to tune the Application metadata generation.
|
||||
*/
|
||||
private final Metadata metadata = new Metadata();
|
||||
|
||||
private final ContainerImage containerImage = new ContainerImage();
|
||||
|
||||
private final Maven maven = new Maven();
|
||||
|
||||
private String bootPluginConfiguration;
|
||||
|
||||
public String getBootPluginConfiguration() {
|
||||
return bootPluginConfiguration;
|
||||
}
|
||||
|
||||
public void setBootPluginConfiguration(String bootPluginConfiguration) {
|
||||
this.bootPluginConfiguration = bootPluginConfiguration;
|
||||
}
|
||||
|
||||
public Map<String, String> getProperties() {
|
||||
return properties;
|
||||
}
|
||||
|
||||
public void setProperties(Map<String, String> properties) {
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
public Maven getMaven() {
|
||||
return maven;
|
||||
}
|
||||
|
||||
public Metadata getMetadata() {
|
||||
return metadata;
|
||||
}
|
||||
|
||||
public ContainerImage getContainerImage() {
|
||||
return containerImage;
|
||||
}
|
||||
|
||||
public String getBootVersion() {
|
||||
return bootVersion;
|
||||
}
|
||||
|
||||
public void setBootVersion(String bootVersion) {
|
||||
this.bootVersion = bootVersion;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public void setVersion(String version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
public AppDefinition.AppType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(AppDefinition.AppType type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getConfigClass() {
|
||||
return configClass;
|
||||
}
|
||||
|
||||
public void setConfigClass(String configClass) {
|
||||
this.configClass = configClass;
|
||||
}
|
||||
|
||||
public String getGroupId() {
|
||||
return groupId;
|
||||
}
|
||||
|
||||
public void setGroupId(String appGroupId) {
|
||||
this.groupId = appGroupId;
|
||||
}
|
||||
|
||||
public String getFunctionDefinition() {
|
||||
return (!StringUtils.isEmpty(this.functionDefinition)) ? this.functionDefinition :
|
||||
this.name + this.functionType();
|
||||
}
|
||||
|
||||
public void setFunctionDefinition(String functionDefinition) {
|
||||
this.functionDefinition = functionDefinition;
|
||||
}
|
||||
|
||||
private String functionType() {
|
||||
switch (this.type) {
|
||||
case processor:
|
||||
return "Function";
|
||||
case sink:
|
||||
return "Consumer";
|
||||
case source:
|
||||
return "Supplier";
|
||||
}
|
||||
throw new IllegalArgumentException("Unknown App type:" + this.type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Parameters used to tune the Application metadata generation. It allows to set a type or name based filters
|
||||
* that filer-in the subset all application configuration metadata. In addition to the explicitly specified
|
||||
* filters, the Mojo automatically populates the filters with values found in the
|
||||
* 'dataflow-configuration-metadata-whitelist.properties" or 'dataflow-configuration-metadata.properties' files.
|
||||
*
|
||||
* You can also specify the version of the metadata generation plugin.
|
||||
*/
|
||||
public static class Metadata {
|
||||
|
||||
/**
|
||||
* list of source types from application's configuration metadata to include in the visible metadata.
|
||||
*/
|
||||
private List<String> sourceTypeFilters = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* list of property names from application's configuration metadata to include in the visible metadata.
|
||||
*/
|
||||
private List<String> nameFilters = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Version of the metadata maven plugin to be used.
|
||||
*/
|
||||
private String mavenPluginVersion;
|
||||
|
||||
public List<String> getSourceTypeFilters() {
|
||||
return sourceTypeFilters;
|
||||
}
|
||||
|
||||
public void setSourceTypeFilters(List<String> sourceTypeFilters) {
|
||||
this.sourceTypeFilters = sourceTypeFilters;
|
||||
}
|
||||
|
||||
public List<String> getNameFilters() {
|
||||
return nameFilters;
|
||||
}
|
||||
|
||||
public void setNameFilters(List<String> nameFilters) {
|
||||
this.nameFilters = nameFilters;
|
||||
}
|
||||
|
||||
public String getMavenPluginVersion() {
|
||||
return mavenPluginVersion;
|
||||
}
|
||||
|
||||
public void setMavenPluginVersion(String mavenPluginVersion) {
|
||||
this.mavenPluginVersion = mavenPluginVersion;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Configuration for injection the application's visible, configuration metadata into the Container image.
|
||||
*/
|
||||
public static class ContainerImage {
|
||||
|
||||
/**
|
||||
* Target container image. Docker and OCI are supported. If not specified the Docker is selected.
|
||||
*/
|
||||
private AppDefinition.ContainerImageFormat format = null;
|
||||
|
||||
/**
|
||||
* Target container image organization name.
|
||||
*/
|
||||
private String orgName;
|
||||
|
||||
/**
|
||||
* Base images to be used by the target container image.
|
||||
*/
|
||||
private String baseImage;
|
||||
|
||||
/**
|
||||
* Enable or disable the inclusion of application's metadata into the image's labels.
|
||||
*/
|
||||
private boolean enableMetadata = true;
|
||||
|
||||
public AppDefinition.ContainerImageFormat getFormat() {
|
||||
return format;
|
||||
}
|
||||
|
||||
public void setFormat(AppDefinition.ContainerImageFormat format) {
|
||||
this.format = format;
|
||||
}
|
||||
|
||||
public String getOrgName() {
|
||||
return orgName;
|
||||
}
|
||||
|
||||
public void setOrgName(String orgName) {
|
||||
this.orgName = orgName;
|
||||
}
|
||||
|
||||
public boolean isEnableMetadata() {
|
||||
return enableMetadata;
|
||||
}
|
||||
|
||||
public void setEnableMetadata(boolean enableMetadata) {
|
||||
this.enableMetadata = enableMetadata;
|
||||
}
|
||||
|
||||
public String getBaseImage() {
|
||||
return baseImage;
|
||||
}
|
||||
|
||||
public void setBaseImage(String baseImage) {
|
||||
this.baseImage = baseImage;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Binder specific properties to be applied in addition to the {@link Application} parameters.
|
||||
*/
|
||||
public static class Binder {
|
||||
|
||||
/**
|
||||
* Application properties specific for the binder. Contributed to the generated application.properties file.
|
||||
*/
|
||||
private List<String> properties = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Binder specific maven configurations. Applied in addition to the {@link Application}'s maven configurations.
|
||||
*/
|
||||
private final Maven maven = new Maven();
|
||||
|
||||
|
||||
public Maven getMaven() {
|
||||
return maven;
|
||||
}
|
||||
|
||||
public List<String> getProperties() {
|
||||
return properties;
|
||||
}
|
||||
|
||||
public void setProperties(List<String> properties) {
|
||||
this.properties = properties;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Maven configuration used inside the {@link Application} and {@link Binder} configurations.
|
||||
*/
|
||||
public static class Maven {
|
||||
|
||||
/**
|
||||
* Custom maven properties. Contributed to the generated POM's properties section.
|
||||
*/
|
||||
private Map<String, String> properties = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Custom maven management dependencies. Contributed to the generated POM's dependencyManagement section.
|
||||
*/
|
||||
private List<Dependency> dependencyManagement = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Custom maven dependencies. Contributed to the generated POM's dependencies section.
|
||||
*/
|
||||
private List<Dependency> dependencies = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Custom maven plugins. Contributed to the generated POM's plugins section.
|
||||
*
|
||||
* Note: if the plugin definition uses a configuration block then the content must be wrapped within a
|
||||
* <pre>@code{
|
||||
* <![CDATA[ ... ]]>
|
||||
* }</pre> section! Find more: {@link MavenXmlWriter#toXml(Plugin)}.
|
||||
*/
|
||||
private List<Plugin> plugins = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Custom maven repositories. Contributed to the generated POM's repositories section.
|
||||
*/
|
||||
private List<Repository> repositories = new ArrayList<>();
|
||||
|
||||
public Map<String, String> getProperties() {
|
||||
return properties;
|
||||
}
|
||||
|
||||
public void setProperties(Map<String, String> properties) {
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
public List<Dependency> getDependencyManagement() {
|
||||
return dependencyManagement;
|
||||
}
|
||||
|
||||
public void setDependencyManagement(List<Dependency> dependencyManagement) {
|
||||
this.dependencyManagement = dependencyManagement;
|
||||
}
|
||||
|
||||
public List<Dependency> getDependencies() {
|
||||
return dependencies;
|
||||
}
|
||||
|
||||
public void setDependencies(List<Dependency> dependencies) {
|
||||
this.dependencies = dependencies;
|
||||
}
|
||||
|
||||
public List<Plugin> getPlugins() {
|
||||
return plugins;
|
||||
}
|
||||
|
||||
public void setPlugins(List<Plugin> plugins) {
|
||||
this.plugins = plugins;
|
||||
}
|
||||
|
||||
public List<Repository> getRepositories() {
|
||||
return repositories;
|
||||
}
|
||||
|
||||
public void setRepositories(List<Repository> repositories) {
|
||||
this.repositories = repositories;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,308 @@
|
||||
/*
|
||||
* Copyright 2020-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.dataflow.app.plugin.generator;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Application configurations used to parameterize the project templates.
|
||||
*
|
||||
* @author Christian Tzolov
|
||||
* @author Soby Chacko
|
||||
*/
|
||||
public class AppDefinition {
|
||||
|
||||
/**
|
||||
* Marker 'configClass' value that indicates that this is an autoconfiguration and the @Import statement should be
|
||||
* dropped.
|
||||
*/
|
||||
public static final String AUTOCONFIGURATION_MARKER = "AUTOCONFIGURATION";
|
||||
|
||||
/**
|
||||
* Application name.
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* Application type.
|
||||
*/
|
||||
private AppType type;
|
||||
|
||||
/**
|
||||
* Application version.
|
||||
*/
|
||||
private String version;
|
||||
|
||||
/**
|
||||
* Spring Boot version used as a parent by the application.
|
||||
*/
|
||||
private String springBootVersion;
|
||||
|
||||
/**
|
||||
* Application's backing Spring configuration class.
|
||||
*/
|
||||
private String configClass;
|
||||
|
||||
/**
|
||||
* Application's group ID.
|
||||
*/
|
||||
private String groupId;
|
||||
|
||||
/**
|
||||
* Spring Cloud Function definition.
|
||||
*/
|
||||
private String functionDefinition;
|
||||
|
||||
/**
|
||||
* Additional application properties.
|
||||
*/
|
||||
private List<String> properties = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Maven related configurations to be applied for this App definition.
|
||||
*/
|
||||
private final MavenDefinition maven = new MavenDefinition();
|
||||
|
||||
/**
|
||||
* ContainerImage related configurations to be applied for this App definition.
|
||||
*/
|
||||
private final ContainerImage containerImage = new ContainerImage();
|
||||
|
||||
/**
|
||||
* Application metadata related configurations to be applied for this App definition.
|
||||
*/
|
||||
private final Metadata metadata = new Metadata();
|
||||
|
||||
private String bootPluginConfiguration;
|
||||
|
||||
public String getBootPluginConfiguration() {
|
||||
return bootPluginConfiguration;
|
||||
}
|
||||
|
||||
public void setBootPluginConfiguration(String bootPluginConfiguration) {
|
||||
this.bootPluginConfiguration = bootPluginConfiguration;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public AppType getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(AppType type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public void setVersion(String version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
||||
public String getSpringBootVersion() {
|
||||
return springBootVersion;
|
||||
}
|
||||
|
||||
public void setSpringBootVersion(String springBootVersion) {
|
||||
this.springBootVersion = springBootVersion;
|
||||
}
|
||||
|
||||
public List<String> getProperties() {
|
||||
return properties;
|
||||
}
|
||||
|
||||
public void setProperties(List<String> properties) {
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
public MavenDefinition getMaven() {
|
||||
return maven;
|
||||
}
|
||||
|
||||
public ContainerImage getContainerImage() {
|
||||
return containerImage;
|
||||
}
|
||||
|
||||
public Metadata getMetadata() {
|
||||
return metadata;
|
||||
}
|
||||
|
||||
public boolean isSupplier() {
|
||||
return type == AppType.source;
|
||||
}
|
||||
|
||||
public boolean isConsumer() {
|
||||
return type == AppType.sink;
|
||||
}
|
||||
|
||||
public boolean isFunction() {
|
||||
return type == AppType.processor;
|
||||
}
|
||||
|
||||
public boolean isAutoconfiguration() {
|
||||
return AUTOCONFIGURATION_MARKER.equalsIgnoreCase(configClass.trim());
|
||||
}
|
||||
|
||||
public String getConfigClass() {
|
||||
return configClass;
|
||||
}
|
||||
|
||||
public void setConfigClass(String configClass) {
|
||||
this.configClass = configClass;
|
||||
}
|
||||
|
||||
public String getGroupId() {
|
||||
return groupId;
|
||||
}
|
||||
|
||||
public void setGroupId(String groupId) {
|
||||
this.groupId = groupId;
|
||||
}
|
||||
|
||||
public String getFunctionDefinition() {
|
||||
return functionDefinition;
|
||||
}
|
||||
|
||||
public void setFunctionDefinition(String functionDefinition) {
|
||||
this.functionDefinition = functionDefinition;
|
||||
}
|
||||
|
||||
public enum ContainerImageFormat {
|
||||
/**
|
||||
* Docker image format.
|
||||
*/
|
||||
Docker,
|
||||
/**
|
||||
* OCI format.
|
||||
*/
|
||||
OCI
|
||||
}
|
||||
|
||||
public enum AppType {
|
||||
/**
|
||||
* source type.
|
||||
*/
|
||||
source,
|
||||
/**
|
||||
* processor type.
|
||||
*/
|
||||
processor,
|
||||
/**
|
||||
* sink type.
|
||||
*/
|
||||
sink
|
||||
}
|
||||
|
||||
public static class ContainerImage {
|
||||
/**
|
||||
* Allow to generate either Docker or OCI image formats.
|
||||
*/
|
||||
private ContainerImageFormat format = ContainerImageFormat.Docker;
|
||||
|
||||
/**
|
||||
* True will attempt to inline the (white) filtered Spring Boot metadata as Base64 encoded property.
|
||||
*/
|
||||
private boolean enableMetadata = false;
|
||||
|
||||
private String orgName = "springcloudstream";
|
||||
|
||||
private String tag = "latest";
|
||||
|
||||
private String baseImage = "springcloud/baseimage:1.0.4";
|
||||
|
||||
public ContainerImageFormat getFormat() {
|
||||
return format;
|
||||
}
|
||||
|
||||
public void setFormat(ContainerImageFormat format) {
|
||||
this.format = format;
|
||||
}
|
||||
|
||||
public boolean isEnableMetadata() {
|
||||
return enableMetadata;
|
||||
}
|
||||
|
||||
public void setEnableMetadata(boolean enableMetadata) {
|
||||
this.enableMetadata = enableMetadata;
|
||||
}
|
||||
|
||||
public String getOrgName() {
|
||||
return orgName;
|
||||
}
|
||||
|
||||
public void setOrgName(String orgName) {
|
||||
this.orgName = orgName;
|
||||
}
|
||||
|
||||
public String getTag() {
|
||||
return tag;
|
||||
}
|
||||
|
||||
public void setTag(String tag) {
|
||||
this.tag = tag;
|
||||
}
|
||||
|
||||
public String getBaseImage() {
|
||||
return baseImage;
|
||||
}
|
||||
|
||||
public void setBaseImage(String baseImage) {
|
||||
this.baseImage = baseImage;
|
||||
}
|
||||
}
|
||||
|
||||
public static class Metadata {
|
||||
private List<String> sourceTypeFilters = new ArrayList<>();
|
||||
|
||||
private List<String> nameFilters = new ArrayList<>();
|
||||
|
||||
private String mavenPluginVersion;
|
||||
|
||||
public List<String> getSourceTypeFilters() {
|
||||
return sourceTypeFilters;
|
||||
}
|
||||
|
||||
public void setSourceTypeFilters(List<String> sourceTypeFilters) {
|
||||
this.sourceTypeFilters = sourceTypeFilters;
|
||||
}
|
||||
|
||||
public List<String> getNameFilters() {
|
||||
return nameFilters;
|
||||
}
|
||||
|
||||
public void setNameFilters(List<String> nameFilters) {
|
||||
this.nameFilters = nameFilters;
|
||||
}
|
||||
|
||||
public String getMavenPluginVersion() {
|
||||
return mavenPluginVersion;
|
||||
}
|
||||
|
||||
public void setMavenPluginVersion(String mavenPluginVersion) {
|
||||
this.mavenPluginVersion = mavenPluginVersion;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright 2020-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.dataflow.app.plugin.generator;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Binder configurations used to parameterize the project templates.
|
||||
*
|
||||
* @author Christian Tzolov
|
||||
*/
|
||||
public class BinderDefinition {
|
||||
|
||||
/**
|
||||
* Binder name.
|
||||
*/
|
||||
private String name;
|
||||
|
||||
/**
|
||||
* Binder specific, Maven configurations contributed to the generated poms.
|
||||
*/
|
||||
private final MavenDefinition maven = new MavenDefinition();
|
||||
|
||||
/**
|
||||
* Binder specific application properties contributed to the generated application.properties.
|
||||
*/
|
||||
private List<String> properties = new ArrayList<>();
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public MavenDefinition getMaven() {
|
||||
return maven;
|
||||
}
|
||||
|
||||
public List<String> getProperties() {
|
||||
return properties;
|
||||
}
|
||||
|
||||
public void setProperties(List<String> properties) {
|
||||
this.properties = properties;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright 2020-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.dataflow.app.plugin.generator;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Maven configurations used by the {@link AppDefinition} and {@link BinderDefinition} to parametrize the generated POMs.
|
||||
*
|
||||
* @author Christian Tzolov
|
||||
*/
|
||||
public class MavenDefinition {
|
||||
/**
|
||||
* Contributes the properties to the Maven's properties section.
|
||||
*/
|
||||
private List<String> properties = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Contributes the dependencyManagement entries to the Maven's dependencyManagement dependencies.
|
||||
*/
|
||||
private List<String> dependencyManagement = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Contributes the dependency entries to the Maven's dependencies section.
|
||||
*/
|
||||
private List<String> dependencies = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Contributes the plugin entries to the Maven's plugins section.
|
||||
*/
|
||||
private List<String> plugins = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Contributes the repository entries to the Maven's repositories section.
|
||||
*/
|
||||
private List<String> repositories = new ArrayList<>();
|
||||
|
||||
public List<String> getProperties() {
|
||||
return properties;
|
||||
}
|
||||
|
||||
public void setProperties(List<String> properties) {
|
||||
this.properties = properties;
|
||||
}
|
||||
|
||||
public List<String> getDependencyManagement() {
|
||||
return dependencyManagement;
|
||||
}
|
||||
|
||||
public void setDependencyManagement(List<String> dependencyManagement) {
|
||||
this.dependencyManagement = dependencyManagement;
|
||||
}
|
||||
|
||||
public List<String> getDependencies() {
|
||||
return dependencies;
|
||||
}
|
||||
|
||||
public void setDependencies(List<String> dependencies) {
|
||||
this.dependencies = dependencies;
|
||||
}
|
||||
|
||||
public List<String> getPlugins() {
|
||||
return plugins;
|
||||
}
|
||||
|
||||
public void setPlugins(List<String> plugins) {
|
||||
this.plugins = plugins;
|
||||
}
|
||||
|
||||
public List<String> getRepositories() {
|
||||
return repositories;
|
||||
}
|
||||
|
||||
public void setRepositories(List<String> repositories) {
|
||||
this.repositories = repositories;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,237 @@
|
||||
/*
|
||||
* Copyright 2020-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.dataflow.app.plugin.generator;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Properties;
|
||||
|
||||
import com.samskivert.mustache.Mustache;
|
||||
import com.samskivert.mustache.Template;
|
||||
import org.apache.commons.io.FileUtils;
|
||||
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* @author Christian Tzolov
|
||||
*/
|
||||
public final class ProjectGenerator {
|
||||
|
||||
private ProjectGenerator() {
|
||||
}
|
||||
|
||||
public static ProjectGenerator getInstance() {
|
||||
return new ProjectGenerator();
|
||||
}
|
||||
|
||||
// Utils
|
||||
public static File mkdirs(File dir) {
|
||||
if (!dir.exists()) {
|
||||
dir.mkdirs();
|
||||
}
|
||||
if (!dir.isDirectory()) {
|
||||
throw new IllegalStateException("Not a directory: " + dir);
|
||||
}
|
||||
return dir;
|
||||
}
|
||||
|
||||
public static void copy(String content, File file) throws IOException {
|
||||
Files.copy(new ByteArrayInputStream(content.getBytes()), file.toPath(), StandardCopyOption.REPLACE_EXISTING);
|
||||
}
|
||||
|
||||
public static String toPkg(String text) {
|
||||
return text.replace("-", ".");
|
||||
}
|
||||
|
||||
public static String capitalize(String text) {
|
||||
return text.substring(0, 1).toUpperCase() + text.substring(1);
|
||||
}
|
||||
|
||||
public static String camelCase(String text) {
|
||||
return Arrays.stream(text.split("-")).reduce("", (r, p) -> r + capitalize(p));
|
||||
}
|
||||
|
||||
public static File pkgToDir(File parent, String packageName) {
|
||||
String[] names = packageName.split("\\.");
|
||||
File result = parent;
|
||||
for (String p : names) {
|
||||
result = file(result, p);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static File file(File parent, String child) {
|
||||
return new File(parent, child);
|
||||
}
|
||||
|
||||
public void generate(ProjectGeneratorProperties generatorProperties) throws IOException {
|
||||
|
||||
Map<String, Object> modulesTemplateProperties = new HashMap<>();
|
||||
// register {{#capitalize}}...{{/capitalize}} function.
|
||||
modulesTemplateProperties.put("capitalize", (Mustache.Lambda) (frag, out) -> out.write(capitalize(frag.execute().trim())));
|
||||
// register {{#camelCase}}...{{/camelCase}} function.
|
||||
modulesTemplateProperties.put("camelCase", (Mustache.Lambda) (frag, out) -> out.write(camelCase(frag.execute().trim())));
|
||||
|
||||
modulesTemplateProperties.put("app", generatorProperties.getAppDefinition());
|
||||
modulesTemplateProperties.put("binders", generatorProperties.getBinders());
|
||||
|
||||
// ---------------------------------
|
||||
// Generate apps container POM
|
||||
// ---------------------------------
|
||||
File appParentDir = mkdirs(generatorProperties.getOutputFolder());
|
||||
copy(materialize("template/apps-modules-pom.xml", modulesTemplateProperties),
|
||||
file(appParentDir, "pom.xml"));
|
||||
// maven wrapper
|
||||
copyMavenWrapper(appParentDir);
|
||||
|
||||
// ---------------------------------
|
||||
// Generate App projects
|
||||
// ---------------------------------
|
||||
Assert.notEmpty(generatorProperties.getBinders(), "At least one Binder must be provided");
|
||||
for (BinderDefinition binder : generatorProperties.getBinders()) {
|
||||
generateAppProject(appParentDir, modulesTemplateProperties, generatorProperties.getAppDefinition(),
|
||||
generatorProperties.getProjectResourcesDirectory(), binder);
|
||||
}
|
||||
}
|
||||
|
||||
private void generateAppProject(File appRootDirectory, Map<String, Object> containerTemplateProperties,
|
||||
AppDefinition appDefinition, File projectResourcesDirectory, BinderDefinition binder) throws IOException {
|
||||
|
||||
String appClassName = String.format("%s%s%sApplication",
|
||||
camelCase(appDefinition.getName()),
|
||||
capitalize(appDefinition.getType().name()),
|
||||
capitalize(binder.getName()));
|
||||
|
||||
String appPackageName = String.format("%s.%s.%s.%s",
|
||||
appDefinition.getGroupId(),
|
||||
toPkg(appDefinition.getName()),
|
||||
appDefinition.getType(),
|
||||
binder.getName());
|
||||
|
||||
Map<String, Object> appTemplateProperties = new HashMap<>(containerTemplateProperties);
|
||||
|
||||
// Shortcut substitutions. Prevent complicated expressions in the templates.
|
||||
appTemplateProperties.put("app-class-name", appClassName);
|
||||
appTemplateProperties.put("app-package-name", appPackageName);
|
||||
appTemplateProperties.put("app-binder", binder);
|
||||
|
||||
// app POM
|
||||
File appDir =
|
||||
mkdirs(file(appRootDirectory, appDefinition.getName() + "-" + appDefinition.getType() + "-" + binder.getName()));
|
||||
|
||||
copy(materialize("template/app-pom.xml", appTemplateProperties), file(appDir, "pom.xml"));
|
||||
|
||||
File appMainSrcDir = mkdirs(pkgToDir(appDir, "src.main.java." + appPackageName));
|
||||
|
||||
File appMainResourceDir = mkdirs(pkgToDir(appDir, "src.main.resources"));
|
||||
|
||||
// copy the entire project's src/main/resources directory
|
||||
if (projectResourcesDirectory != null && projectResourcesDirectory.exists()) {
|
||||
FileUtils.copyDirectory(projectResourcesDirectory, appMainResourceDir);
|
||||
}
|
||||
|
||||
// application.properties
|
||||
String materializedAppProperties = materialize("template/app.properties", appTemplateProperties);
|
||||
// Note: the application properties file may already exist from the parent's project src/main/resources dir.
|
||||
File appPropertyFile = file(appMainResourceDir, "application.properties");
|
||||
//FileUtils.writeStringToFile(appPropertyFile, materializedAppProperties, "UTF8", true);
|
||||
Properties appProps = new Properties();
|
||||
if (appPropertyFile.exists()) {
|
||||
appProps.load(new FileInputStream(appPropertyFile));
|
||||
}
|
||||
Properties genAppProps = new Properties();
|
||||
genAppProps.load(new ByteArrayInputStream(materializedAppProperties.getBytes(StandardCharsets.UTF_8)));
|
||||
|
||||
// Generated properties override the inherited!
|
||||
appProps.putAll(genAppProps);
|
||||
appProps.store(new FileWriter(appPropertyFile), "App generator properties");
|
||||
|
||||
copy(materialize("template/App.java", appTemplateProperties),
|
||||
file(appMainSrcDir, appClassName + ".java"));
|
||||
|
||||
// TESTS
|
||||
File appTestSrcDir = mkdirs(pkgToDir(appDir, "src.test.java." + appPackageName));
|
||||
|
||||
copy(materialize("template/AppTests.java", appTemplateProperties),
|
||||
file(appTestSrcDir, appClassName + "Tests.java"));
|
||||
|
||||
// README
|
||||
copy(materialize("template/README.adoc", appTemplateProperties),
|
||||
file(appDir, "README.adoc"));
|
||||
|
||||
// maven wrapper
|
||||
copyMavenWrapper(appDir);
|
||||
}
|
||||
|
||||
private void copyMavenWrapper(File appDir) throws IOException {
|
||||
|
||||
// mvnw
|
||||
copyResource("template/mvnw", file(appDir, "mvnw"));
|
||||
file(appDir, "mvnw").setExecutable(true);
|
||||
|
||||
copyResource("template/mvnw.cmd", file(appDir, "mvnw.cmd"));
|
||||
|
||||
File dotMavenDir = mkdirs(new File(appDir, ".mvn"));
|
||||
|
||||
// .mvn/jvm.config
|
||||
copyResource("template/.mvn/jvm.config", file(dotMavenDir, "jvm.config"));
|
||||
|
||||
// .mvn/maven.config
|
||||
copyResource("template/.mvn/maven.config", file(dotMavenDir, "maven.config"));
|
||||
|
||||
File dotMavenWrapper = mkdirs(file(appDir, ".mvn/wrapper"));
|
||||
|
||||
// .mvn/wrapper/maven-wrapper.jar
|
||||
copyResource("template/.mvn/wrapper/maven-wrapper.jar",
|
||||
file(dotMavenWrapper, "maven-wrapper.jar"));
|
||||
|
||||
// .mvn/wrapper/maven-wrapper.properties
|
||||
copyResource("template/.mvn/wrapper/maven-wrapper.properties",
|
||||
file(dotMavenWrapper, "maven-wrapper.properties"));
|
||||
|
||||
// .mvn/wrapper/MavenWrapperDownloader.java
|
||||
copyResource("template/.mvn/wrapper/MavenWrapperDownloader.java",
|
||||
file(dotMavenWrapper, "MavenWrapperDownloader.java"));
|
||||
}
|
||||
|
||||
private String materialize(String templatePath, Map<String, Object> templateProperties) throws IOException {
|
||||
try (InputStreamReader resourcesTemplateReader = new InputStreamReader(
|
||||
Objects.requireNonNull(this.getClass().getClassLoader().getResourceAsStream(templatePath)))) {
|
||||
Template resourceTemplate = Mustache.compiler().escapeHTML(false).compile(resourcesTemplateReader);
|
||||
return resourceTemplate.execute(templateProperties);
|
||||
}
|
||||
}
|
||||
|
||||
private void copyResource(String resourcePath, File toFile) throws IOException {
|
||||
try (InputStream resourcesStream = Objects.requireNonNull(
|
||||
this.getClass().getClassLoader().getResourceAsStream(resourcePath))) {
|
||||
Files.copy(resourcesStream, toFile.toPath(), StandardCopyOption.REPLACE_EXISTING);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright 2020-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.dataflow.app.plugin.generator;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Christian Tzolov
|
||||
*/
|
||||
public class ProjectGeneratorProperties {
|
||||
|
||||
/**
|
||||
* Source, processor and sink application configuration.
|
||||
*/
|
||||
private AppDefinition appDefinition;
|
||||
|
||||
/**
|
||||
* Location where the project source files are written.
|
||||
*/
|
||||
private File outputFolder = new File("./target/output");
|
||||
|
||||
/**
|
||||
* List of binders to generate applications for.
|
||||
*/
|
||||
private List<BinderDefinition> binders;
|
||||
|
||||
/**
|
||||
* The location of a project's src/main/resources directory.
|
||||
*/
|
||||
private File projectResourcesDirectory;
|
||||
|
||||
public File getOutputFolder() {
|
||||
return outputFolder;
|
||||
}
|
||||
|
||||
public void setOutputFolder(File outputFolder) {
|
||||
this.outputFolder = outputFolder;
|
||||
}
|
||||
|
||||
public AppDefinition getAppDefinition() {
|
||||
return appDefinition;
|
||||
}
|
||||
|
||||
public void setAppDefinition(AppDefinition appDefinition) {
|
||||
this.appDefinition = appDefinition;
|
||||
}
|
||||
|
||||
public List<BinderDefinition> getBinders() {
|
||||
return binders;
|
||||
}
|
||||
|
||||
public void setBinderDefinitions(List<BinderDefinition> binders) {
|
||||
this.binders = binders;
|
||||
}
|
||||
|
||||
public File getProjectResourcesDirectory() {
|
||||
return projectResourcesDirectory;
|
||||
}
|
||||
|
||||
public void setProjectResourcesDirectory(File projectResourcesDirectory) {
|
||||
this.projectResourcesDirectory = projectResourcesDirectory;
|
||||
}
|
||||
}
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 63 KiB |
@@ -0,0 +1 @@
|
||||
-Xmx1024m -XX:CICompilerCount=1 -XX:TieredStopAtLevel=1 -Djava.security.egd=file:/dev/./urandom
|
||||
@@ -0,0 +1 @@
|
||||
-DaltSnapshotDeploymentRepository=repo.spring.io::default::https://repo.spring.io/libs-snapshot-local -P spring
|
||||
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
Licensed to the Apache Software Foundation (ASF) under one
|
||||
or more contributor license agreements. See the NOTICE file
|
||||
distributed with this work for additional information
|
||||
regarding copyright ownership. The ASF licenses this file
|
||||
to you under the Apache License, Version 2.0 (the
|
||||
"License"); you may not use this file except in compliance
|
||||
with the License. You may obtain a copy of the License at
|
||||
|
||||
https://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing,
|
||||
software distributed under the License is distributed on an
|
||||
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
KIND, either express or implied. See the License for the
|
||||
specific language governing permissions and limitations
|
||||
under the License.
|
||||
*/
|
||||
|
||||
import java.net.*;
|
||||
import java.io.*;
|
||||
import java.nio.channels.*;
|
||||
import java.util.Properties;
|
||||
|
||||
public class MavenWrapperDownloader {
|
||||
|
||||
/**
|
||||
* Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided.
|
||||
*/
|
||||
private static final String DEFAULT_DOWNLOAD_URL =
|
||||
"https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar";
|
||||
|
||||
/**
|
||||
* Path to the maven-wrapper.properties file, which might contain a downloadUrl property to
|
||||
* use instead of the default one.
|
||||
*/
|
||||
private static final String MAVEN_WRAPPER_PROPERTIES_PATH =
|
||||
".mvn/wrapper/maven-wrapper.properties";
|
||||
|
||||
/**
|
||||
* Path where the maven-wrapper.jar will be saved to.
|
||||
*/
|
||||
private static final String MAVEN_WRAPPER_JAR_PATH =
|
||||
".mvn/wrapper/maven-wrapper.jar";
|
||||
|
||||
/**
|
||||
* Name of the property which should be used to override the default download url for the wrapper.
|
||||
*/
|
||||
private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl";
|
||||
|
||||
public static void main(String args[]) {
|
||||
System.out.println("- Downloader started");
|
||||
File baseDirectory = new File(args[0]);
|
||||
System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath());
|
||||
|
||||
// If the maven-wrapper.properties exists, read it and check if it contains a custom
|
||||
// wrapperUrl parameter.
|
||||
File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH);
|
||||
String url = DEFAULT_DOWNLOAD_URL;
|
||||
if(mavenWrapperPropertyFile.exists()) {
|
||||
FileInputStream mavenWrapperPropertyFileInputStream = null;
|
||||
try {
|
||||
mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile);
|
||||
Properties mavenWrapperProperties = new Properties();
|
||||
mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream);
|
||||
url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url);
|
||||
} catch (IOException e) {
|
||||
System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'");
|
||||
} finally {
|
||||
try {
|
||||
if(mavenWrapperPropertyFileInputStream != null) {
|
||||
mavenWrapperPropertyFileInputStream.close();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
// Ignore ...
|
||||
}
|
||||
}
|
||||
}
|
||||
System.out.println("- Downloading from: : " + url);
|
||||
|
||||
File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH);
|
||||
if(!outputFile.getParentFile().exists()) {
|
||||
if(!outputFile.getParentFile().mkdirs()) {
|
||||
System.out.println(
|
||||
"- ERROR creating output direcrory '" + outputFile.getParentFile().getAbsolutePath() + "'");
|
||||
}
|
||||
}
|
||||
System.out.println("- Downloading to: " + outputFile.getAbsolutePath());
|
||||
try {
|
||||
downloadFileFromURL(url, outputFile);
|
||||
System.out.println("Done");
|
||||
System.exit(0);
|
||||
} catch (Throwable e) {
|
||||
System.out.println("- Error downloading");
|
||||
e.printStackTrace();
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
private static void downloadFileFromURL(String urlString, File destination) throws Exception {
|
||||
URL website = new URL(urlString);
|
||||
ReadableByteChannel rbc;
|
||||
rbc = Channels.newChannel(website.openStream());
|
||||
FileOutputStream fos = new FileOutputStream(destination);
|
||||
fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE);
|
||||
fos.close();
|
||||
rbc.close();
|
||||
}
|
||||
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1 @@
|
||||
distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.5.4/apache-maven-3.5.4-bin.zip
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2019-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package {{app-package-name}};
|
||||
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
|
||||
@SpringBootApplication
|
||||
{{^app.autoconfiguration}}
|
||||
@Import({ {{app.configClass}} })
|
||||
{{/app.autoconfiguration}}
|
||||
public class {{app-class-name}} {
|
||||
|
||||
public static void main(String[] args) {
|
||||
SpringApplication.run({{app-class-name}}.class, args);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* Copyright 2019-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package {{app-package-name}};
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
|
||||
@SpringBootTest
|
||||
public class {{app-class-name}}Tests {
|
||||
|
||||
@Test
|
||||
public void contextLoads() {
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
= Spring Cloud Stream {{#camelCase}}{{app.name}}{{/camelCase}} {{#capitalize}}{{app.type}}{{/capitalize}} {{#capitalize}}{{app-binder.name}}{{/capitalize}} Binder Application
|
||||
@@ -0,0 +1,309 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
|
||||
xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-parent</artifactId>
|
||||
<version>{{app.springBootVersion}}</version>
|
||||
<relativePath></relativePath>
|
||||
</parent>
|
||||
<groupId>{{app.groupId}}</groupId>
|
||||
<artifactId>{{app.name}}-{{app.type}}-{{app-binder.name}}</artifactId>
|
||||
<version>{{app.version}}</version>
|
||||
<name>{{app.name}}-{{app.type}}-{{app-binder.name}}</name>
|
||||
<description>Spring Cloud Stream {{#camelCase}}{{app.name}}{{/camelCase}} {{#capitalize}}{{app.type}}{{/capitalize}} {{#capitalize}}{{app-binder.name}}{{/capitalize}} Binder Application
|
||||
</description>
|
||||
|
||||
<distributionManagement>
|
||||
<repository>
|
||||
<id>repo.spring.io</id>
|
||||
<name>Spring Release Repository</name>
|
||||
<url>https://repo.spring.io/libs-release-local</url>
|
||||
</repository>
|
||||
<snapshotRepository>
|
||||
<id>repo.spring.io</id>
|
||||
<name>Spring Snapshot Repository</name>
|
||||
<url>https://repo.spring.io/libs-snapshot-local</url>
|
||||
</snapshotRepository>
|
||||
</distributionManagement>
|
||||
|
||||
<properties>
|
||||
<skipTests>true</skipTests>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<!-- (begin) maven properties -->
|
||||
{{#app.maven.properties}}
|
||||
{{this}}
|
||||
{{/app.maven.properties}}
|
||||
|
||||
{{#app-binder.maven.properties}}
|
||||
{{this}}
|
||||
{{/app-binder.maven.properties}}
|
||||
<!-- (end) maven properties -->
|
||||
</properties>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<!-- (begin) managed dependencies -->
|
||||
{{#app-binder.maven.dependencyManagement}}
|
||||
{{this}}
|
||||
{{/app-binder.maven.dependencyManagement}}
|
||||
|
||||
{{#app.maven.dependencyManagement}}
|
||||
{{this}}
|
||||
{{/app.maven.dependencyManagement}}
|
||||
<!-- (end) managed dependencies -->
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<dependencies>
|
||||
<!-- (begin) additional dependencies -->
|
||||
{{#app.maven.dependencies}}
|
||||
{{this}}
|
||||
{{/app.maven.dependencies}}
|
||||
|
||||
{{#app-binder.maven.dependencies}}
|
||||
{{this}}
|
||||
{{/app-binder.maven.dependencies}}
|
||||
<!-- (end) additional dependencies -->
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<repositories>
|
||||
<!-- (begin) additional repositories -->
|
||||
{{#app.maven.repositories}}
|
||||
{{this}}
|
||||
{{/app.maven.repositories}}
|
||||
|
||||
{{#app-binder.maven.repositories}}
|
||||
{{this}}
|
||||
{{/app-binder.maven.repositories}}
|
||||
<!-- (end) additional repositories -->
|
||||
|
||||
<repository>
|
||||
<snapshots>
|
||||
<enabled>true</enabled>
|
||||
</snapshots>
|
||||
<id>spring-snapshots</id>
|
||||
<name>Spring Snapshots</name>
|
||||
<url>https://repo.spring.io/snapshot</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
<id>spring-milestones</id>
|
||||
<name>Spring Milestones</name>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<pluginRepositories>
|
||||
<pluginRepository>
|
||||
<snapshots>
|
||||
<enabled>true</enabled>
|
||||
</snapshots>
|
||||
<id>spring-snapshots</id>
|
||||
<name>Spring Snapshots</name>
|
||||
<url>https://repo.spring.io/snapshot</url>
|
||||
</pluginRepository>
|
||||
<pluginRepository>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
<id>spring-milestones</id>
|
||||
<name>Spring Milestones</name>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
</pluginRepository>
|
||||
</pluginRepositories>
|
||||
<build>
|
||||
<plugins>
|
||||
<!-- (begin) additional plugins -->
|
||||
{{#app.maven.plugins}}
|
||||
{{this}}
|
||||
{{/app.maven.plugins}}
|
||||
|
||||
{{#app-binder.maven.plugins}}
|
||||
{{this}}
|
||||
{{/app-binder.maven.plugins}}
|
||||
<!-- (end) additional plugins -->
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
{{#app.bootPluginConfiguration}}
|
||||
<configuration>
|
||||
{{this}}
|
||||
</configuration>
|
||||
{{/app.bootPluginConfiguration}}
|
||||
</plugin>
|
||||
|
||||
<plugin>
|
||||
<groupId>com.google.cloud.tools</groupId>
|
||||
<artifactId>jib-maven-plugin</artifactId>
|
||||
<version>3.3.0</version>
|
||||
<configuration>
|
||||
<from>
|
||||
<image>{{app.containerImage.baseImage}}</image>
|
||||
</from>
|
||||
<to>
|
||||
<image>{{app.containerImage.orgName}}/${project.artifactId}:{{app.containerImage.tag}}</image>
|
||||
</to>
|
||||
<container>
|
||||
<creationTime>USE_CURRENT_TIMESTAMP</creationTime>
|
||||
<format>{{app.containerImage.format}}</format>
|
||||
{{#app.containerImage.enableMetadata}}
|
||||
<labels>
|
||||
<org.springframework.cloud.dataflow.spring-configuration-metadata.json>
|
||||
${org.springframework.cloud.dataflow.spring.configuration.metadata.json}
|
||||
</org.springframework.cloud.dataflow.spring-configuration-metadata.json>
|
||||
<application.name>${project.artifactId}</application.name>
|
||||
<application.version>${project.version}</application.version>
|
||||
</labels>
|
||||
{{/app.containerImage.enableMetadata}}
|
||||
</container>
|
||||
</configuration>
|
||||
</plugin>
|
||||
|
||||
{{#app.containerImage.enableMetadata}}
|
||||
<!--
|
||||
Use of properties-maven-plugin to load the encoded metadata properties created by the jib-maven-plugin
|
||||
Use: Use: ./mvnw clean install jib:dockerBuild or ./mvnw clean install jib:build
|
||||
-->
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>properties-maven-plugin</artifactId>
|
||||
<version>1.0.0</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<phase>process-classes</phase>
|
||||
<goals>
|
||||
<goal>read-project-properties</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<files>
|
||||
<file>
|
||||
${project.build.outputDirectory}/META-INF/spring-configuration-metadata-encoded.properties
|
||||
</file>
|
||||
</files>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
{{/app.containerImage.enableMetadata}}
|
||||
|
||||
<plugin>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-dataflow-apps-metadata-plugin</artifactId>
|
||||
<version>{{app.metadata.mavenPluginVersion}}</version>
|
||||
<configuration>
|
||||
{{#app.containerImage.enableMetadata}}
|
||||
<storeFilteredMetadata>true</storeFilteredMetadata>
|
||||
<metadataFilter>
|
||||
<names>
|
||||
{{#app.metadataNameFilters}}
|
||||
<filter>{{this}}</filter>
|
||||
{{/app.metadataNameFilters}}
|
||||
</names>
|
||||
<sourceTypes>
|
||||
{{#app.metadata.sourceTypeFilters}}
|
||||
<filter>{{this}}</filter>
|
||||
{{/app.metadata.sourceTypeFilters}}
|
||||
</sourceTypes>
|
||||
</metadataFilter>
|
||||
{{/app.containerImage.enableMetadata}}
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>aggregate-metadata</id>
|
||||
<phase>compile</phase>
|
||||
<goals>
|
||||
<goal>aggregate-metadata</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<version>2.21.0</version>
|
||||
<configuration>
|
||||
<skipTests>${skipTests}</skipTests>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-javadoc-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>javadoc</id>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<quiet>true</quiet>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-source-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>attach-sources</id>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>milestone</id>
|
||||
<distributionManagement>
|
||||
<repository>
|
||||
<id>repo.spring.io</id>
|
||||
<name>Spring Milestone Repository</name>
|
||||
<url>https://repo.spring.io/libs-milestone-local</url>
|
||||
</repository>
|
||||
</distributionManagement>
|
||||
</profile>
|
||||
<profile>
|
||||
<id>central</id>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-gpg-plugin</artifactId>
|
||||
<version>1.6</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>sign-artifacts</id>
|
||||
<phase>verify</phase>
|
||||
<goals>
|
||||
<goal>sign</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<distributionManagement>
|
||||
<repository>
|
||||
<id>sonatype-nexus-staging</id>
|
||||
<name>Nexus Release Repository</name>
|
||||
<url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
|
||||
</repository>
|
||||
<snapshotRepository>
|
||||
<id>sonatype-nexus-snapshots</id>
|
||||
<name>Sonatype Nexus Snapshots</name>
|
||||
<url>https://oss.sonatype.org/content/repositories/snapshots/</url>
|
||||
</snapshotRepository>
|
||||
</distributionManagement>
|
||||
</profile>
|
||||
</profiles>
|
||||
</project>
|
||||
@@ -0,0 +1,30 @@
|
||||
spring.application.name=${vcap.application.name:{{app.name}}-{{app.type}}}
|
||||
info.app.name=@project.artifactId@
|
||||
info.app.description=@project.description@
|
||||
info.app.version=@project.version@
|
||||
management.endpoints.web.exposure.include=health,info,bindings
|
||||
management.endpoints.web.discovery.enabled=true
|
||||
management.info.env.enabled=true
|
||||
spring.cloud.function.definition={{app.functionDefinition}}
|
||||
|
||||
{{#app.consumer}}
|
||||
spring.cloud.stream.function.bindings.{{app.functionDefinition}}-in-0=input
|
||||
{{/app.consumer}}
|
||||
|
||||
{{#app.supplier}}
|
||||
spring.cloud.stream.function.bindings.{{app.functionDefinition}}-out-0=output
|
||||
{{/app.supplier}}
|
||||
|
||||
{{#app.function}}
|
||||
spring.cloud.stream.function.bindings.{{app.functionDefinition}}-in-0=input
|
||||
spring.cloud.stream.function.bindings.{{app.functionDefinition}}-out-0=output
|
||||
{{/app.function}}
|
||||
|
||||
{{#app.properties}}
|
||||
{{this}}
|
||||
{{/app.properties}}
|
||||
|
||||
{{#app-binder.properties}}
|
||||
{{this}}
|
||||
{{/app-binder.properties}}
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>{{app.groupId}}</groupId>
|
||||
<artifactId>{{app.name}}-{{app.type}}-apps</artifactId>
|
||||
<version>{{app.version}}</version>
|
||||
<packaging>pom</packaging>
|
||||
|
||||
<name>Apps Modules</name>
|
||||
<description>Parent project for generated apps project modules</description>
|
||||
<url>http://spring.io/spring-cloud</url>
|
||||
<licenses>
|
||||
<license>
|
||||
<name>Apache License, Version 2.0</name>
|
||||
<url>http://www.apache.org/licenses/LICENSE-2.0</url>
|
||||
<comments>Copyright 2014-2020 the original author or authors.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied.
|
||||
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.</comments>
|
||||
</license>
|
||||
</licenses>
|
||||
<developers>
|
||||
<developer>
|
||||
<id>schacko</id>
|
||||
<name>Soby Chacko</name>
|
||||
<email>schacko at pivotal.io</email>
|
||||
<organization>Pivotal Software, Inc.</organization>
|
||||
<organizationUrl>http://www.spring.io</organizationUrl>
|
||||
<roles>
|
||||
<role>developer</role>
|
||||
</roles>
|
||||
</developer>
|
||||
<developer>
|
||||
<id>tzolov</id>
|
||||
<name>Christian Tzolov</name>
|
||||
<email>ctzolov at pivotal.io</email>
|
||||
<organization>Pivotal Software, Inc.</organization>
|
||||
<organizationUrl>http://www.spring.io</organizationUrl>
|
||||
<roles>
|
||||
<role>developer</role>
|
||||
</roles>
|
||||
</developer>
|
||||
</developers>
|
||||
|
||||
<modules>
|
||||
{{#binders}}
|
||||
<module>{{app.name}}-{{app.type}}-{{this.name}}</module>
|
||||
{{/binders}}
|
||||
</modules>
|
||||
|
||||
<scm>
|
||||
<connection>scm:git:git://github.com/spring-cloud/spring-cloud-stream-app-starters.git</connection>
|
||||
<developerConnection>scm:git:ssh://git@github.com/spring-cloud/spring-cloud-stream-app-starters.git</developerConnection>
|
||||
<url>https://github.com/spring-cloud/spring-cloud-stream-app-starters</url>
|
||||
</scm>
|
||||
<distributionManagement>
|
||||
<repository>
|
||||
<id>repo.spring.io</id>
|
||||
<name>Spring Release Repository</name>
|
||||
<url>https://repo.spring.io/libs-release-local</url>
|
||||
</repository>
|
||||
<snapshotRepository>
|
||||
<id>repo.spring.io</id>
|
||||
<name>Spring Snapshot Repository</name>
|
||||
<url>https://repo.spring.io/libs-snapshot-local</url>
|
||||
</snapshotRepository>
|
||||
</distributionManagement>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>com.google.cloud.tools</groupId>
|
||||
<artifactId>jib-maven-plugin</artifactId>
|
||||
<version>3.3.0</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>milestone</id>
|
||||
<distributionManagement>
|
||||
<repository>
|
||||
<id>repo.spring.io</id>
|
||||
<name>Spring Milestone Repository</name>
|
||||
<url>https://repo.spring.io/libs-milestone-local</url>
|
||||
</repository>
|
||||
</distributionManagement>
|
||||
</profile>
|
||||
</profiles>
|
||||
|
||||
</project>
|
||||
254
spring-cloud-dataflow-apps-plugin/spring-cloud-dataflow-apps-generator-plugin/src/main/resources/template/mvnw
vendored
Executable file
254
spring-cloud-dataflow-apps-plugin/spring-cloud-dataflow-apps-generator-plugin/src/main/resources/template/mvnw
vendored
Executable file
@@ -0,0 +1,254 @@
|
||||
#!/bin/sh
|
||||
# ----------------------------------------------------------------------------
|
||||
# Licensed to the Apache Software Foundation (ASF) under one
|
||||
# or more contributor license agreements. See the NOTICE file
|
||||
# distributed with this work for additional information
|
||||
# regarding copyright ownership. The ASF licenses this file
|
||||
# to you under the Apache License, Version 2.0 (the
|
||||
# "License"); you may not use this file except in compliance
|
||||
# with the License. You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing,
|
||||
# software distributed under the License is distributed on an
|
||||
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
# KIND, either express or implied. See the License for the
|
||||
# specific language governing permissions and limitations
|
||||
# under the License.
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
# ----------------------------------------------------------------------------
|
||||
# Maven2 Start Up Batch script
|
||||
#
|
||||
# Required ENV vars:
|
||||
# ------------------
|
||||
# JAVA_HOME - location of a JDK home dir
|
||||
#
|
||||
# Optional ENV vars
|
||||
# -----------------
|
||||
# M2_HOME - location of maven2's installed home dir
|
||||
# MAVEN_OPTS - parameters passed to the Java VM when running Maven
|
||||
# e.g. to debug Maven itself, use
|
||||
# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
|
||||
# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
|
||||
# ----------------------------------------------------------------------------
|
||||
|
||||
if [ -z "$MAVEN_SKIP_RC" ] ; then
|
||||
|
||||
if [ -f /etc/mavenrc ] ; then
|
||||
. /etc/mavenrc
|
||||
fi
|
||||
|
||||
if [ -f "$HOME/.mavenrc" ] ; then
|
||||
. "$HOME/.mavenrc"
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
# OS specific support. $var _must_ be set to either true or false.
|
||||
cygwin=false;
|
||||
darwin=false;
|
||||
mingw=false
|
||||
case "`uname`" in
|
||||
CYGWIN*) cygwin=true ;;
|
||||
MINGW*) mingw=true;;
|
||||
Darwin*) darwin=true
|
||||
#
|
||||
# Look for the Apple JDKs first to preserve the existing behaviour, and then look
|
||||
# for the new JDKs provided by Oracle.
|
||||
#
|
||||
if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK ] ; then
|
||||
#
|
||||
# Apple JDKs
|
||||
#
|
||||
export JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home
|
||||
fi
|
||||
|
||||
if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Java/JavaVirtualMachines/CurrentJDK ] ; then
|
||||
#
|
||||
# Apple JDKs
|
||||
#
|
||||
export JAVA_HOME=/System/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home
|
||||
fi
|
||||
|
||||
if [ -z "$JAVA_HOME" ] && [ -L "/Library/Java/JavaVirtualMachines/CurrentJDK" ] ; then
|
||||
#
|
||||
# Oracle JDKs
|
||||
#
|
||||
export JAVA_HOME=/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home
|
||||
fi
|
||||
|
||||
if [ -z "$JAVA_HOME" ] && [ -x "/usr/libexec/java_home" ]; then
|
||||
#
|
||||
# Apple JDKs
|
||||
#
|
||||
export JAVA_HOME=`/usr/libexec/java_home`
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -z "$JAVA_HOME" ] ; then
|
||||
if [ -r /etc/gentoo-release ] ; then
|
||||
JAVA_HOME=`java-config --jre-home`
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$M2_HOME" ] ; then
|
||||
## resolve links - $0 may be a link to maven's home
|
||||
PRG="$0"
|
||||
|
||||
# need this for relative symlinks
|
||||
while [ -h "$PRG" ] ; do
|
||||
ls=`ls -ld "$PRG"`
|
||||
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||
if expr "$link" : '/.*' > /dev/null; then
|
||||
PRG="$link"
|
||||
else
|
||||
PRG="`dirname "$PRG"`/$link"
|
||||
fi
|
||||
done
|
||||
|
||||
saveddir=`pwd`
|
||||
|
||||
M2_HOME=`dirname "$PRG"`/..
|
||||
|
||||
# make it fully qualified
|
||||
M2_HOME=`cd "$M2_HOME" && pwd`
|
||||
|
||||
cd "$saveddir"
|
||||
# echo Using m2 at $M2_HOME
|
||||
fi
|
||||
|
||||
# For Cygwin, ensure paths are in UNIX format before anything is touched
|
||||
if $cygwin ; then
|
||||
[ -n "$M2_HOME" ] &&
|
||||
M2_HOME=`cygpath --unix "$M2_HOME"`
|
||||
[ -n "$JAVA_HOME" ] &&
|
||||
JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
|
||||
[ -n "$CLASSPATH" ] &&
|
||||
CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
|
||||
fi
|
||||
|
||||
# For Migwn, ensure paths are in UNIX format before anything is touched
|
||||
if $mingw ; then
|
||||
[ -n "$M2_HOME" ] &&
|
||||
M2_HOME="`(cd "$M2_HOME"; pwd)`"
|
||||
[ -n "$JAVA_HOME" ] &&
|
||||
JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
|
||||
# TODO classpath?
|
||||
fi
|
||||
|
||||
if [ -z "$JAVA_HOME" ]; then
|
||||
javaExecutable="`which javac`"
|
||||
if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
|
||||
# readlink(1) is not available as standard on Solaris 10.
|
||||
readLink=`which readlink`
|
||||
if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
|
||||
if $darwin ; then
|
||||
javaHome="`dirname \"$javaExecutable\"`"
|
||||
javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
|
||||
else
|
||||
javaExecutable="`readlink -f \"$javaExecutable\"`"
|
||||
fi
|
||||
javaHome="`dirname \"$javaExecutable\"`"
|
||||
javaHome=`expr "$javaHome" : '\(.*\)/bin'`
|
||||
JAVA_HOME="$javaHome"
|
||||
export JAVA_HOME
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$JAVACMD" ] ; then
|
||||
if [ -n "$JAVA_HOME" ] ; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
else
|
||||
JAVACMD="`which java`"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ ! -x "$JAVACMD" ] ; then
|
||||
echo "Error: JAVA_HOME is not defined correctly." >&2
|
||||
echo " We cannot execute $JAVACMD" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$JAVA_HOME" ] ; then
|
||||
echo "Warning: JAVA_HOME environment variable is not set."
|
||||
fi
|
||||
|
||||
CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
|
||||
|
||||
# For Cygwin, switch paths to Windows format before running java
|
||||
if $cygwin; then
|
||||
[ -n "$M2_HOME" ] &&
|
||||
M2_HOME=`cygpath --path --windows "$M2_HOME"`
|
||||
[ -n "$JAVA_HOME" ] &&
|
||||
JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
|
||||
[ -n "$CLASSPATH" ] &&
|
||||
CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
|
||||
fi
|
||||
|
||||
# traverses directory structure from process work directory to filesystem root
|
||||
# first directory with .mvn subdirectory is considered project base directory
|
||||
find_maven_basedir() {
|
||||
local basedir=$(pwd)
|
||||
local wdir=$(pwd)
|
||||
while [ "$wdir" != '/' ] ; do
|
||||
if [ -d "$wdir"/.mvn ] ; then
|
||||
basedir=$wdir
|
||||
break
|
||||
fi
|
||||
wdir=$(cd "$wdir/.."; pwd)
|
||||
done
|
||||
echo "${basedir}"
|
||||
}
|
||||
|
||||
# concatenates all lines of a file
|
||||
concat_lines() {
|
||||
if [ -f "$1" ]; then
|
||||
echo "$(tr -s '\n' ' ' < "$1")"
|
||||
fi
|
||||
}
|
||||
|
||||
export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-$(find_maven_basedir)}
|
||||
MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
|
||||
|
||||
# Provide a "standardized" way to retrieve the CLI args that will
|
||||
# work with both Windows and non-Windows executions.
|
||||
MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
|
||||
export MAVEN_CMD_LINE_ARGS
|
||||
|
||||
WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
|
||||
|
||||
echo "Running version check"
|
||||
VERSION=$( sed '\!<parent!,\!</parent!d' `dirname $0`/pom.xml | grep '<version' | head -1 | sed -e 's/.*<version>//' -e 's!</version>.*$!!' )
|
||||
echo "The found version is [${VERSION}]"
|
||||
|
||||
if echo $VERSION | egrep -q 'M|RC'; then
|
||||
echo Activating \"milestone\" profile for version=\"$VERSION\"
|
||||
echo $MAVEN_ARGS | grep -q milestone || MAVEN_ARGS="$MAVEN_ARGS -Pmilestone"
|
||||
else
|
||||
if echo $VERSION | egrep -q 'SNAPSHOT'; then
|
||||
echo Deactivating \"milestone\" profile for version=\"$VERSION\"
|
||||
echo $MAVEN_ARGS | grep -q milestone && MAVEN_ARGS=$(echo $MAVEN_ARGS | sed -e 's/-Pmilestone//')
|
||||
echo Deactivating \"central\" profile for version=\"$VERSION\"
|
||||
echo $MAVEN_ARGS | grep -q central && MAVEN_ARGS=$(echo $MAVEN_ARGS | sed -e 's/-Pcentral//')
|
||||
else
|
||||
echo Deactivating \"milestone\" profile for version=\"$VERSION\"
|
||||
echo $MAVEN_ARGS | grep -q milestone && MAVEN_ARGS=$(echo $MAVEN_ARGS | sed -e 's/-Pmilestone//')
|
||||
echo Activating \"central\" profile for version=\"$VERSION\"
|
||||
echo $MAVEN_ARGS | grep -q milestone || MAVEN_ARGS="$MAVEN_ARGS -Pcentral"
|
||||
fi
|
||||
fi
|
||||
|
||||
exec "$JAVACMD" \
|
||||
$MAVEN_OPTS \
|
||||
-classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
|
||||
"-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
|
||||
${WRAPPER_LAUNCHER} ${MAVEN_ARGS} "$@"
|
||||
@@ -0,0 +1,145 @@
|
||||
@REM ----------------------------------------------------------------------------
|
||||
@REM Licensed to the Apache Software Foundation (ASF) under one
|
||||
@REM or more contributor license agreements. See the NOTICE file
|
||||
@REM distributed with this work for additional information
|
||||
@REM regarding copyright ownership. The ASF licenses this file
|
||||
@REM to you under the Apache License, Version 2.0 (the
|
||||
@REM "License"); you may not use this file except in compliance
|
||||
@REM with the License. You may obtain a copy of the License at
|
||||
@REM
|
||||
@REM https://www.apache.org/licenses/LICENSE-2.0
|
||||
@REM
|
||||
@REM Unless required by applicable law or agreed to in writing,
|
||||
@REM software distributed under the License is distributed on an
|
||||
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
@REM KIND, either express or implied. See the License for the
|
||||
@REM specific language governing permissions and limitations
|
||||
@REM under the License.
|
||||
@REM ----------------------------------------------------------------------------
|
||||
|
||||
@REM ----------------------------------------------------------------------------
|
||||
@REM Maven2 Start Up Batch script
|
||||
@REM
|
||||
@REM Required ENV vars:
|
||||
@REM JAVA_HOME - location of a JDK home dir
|
||||
@REM
|
||||
@REM Optional ENV vars
|
||||
@REM M2_HOME - location of maven2's installed home dir
|
||||
@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
|
||||
@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
|
||||
@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
|
||||
@REM e.g. to debug Maven itself, use
|
||||
@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
|
||||
@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
|
||||
@REM ----------------------------------------------------------------------------
|
||||
|
||||
@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
|
||||
@echo off
|
||||
@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on'
|
||||
@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
|
||||
|
||||
@REM set %HOME% to equivalent of $HOME
|
||||
if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
|
||||
|
||||
@REM Execute a user defined script before this one
|
||||
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
|
||||
@REM check for pre script, once with legacy .bat ending and once with .cmd ending
|
||||
if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
|
||||
if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
|
||||
:skipRcPre
|
||||
|
||||
@setlocal
|
||||
|
||||
set ERROR_CODE=0
|
||||
|
||||
@REM To isolate internal variables from possible post scripts, we use another setlocal
|
||||
@setlocal
|
||||
|
||||
@REM ==== START VALIDATION ====
|
||||
if not "%JAVA_HOME%" == "" goto OkJHome
|
||||
|
||||
echo.
|
||||
echo Error: JAVA_HOME not found in your environment. >&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the >&2
|
||||
echo location of your Java installation. >&2
|
||||
echo.
|
||||
goto error
|
||||
|
||||
:OkJHome
|
||||
if exist "%JAVA_HOME%\bin\java.exe" goto init
|
||||
|
||||
echo.
|
||||
echo Error: JAVA_HOME is set to an invalid directory. >&2
|
||||
echo JAVA_HOME = "%JAVA_HOME%" >&2
|
||||
echo Please set the JAVA_HOME variable in your environment to match the >&2
|
||||
echo location of your Java installation. >&2
|
||||
echo.
|
||||
goto error
|
||||
|
||||
@REM ==== END VALIDATION ====
|
||||
|
||||
:init
|
||||
|
||||
set MAVEN_CMD_LINE_ARGS=%*
|
||||
|
||||
@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
|
||||
@REM Fallback to current working directory if not found.
|
||||
|
||||
set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
|
||||
IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
|
||||
|
||||
set EXEC_DIR=%CD%
|
||||
set WDIR=%EXEC_DIR%
|
||||
:findBaseDir
|
||||
IF EXIST "%WDIR%"\.mvn goto baseDirFound
|
||||
cd ..
|
||||
IF "%WDIR%"=="%CD%" goto baseDirNotFound
|
||||
set WDIR=%CD%
|
||||
goto findBaseDir
|
||||
|
||||
:baseDirFound
|
||||
set MAVEN_PROJECTBASEDIR=%WDIR%
|
||||
cd "%EXEC_DIR%"
|
||||
goto endDetectBaseDir
|
||||
|
||||
:baseDirNotFound
|
||||
set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
|
||||
cd "%EXEC_DIR%"
|
||||
|
||||
:endDetectBaseDir
|
||||
|
||||
IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
|
||||
|
||||
@setlocal EnableExtensions EnableDelayedExpansion
|
||||
for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
|
||||
@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
|
||||
|
||||
:endReadAdditionalConfig
|
||||
|
||||
SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
|
||||
|
||||
set WRAPPER_JAR="".\.mvn\wrapper\maven-wrapper.jar""
|
||||
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
|
||||
|
||||
%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CMD_LINE_ARGS%
|
||||
if ERRORLEVEL 1 goto error
|
||||
goto end
|
||||
|
||||
:error
|
||||
set ERROR_CODE=1
|
||||
|
||||
:end
|
||||
@endlocal & set ERROR_CODE=%ERROR_CODE%
|
||||
|
||||
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
|
||||
@REM check for post script, once with legacy .bat ending and once with .cmd ending
|
||||
if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
|
||||
if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
|
||||
:skipRcPost
|
||||
|
||||
@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
|
||||
if "%MAVEN_BATCH_PAUSE%" == "on" pause
|
||||
|
||||
if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
|
||||
|
||||
exit /B %ERROR_CODE%
|
||||
@@ -0,0 +1,15 @@
|
||||
<assembly
|
||||
xmlns="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/plugins/maven-assembly-plugin/assembly/1.1.2 https://maven.apache.org/xsd/assembly-1.1.2.xsd">
|
||||
<id>${artifactId}</id>
|
||||
<dependencySets>
|
||||
<dependencySet>
|
||||
<includes>
|
||||
<include>${groupId}:${artifactId}</include>
|
||||
</includes>
|
||||
<outputDirectory>.</outputDirectory>
|
||||
<outputFileNameMapping>${artifactId}.jar</outputFileNameMapping>
|
||||
</dependencySet>
|
||||
</dependencySets>
|
||||
</assembly>
|
||||
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Copyright 2020-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.dataflow.app.plugin;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import org.apache.maven.model.Dependency;
|
||||
import org.apache.maven.model.Model;
|
||||
import org.apache.maven.model.Parent;
|
||||
import org.apache.maven.model.Plugin;
|
||||
import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
|
||||
import org.apache.maven.plugin.testing.MojoRule;
|
||||
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Christian Tzolov
|
||||
*/
|
||||
public class MojoHarnessTest {
|
||||
|
||||
@Rule
|
||||
public TemporaryFolder projectHome = new TemporaryFolder();
|
||||
|
||||
@Rule
|
||||
public MojoRule mojoRule = new MojoRule();
|
||||
|
||||
@Test
|
||||
public void testSomething() throws Exception {
|
||||
|
||||
File pomRoot = new File("src/test/resources/unit/http-source-apps/");
|
||||
|
||||
SpringCloudStreamAppGeneratorMojo myMojo = (SpringCloudStreamAppGeneratorMojo)
|
||||
mojoRule.lookupConfiguredMojo(pomRoot, "generate-app");
|
||||
|
||||
assertThat(myMojo).isNotNull();
|
||||
|
||||
myMojo.execute();
|
||||
|
||||
assertThat(new File("./target/apps/http-source-kafka/src/main/resources/test.txt")).exists();
|
||||
|
||||
assertThat(new File("./target/apps/http-source-kafka/src/main/resources/application.properties")).exists();
|
||||
|
||||
Properties applicationProperties = new Properties();
|
||||
applicationProperties.load(new FileReader("./target/apps/http-source-kafka/src/main/resources/application.properties"));
|
||||
assertThat(applicationProperties.getProperty("spring.cloud.function.definition")).isEqualTo("httpSupplier");
|
||||
|
||||
assertThat(applicationProperties.getProperty("static.property")).isEqualTo("bla");
|
||||
|
||||
Model pomModel = getModel(new File("./target/apps"));
|
||||
|
||||
List<Dependency> dependencies = pomModel.getDependencies();
|
||||
assertThat(dependencies.size()).isEqualTo(15);
|
||||
|
||||
assertThat(dependencies.stream()
|
||||
.filter(d -> d.getArtifactId().equals("http-supplier")).count()).isEqualTo(1);
|
||||
|
||||
assertThat(dependencies.stream()
|
||||
.filter(d -> d.getArtifactId().equals("stream-applications-postprocessor-common")).count()).isEqualTo(1);
|
||||
|
||||
assertThat(dependencies.stream()
|
||||
.filter(d -> d.getArtifactId().equals("spring-cloud-stream-binder-kafka")).count()).isEqualTo(1);
|
||||
|
||||
Parent parent = pomModel.getParent();
|
||||
assertThat(parent.getArtifactId()).isEqualTo("spring-boot-starter-parent");
|
||||
assertThat(parent.getVersion()).isEqualTo("2.3.0.M1");
|
||||
|
||||
assertThat(pomModel.getArtifactId()).isEqualTo("http-source-kafka");
|
||||
assertThat(pomModel.getGroupId()).isEqualTo("org.springframework.cloud.stream.app.test");
|
||||
assertThat(pomModel.getName()).isEqualTo("http-source-kafka");
|
||||
assertThat(pomModel.getVersion()).isEqualTo("3.0.0.BUILD-SNAPSHOT");
|
||||
assertThat(pomModel.getDescription()).isEqualTo("Spring Cloud Stream Http Source Kafka Binder Application");
|
||||
|
||||
List<Plugin> plugins = pomModel.getBuild().getPlugins();
|
||||
|
||||
assertThat(plugins.stream().filter(p -> p.getArtifactId().equals("spring-boot-maven-plugin")).count()).isEqualTo(1);
|
||||
assertThat(plugins.stream().filter(p -> p.getArtifactId().equals("properties-maven-plugin")).count()).isEqualTo(1);
|
||||
assertThat(plugins.stream().filter(p -> p.getArtifactId().equals("jib-maven-plugin")).count()).isEqualTo(1);
|
||||
|
||||
Plugin jibPlugin = plugins.stream().filter(p -> p.getArtifactId().equals("jib-maven-plugin")).findFirst().get();
|
||||
assertThat(jibPlugin.getConfiguration().toString())
|
||||
.contains("<org.springframework.cloud.dataflow.spring-configuration-metadata.json>" +
|
||||
"${org.springframework.cloud.dataflow.spring.configuration.metadata.json}" +
|
||||
"</org.springframework.cloud.dataflow.spring-configuration-metadata.json>");
|
||||
assertThat(jibPlugin.getConfiguration().toString()).contains("<image>testspringcloud/${project.artifactId}:3.0.0.BUILD-SNAPSHOT</image>");
|
||||
assertThat(jibPlugin.getConfiguration().toString()).contains("<image>globalBaseImage</image>");
|
||||
assertThat(pomModel.getRepositories().size()).isEqualTo(5);
|
||||
|
||||
assertThat(pomModel.getRepositories().stream().map(r -> r.getId()).collect(Collectors.toList()))
|
||||
.contains("bintray-global", "bintray-application", "bintray-binder");
|
||||
}
|
||||
|
||||
private Model getModel(File rootPath) {
|
||||
File pomXml = new File(new File(rootPath, "http-source-kafka"), "pom.xml");
|
||||
try (InputStream is = new FileInputStream(pomXml)) {
|
||||
return new MavenXpp3Reader().read(is);
|
||||
}
|
||||
catch (IOException | XmlPullParserException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,229 @@
|
||||
/*
|
||||
* Copyright 2020-2022 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.dataflow.app.plugin;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
import org.apache.maven.model.Dependency;
|
||||
import org.apache.maven.model.Model;
|
||||
import org.apache.maven.model.Parent;
|
||||
import org.apache.maven.model.Plugin;
|
||||
import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
|
||||
import org.codehaus.plexus.util.xml.Xpp3Dom;
|
||||
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
|
||||
import org.springframework.cloud.dataflow.app.plugin.generator.AppDefinition;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
|
||||
/**
|
||||
* @author Christian Tzolov
|
||||
* @author Soby Chacko
|
||||
*/
|
||||
public class SpringCloudStreamAppGeneratorMojoTest {
|
||||
|
||||
@Rule
|
||||
public TemporaryFolder projectHome = new TemporaryFolder();
|
||||
|
||||
private SpringCloudStreamAppGeneratorMojo springCloudStreamAppMojo = new SpringCloudStreamAppGeneratorMojo();
|
||||
|
||||
private Class<? extends SpringCloudStreamAppGeneratorMojo> mojoClazz = springCloudStreamAppMojo.getClass();
|
||||
|
||||
private SpringCloudStreamAppGeneratorMojo.Application application;
|
||||
|
||||
@Before
|
||||
public void before() throws NoSuchFieldException {
|
||||
|
||||
application = new SpringCloudStreamAppGeneratorMojo.Application();
|
||||
application.setName("log");
|
||||
application.setType(AppDefinition.AppType.sink);
|
||||
application.setVersion("3.0.0.BUILD-SNAPSHOT");
|
||||
application.setConfigClass("io.pivotal.java.function.log.consumer.LogConsumerConfiguration.class");
|
||||
|
||||
application.getContainerImage().setFormat(AppDefinition.ContainerImageFormat.Docker);
|
||||
application.getContainerImage().setBaseImage("base/image");
|
||||
|
||||
application.getMetadata().getSourceTypeFilters().add("io.pivotal.java.function.log.consumer.LogConsumerProperties");
|
||||
application.getMetadata().getNameFilters().add("server.port");
|
||||
|
||||
application.getProperties().put("spring.cloud.streamapp.security.enabled", "false");
|
||||
application.getProperties().put("spring.cloud.streamapp.security.csrf-enabled", "false");
|
||||
|
||||
Dependency dep = new Dependency();
|
||||
dep.setGroupId("io.pivotal.java.function");
|
||||
dep.setArtifactId("log-consumer");
|
||||
dep.setVersion("1.0.0.BUILD-SNAPSHOT");
|
||||
|
||||
application.getMaven().getDependencies().add(dep);
|
||||
|
||||
// BOM
|
||||
application.setBootVersion("2.3.0.M1");
|
||||
application.getMetadata().setMavenPluginVersion("1.0.2.BUILD-SNAPSHOT");
|
||||
|
||||
setMojoProperty("application", application);
|
||||
|
||||
//Binders
|
||||
SpringCloudStreamAppGeneratorMojo.Binder kafkaBinder = new SpringCloudStreamAppGeneratorMojo.Binder();
|
||||
Dependency kafkaDep = new Dependency();
|
||||
kafkaDep.setGroupId("org.springframework.cloud");
|
||||
kafkaDep.setArtifactId("spring-cloud-stream-binder-kafka");
|
||||
kafkaBinder.getMaven().getDependencies().add(kafkaDep);
|
||||
|
||||
SpringCloudStreamAppGeneratorMojo.Binder rabbitBinder = new SpringCloudStreamAppGeneratorMojo.Binder();
|
||||
Dependency rabbitDep = new Dependency();
|
||||
rabbitDep.setGroupId("org.springframework.cloud");
|
||||
rabbitDep.setArtifactId("spring-cloud-stream-binder-rabbit");
|
||||
rabbitBinder.getMaven().getDependencies().add(rabbitDep);
|
||||
|
||||
Map<String, SpringCloudStreamAppGeneratorMojo.Binder> binders = new HashMap<>();
|
||||
binders.put("kafka", kafkaBinder);
|
||||
binders.put("rabbit", rabbitBinder);
|
||||
|
||||
setMojoProperty("binders", binders);
|
||||
|
||||
//setMojoProperty("generatedProjectHome", "./target/apps");
|
||||
setMojoProperty("generatedProjectHome", projectHome.getRoot().getAbsolutePath());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWithDisabledContainerMetadata() throws Exception {
|
||||
|
||||
// disable metadata in container image (Default)
|
||||
application.getContainerImage().setEnableMetadata(false);
|
||||
|
||||
springCloudStreamAppMojo.execute();
|
||||
|
||||
//Model pomModel = getModel(new File("./target/apps"));
|
||||
Model pomModel = getModel(new File(projectHome.getRoot().getAbsolutePath()));
|
||||
List<Plugin> plugins = pomModel.getBuild().getPlugins();
|
||||
|
||||
// The properties-maven-plugin should not be defined if the container metadata is not enabled.
|
||||
assertThat(plugins.stream().filter(p -> p.getArtifactId().equals("properties-maven-plugin")).count()).isEqualTo(0);
|
||||
|
||||
assertThat(plugins.stream().filter(p -> p.getArtifactId().equals("jib-maven-plugin")).count()).isEqualTo(1);
|
||||
|
||||
Plugin jibPlugin = plugins.stream().filter(p -> p.getArtifactId().equals("jib-maven-plugin")).findFirst().get();
|
||||
assertThat(jibPlugin.getConfiguration().toString())
|
||||
.doesNotContain("<org.springframework.cloud.dataflow.spring-configuration-metadata.json>" +
|
||||
"${org.springframework.cloud.dataflow.spring.configuration.metadata.json}" +
|
||||
"</org.springframework.cloud.dataflow.spring-configuration-metadata.json>");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDefaultProjectCreationByPlugin() throws Exception {
|
||||
|
||||
// Enable Metadata in Container Image!
|
||||
application.getContainerImage().setEnableMetadata(true);
|
||||
|
||||
springCloudStreamAppMojo.execute();
|
||||
|
||||
//assertGeneratedPomXml(new File("./target/apps"));
|
||||
assertGeneratedPomXml(new File(projectHome.getRoot().getAbsolutePath()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCustomBootMavenPluginConfiguration() throws Exception {
|
||||
application.setBootPluginConfiguration("<![CDATA[\n" +
|
||||
" <requiresUnpack>\n" +
|
||||
" <dependency>\n" +
|
||||
" <groupId>org.python</groupId>\n" +
|
||||
" <artifactId>jython-standalone</artifactId>\n" +
|
||||
" </dependency>\n" +
|
||||
" </requiresUnpack>\n" +
|
||||
" ]]>");
|
||||
|
||||
springCloudStreamAppMojo.execute();
|
||||
|
||||
Model pomModel = getModel(new File(projectHome.getRoot().getAbsolutePath()));
|
||||
List<Plugin> plugins = pomModel.getBuild().getPlugins();
|
||||
final Optional<Plugin> bootPlugin = plugins.stream().filter(p -> p.getArtifactId().equals("spring-boot-maven-plugin")).findFirst();
|
||||
assertThat(bootPlugin.isPresent()).isTrue();
|
||||
final Plugin plugin = bootPlugin.get();
|
||||
final Xpp3Dom configuration = (Xpp3Dom) plugin.getConfiguration();
|
||||
assertThat(configuration.getValue().contains("<requiresUnpack>")).isTrue();
|
||||
assertThat(configuration.getValue().contains("jython-standalone")).isTrue();
|
||||
assertThat(configuration.getValue().contains("</requiresUnpack>")).isTrue();
|
||||
}
|
||||
|
||||
private void assertGeneratedPomXml(File rootPath) {
|
||||
|
||||
Model pomModel = getModel(rootPath);
|
||||
|
||||
List<Dependency> dependencies = pomModel.getDependencies();
|
||||
assertThat(dependencies.size()).isEqualTo(3);
|
||||
|
||||
assertThat(dependencies.stream()
|
||||
.filter(d -> d.getArtifactId().equals("log-consumer")).count()).isEqualTo(1);
|
||||
|
||||
assertThat(dependencies.stream()
|
||||
.filter(d -> d.getArtifactId().equals("spring-cloud-stream-binder-kafka")).count()).isEqualTo(1);
|
||||
|
||||
Parent parent = pomModel.getParent();
|
||||
assertThat(parent.getArtifactId()).isEqualTo("spring-boot-starter-parent");
|
||||
assertThat(parent.getVersion()).isEqualTo("2.3.0.M1");
|
||||
|
||||
assertThat(pomModel.getArtifactId()).isEqualTo("log-sink-kafka");
|
||||
assertThat(pomModel.getGroupId()).isEqualTo("org.springframework.cloud.stream.app");
|
||||
assertThat(pomModel.getName()).isEqualTo("log-sink-kafka");
|
||||
assertThat(pomModel.getVersion()).isEqualTo("3.0.0.BUILD-SNAPSHOT");
|
||||
assertThat(pomModel.getDescription()).isEqualTo("Spring Cloud Stream Log Sink Kafka Binder Application");
|
||||
|
||||
List<Plugin> plugins = pomModel.getBuild().getPlugins();
|
||||
assertThat(plugins.stream().filter(p -> p.getArtifactId().equals("spring-boot-maven-plugin")).count()).isEqualTo(1);
|
||||
assertThat(plugins.stream().filter(p -> p.getArtifactId().equals("properties-maven-plugin")).count()).isEqualTo(1);
|
||||
assertThat(plugins.stream().filter(p -> p.getArtifactId().equals("jib-maven-plugin")).count()).isEqualTo(1);
|
||||
|
||||
Plugin jibPlugin = plugins.stream().filter(p -> p.getArtifactId().equals("jib-maven-plugin")).findFirst().get();
|
||||
assertThat(jibPlugin.getConfiguration().toString())
|
||||
.contains("<org.springframework.cloud.dataflow.spring-configuration-metadata.json>" +
|
||||
"${org.springframework.cloud.dataflow.spring.configuration.metadata.json}" +
|
||||
"</org.springframework.cloud.dataflow.spring-configuration-metadata.json>");
|
||||
assertThat(jibPlugin.getConfiguration().toString()).contains("<image>base/image</image>");
|
||||
|
||||
assertThat(pomModel.getRepositories().size()).isEqualTo(2);
|
||||
}
|
||||
|
||||
private Model getModel(File rootPath) {
|
||||
File pomXml = new File(new File(rootPath, "log-sink-kafka"), "pom.xml");
|
||||
try (InputStream is = new FileInputStream(pomXml)) {
|
||||
return new MavenXpp3Reader().read(is);
|
||||
}
|
||||
catch (IOException | XmlPullParserException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void setMojoProperty(String propertyName, Object value) throws NoSuchFieldException {
|
||||
Field mojoProperty = mojoClazz.getDeclaredField(propertyName);
|
||||
mojoProperty.setAccessible(true);
|
||||
ReflectionUtils.setField(mojoProperty, springCloudStreamAppMojo, value);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,302 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>org.springframework.cloud.stream.app</groupId>
|
||||
<artifactId>http-source-apps</artifactId>
|
||||
<version>3.0.0.BUILD-SNAPSHOT</version>
|
||||
<name>http-source-apps</name>
|
||||
<description>http source apps</description>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<properties>
|
||||
<spring-boot.version>2.3.0.M1</spring-boot.version>
|
||||
<stream-apps-core.version>3.0.0.BUILD-SNAPSHOT</stream-apps-core.version>
|
||||
<java-cfenv-boot.version>2.1.1.RELEASE</java-cfenv-boot.version>
|
||||
<app-metadata-maven-plugin-version>1.0.2.BUILD-SNAPSHOT</app-metadata-maven-plugin-version>
|
||||
|
||||
<!-- Emulate the properties that otherwise should come from the stream-apps-parent parent -->
|
||||
<java-functions.version>1.0.0.BUILD-SNAPSHOT</java-functions.version>
|
||||
<spring-cloud-dependencies.version>Hoxton.RELEASE</spring-cloud-dependencies.version>
|
||||
<spring-cloud-stream-dependencies.version>Horsham.SR2</spring-cloud-stream-dependencies.version>
|
||||
<spring-cloud-function-dependencies.version>3.0.2.RELEASE</spring-cloud-function-dependencies.version>
|
||||
<apps.base-image>springcloud/baseimage:1.0.4</apps.base-image>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<pluginManagement>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-dataflow-apps-generator-plugin</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>app-gen</id>
|
||||
<phase>package</phase>
|
||||
<goals>
|
||||
<goal>generate-app</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
<configuration>
|
||||
<global>
|
||||
<application>
|
||||
<bootVersion>${spring-boot.version}</bootVersion>
|
||||
<metadata>
|
||||
<mavenPluginVersion>2.0.2.BUILD-SNAPSHOT</mavenPluginVersion>
|
||||
</metadata>
|
||||
<containerImage>
|
||||
<orgName>globalOrgName</orgName>
|
||||
<baseImage>globalBaseImage</baseImage>
|
||||
<enableMetadata>true</enableMetadata>
|
||||
</containerImage>
|
||||
<properties>
|
||||
<appProperty1>value1</appProperty1>
|
||||
<appProperty2>value2</appProperty2>
|
||||
</properties>
|
||||
<maven>
|
||||
<properties>
|
||||
<global.maven.prop1>value1</global.maven.prop1>
|
||||
<global.maven.prop2>value2</global.maven.prop2>
|
||||
</properties>
|
||||
<dependencyManagement>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-stream-dependencies</artifactId>
|
||||
<version>${spring-cloud-stream-dependencies.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-function-dependencies</artifactId>
|
||||
<version>${spring-cloud-function-dependencies.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-dependencies</artifactId>
|
||||
<version>${spring-cloud-dependencies.version}</version>
|
||||
</dependency>
|
||||
</dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud.stream.app</groupId>
|
||||
<artifactId>stream-apps-security-common</artifactId>
|
||||
<version>${stream-apps-core.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud.stream.app</groupId>
|
||||
<artifactId>stream-apps-micrometer-common</artifactId>
|
||||
<version>${stream-apps-core.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud.stream.app</groupId>
|
||||
<artifactId>stream-applications-postprocessor-common</artifactId>
|
||||
<version>3.0.0-SNAPSHOT</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.micrometer</groupId>
|
||||
<artifactId>micrometer-registry-influx</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.micrometer</groupId>
|
||||
<artifactId>micrometer-registry-prometheus</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.micrometer</groupId>
|
||||
<artifactId>micrometer-registry-datadog</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.pivotal.cfenv</groupId>
|
||||
<artifactId>java-cfenv-boot</artifactId>
|
||||
<version>${java-cfenv-boot.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-logging</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-security</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.logaritex</groupId>
|
||||
<artifactId>test-additional-maven-plugin</artifactId>
|
||||
<version>3.0.0</version>
|
||||
<configuration>
|
||||
<![CDATA[
|
||||
<from>
|
||||
<image>${apps.base-image}</image>
|
||||
</from>
|
||||
<to>
|
||||
<image>springcloudstream:${project.artifactId}:3.0.0.BUILD-SNAPSHOT</image>
|
||||
</to>
|
||||
<container>
|
||||
<creationTime>USE_CURRENT_TIMESTAMP</creationTime>
|
||||
<format>Docker</format>
|
||||
<labels>
|
||||
<org.springframework.cloud.dataflow.spring-configuration-metadata.json>${org.springframework.cloud.dataflow.spring.configuration.metadata.json}</org.springframework.cloud.dataflow.spring-configuration-metadata.json>
|
||||
</labels>
|
||||
</container>
|
||||
]]>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>sign-artifacts</id>
|
||||
<phase>verify</phase>
|
||||
<goals>
|
||||
<goal>sign</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
<repositories>
|
||||
<repository>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
<id>bintray-global</id>
|
||||
<name>bintray-global</name>
|
||||
<url>https://dl.bintray.com/globbals/maven</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
</maven>
|
||||
</application>
|
||||
|
||||
<binders>
|
||||
<kafka>
|
||||
<maven>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-stream-binder-kafka</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<repositories>
|
||||
<repository>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
<id>bintray-binder</id>
|
||||
<name>bintray-binder</name>
|
||||
<url>https://dl.bintray.com/binder/maven</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
</maven>
|
||||
</kafka>
|
||||
<rabbit>
|
||||
<maven>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-stream-binder-rabbit</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</maven>
|
||||
</rabbit>
|
||||
</binders>
|
||||
</global>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</pluginManagement>
|
||||
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-dataflow-apps-generator-plugin</artifactId>
|
||||
<version>1.0.0-SNAPSHOT</version>
|
||||
|
||||
<configuration>
|
||||
<generatedProjectHome>./target/apps</generatedProjectHome>
|
||||
<application>
|
||||
<name>http</name>
|
||||
<type>source</type>
|
||||
<version>${project.version}</version>
|
||||
<configClass>io.pivotal.java.function.http.supplier.HttpSupplierConfiguration.class</configClass>
|
||||
<groupId>org.springframework.cloud.stream.app.test</groupId>
|
||||
|
||||
<properties>
|
||||
<spring.main.web-application-type>reactive</spring.main.web-application-type>
|
||||
<spring.cloud.streamapp.security.enabled>false</spring.cloud.streamapp.security.enabled>
|
||||
<spring.cloud.streamapp.security.csrf-enabled>false</spring.cloud.streamapp.security.csrf-enabled>
|
||||
<!-- override global property -->
|
||||
<appProperty2>value2Updated</appProperty2>
|
||||
</properties>
|
||||
|
||||
<containerImage>
|
||||
<orgName>testspringcloud</orgName>
|
||||
<enableMetadata>true</enableMetadata>
|
||||
</containerImage>
|
||||
|
||||
<maven>
|
||||
<properties>
|
||||
<random.maven.prop>value1</random.maven.prop>
|
||||
</properties>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>io.pivotal.java.function</groupId>
|
||||
<artifactId>http-supplier</artifactId>
|
||||
<version>${java-functions.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
<repositories>
|
||||
<repository>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
<id>bintray-application</id>
|
||||
<name>bintray-app</name>
|
||||
<url>https://dl.bintray.com/app/maven</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
</maven>
|
||||
|
||||
<metadata>
|
||||
<sourceTypeFilters>
|
||||
<filter>io.pivotal.java.function.http.supplier.HttpSourceProperties</filter>
|
||||
<filter>io.pivotal.java.function.http.supplier.HttpSourceProperties$Cors</filter>
|
||||
</sourceTypeFilters>
|
||||
<nameFilters>
|
||||
<filter>server.port</filter>
|
||||
</nameFilters>
|
||||
</metadata>
|
||||
</application>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-app-starter-metadata-maven-plugin</artifactId>
|
||||
<version>2.0.0.BUILD-SNAPSHOT</version>
|
||||
<configuration>
|
||||
<storeFilteredMetadata>true</storeFilteredMetadata>
|
||||
|
||||
<metadataFilter>
|
||||
<names>
|
||||
<filter>server.port</filter>
|
||||
</names>
|
||||
<sourceTypes>
|
||||
<filter>io.pivotal.java.function.http.supplier.HttpSourceProperties</filter>
|
||||
<filter>io.pivotal.java.function.http.supplier.HttpSourceProperties$Cors</filter>
|
||||
</sourceTypes>
|
||||
</metadataFilter>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
@@ -0,0 +1 @@
|
||||
static.property=bla
|
||||
@@ -0,0 +1 @@
|
||||
test
|
||||
@@ -0,0 +1,95 @@
|
||||
= Spring Cloud Stream & Task Maven Metadata Plugin
|
||||
|
||||
Maven plugin for aggregating Spring Boot metadata from all dependencies of a project into
|
||||
a single metadata-only artifact.
|
||||
|
||||
== Usage
|
||||
|
||||
To use this plugin, configure this plugin for your app project (either directly or through a parent POM):
|
||||
```
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.cloud.stream.app.plugin</groupId>
|
||||
<artifactId>spring-cloud-app-starter-metadata-maven-plugin</artifactId>
|
||||
<version>2.0.0.BUILD-SNAPSHOT</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>aggregate-metadata</id>
|
||||
<phase>compile</phase>
|
||||
<goals>
|
||||
<goal>aggregate-metadata</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
```
|
||||
|
||||
This will produce and attach to the build a jar file named `<artifactId>-<version>-metadata.jar` (`metadata` being the
|
||||
maven classifier used for the artifact, which can be customized as such:)
|
||||
```
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.cloud.stream.app.plugin</groupId>
|
||||
<artifactId>spring-cloud-app-starter-metadata-maven-plugin</artifactId>
|
||||
<version>2.0.0.BUILD-SNAPSHOT</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>aggregate-metadata</id>
|
||||
<phase>compile</phase>
|
||||
<goals>
|
||||
<goal>aggregate-metadata</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<classifier>foobar</classifier>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
```
|
||||
|
||||
You can filter in subset of the gathered metadata and store it into a java property file: `META-INF/spring-configuration-metadata-encoded.properties`.
|
||||
This file has single property `org.springframework.cloud.dataflow.spring.configuration.metadata.json` which contains the pre-filtered metadata encoded as Base64.
|
||||
To activate this feature you need to set the `storeFilteredMetadata` parameter to `true`. Use the `metadataFilter` to configure the whitelisted metadata content to include.
|
||||
For example:
|
||||
```
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-app-starter-metadata-maven-plugin</artifactId>
|
||||
<version>2.0.0.BUILD-SNAPSHOT</version>
|
||||
|
||||
<configuration>
|
||||
<storeFilteredMetadata>true</storeFilteredMetadata>
|
||||
|
||||
<metadataFilter>
|
||||
<names>
|
||||
<filter>server.port</filter>
|
||||
</names>
|
||||
<sourceTypes>
|
||||
<filter>io.pivotal.java.function.http.supplier.HttpSourceProperties</filter>
|
||||
<filter>io.pivotal.java.function.http.supplier.HttpSourceProperties$Cors</filter>
|
||||
</sourceTypes>
|
||||
</metadataFilter>
|
||||
</configuration>
|
||||
|
||||
<executions>
|
||||
<execution>
|
||||
<id>aggregate-metadata</id>
|
||||
<phase>compile</phase>
|
||||
<goals>
|
||||
<goal>aggregate-metadata</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
```
|
||||
|
||||
@@ -0,0 +1,150 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<artifactId>spring-cloud-dataflow-apps-metadata-plugin</artifactId>
|
||||
<packaging>maven-plugin</packaging>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-dataflow-apps-plugin-parent</artifactId>
|
||||
<version>1.0.8-SNAPSHOT</version>
|
||||
<relativePath>..</relativePath>
|
||||
</parent>
|
||||
|
||||
<properties>
|
||||
<maven.version>3.6.3</maven.version>
|
||||
<junit.version>4.12</junit.version>
|
||||
<assertj.version>3.11.1</assertj.version>
|
||||
<commons-text.version>1.8</commons-text.version>
|
||||
<spring.version>5.2.8.RELEASE</spring.version>
|
||||
<snakeyaml.version>1.26</snakeyaml.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.apache.maven</groupId>
|
||||
<artifactId>maven-plugin-api</artifactId>
|
||||
<version>${maven.version}</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-core</artifactId>
|
||||
<version>${spring.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework</groupId>
|
||||
<artifactId>spring-beans</artifactId>
|
||||
<version>${spring.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.yaml</groupId>
|
||||
<artifactId>snakeyaml</artifactId>
|
||||
<version>${snakeyaml.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.maven</groupId>
|
||||
<artifactId>maven-core</artifactId>
|
||||
<version>${maven.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||
<version>2.3.2.RELEASE</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.rsocket</groupId>
|
||||
<artifactId>rsocket-core</artifactId>
|
||||
<version>1.0.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-loader</artifactId>
|
||||
<version>2.3.2.RELEASE</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>${junit.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.assertj</groupId>
|
||||
<artifactId>assertj-core</artifactId>
|
||||
<version>${assertj.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.maven.plugin-tools</groupId>
|
||||
<artifactId>maven-plugin-annotations</artifactId>
|
||||
<version>3.4</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-text</artifactId>
|
||||
<version>${commons-text.version}</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-plugin-plugin</artifactId>
|
||||
<version>3.5</version>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>1.8</source>
|
||||
<target>1.8</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>spring</id>
|
||||
<repositories>
|
||||
<repository>
|
||||
<snapshots>
|
||||
<enabled>true</enabled>
|
||||
</snapshots>
|
||||
<id>spring-snapshots</id>
|
||||
<name>Spring Snapshots</name>
|
||||
<url>https://repo.spring.io/snapshot</url>
|
||||
</repository>
|
||||
<repository>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
<id>spring-milestones</id>
|
||||
<name>Spring Milestones</name>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
</repository>
|
||||
</repositories>
|
||||
<pluginRepositories>
|
||||
<pluginRepository>
|
||||
<snapshots>
|
||||
<enabled>true</enabled>
|
||||
</snapshots>
|
||||
<id>spring-snapshots</id>
|
||||
<name>Spring Snapshots</name>
|
||||
<url>https://repo.spring.io/snapshot</url>
|
||||
</pluginRepository>
|
||||
<pluginRepository>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
<id>spring-milestones</id>
|
||||
<name>Spring Milestones</name>
|
||||
<url>https://repo.spring.io/milestone</url>
|
||||
</pluginRepository>
|
||||
</pluginRepositories>
|
||||
</profile>
|
||||
</profiles>
|
||||
</project>
|
||||
@@ -0,0 +1,625 @@
|
||||
/*
|
||||
* Copyright 2017-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.dataflow.app.plugin;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.nio.file.Paths;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Properties;
|
||||
import java.util.jar.JarOutputStream;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
import org.apache.commons.text.StringEscapeUtils;
|
||||
import org.apache.maven.plugin.AbstractMojo;
|
||||
import org.apache.maven.plugin.MojoExecutionException;
|
||||
import org.apache.maven.plugins.annotations.Component;
|
||||
import org.apache.maven.plugins.annotations.LifecyclePhase;
|
||||
import org.apache.maven.plugins.annotations.Mojo;
|
||||
import org.apache.maven.plugins.annotations.Parameter;
|
||||
import org.apache.maven.plugins.annotations.ResolutionScope;
|
||||
import org.apache.maven.project.MavenProject;
|
||||
import org.apache.maven.project.MavenProjectHelper;
|
||||
|
||||
import org.springframework.beans.factory.config.YamlPropertiesFactoryBean;
|
||||
import org.springframework.boot.configurationprocessor.metadata.ConfigurationMetadata;
|
||||
import org.springframework.boot.configurationprocessor.metadata.ItemHint;
|
||||
import org.springframework.boot.configurationprocessor.metadata.ItemMetadata;
|
||||
import org.springframework.boot.configurationprocessor.metadata.JsonMarshaller;
|
||||
import org.springframework.core.io.FileSystemResource;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import static org.springframework.boot.configurationprocessor.metadata.ItemHint.ValueHint;
|
||||
import static org.springframework.boot.configurationprocessor.metadata.ItemHint.ValueProvider;
|
||||
|
||||
/**
|
||||
* A maven plugin that will gather all Spring Boot metadata files from all transitive dependencies and will aggregate
|
||||
* them in one metadata-only artifact.
|
||||
*
|
||||
* @author Eric Bottard
|
||||
* @author David Turanski
|
||||
* @author Christian Tzolov
|
||||
* @author Ilayaperumal Gopinathan
|
||||
*/
|
||||
@Mojo(
|
||||
name = "aggregate-metadata",
|
||||
requiresDependencyResolution = ResolutionScope.RUNTIME,
|
||||
defaultPhase = LifecyclePhase.COMPILE
|
||||
)
|
||||
public class MetadataAggregationMojo extends AbstractMojo {
|
||||
|
||||
static final String METADATA_PATH = "META-INF/spring-configuration-metadata.json";
|
||||
|
||||
static final String VISIBLE_PROPERTIES_PATH = "META-INF/dataflow-configuration-metadata.properties";
|
||||
|
||||
static final String DEPRECATED_WHITELIST_PATH = "META-INF/dataflow-configuration-metadata-whitelist.properties";
|
||||
|
||||
static final String DEPRECATED_BACKUP_WHITELIST_PATH = "META-INF/spring-configuration-metadata-whitelist.properties";
|
||||
|
||||
static final String CONFIGURATION_PROPERTIES_CLASSES = "configuration-properties.classes";
|
||||
|
||||
static final String CONFIGURATION_PROPERTIES_NAMES = "configuration-properties.names";
|
||||
|
||||
static final String CONFIGURATION_PROPERTIES_INBOUND_PORTS = "configuration-properties.inbound-ports";
|
||||
|
||||
static final String CONFIGURATION_PROPERTIES_OUTBOUND_PORTS = "configuration-properties.outbound-ports";
|
||||
|
||||
static final String SPRING_CLOUD_FUNCTION_DEFINITION = "spring.cloud.function.definition";
|
||||
|
||||
static final String SPRING_CLOUD_STREAM_FUNCTION_DEFINITION = "spring.cloud.stream.function.definition";
|
||||
|
||||
static final String SPRING_CLOUD_STREAM_FUNCTION_BINDINGS = "spring.cloud.stream.function.bindings";
|
||||
|
||||
static final String SPRING_CLOUD_DATAFLOW_PORT_MAPPING_PROPERTIES = "dataflow-configuration-port-mapping.properties";
|
||||
|
||||
static final String SPRING_CLOUD_DATAFLOW_OPTION_GROUPS_PROPERTIES = "dataflow-configuration-option-groups.properties";
|
||||
|
||||
@Parameter(defaultValue = "${project}")
|
||||
private MavenProject mavenProject;
|
||||
|
||||
@Parameter(defaultValue = "metadata")
|
||||
private String classifier;
|
||||
|
||||
@Component
|
||||
private MavenProjectHelper projectHelper;
|
||||
|
||||
@Parameter
|
||||
private boolean storeFilteredMetadata;
|
||||
|
||||
@Parameter
|
||||
private MetadataFilter metadataFilter;
|
||||
|
||||
private final JsonMarshaller jsonMarshaller = new JsonMarshaller();
|
||||
|
||||
public void execute() throws MojoExecutionException {
|
||||
Result result = new Result(gatherConfigurationMetadata(null), gatherVisibleMetadata());
|
||||
produceArtifact(result);
|
||||
|
||||
if (storeFilteredMetadata) {
|
||||
getLog().debug("propertyClassFilter: " + metadataFilter);
|
||||
if (metadataFilter == null) {
|
||||
metadataFilter = new MetadataFilter();
|
||||
}
|
||||
if (result.visible.containsKey(CONFIGURATION_PROPERTIES_CLASSES)) {
|
||||
String[] sourceTypes = result.visible.getProperty(CONFIGURATION_PROPERTIES_CLASSES, "").split(",");
|
||||
if (sourceTypes != null && sourceTypes.length > 0) {
|
||||
if (metadataFilter.getSourceTypes() == null) {
|
||||
metadataFilter.setSourceTypes(new ArrayList<>());
|
||||
}
|
||||
for (String sourceType : sourceTypes) {
|
||||
sourceType = sourceType.trim();
|
||||
if (!metadataFilter.getSourceTypes().contains(sourceType)) {
|
||||
metadataFilter.getSourceTypes().add(sourceType);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (result.visible.containsKey(CONFIGURATION_PROPERTIES_NAMES)) {
|
||||
String[] names = result.visible.getProperty(CONFIGURATION_PROPERTIES_NAMES, "").split(",");
|
||||
if (names != null && names.length > 0) {
|
||||
if (metadataFilter.getNames() == null) {
|
||||
metadataFilter.setNames(new ArrayList<>());
|
||||
}
|
||||
for (String name : names) {
|
||||
name = name.trim();
|
||||
if (!metadataFilter.getNames().contains(name)) {
|
||||
metadataFilter.getNames().add(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (result.visible.containsKey(CONFIGURATION_PROPERTIES_CLASSES)) {
|
||||
String[] sourceTypes = result.visible.getProperty(CONFIGURATION_PROPERTIES_CLASSES, "").split(",");
|
||||
metadataFilter.getSourceTypes().addAll(Arrays.asList(sourceTypes));
|
||||
}
|
||||
|
||||
storeFilteredMetadata();
|
||||
}
|
||||
//Add port mapping configuration based on the application configuration.
|
||||
storeInboundOutboundPortMappingConfigurations(result.getPortMappingProperties());
|
||||
}
|
||||
|
||||
/**
|
||||
* Store pre-filtered and json-escaped metadata into a property file.
|
||||
*/
|
||||
private void storeFilteredMetadata() throws MojoExecutionException {
|
||||
File projectMetaInfFolder = new File(mavenProject.getBuild().getOutputDirectory(), "META-INF");
|
||||
if (!projectMetaInfFolder.exists()) {
|
||||
if (!projectMetaInfFolder.mkdir()) {
|
||||
throw new MojoExecutionException("Error creating META-INF folder for port mapping file!");
|
||||
}
|
||||
}
|
||||
try (FileWriter fileWriter = new FileWriter(
|
||||
new File(projectMetaInfFolder, "spring-configuration-metadata-encoded.properties"))) {
|
||||
ConfigurationMetadata metadata = gatherConfigurationMetadata(metadataFilter);
|
||||
String escapedJson = StringEscapeUtils.escapeJson(toJson(metadata));
|
||||
fileWriter.write("org.springframework.cloud.dataflow.spring.configuration.metadata.json=" + escapedJson);
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new MojoExecutionException("Error creating file ", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void storeInboundOutboundPortMappingConfigurations(Properties properties) throws MojoExecutionException {
|
||||
File projectMetaInfFolder = new File(mavenProject.getBuild().getOutputDirectory(), "META-INF");
|
||||
if (!projectMetaInfFolder.exists()) {
|
||||
if (!projectMetaInfFolder.mkdir()) {
|
||||
throw new MojoExecutionException("Error creating META-INF folder for port mapping file!");
|
||||
}
|
||||
}
|
||||
try (FileWriter fileWriter = new FileWriter(
|
||||
new File(projectMetaInfFolder, SPRING_CLOUD_DATAFLOW_PORT_MAPPING_PROPERTIES))) {
|
||||
properties.store(fileWriter, "Spring Cloud DataFlow Port Mapping");
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new MojoExecutionException("Error creating file ", e);
|
||||
}
|
||||
}
|
||||
|
||||
private String toJson(ConfigurationMetadata metadata) throws IOException {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
jsonMarshaller.write(metadata, baos);
|
||||
String json = baos.toString();
|
||||
|
||||
// Hack to workaround the https://github.com/mojohaus/properties-maven-plugin/issues/27 and
|
||||
// https://github.com/mojohaus/properties-maven-plugin/pull/38 properties-maven-plugin issues.
|
||||
json = json.replaceAll("\\$\\{", "{");
|
||||
|
||||
return json;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read all existing metadata from this project runtime dependencies and merge them in a single object.
|
||||
*/
|
||||
/*default*/ Properties gatherVisibleMetadata() throws MojoExecutionException {
|
||||
Properties visible = new Properties();
|
||||
List<String> inboundPorts = new ArrayList<>();
|
||||
List<String> outboundPorts = new ArrayList<>();
|
||||
try {
|
||||
for (String path : mavenProject.getRuntimeClasspathElements()) {
|
||||
if (Files.isDirectory(Paths.get(path))) {
|
||||
for (String visibleProperties : new String[] { VISIBLE_PROPERTIES_PATH, DEPRECATED_WHITELIST_PATH,
|
||||
DEPRECATED_BACKUP_WHITELIST_PATH }) {
|
||||
Optional<Properties> properties;
|
||||
properties = getVisibleFromFile(Paths.get(path, visibleProperties));
|
||||
if (properties.isPresent()) {
|
||||
if (!visibleProperties.equals(VISIBLE_PROPERTIES_PATH)) {
|
||||
getLog().warn("Use of " + visibleProperties + " is deprecated." +
|
||||
" Please use " + VISIBLE_PROPERTIES_PATH);
|
||||
|
||||
}
|
||||
visible = properties.get();
|
||||
break;
|
||||
}
|
||||
}
|
||||
File dir = new File(path);
|
||||
for (File file : dir.listFiles()) {
|
||||
Properties properties = new Properties();
|
||||
if (file.isFile() && file.canRead() && file.getName().endsWith(".properties")) {
|
||||
try (InputStream is = new FileInputStream(file)) {
|
||||
properties.load(is);
|
||||
}
|
||||
}
|
||||
if (file.isFile() && file.canRead() && (file.getName().endsWith(".yaml") || file.getName()
|
||||
.endsWith(".yml"))) {
|
||||
YamlPropertiesFactoryBean yamlPropertiesFactoryBean = new YamlPropertiesFactoryBean();
|
||||
yamlPropertiesFactoryBean.setResources(new FileSystemResource(file));
|
||||
properties = yamlPropertiesFactoryBean.getObject();
|
||||
}
|
||||
if (!properties.isEmpty()) {
|
||||
String functionDefinitions = null;
|
||||
if (properties.containsKey(SPRING_CLOUD_FUNCTION_DEFINITION)) {
|
||||
functionDefinitions = properties.getProperty(SPRING_CLOUD_FUNCTION_DEFINITION);
|
||||
}
|
||||
else if (properties.containsKey(SPRING_CLOUD_STREAM_FUNCTION_DEFINITION)) {
|
||||
functionDefinitions = properties
|
||||
.getProperty(SPRING_CLOUD_STREAM_FUNCTION_DEFINITION);
|
||||
}
|
||||
for (String functionDefinition : StringUtils
|
||||
.delimitedListToStringArray(functionDefinitions, ";")) {
|
||||
if (functionDefinition != null) {
|
||||
for (Object propertyKey : properties.keySet()) {
|
||||
if (((String) propertyKey).startsWith(
|
||||
String.format("%s.%s-in-", SPRING_CLOUD_STREAM_FUNCTION_BINDINGS,
|
||||
functionDefinition))) {
|
||||
inboundPorts.add(properties.getProperty((String) propertyKey));
|
||||
}
|
||||
if (((String) propertyKey).startsWith(
|
||||
String.format("%s.%s-out-", SPRING_CLOUD_STREAM_FUNCTION_BINDINGS,
|
||||
functionDefinition))) {
|
||||
outboundPorts.add(properties.getProperty((String) propertyKey));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
try (ZipFile zipFile = new ZipFile(new File(path))) {
|
||||
ZipEntry entry;
|
||||
for (String zipEntry : new String[] { VISIBLE_PROPERTIES_PATH, DEPRECATED_WHITELIST_PATH,
|
||||
DEPRECATED_BACKUP_WHITELIST_PATH }) {
|
||||
entry = zipFile.getEntry(zipEntry);
|
||||
if (entry != null) {
|
||||
if (!zipEntry.equals(VISIBLE_PROPERTIES_PATH)) {
|
||||
getLog().warn("Use of " + zipEntry + " is deprecated." +
|
||||
" Please use " + VISIBLE_PROPERTIES_PATH);
|
||||
}
|
||||
visible = getVisibleFromZipFile(visible, path, zipFile, entry);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new MojoExecutionException("Exception trying to read metadata from dependencies of project", e);
|
||||
}
|
||||
if (!inboundPorts.isEmpty()) {
|
||||
visible.put(CONFIGURATION_PROPERTIES_INBOUND_PORTS,
|
||||
StringUtils.arrayToCommaDelimitedString(inboundPorts.toArray(new String[0])));
|
||||
}
|
||||
if (!outboundPorts.isEmpty()) {
|
||||
visible.put(CONFIGURATION_PROPERTIES_OUTBOUND_PORTS,
|
||||
StringUtils.arrayToCommaDelimitedString(outboundPorts.toArray(new String[0])));
|
||||
}
|
||||
return visible;
|
||||
}
|
||||
|
||||
/*default*/ ConfigurationMetadata gatherConfigurationMetadata(MetadataFilter metadataFilters)
|
||||
throws MojoExecutionException {
|
||||
ConfigurationMetadata metadata = new ConfigurationMetadata();
|
||||
try {
|
||||
for (String path : mavenProject.getRuntimeClasspathElements()) {
|
||||
File file = new File(path);
|
||||
if (file.isDirectory()) {
|
||||
File localMetadata = new File(file, METADATA_PATH);
|
||||
if (localMetadata.canRead()) {
|
||||
try (InputStream is = new FileInputStream(localMetadata)) {
|
||||
ConfigurationMetadata depMetadata = jsonMarshaller.read(is);
|
||||
depMetadata = filterMetadata(depMetadata, metadataFilters);
|
||||
getLog().debug("Merging metadata from " + path);
|
||||
addEnumHints(depMetadata, getClassLoader(path));
|
||||
metadata.merge(depMetadata);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
try (ZipFile zipFile = new ZipFile(file)) {
|
||||
ZipEntry entry = zipFile.getEntry(METADATA_PATH);
|
||||
if (entry != null) {
|
||||
try (InputStream inputStream = zipFile.getInputStream(entry)) {
|
||||
ConfigurationMetadata depMetadata = jsonMarshaller.read(inputStream);
|
||||
depMetadata = filterMetadata(depMetadata, metadataFilters);
|
||||
getLog().debug("Merging metadata from " + path);
|
||||
addEnumHints(depMetadata, getClassLoader(path));
|
||||
metadata.merge(depMetadata);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Replace all escaped double quotes by a single one.
|
||||
metadata.getItems().stream().forEach(itemMetadata -> {
|
||||
if (!StringUtils.isEmpty(itemMetadata.getDescription()) && itemMetadata.getDescription()
|
||||
.contains("\"")) {
|
||||
itemMetadata.setDescription(itemMetadata.getDescription().replaceAll("\"", "'"));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
throw new MojoExecutionException("Exception trying to read metadata from dependencies of project", e);
|
||||
}
|
||||
return metadata;
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private ConfigurationMetadata filterMetadata(ConfigurationMetadata metadata, MetadataFilter metadataFilters) {
|
||||
if (metadataFilters == null
|
||||
|| (CollectionUtils.isEmpty(metadataFilters.getNames()) && CollectionUtils
|
||||
.isEmpty(metadataFilters.getSourceTypes()))) {
|
||||
return metadata; // nothing to filter by so take all;
|
||||
}
|
||||
|
||||
List<String> sourceTypeFilters = CollectionUtils.isEmpty(metadataFilters.getSourceTypes()) ?
|
||||
Collections.EMPTY_LIST : metadataFilters.getSourceTypes();
|
||||
|
||||
List<String> nameFilters = CollectionUtils.isEmpty(metadataFilters.getNames()) ?
|
||||
Collections.EMPTY_LIST : metadataFilters.getNames();
|
||||
|
||||
ConfigurationMetadata filteredMetadata = new ConfigurationMetadata();
|
||||
List<String> visibleNames = new ArrayList<>();
|
||||
for (ItemMetadata itemMetadata : metadata.getItems()) {
|
||||
String metadataName = itemMetadata.getName();
|
||||
String metadataSourceType = itemMetadata.getSourceType();
|
||||
if (StringUtils.hasText(metadataSourceType) && sourceTypeFilters.contains(metadataSourceType.trim())) {
|
||||
filteredMetadata.add(itemMetadata);
|
||||
visibleNames.add(itemMetadata.getName());
|
||||
}
|
||||
if (StringUtils.hasText(metadataName) && nameFilters.contains(metadataName.trim())) {
|
||||
filteredMetadata.add(itemMetadata);
|
||||
visibleNames.add(itemMetadata.getName());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// copy the hits only for the visible metadata.
|
||||
for (ItemHint itemHint : metadata.getHints()) {
|
||||
if (itemHint != null && visibleNames.contains(itemHint.getName())) {
|
||||
filteredMetadata.add(itemHint);
|
||||
}
|
||||
}
|
||||
|
||||
return filteredMetadata;
|
||||
}
|
||||
|
||||
private Properties getVisibleFromZipFile(Properties visible, String path, ZipFile zipFile, ZipEntry entry)
|
||||
throws IOException {
|
||||
try (InputStream inputStream = zipFile.getInputStream(entry)) {
|
||||
getLog().debug("Merging visible metadata from " + path);
|
||||
visible = merge(visible, inputStream);
|
||||
}
|
||||
return visible;
|
||||
}
|
||||
|
||||
private Optional<Properties> getVisibleFromFile(Path visiblePropertiesPath) throws IOException {
|
||||
File localVisible = visiblePropertiesPath.toFile();
|
||||
if (localVisible.canRead()) {
|
||||
Properties visible = new Properties();
|
||||
try (InputStream is = new FileInputStream(localVisible)) {
|
||||
getLog().debug("!!!! Merging visible metadata from " + visiblePropertiesPath.toString());
|
||||
visible = merge(visible, is);
|
||||
return Optional.of(visible);
|
||||
}
|
||||
}
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
Properties merge(Properties visible, InputStream is) throws IOException {
|
||||
Properties mergedProperties = new Properties();
|
||||
mergedProperties.load(is);
|
||||
|
||||
if (!mergedProperties.containsKey(CONFIGURATION_PROPERTIES_CLASSES) && !mergedProperties
|
||||
.containsKey(CONFIGURATION_PROPERTIES_NAMES)) {
|
||||
getLog().warn(String.format("Visible properties does not contain any required keys: %s",
|
||||
StringUtils.arrayToCommaDelimitedString(new String[] {
|
||||
CONFIGURATION_PROPERTIES_CLASSES,
|
||||
CONFIGURATION_PROPERTIES_NAMES
|
||||
})));
|
||||
return visible;
|
||||
}
|
||||
|
||||
if (!CollectionUtils.isEmpty(visible)) {
|
||||
mergeCommaDelimitedValue(visible, mergedProperties, CONFIGURATION_PROPERTIES_CLASSES);
|
||||
mergeCommaDelimitedValue(visible, mergedProperties, CONFIGURATION_PROPERTIES_NAMES);
|
||||
}
|
||||
|
||||
return mergedProperties;
|
||||
}
|
||||
|
||||
private void mergeCommaDelimitedValue(Properties currentProperties, Properties newProperties, String key) {
|
||||
if (currentProperties.containsKey(key) || newProperties.containsKey(key)) {
|
||||
Collection<String> values = StringUtils.commaDelimitedListToSet(currentProperties.getProperty(key));
|
||||
values.addAll(StringUtils.commaDelimitedListToSet(newProperties.getProperty(key)));
|
||||
if (newProperties.containsKey(key)) {
|
||||
getLog().debug(String.format("Merging visible property %s=%s", key, newProperties.getProperty(key)));
|
||||
}
|
||||
newProperties.setProperty(key, StringUtils.collectionToCommaDelimitedString(values));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a jar file with the given metadata and "attach" it to the current maven project.
|
||||
*/
|
||||
/*default*/ void produceArtifact(Result result) throws MojoExecutionException {
|
||||
String artifactLocation = String
|
||||
.format("target/%s-%s-%s.jar", mavenProject.getArtifactId(), mavenProject.getVersion(), classifier);
|
||||
File output = new File(mavenProject.getBasedir(), artifactLocation);
|
||||
try (JarOutputStream jos = new JarOutputStream(new FileOutputStream(output))) {
|
||||
ZipEntry entry = new ZipEntry(METADATA_PATH);
|
||||
jos.putNextEntry(entry);
|
||||
jsonMarshaller.write(result.metadata, jos);
|
||||
|
||||
entry = new ZipEntry(VISIBLE_PROPERTIES_PATH);
|
||||
jos.putNextEntry(entry);
|
||||
result.visible.store(jos, "Describes visible properties for this app");
|
||||
|
||||
entry = new ZipEntry(DEPRECATED_WHITELIST_PATH);
|
||||
jos.putNextEntry(entry);
|
||||
result.visible.store(jos, "DEPRECATED: Describes visible properties for this app");
|
||||
|
||||
entry = new ZipEntry(DEPRECATED_BACKUP_WHITELIST_PATH);
|
||||
jos.putNextEntry(entry);
|
||||
result.visible.store(jos, "DEPRECATED: Describes visible properties for this app");
|
||||
|
||||
entry = new ZipEntry("META-INF/" + SPRING_CLOUD_DATAFLOW_PORT_MAPPING_PROPERTIES);
|
||||
jos.putNextEntry(entry);
|
||||
|
||||
entry = new ZipEntry("META-INF/" + SPRING_CLOUD_DATAFLOW_OPTION_GROUPS_PROPERTIES);
|
||||
jos.putNextEntry(entry);
|
||||
|
||||
result.getPortMappingProperties().store(jos, "Describes visible port mapping properties for this app");
|
||||
|
||||
getLog().info(String.format("Attaching %s to current project", output.getCanonicalPath()));
|
||||
projectHelper.attachArtifact(mavenProject, output, classifier);
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new MojoExecutionException("Error writing to file", e);
|
||||
}
|
||||
}
|
||||
|
||||
void addEnumHints(ConfigurationMetadata configurationMetadata, ClassLoader classLoader) {
|
||||
|
||||
Map<String, List<ValueProvider>> providers = new HashMap<>();
|
||||
|
||||
Map<String, ItemHint> itemHints = new HashMap<>();
|
||||
|
||||
for (ItemMetadata property : configurationMetadata.getItems()) {
|
||||
|
||||
if (property.isOfItemType(ItemMetadata.ItemType.PROPERTY)) {
|
||||
|
||||
if (ClassUtils.isPresent(property.getType(), classLoader)) {
|
||||
Class<?> clazz = ClassUtils.resolveClassName(property.getType(), classLoader);
|
||||
if (clazz.isEnum()) {
|
||||
List<ValueHint> valueHints = new ArrayList<>();
|
||||
for (Object o : clazz.getEnumConstants()) {
|
||||
valueHints.add(new ValueHint(o, null));
|
||||
}
|
||||
|
||||
if (!providers.containsKey(property.getType())) {
|
||||
providers.put(property.getType(), new ArrayList<ValueProvider>());
|
||||
}
|
||||
|
||||
//Equals is not correct for ValueProvider
|
||||
|
||||
boolean found = false;
|
||||
for (ValueProvider valueProvider : providers.get(property.getType())) {
|
||||
if (valueProvider.getName().equals(property.getType())) {
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
providers.get(property.getType()).add(new ValueProvider(property.getType(), null));
|
||||
}
|
||||
|
||||
itemHints.put(property.getType(), new ItemHint(property.getName(), valueHints,
|
||||
new ArrayList<>(providers.get(property.getType()))));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!CollectionUtils.isEmpty(itemHints)) {
|
||||
for (ItemHint itemHint : itemHints.values()) {
|
||||
configurationMetadata.add(itemHint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private ClassLoader getClassLoader(String jarPath) {
|
||||
ClassLoader classLoader = null;
|
||||
try {
|
||||
classLoader = new URLClassLoader(new URL[] { new URL("file://" + jarPath) },
|
||||
this.getClass().getClassLoader());
|
||||
}
|
||||
catch (MalformedURLException e) {
|
||||
// pass through
|
||||
}
|
||||
return classLoader;
|
||||
}
|
||||
|
||||
public static class MetadataFilter {
|
||||
private List<String> names;
|
||||
|
||||
private List<String> sourceTypes;
|
||||
|
||||
public List<String> getNames() {
|
||||
return names;
|
||||
}
|
||||
|
||||
public void setNames(List<String> names) {
|
||||
this.names = names;
|
||||
}
|
||||
|
||||
public List<String> getSourceTypes() {
|
||||
return sourceTypes;
|
||||
}
|
||||
|
||||
public void setSourceTypes(List<String> sourceTypes) {
|
||||
this.sourceTypes = sourceTypes;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "MetadataFilter{" +
|
||||
"name=" + names +
|
||||
", sourceType=" + sourceTypes +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A tuple holding both configuration metadata and the whitelist properties.
|
||||
*
|
||||
* @author Eric Bottard
|
||||
*/
|
||||
/*default*/ static final class Result {
|
||||
private final ConfigurationMetadata metadata;
|
||||
|
||||
private final Properties visible;
|
||||
|
||||
private Properties getPortMappingProperties() {
|
||||
Properties portMappingProperties = new Properties();
|
||||
visible.entrySet().stream()
|
||||
.filter(e -> e.getKey().equals(CONFIGURATION_PROPERTIES_OUTBOUND_PORTS) || e.getKey().equals(CONFIGURATION_PROPERTIES_INBOUND_PORTS))
|
||||
.forEach(e -> portMappingProperties.put(e.getKey(), e.getValue()));
|
||||
return portMappingProperties;
|
||||
}
|
||||
|
||||
private Result(ConfigurationMetadata metadata, Properties visible) {
|
||||
this.metadata = metadata;
|
||||
this.visible = visible;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2018-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.dataflow.app.plugin;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.boot.configurationprocessor.metadata.ConfigurationMetadata;
|
||||
import org.springframework.boot.configurationprocessor.metadata.ItemHint;
|
||||
import org.springframework.boot.configurationprocessor.metadata.JsonMarshaller;
|
||||
import org.springframework.cloud.dataflow.completion.Expresso;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author David Turanski
|
||||
**/
|
||||
public class EnumHintProviderTest {
|
||||
private JsonMarshaller jsonMarshaller = new JsonMarshaller();
|
||||
|
||||
@Test
|
||||
public void test() throws Exception {
|
||||
ConfigurationMetadata configurationMetadata = jsonMarshaller.read(new ClassPathResource("META-INF/spring"
|
||||
+ "-configuration-metadata.json").getInputStream());
|
||||
|
||||
new MetadataAggregationMojo().addEnumHints(configurationMetadata, this.getClass().getClassLoader());
|
||||
|
||||
assertThat(configurationMetadata.getHints()).hasSize(1);
|
||||
|
||||
ItemHint itemHint = configurationMetadata.getHints().get(0);
|
||||
|
||||
|
||||
// equals fails on ValueHint so ...
|
||||
// assertThat(new ItemHint.ValueHint("SINGLE",null)).isEqualTo(new ItemHint.ValueHint("SINGLE",null));
|
||||
|
||||
assertThat(itemHint.getValues()).hasSize(2);
|
||||
|
||||
assertThat(itemHint.getValues().get(0).getValue()).isEqualTo(Expresso.SINGLE);
|
||||
assertThat(itemHint.getValues().get(1).getValue()).isEqualTo(Expresso.DOUBLE);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright 2018-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.dataflow.app.plugin;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Properties;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.springframework.cloud.dataflow.app.plugin.MetadataAggregationMojo.CONFIGURATION_PROPERTIES_CLASSES;
|
||||
import static org.springframework.cloud.dataflow.app.plugin.MetadataAggregationMojo.CONFIGURATION_PROPERTIES_NAMES;
|
||||
|
||||
/**
|
||||
* @author David Turanski
|
||||
**/
|
||||
|
||||
public class MergeWhitelistPropertiesTest {
|
||||
|
||||
@Test
|
||||
public void merge() throws IOException {
|
||||
Properties properties1 = new Properties();
|
||||
properties1.load(new ClassPathResource("META-INF/whitelist-1.properties").getInputStream());
|
||||
|
||||
Properties properties2 = new MetadataAggregationMojo().merge(properties1,
|
||||
new ClassPathResource("META-INF/whitelist-2.properties").getInputStream());
|
||||
|
||||
assertThat(properties2).containsKeys(CONFIGURATION_PROPERTIES_CLASSES, CONFIGURATION_PROPERTIES_NAMES);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void mergeReverseOrder() throws IOException {
|
||||
Properties properties1 = new Properties();
|
||||
properties1.load(new ClassPathResource("META-INF/whitelist-2.properties").getInputStream());
|
||||
|
||||
Properties properties2 = new MetadataAggregationMojo().merge(properties1,
|
||||
new ClassPathResource("META-INF/whitelist-1.properties").getInputStream());
|
||||
|
||||
assertThat(properties2).containsKeys(CONFIGURATION_PROPERTIES_CLASSES, CONFIGURATION_PROPERTIES_NAMES);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright 2018-2020 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.dataflow.completion;
|
||||
|
||||
/**
|
||||
* @author David Turanski
|
||||
**/
|
||||
public enum Expresso {
|
||||
SINGLE,
|
||||
DOUBLE;
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"groups": [
|
||||
{
|
||||
"name": "filter",
|
||||
"type": "foo.bar.FilterProperties",
|
||||
"sourceType": "foo.bar.FilterProperties"
|
||||
}
|
||||
],
|
||||
"properties": [
|
||||
{
|
||||
"name": "filter.expression",
|
||||
"type": "org.springframework.expression.Expression",
|
||||
"description": "A predicate to evaluate",
|
||||
"sourceType": "foo.bar.FilterProperties",
|
||||
"defaultValue": "true"
|
||||
},
|
||||
{
|
||||
"name": "filter.expresso",
|
||||
"type": "org.springframework.cloud.dataflow.completion.Expresso",
|
||||
"description": "A property of type enum and whose name starts like 'expression'",
|
||||
"sourceType": "foo.bar.FilterProperties"
|
||||
}
|
||||
],
|
||||
"hints": [
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
configuration-properties.classes=\
|
||||
org.springframework.cloud.stream.app.tasklaunchrequest.DataflowTaskLaunchRequestProperties
|
||||
@@ -0,0 +1,25 @@
|
||||
configuration-properties.classes=\
|
||||
org.springframework.cloud.stream.app.trigger.TriggerPropertiesMaxMessagesDefaultUnlimited
|
||||
configuration-properties.names=\
|
||||
sftp.auto-create-local-dir,\
|
||||
sftp.delete-remote-files,\
|
||||
sftp.directories,\
|
||||
sftp.factories,\
|
||||
sftp.factory.allow-unknown-keys,\
|
||||
sftp.factory.cache-sessions,\
|
||||
sftp.factory.host,\
|
||||
sftp.factory.known-hosts-expression,\
|
||||
sftp.factory.pass-phrase,\
|
||||
sftp.factory.password,\
|
||||
sftp.factory.port,\
|
||||
sftp.factory.private-key,\
|
||||
sftp.factory.username,\
|
||||
sftp.fair,\
|
||||
sftp.filename-pattern,\
|
||||
sftp.filename-regex,\
|
||||
sftp.list-only,\
|
||||
sftp.local-dir,\
|
||||
sftp.max-fetch,\
|
||||
sftp.preserve-timestamp,\
|
||||
sftp.remote-dir,\
|
||||
sftp.remote-file-separator
|
||||
Reference in New Issue
Block a user