├── .circleci
└── config.yml
├── .github
├── CONTRIBUTING.md
├── ISSUE_TEMPLATE.md
└── dco.yml
├── .gitignore
├── .mvn
├── jvm.config
├── maven.config
└── wrapper
│ ├── maven-wrapper.jar
│ └── maven-wrapper.properties
├── .settings.xml
├── Guardfile
├── LICENSE.txt
├── README.adoc
├── docs
├── pom.xml
└── src
│ └── main
│ ├── asciidoc
│ ├── README.adoc
│ ├── ghpages.sh
│ ├── images
│ │ ├── spring-cloud-launcher-eureka-dashboard.png
│ │ └── spring-cloud-launcher-log.png
│ ├── index.adoc
│ ├── install.adoc
│ ├── intro.adoc
│ ├── sagan-boot.adoc
│ ├── sagan-index.adoc
│ └── spring-cloud-cli.adoc
│ └── ruby
│ └── generate_readme.sh
├── mvnw
├── mvnw.cmd
├── pom.xml
├── spring-cloud-cli-integration-tests
├── .gitignore
├── README.md
├── pom.xml
├── samples
│ ├── app.groovy
│ ├── configserver.groovy
│ ├── eureka.groovy
│ ├── eurekaserver.groovy
│ ├── rabbit.groovy
│ └── stubrunner.groovy
└── src
│ └── test
│ └── java
│ └── org
│ └── springframework
│ └── cloud
│ └── cli
│ ├── CliTester.java
│ ├── OutputCapture.java
│ └── SampleIntegrationTests.java
├── spring-cloud-cli
├── .gitignore
├── README.md
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── org
│ │ │ └── springframework
│ │ │ ├── boot
│ │ │ └── groovy
│ │ │ │ └── cloud
│ │ │ │ └── EnableBinding.java
│ │ │ └── cloud
│ │ │ └── cli
│ │ │ ├── command
│ │ │ ├── CloudCommandFactory.java
│ │ │ ├── encrypt
│ │ │ │ ├── BaseEncryptOptionHandler.java
│ │ │ │ ├── DecryptCommand.java
│ │ │ │ ├── EncryptCommand.java
│ │ │ │ ├── EncryptorFactory.java
│ │ │ │ ├── KeyFormatException.java
│ │ │ │ └── MissingKeyException.java
│ │ │ └── url
│ │ │ │ ├── BaseEncodeOptionHandler.java
│ │ │ │ ├── UrlDecodeCommand.java
│ │ │ │ └── UrlEncodeCommand.java
│ │ │ └── compiler
│ │ │ ├── BaseStreamCompilerAutoConfiguration.java
│ │ │ ├── ConfigServerCompilerAutoConfiguration.java
│ │ │ ├── EurekaClientCompilerAutoConfiguration.java
│ │ │ ├── EurekaServerCompilerAutoConfiguration.java
│ │ │ ├── JavaVersion.java
│ │ │ ├── OAuth2LoadBalancedCompilerAutoConfiguration.java
│ │ │ ├── SpringCloudBomAstTransformation.java
│ │ │ ├── SpringCloudCompilerAutoConfiguration.java
│ │ │ ├── StreamKafkaCompilerAutoConfiguration.java
│ │ │ ├── StreamRabbitCompilerAutoConfiguration.java
│ │ │ └── StubRunnerCompilerAutoConfiguration.java
│ └── resources
│ │ └── META-INF
│ │ ├── services
│ │ ├── org.springframework.boot.cli.command.CommandFactory
│ │ ├── org.springframework.boot.cli.compiler.CompilerAutoConfiguration
│ │ └── org.springframework.boot.cli.compiler.SpringBootAstTransformation
│ │ └── springcloudbom-version.txt
│ └── test
│ ├── java
│ └── org
│ │ └── springframework
│ │ └── cloud
│ │ └── cli
│ │ ├── command
│ │ ├── encrypt
│ │ │ ├── DecryptCommandTests.java
│ │ │ └── EncryptCommandTests.java
│ │ └── url
│ │ │ ├── OutputCapture.java
│ │ │ ├── UrlDecodeCommandTest.java
│ │ │ └── UrlEncodeCommandTest.java
│ │ └── compiler
│ │ └── SpringCloudBomAstTransformationTests.java
│ └── resources
│ ├── application.yml
│ ├── keystore.jks
│ └── private.pem
└── spring-cloud-launcher
├── README.md
├── pom.xml
├── spring-cloud-launcher-cli
├── pom.xml
└── src
│ ├── main
│ └── java
│ │ └── org
│ │ └── springframework
│ │ └── cloud
│ │ └── launcher
│ │ └── cli
│ │ └── LauncherCommand.java
│ └── test
│ ├── java
│ └── org
│ │ └── springframework
│ │ └── cloud
│ │ └── launcher
│ │ └── cli
│ │ ├── LauncherCommandTests.java
│ │ └── OutputCapture.java
│ └── resources
│ └── cloud-test.yml
├── spring-cloud-launcher-configserver
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── org
│ │ │ └── springframework
│ │ │ └── cloud
│ │ │ └── launcher
│ │ │ └── configserver
│ │ │ └── ConfigServerApplication.java
│ └── resources
│ │ ├── META-INF
│ │ ├── thin-rabbit.properties
│ │ └── thin.properties
│ │ ├── application.yml
│ │ └── launcher
│ │ └── application.yml
│ └── test
│ └── java
│ └── org
│ └── springframework
│ └── cloud
│ └── launcher
│ └── configserver
│ └── DeployerApplicationTests.java
├── spring-cloud-launcher-dataflow
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── org
│ │ │ └── springframework
│ │ │ └── cloud
│ │ │ └── launcher
│ │ │ └── dataflow
│ │ │ └── DataFlowApplication.java
│ └── resources
│ │ ├── META-INF
│ │ └── thin-rabbit.properties
│ │ ├── application.yml
│ │ └── bootstrap.yml
│ └── test
│ └── java
│ └── org
│ └── springframework
│ └── cloud
│ └── launcher
│ └── dataflow
│ └── DeployerApplicationTests.java
├── spring-cloud-launcher-deployer
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── org
│ │ │ └── springframework
│ │ │ └── cloud
│ │ │ └── launcher
│ │ │ └── deployer
│ │ │ ├── Deployer.java
│ │ │ ├── DeployerApplication.java
│ │ │ ├── DeployerConfiguration.java
│ │ │ └── DeployerProperties.java
│ └── resources
│ │ ├── META-INF
│ │ ├── cli-version.txt
│ │ ├── thin-local.properties
│ │ ├── thin-rabbit.properties
│ │ └── thin-thin.properties
│ │ ├── cloud.yml
│ │ └── launcher-banner.txt
│ └── test
│ ├── java
│ └── org
│ │ └── springframework
│ │ └── cloud
│ │ └── launcher
│ │ └── deployer
│ │ ├── DeployerApplicationTests.java
│ │ └── LauncherAppDeployerTests.java
│ └── resources
│ └── cloud-test.yml
├── spring-cloud-launcher-eureka
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── org
│ │ │ └── springframework
│ │ │ └── cloud
│ │ │ └── launcher
│ │ │ └── eureka
│ │ │ └── EurekaApplication.java
│ └── resources
│ │ ├── META-INF
│ │ └── thin-rabbit.properties
│ │ ├── application.yml
│ │ └── bootstrap.yml
│ └── test
│ └── java
│ └── org
│ └── springframework
│ └── cloud
│ └── launcher
│ └── eureka
│ └── DeployerApplicationTests.java
├── spring-cloud-launcher-h2
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── org
│ │ │ └── springframework
│ │ │ └── cloud
│ │ │ └── launcher
│ │ │ └── h2
│ │ │ └── H2Application.java
│ └── resources
│ │ ├── META-INF
│ │ └── thin-rabbit.properties
│ │ ├── application.yml
│ │ └── bootstrap.yml
│ └── test
│ └── java
│ └── org
│ └── springframework
│ └── cloud
│ └── launcher
│ └── h2
│ └── DeployerApplicationTests.java
├── spring-cloud-launcher-kafka
├── pom.xml
└── src
│ ├── main
│ ├── java
│ │ └── org
│ │ │ └── springframework
│ │ │ └── cloud
│ │ │ └── launcher
│ │ │ └── kafka
│ │ │ └── KafkaApplication.java
│ └── resources
│ │ ├── application.yml
│ │ └── bootstrap.yml
│ └── test
│ └── java
│ └── org
│ └── springframework
│ └── cloud
│ └── launcher
│ └── kafka
│ └── DeployerApplicationTests.java
└── spring-cloud-launcher-stubrunner
├── pom.xml
└── src
├── main
├── java
│ └── org
│ │ └── springframework
│ │ └── cloud
│ │ └── launcher
│ │ └── stubrunner
│ │ └── StubRunnerApplication.java
└── resources
│ ├── META-INF
│ └── thin-rabbit.properties
│ ├── application.yml
│ └── launcher
│ └── application.yml
└── test
└── java
└── org
└── springframework
└── cloud
└── launcher
└── stubrunner
└── DeployerApplicationTests.java
/.circleci/config.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | jobs:
3 | build:
4 | docker:
5 | - image: springcloud/pipeline-base
6 | user: appuser
7 | environment:
8 | _JAVA_OPTIONS: "-Xms1024m -Xmx2048m"
9 | TERM: dumb
10 | branches:
11 | ignore:
12 | - gh-pages # list of branches to ignore
13 | steps:
14 | - checkout
15 | - restore_cache:
16 | key: sc-commons-{{ .Branch }}
17 | - run:
18 | name: "Download dependencies"
19 | command: ./mvnw -s .settings.xml -U --fail-never dependency:go-offline || true
20 | - save_cache:
21 | key: sc-commons-{{ .Branch }}
22 | paths:
23 | - ~/.m2
24 | - run:
25 | name: "Running build"
26 | command: ./mvnw -s .settings.xml clean org.jacoco:jacoco-maven-plugin:prepare-agent install -U -P sonar -nsu --batch-mode -Dmaven.test.redirectTestOutputToFile=true -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn
27 | - run:
28 | name: "Aggregate test results"
29 | when: always
30 | command: |
31 | mkdir -p ~/junit/
32 | find . -type f -regex ".*/target/.*-reports/.*" -exec cp {} ~/junit/ \;
33 | bash <(curl -s https://codecov.io/bash)
34 | - store_artifacts:
35 | path: ~/junit/
36 | destination: artifacts
37 | - store_test_results:
38 | path: ~/junit/
39 | destination: testartifacts
40 |
--------------------------------------------------------------------------------
/.github/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 |
2 | # Contributing
3 |
4 | Spring Cloud is released under the non-restrictive Apache 2.0 license,
5 | and follows a very standard Github development process, using Github
6 | tracker for issues and merging pull requests into master. If you want
7 | to contribute even something trivial please do not hesitate, but
8 | follow the guidelines below.
9 |
10 | ## Sign the Contributor License Agreement
11 | Before we accept a non-trivial patch or pull request we will need you to sign the
12 | [Contributor License Agreement](https://cla.pivotal.io/sign/spring).
13 | Signing the contributor's agreement does not grant anyone commit rights to the main
14 | repository, but it does mean that we can accept your contributions, and you will get an
15 | author credit if we do. Active contributors might be asked to join the core team, and
16 | given the ability to merge pull requests.
17 |
18 | ## Code of Conduct
19 | This project adheres to the Contributor Covenant [code of
20 | conduct](https://github.com/spring-cloud/spring-cloud-build/blob/main/docs/modules/ROOT/partials/code-of-conduct.adoc). By participating, you are expected to uphold this code. Please report
21 | unacceptable behavior to spring-code-of-conduct@pivotal.io.
22 |
23 | ## Code Conventions and Housekeeping
24 | None of these is essential for a pull request, but they will all help. They can also be
25 | added after the original pull request but before a merge.
26 |
27 | * Use the Spring Framework code format conventions. If you use Eclipse
28 | you can import formatter settings using the
29 | `eclipse-code-formatter.xml` file from the [Spring
30 | Cloud Build](https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/spring-cloud-dependencies-parent/eclipse-code-formatter.xml) project. If using IntelliJ, you can use the
31 | [Eclipse Code Formatter Plugin](https://plugins.jetbrains.com/plugin/6546) to import the same file.
32 | * Make sure all new `.java` files to have a simple Javadoc class comment with at least an
33 | `@author` tag identifying you, and preferably at least a paragraph on what the class is
34 | for.
35 | * Add the ASF license header comment to all new `.java` files (copy from existing files
36 | in the project)
37 | * Add yourself as an `@author` to the .java files that you modify substantially (more
38 | than cosmetic changes).
39 | * Add some Javadocs and, if you change the namespace, some XSD doc elements.
40 | * A few unit tests would help a lot as well -- someone has to do it.
41 | * If no-one else is using your branch, please rebase it against the current master (or
42 | other target branch in the main project).
43 | * When writing a commit message please follow [these conventions](https://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html),
44 | if you are fixing an existing issue please add `Fixes gh-XXXX` at the end of the commit
45 | message (where XXXX is the issue number).
46 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE.md:
--------------------------------------------------------------------------------
1 |
21 |
--------------------------------------------------------------------------------
/.github/dco.yml:
--------------------------------------------------------------------------------
1 | require:
2 | members: false
3 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *~
2 | #*
3 | *#
4 | .#*
5 | .classpath
6 | .project
7 | .settings
8 | .springBeans
9 | .gradle
10 | build/
11 | bin/
12 | _site/
13 | target/
14 | *.iml
15 | .idea
16 | .factorypath
17 | *.versionsBackup
18 | .flattened-pom.xml
19 | .sdkmanrc
20 |
--------------------------------------------------------------------------------
/.mvn/jvm.config:
--------------------------------------------------------------------------------
1 | -Xmx1024m -XX:CICompilerCount=1 -XX:TieredStopAtLevel=1 -Djava.security.egd=file:/dev/./urandom
--------------------------------------------------------------------------------
/.mvn/maven.config:
--------------------------------------------------------------------------------
1 | -DaltSnapshotDeploymentRepository=repo.spring.io::default::https://repo.spring.io/libs-snapshot-local -P spring
2 |
--------------------------------------------------------------------------------
/.mvn/wrapper/maven-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spring-cloud/spring-cloud-cli/e240bea402c09921cbcfee84bc9d9d74ce87bf4d/.mvn/wrapper/maven-wrapper.jar
--------------------------------------------------------------------------------
/.mvn/wrapper/maven-wrapper.properties:
--------------------------------------------------------------------------------
1 | distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.4/apache-maven-3.5.4-bin.zip
2 |
--------------------------------------------------------------------------------
/.settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | repo.spring.io
6 | ${env.CI_DEPLOY_USERNAME}
7 | ${env.CI_DEPLOY_PASSWORD}
8 |
9 |
10 |
11 |
12 |
18 | spring
19 | true
20 |
21 |
22 | spring-snapshots
23 | Spring Snapshots
24 | https://repo.spring.io/libs-snapshot-local
25 |
26 | true
27 |
28 |
29 |
30 | spring-milestones
31 | Spring Milestones
32 | https://repo.spring.io/libs-milestone-local
33 |
34 | false
35 |
36 |
37 |
38 | spring-releases
39 | Spring Releases
40 | https://repo.spring.io/release
41 |
42 | false
43 |
44 |
45 |
46 |
47 |
48 | spring-snapshots
49 | Spring Snapshots
50 | https://repo.spring.io/libs-snapshot-local
51 |
52 | true
53 |
54 |
55 |
56 | spring-milestones
57 | Spring Milestones
58 | https://repo.spring.io/libs-milestone-local
59 |
60 | false
61 |
62 |
63 |
64 |
65 |
66 |
67 |
--------------------------------------------------------------------------------
/Guardfile:
--------------------------------------------------------------------------------
1 | require 'asciidoctor'
2 | require 'erb'
3 | require './src/main/ruby/readme.rb'
4 |
5 | options = {:mkdirs => true, :safe => :unsafe, :attributes => ['linkcss', 'allow-uri-read']}
6 |
7 | guard 'shell' do
8 | watch(/^src\/[A-Z-a-z][^#]*\.adoc$/) {|m|
9 | SpringCloud::Build.render_file('src/main/asciidoc/README.adoc', :to_file => './README.adoc')
10 | Asciidoctor.render_file('src/main/asciidoc/spring-cloud-cli.adoc', options.merge(:to_dir => 'target/generated-docs'))
11 | }
12 | end
13 |
--------------------------------------------------------------------------------
/docs/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 | org.springframework.cloud
6 | spring-cloud-cli-docs
7 |
8 | org.springframework.cloud
9 | spring-cloud-cli-parent
10 | 3.1.2-SNAPSHOT
11 |
12 | jar
13 | Spring Cloud Cli Docs
14 | Spring Cloud Docs
15 |
16 | spring-cloud-cli
17 | ${basedir}/..
18 | deploy
19 |
20 | none
21 |
22 |
23 | src/main/asciidoc
24 |
25 |
26 |
27 | maven-deploy-plugin
28 |
29 | true
30 |
31 |
32 |
33 | org.sonatype.plugins
34 | nexus-staging-maven-plugin
35 |
36 | true
37 |
38 |
39 |
40 |
41 |
42 |
43 | docs
44 |
45 |
46 |
47 | pl.project13.maven
48 | git-commit-id-plugin
49 |
50 |
51 | org.apache.maven.plugins
52 | maven-dependency-plugin
53 |
54 |
55 | org.apache.maven.plugins
56 | maven-resources-plugin
57 |
58 |
59 | org.codehaus.mojo
60 | exec-maven-plugin
61 |
62 |
63 | org.asciidoctor
64 | asciidoctor-maven-plugin
65 |
66 |
67 | org.apache.maven.plugins
68 | maven-antrun-plugin
69 |
70 |
71 | maven-deploy-plugin
72 |
73 |
74 |
75 |
76 |
77 |
78 |
--------------------------------------------------------------------------------
/docs/src/main/asciidoc/README.adoc:
--------------------------------------------------------------------------------
1 | image:https://circleci.com/gh/spring-cloud/spring-cloud-cli.svg?style=svg["CircleCI", link="https://circleci.com/gh/spring-cloud/spring-cloud-cli"]
2 |
3 | include::intro.adoc[]
4 |
5 | == Installation
6 |
7 | include::install.adoc[]
8 |
9 | == Building
10 |
11 | include::https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/3.1.x/docs/src/main/asciidoc/building.adoc[]
12 |
13 | == Contributing
14 |
15 | include::https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/3.1.x/docs/src/main/asciidoc/contributing.adoc[]
16 |
--------------------------------------------------------------------------------
/docs/src/main/asciidoc/images/spring-cloud-launcher-eureka-dashboard.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spring-cloud/spring-cloud-cli/e240bea402c09921cbcfee84bc9d9d74ce87bf4d/docs/src/main/asciidoc/images/spring-cloud-launcher-eureka-dashboard.png
--------------------------------------------------------------------------------
/docs/src/main/asciidoc/images/spring-cloud-launcher-log.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spring-cloud/spring-cloud-cli/e240bea402c09921cbcfee84bc9d9d74ce87bf4d/docs/src/main/asciidoc/images/spring-cloud-launcher-log.png
--------------------------------------------------------------------------------
/docs/src/main/asciidoc/index.adoc:
--------------------------------------------------------------------------------
1 | spring-cloud-cli.adoc
--------------------------------------------------------------------------------
/docs/src/main/asciidoc/install.adoc:
--------------------------------------------------------------------------------
1 | To install, make
2 | sure you have
3 | https://github.com/spring-projects/spring-boot[Spring Boot CLI]
4 | (2.0.0 or better):
5 |
6 | $ spring version
7 | Spring CLI v2.2.3.RELEASE
8 |
9 | E.g. for SDKMan users
10 |
11 | ```
12 | $ sdk install springboot 2.2.3.RELEASE
13 | $ sdk use springboot 2.2.3.RELEASE
14 | ```
15 |
16 | and install the Spring Cloud plugin
17 |
18 | ```
19 | $ mvn install
20 | $ spring install org.springframework.cloud:spring-cloud-cli:2.2.0.RELEASE
21 | ```
22 |
23 | IMPORTANT: **Prerequisites:** to use the encryption and decryption features
24 | you need the full-strength JCE installed in your JVM (it's not there by default).
25 | You can download the "Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files"
26 | from Oracle, and follow instructions for installation (essentially replace the 2 policy files
27 | in the JRE lib/security directory with the ones that you downloaded).
28 |
--------------------------------------------------------------------------------
/docs/src/main/asciidoc/intro.adoc:
--------------------------------------------------------------------------------
1 | Spring Boot CLI provides https://projects.spring.io/spring-boot[Spring
2 | Boot] command line features for https://github.com/spring-cloud[Spring
3 | Cloud]. You can write Groovy scripts to run Spring Cloud component
4 | applications (e.g. `@EnableEurekaServer`). You can also easily do
5 | things like encryption and decryption to support Spring Cloud Config
6 | clients with secret configuration values. With the Launcher CLI you
7 | can launch services like Eureka, Zipkin, Config Server
8 | conveniently all at once from the command line (very useful at
9 | development time).
10 |
11 |
--------------------------------------------------------------------------------
/docs/src/main/asciidoc/sagan-boot.adoc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spring-cloud/spring-cloud-cli/e240bea402c09921cbcfee84bc9d9d74ce87bf4d/docs/src/main/asciidoc/sagan-boot.adoc
--------------------------------------------------------------------------------
/docs/src/main/asciidoc/sagan-index.adoc:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spring-cloud/spring-cloud-cli/e240bea402c09921cbcfee84bc9d9d74ce87bf4d/docs/src/main/asciidoc/sagan-index.adoc
--------------------------------------------------------------------------------
/docs/src/main/asciidoc/spring-cloud-cli.adoc:
--------------------------------------------------------------------------------
1 | = Spring Boot Cloud CLI
2 | :github: https://github.com/spring-cloud/spring-cloud-cli
3 | :githubmaster: {github}/tree/master
4 | :docslink: {githubmaster}/docs/src/main/asciidoc
5 | :nofooter:
6 |
7 | include::intro.adoc[]
8 |
9 | include::https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/3.1.x/docs/src/main/asciidoc/contributing-docs.adoc[]
10 |
11 | == Installation
12 |
13 | include::install.adoc[]
14 |
15 | == Running Spring Cloud Services in Development
16 |
17 | The Launcher CLI can be used to run common services like Eureka,
18 | Config Server etc. from the command line. To list the available
19 | services you can do `spring cloud --list`, and to launch a default set
20 | of services just `spring cloud`. To choose the services to deploy,
21 | just list them on the command line, e.g.
22 |
23 | ----
24 | $ spring cloud eureka configserver h2 kafka stubrunner zipkin
25 | ----
26 |
27 | Summary of supported deployables:
28 |
29 | [options="header"]
30 | |===
31 | |Service | Name | Address | Description
32 |
33 | |eureka | Eureka Server | http://localhost:8761
34 | | Eureka server for service registration and discovery. All the other services show up in its catalog by default.
35 |
36 | |configserver | Config Server | http://localhost:8888
37 | |Spring Cloud Config Server running in the "native" profile and serving configuration from the local directory ./launcher
38 |
39 | |h2 | H2 Database | http://localhost:9095 (console), jdbc:h2:tcp://localhost:9096/{data}
40 | | Relation database service. Use a file path for `{data}` (e.g. `./target/test`) when you connect. Remember that you can add `;MODE=MYSQL` or `;MODE=POSTGRESQL` to connect with compatibility to other server types.
41 |
42 | |kafka | Kafka Broker | http://localhost:9091 (actuator endpoints), localhost:9092
43 | |
44 |
45 | |dataflow | Dataflow Server | http://localhost:9393
46 | | Spring Cloud Dataflow server with UI at /admin-ui. Connect the Dataflow shell to target at root path.
47 |
48 | |zipkin | Zipkin Server | http://localhost:9411
49 | | Zipkin Server with UI for visualizing traces. Stores span data in memory and accepts them via HTTP POST of JSON data.
50 |
51 | |stubrunner | Stub Runner Boot | http://localhost:8750
52 | | Downloads WireMock stubs, starts WireMock and feeds the started servers with stored stubs. Pass `stubrunner.ids` to pass stub coordinates and then go to `http://localhost:8750/stubs`.
53 | |===
54 |
55 | Each of these apps can be configured using a local YAML file with the same name (in the current
56 | working directory or a subdirectory called "config" or in `~/.spring-cloud`). E.g. in `configserver.yml` you might want to
57 | do something like this to locate a local git repository for the backend:
58 |
59 | .configserver.yml
60 | [source,yaml,indent=0]
61 | ----
62 | spring:
63 | profiles:
64 | active: git
65 | cloud:
66 | config:
67 | server:
68 | git:
69 | uri: file://${user.home}/dev/demo/config-repo
70 | ----
71 |
72 | E.g. in Stub Runner app you could fetch stubs from your local `.m2` in the following way.
73 |
74 | .stubrunner.yml
75 | [source,yaml,indent=0]
76 | ----
77 | stubrunner:
78 | workOffline: true
79 | ids:
80 | - com.example:beer-api-producer:+:9876
81 | ----
82 |
83 | === Adding Additional Applications
84 |
85 | Additional applications can be added to `./config/cloud.yml` (not
86 | `./config.yml` because that would replace the defaults), e.g. with
87 |
88 | .config/cloud.yml
89 | [source,yaml]
90 | ----
91 | spring:
92 | cloud:
93 | launcher:
94 | deployables:
95 | source:
96 | coordinates: maven://com.example:source:0.0.1-SNAPSHOT
97 | port: 7000
98 | sink:
99 | coordinates: maven://com.example:sink:0.0.1-SNAPSHOT
100 | port: 7001
101 | ----
102 |
103 | when you list the apps:
104 |
105 | [source]
106 | ----
107 | $ spring cloud --list
108 | source sink configserver dataflow eureka h2 kafka stubrunner zipkin
109 | ----
110 |
111 | (notice the additional apps at the start of the list).
112 |
113 | == Writing Groovy Scripts and Running Applications
114 |
115 | Spring Cloud CLI has support for most of the Spring Cloud declarative
116 | features, such as the `@Enable*` class of annotations. For example,
117 | here is a fully functional Eureka server
118 |
119 | .app.groovy
120 | [source,groovy,indent=0]
121 | ----
122 | @EnableEurekaServer
123 | class Eureka {}
124 | ----
125 |
126 | which you can run from the command line like this
127 |
128 | ----
129 | $ spring run app.groovy
130 | ----
131 |
132 | To include additional dependencies, often it suffices just to add the
133 | appropriate feature-enabling annotation, e.g. `@EnableConfigServer`,
134 | `@EnableOAuth2Sso` or `@EnableEurekaClient`. To manually include a
135 | dependency you can use a `@Grab` with the special "Spring Boot" short
136 | style artifact co-ordinates, i.e. with just the artifact ID (no need
137 | for group or version information), e.g. to set up a client app to
138 | listen on AMQP for management events from the Spring CLoud Bus:
139 |
140 | .app.groovy
141 | [source,groovy,indent=0]
142 | ----
143 | @Grab('spring-cloud-starter-bus-amqp')
144 | @RestController
145 | class Service {
146 | @RequestMapping('/')
147 | def home() { [message: 'Hello'] }
148 | }
149 | ----
150 |
151 | == Encryption and Decryption
152 |
153 | The Spring Cloud CLI comes with an "encrypt" and a "decrypt"
154 | command. Both accept arguments in the same form with a key specified
155 | as a mandatory "--key", e.g.
156 |
157 | ----
158 | $ spring encrypt mysecret --key foo
159 | 682bc583f4641835fa2db009355293665d2647dade3375c0ee201de2a49f7bda
160 | $ spring decrypt --key foo 682bc583f4641835fa2db009355293665d2647dade3375c0ee201de2a49f7bda
161 | mysecret
162 | ----
163 |
164 | To use a key in a file (e.g. an RSA public key for encyption) prepend
165 | the key value with "@" and provide the file path, e.g.
166 |
167 | ----
168 | $ spring encrypt mysecret --key @${HOME}/.ssh/id_rsa.pub
169 | AQAjPgt3eFZQXwt8tsHAVv/QHiY5sI2dRcR+...
170 | ----
171 |
--------------------------------------------------------------------------------
/docs/src/main/ruby/generate_readme.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 |
3 | base_dir = File.join(File.dirname(__FILE__),'../../..')
4 | src_dir = File.join(base_dir, "/src/main/asciidoc")
5 | require 'asciidoctor'
6 | require 'optparse'
7 |
8 | options = {}
9 | file = "#{src_dir}/README.adoc"
10 |
11 | OptionParser.new do |o|
12 | o.on('-o OUTPUT_FILE', 'Output file (default is stdout)') { |file| options[:to_file] = file unless file=='-' }
13 | o.on('-h', '--help') { puts o; exit }
14 | o.parse!
15 | end
16 |
17 | file = ARGV[0] if ARGV.length>0
18 |
19 | # Copied from https://github.com/asciidoctor/asciidoctor-extensions-lab/blob/master/scripts/asciidoc-coalescer.rb
20 | doc = Asciidoctor.load_file file, safe: :unsafe, header_only: true, attributes: options[:attributes]
21 | header_attr_names = (doc.instance_variable_get :@attributes_modified).to_a
22 | header_attr_names.each {|k| doc.attributes[%(#{k}!)] = '' unless doc.attr? k }
23 | attrs = doc.attributes
24 | attrs['allow-uri-read'] = true
25 | puts attrs
26 |
27 | out = "// Do not edit this file (e.g. go instead to src/main/asciidoc)\n\n"
28 | doc = Asciidoctor.load_file file, safe: :unsafe, parse: false, attributes: attrs
29 | out << doc.reader.read
30 |
31 | unless options[:to_file]
32 | puts out
33 | else
34 | File.open(options[:to_file],'w+') do |file|
35 | file.write(out)
36 | end
37 | end
38 |
--------------------------------------------------------------------------------
/mvnw.cmd:
--------------------------------------------------------------------------------
1 | @REM ----------------------------------------------------------------------------
2 | @REM Licensed to the Apache Software Foundation (ASF) under one
3 | @REM or more contributor license agreements. See the NOTICE file
4 | @REM distributed with this work for additional information
5 | @REM regarding copyright ownership. The ASF licenses this file
6 | @REM to you under the Apache License, Version 2.0 (the
7 | @REM "License"); you may not use this file except in compliance
8 | @REM with the License. You may obtain a copy of the License at
9 | @REM
10 | @REM https://www.apache.org/licenses/LICENSE-2.0
11 | @REM
12 | @REM Unless required by applicable law or agreed to in writing,
13 | @REM software distributed under the License is distributed on an
14 | @REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 | @REM KIND, either express or implied. See the License for the
16 | @REM specific language governing permissions and limitations
17 | @REM under the License.
18 | @REM ----------------------------------------------------------------------------
19 |
20 | @REM ----------------------------------------------------------------------------
21 | @REM Maven2 Start Up Batch script
22 | @REM
23 | @REM Required ENV vars:
24 | @REM JAVA_HOME - location of a JDK home dir
25 | @REM
26 | @REM Optional ENV vars
27 | @REM M2_HOME - location of maven2's installed home dir
28 | @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
29 | @REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
30 | @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
31 | @REM e.g. to debug Maven itself, use
32 | @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
33 | @REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
34 | @REM ----------------------------------------------------------------------------
35 |
36 | @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
37 | @echo off
38 | @REM enable echoing my setting MAVEN_BATCH_ECHO to 'on'
39 | @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
40 |
41 | @REM set %HOME% to equivalent of $HOME
42 | if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
43 |
44 | @REM Execute a user defined script before this one
45 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
46 | @REM check for pre script, once with legacy .bat ending and once with .cmd ending
47 | if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
48 | if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
49 | :skipRcPre
50 |
51 | @setlocal
52 |
53 | set ERROR_CODE=0
54 |
55 | @REM To isolate internal variables from possible post scripts, we use another setlocal
56 | @setlocal
57 |
58 | @REM ==== START VALIDATION ====
59 | if not "%JAVA_HOME%" == "" goto OkJHome
60 |
61 | echo.
62 | echo Error: JAVA_HOME not found in your environment. >&2
63 | echo Please set the JAVA_HOME variable in your environment to match the >&2
64 | echo location of your Java installation. >&2
65 | echo.
66 | goto error
67 |
68 | :OkJHome
69 | if exist "%JAVA_HOME%\bin\java.exe" goto init
70 |
71 | echo.
72 | echo Error: JAVA_HOME is set to an invalid directory. >&2
73 | echo JAVA_HOME = "%JAVA_HOME%" >&2
74 | echo Please set the JAVA_HOME variable in your environment to match the >&2
75 | echo location of your Java installation. >&2
76 | echo.
77 | goto error
78 |
79 | @REM ==== END VALIDATION ====
80 |
81 | :init
82 |
83 | set MAVEN_CMD_LINE_ARGS=%*
84 |
85 | @REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
86 | @REM Fallback to current working directory if not found.
87 |
88 | set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
89 | IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
90 |
91 | set EXEC_DIR=%CD%
92 | set WDIR=%EXEC_DIR%
93 | :findBaseDir
94 | IF EXIST "%WDIR%"\.mvn goto baseDirFound
95 | cd ..
96 | IF "%WDIR%"=="%CD%" goto baseDirNotFound
97 | set WDIR=%CD%
98 | goto findBaseDir
99 |
100 | :baseDirFound
101 | set MAVEN_PROJECTBASEDIR=%WDIR%
102 | cd "%EXEC_DIR%"
103 | goto endDetectBaseDir
104 |
105 | :baseDirNotFound
106 | set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
107 | cd "%EXEC_DIR%"
108 |
109 | :endDetectBaseDir
110 |
111 | IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
112 |
113 | @setlocal EnableExtensions EnableDelayedExpansion
114 | for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
115 | @endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
116 |
117 | :endReadAdditionalConfig
118 |
119 | SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
120 |
121 | set WRAPPER_JAR="".\.mvn\wrapper\maven-wrapper.jar""
122 | set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
123 |
124 | %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%
125 | if ERRORLEVEL 1 goto error
126 | goto end
127 |
128 | :error
129 | set ERROR_CODE=1
130 |
131 | :end
132 | @endlocal & set ERROR_CODE=%ERROR_CODE%
133 |
134 | if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
135 | @REM check for post script, once with legacy .bat ending and once with .cmd ending
136 | if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
137 | if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
138 | :skipRcPost
139 |
140 | @REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
141 | if "%MAVEN_BATCH_PAUSE%" == "on" pause
142 |
143 | if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
144 |
145 | exit /B %ERROR_CODE%
146 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 | org.springframework.cloud
7 | spring-cloud-cli-parent
8 | 3.1.2-SNAPSHOT
9 |
10 | org.springframework.cloud
11 | spring-cloud-build
12 | 3.1.4-SNAPSHOT
13 |
14 |
15 | pom
16 | Spring Cloud Cli Parent
17 | Spring Cloud Cli
18 | https://projects.spring.io/spring-cloud/
19 |
20 | https://github.com/spring-cloud/spring-cloud-cli
21 | scm:git:git://github.com/spring-cloud/spring-cloud-cli.git
22 |
23 |
24 | scm:git:ssh://git@github.com/spring-cloud/spring-cloud-cli.git
25 |
26 | HEAD
27 |
28 |
29 | cli
30 | spring-cloud-cli
31 | ${basedir}/..
32 | 2.6.8
33 | 2021.0.4-SNAPSHOT
34 |
35 |
36 | spring-cloud-launcher
37 | spring-cloud-cli
38 | spring-cloud-cli-integration-tests
39 | docs
40 |
41 |
42 |
43 |
44 | org.codehaus.mojo
45 | flatten-maven-plugin
46 |
47 |
48 |
49 |
50 |
51 | spring
52 |
53 |
54 | spring-snapshots
55 | Spring Snapshots
56 | https://repo.spring.io/snapshot
57 |
58 | true
59 |
60 |
61 | false
62 |
63 |
64 |
65 | spring-milestones
66 | Spring Milestones
67 | https://repo.spring.io/milestone
68 |
69 | false
70 |
71 |
72 |
73 | spring-releases
74 | Spring Releases
75 | https://repo.spring.io/release
76 |
77 | false
78 |
79 |
80 |
81 |
82 |
83 | spring-snapshots
84 | Spring Snapshots
85 | https://repo.spring.io/snapshot
86 |
87 | true
88 |
89 |
90 |
91 | spring-milestones
92 | Spring Milestones
93 | https://repo.spring.io/milestone
94 |
95 | false
96 |
97 |
98 |
99 | spring-releases
100 | Spring Releases
101 | https://repo.spring.io/release
102 |
103 | false
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 | org.springframework.boot
113 | spring-boot-dependencies
114 | ${spring-boot.version}
115 | pom
116 | import
117 |
118 |
119 | org.springframework.cloud
120 | spring-cloud-dependencies
121 | ${spring-cloud.version}
122 | pom
123 | import
124 |
125 |
126 | org.springframework.cloud
127 | spring-cloud-starter-stream-kafka
128 |
129 |
130 | org.apache.kafka
131 | kafka_2.11
132 |
133 |
134 |
135 |
136 | net.sf.jopt-simple
137 | jopt-simple
138 | 5.0.4
139 |
140 |
141 |
142 |
143 |
--------------------------------------------------------------------------------
/spring-cloud-cli-integration-tests/.gitignore:
--------------------------------------------------------------------------------
1 | /target/
2 |
--------------------------------------------------------------------------------
/spring-cloud-cli-integration-tests/README.md:
--------------------------------------------------------------------------------
1 | Spring Boot command line features for
2 | [Spring Cloud](https://github.com/spring-cloud). To install, make
3 | sure you have
4 | [Spring Boot CLI](https://github.com/spring-projects/spring-boot)
5 | (1.1.x with x>=5):
6 |
7 | $ spring version
8 | Spring CLI v1.1.5.RELEASE
9 |
10 |
--------------------------------------------------------------------------------
/spring-cloud-cli-integration-tests/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | spring-cloud-cli-integration-tests
8 | jar
9 |
10 | spring-cloud-cli-integration-tests
11 | Spring Patform Cli integration project
12 |
13 |
14 | org.springframework.cloud
15 | spring-cloud-cli-parent
16 | 3.1.2-SNAPSHOT
17 |
18 |
19 |
20 |
21 |
22 | org.apache.maven
23 | maven-settings-builder
24 | ${maven.version}
25 |
26 |
27 |
28 |
29 |
30 |
31 | org.springframework.cloud
32 | spring-cloud-cli
33 | ${project.version}
34 | provided
35 |
36 |
37 | org.springframework.boot
38 | spring-boot-cli
39 | ${spring-boot.version}
40 | provided
41 |
42 |
43 | commons-logging
44 | commons-logging
45 | 1.2
46 | provided
47 |
48 |
49 | org.springframework.boot
50 | spring-boot-starter-test
51 | test
52 |
53 |
54 | junit
55 | junit
56 | test
57 |
58 |
59 |
60 |
61 | UTF-8
62 | 1.8
63 | 1.8
64 | 3.6.3
65 |
66 |
67 |
68 |
69 |
70 | maven-deploy-plugin
71 |
72 | true
73 |
74 |
75 |
76 | org.sonatype.plugins
77 | nexus-staging-maven-plugin
78 |
79 | true
80 |
81 |
82 |
83 | maven-jar-plugin
84 |
85 | true
86 |
87 |
88 |
89 | maven-install-plugin
90 |
91 | true
92 |
93 |
94 |
95 | maven-gpg-plugin
96 |
97 | true
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 | org.eclipse.m2e
106 | lifecycle-mapping
107 | 1.0.0
108 |
109 |
110 |
111 |
112 |
113 |
114 | org.codehaus.mojo
115 |
116 |
117 | exec-maven-plugin
118 |
119 |
120 | [1.6.0,)
121 |
122 |
123 | exec
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
--------------------------------------------------------------------------------
/spring-cloud-cli-integration-tests/samples/app.groovy:
--------------------------------------------------------------------------------
1 | package org.test
2 |
3 | @Component
4 | class Example implements CommandLineRunner {
5 |
6 | @Autowired
7 | private MyService myService
8 |
9 | void run(String... args) {
10 | println "Hello ${this.myService.sayWorld()} From ${getClass().getClassLoader().getResource('samples/app.groovy')}"
11 | }
12 | }
13 |
14 |
15 | @Service
16 | class MyService {
17 |
18 | String sayWorld() {
19 | return "World!"
20 | }
21 | }
22 |
23 |
--------------------------------------------------------------------------------
/spring-cloud-cli-integration-tests/samples/configserver.groovy:
--------------------------------------------------------------------------------
1 | package org.test
2 |
3 | @EnableConfigServer
4 | class Example {
5 | }
6 |
7 |
--------------------------------------------------------------------------------
/spring-cloud-cli-integration-tests/samples/eureka.groovy:
--------------------------------------------------------------------------------
1 | package org.test
2 |
3 | @EnableDiscoveryClient
4 | class Example {
5 | }
6 |
7 |
--------------------------------------------------------------------------------
/spring-cloud-cli-integration-tests/samples/eurekaserver.groovy:
--------------------------------------------------------------------------------
1 | package org.test
2 |
3 | @EnableEurekaServer
4 | class Example {
5 | }
6 |
7 |
--------------------------------------------------------------------------------
/spring-cloud-cli-integration-tests/samples/rabbit.groovy:
--------------------------------------------------------------------------------
1 | package org.test
2 |
3 | @EnableBinding(value=Source, transport="rabbit")
4 | class Example {
5 | }
6 |
7 |
--------------------------------------------------------------------------------
/spring-cloud-cli-integration-tests/samples/stubrunner.groovy:
--------------------------------------------------------------------------------
1 | package org.test
2 |
3 | @EnableStubRunnerServer
4 | class Example {
5 | }
6 |
7 |
--------------------------------------------------------------------------------
/spring-cloud-cli-integration-tests/src/test/java/org/springframework/cloud/cli/CliTester.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012-2014 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cloud.cli;
18 |
19 | import java.io.BufferedReader;
20 | import java.io.File;
21 | import java.io.InputStream;
22 | import java.io.InputStreamReader;
23 | import java.lang.reflect.Field;
24 | import java.net.URI;
25 | import java.net.URL;
26 | import java.util.ArrayList;
27 | import java.util.List;
28 | import java.util.concurrent.Callable;
29 | import java.util.concurrent.Executors;
30 | import java.util.concurrent.Future;
31 | import java.util.concurrent.TimeUnit;
32 |
33 | import org.junit.Assume;
34 | import org.junit.rules.TestRule;
35 | import org.junit.runner.Description;
36 | import org.junit.runners.model.Statement;
37 |
38 | import org.springframework.boot.cli.command.AbstractCommand;
39 | import org.springframework.boot.cli.command.OptionParsingCommand;
40 | import org.springframework.boot.cli.command.archive.JarCommand;
41 | import org.springframework.boot.cli.command.grab.GrabCommand;
42 | import org.springframework.boot.cli.command.run.RunCommand;
43 | import org.springframework.boot.test.system.OutputCaptureRule;
44 | import org.springframework.util.SocketUtils;
45 |
46 | /**
47 | * {@link TestRule} that can be used to invoke CLI commands.
48 | *
49 | * @author Phillip Webb
50 | * @author Dave Syer
51 | * @author Andy Wilkinson
52 | */
53 | public class CliTester implements TestRule {
54 |
55 | private final OutputCaptureRule outputCapture = new OutputCaptureRule();
56 |
57 | private long timeout = TimeUnit.MINUTES.toMillis(6);
58 |
59 | private final List commands = new ArrayList();
60 |
61 | private final String prefix;
62 |
63 | private final int port = SocketUtils.findAvailableTcpPort();
64 |
65 | public CliTester(String prefix) {
66 | this.prefix = prefix;
67 | }
68 |
69 | public void setTimeout(long timeout) {
70 | this.timeout = timeout;
71 | }
72 |
73 | public String run(String... args) throws Exception {
74 | Future future = submitCommand(new RunCommand(), args);
75 | this.commands.add(future.get(this.timeout, TimeUnit.MILLISECONDS));
76 | return getOutput();
77 | }
78 |
79 | public String grab(String... args) throws Exception {
80 | Future future = submitCommand(new GrabCommand(), args);
81 | this.commands.add(future.get(this.timeout, TimeUnit.MILLISECONDS));
82 | return getOutput();
83 | }
84 |
85 | public String jar(String... args) throws Exception {
86 | Future future = submitCommand(new JarCommand(), args);
87 | this.commands.add(future.get(this.timeout, TimeUnit.MILLISECONDS));
88 | return getOutput();
89 | }
90 |
91 | private Future submitCommand(final T command,
92 | String... args) {
93 | clearUrlHandler();
94 | final String[] sources = getSources(args);
95 | return Executors.newSingleThreadExecutor().submit(new Callable() {
96 | @Override
97 | public T call() throws Exception {
98 | ClassLoader loader = Thread.currentThread().getContextClassLoader();
99 | System.setProperty("server.port", String.valueOf(CliTester.this.port));
100 | try {
101 | command.run(sources);
102 | return command;
103 | }
104 | finally {
105 | System.clearProperty("server.port");
106 | Thread.currentThread().setContextClassLoader(loader);
107 | }
108 | }
109 | });
110 | }
111 |
112 | /**
113 | * The TomcatURLStreamHandlerFactory fails if the factory is already set, use
114 | * reflection to reset it.
115 | */
116 | private void clearUrlHandler() {
117 | try {
118 | Field field = URL.class.getDeclaredField("factory");
119 | field.setAccessible(true);
120 | field.set(null, null);
121 | }
122 | catch (Exception ex) {
123 | throw new IllegalStateException(ex);
124 | }
125 | }
126 |
127 | protected String[] getSources(String... args) {
128 | final String[] sources = new String[args.length];
129 | for (int i = 0; i < args.length; i++) {
130 | String arg = args[i];
131 | if (!arg.endsWith(".groovy") && !arg.endsWith(".xml")) {
132 | if (new File(this.prefix + arg).isDirectory()) {
133 | sources[i] = this.prefix + arg;
134 | }
135 | else {
136 | sources[i] = arg;
137 | }
138 | }
139 | else {
140 | sources[i] = this.prefix + arg;
141 | }
142 | }
143 | return sources;
144 | }
145 |
146 | public String getOutput() {
147 | return this.outputCapture.toString();
148 | }
149 |
150 | @Override
151 | public Statement apply(final Statement base, final Description description) {
152 | final Statement statement = CliTester.this.outputCapture
153 | .apply(new RunLauncherStatement(base), description);
154 | return new Statement() {
155 |
156 | @Override
157 | public void evaluate() throws Throwable {
158 | Assume.assumeTrue(
159 | "Not running sample integration tests because integration profile not active",
160 | System.getProperty("spring.profiles.active", "integration")
161 | .contains("integration"));
162 | statement.evaluate();
163 | }
164 | };
165 | }
166 |
167 | public String getHttpOutput() {
168 | return getHttpOutput("/");
169 | }
170 |
171 | public String getHttpOutput(String uri) {
172 | try {
173 | InputStream stream = URI.create("http://localhost:" + this.port + uri).toURL()
174 | .openStream();
175 | BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
176 | String line;
177 | StringBuilder result = new StringBuilder();
178 | while ((line = reader.readLine()) != null) {
179 | result.append(line);
180 | }
181 | return result.toString();
182 | }
183 | catch (Exception ex) {
184 | throw new IllegalStateException(ex);
185 | }
186 | }
187 |
188 | private final class RunLauncherStatement extends Statement {
189 |
190 | private final Statement base;
191 |
192 | private RunLauncherStatement(Statement base) {
193 | this.base = base;
194 | }
195 |
196 | @Override
197 | public void evaluate() throws Throwable {
198 | System.setProperty("disableSpringSnapshotRepos", "false");
199 | try {
200 | try {
201 | this.base.evaluate();
202 | }
203 | finally {
204 | for (AbstractCommand command : CliTester.this.commands) {
205 | if (command != null && command instanceof RunCommand) {
206 | ((RunCommand) command).stop();
207 | }
208 | }
209 | System.clearProperty("disableSpringSnapshotRepos");
210 | }
211 | }
212 | catch (Exception ex) {
213 | throw new IllegalStateException(ex);
214 | }
215 | }
216 | }
217 |
218 | }
219 |
--------------------------------------------------------------------------------
/spring-cloud-cli-integration-tests/src/test/java/org/springframework/cloud/cli/OutputCapture.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012-2014 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cloud.cli;
18 |
19 | import java.io.ByteArrayOutputStream;
20 | import java.io.IOException;
21 | import java.io.OutputStream;
22 | import java.io.PrintStream;
23 |
24 | import org.junit.rules.TestRule;
25 | import org.junit.runner.Description;
26 | import org.junit.runners.model.Statement;
27 |
28 | /**
29 | * Capture output from System.out and System.err.
30 | *
31 | * @author Phillip Webb
32 | */
33 | public class OutputCapture implements TestRule {
34 |
35 | private CaptureOutputStream captureOut;
36 |
37 | private CaptureOutputStream captureErr;
38 |
39 | private ByteArrayOutputStream copy;
40 |
41 | @Override
42 | public Statement apply(final Statement base, Description description) {
43 | return new Statement() {
44 | @Override
45 | public void evaluate() throws Throwable {
46 | captureOutput();
47 | try {
48 | base.evaluate();
49 | }
50 | finally {
51 | releaseOutput();
52 | }
53 | }
54 | };
55 | }
56 |
57 | protected void captureOutput() {
58 | this.copy = new ByteArrayOutputStream();
59 | this.captureOut = new CaptureOutputStream(System.out, this.copy);
60 | this.captureErr = new CaptureOutputStream(System.err, this.copy);
61 | System.setOut(new PrintStream(this.captureOut));
62 | System.setErr(new PrintStream(this.captureErr));
63 | }
64 |
65 | protected void releaseOutput() {
66 | System.setOut(this.captureOut.getOriginal());
67 | System.setErr(this.captureErr.getOriginal());
68 | this.copy = null;
69 | }
70 |
71 | public void flush() {
72 | try {
73 | this.captureOut.flush();
74 | this.captureErr.flush();
75 | }
76 | catch (IOException ex) {
77 | // ignore
78 | }
79 | }
80 |
81 | @Override
82 | public String toString() {
83 | flush();
84 | return this.copy.toString();
85 | }
86 |
87 | private static class CaptureOutputStream extends OutputStream {
88 |
89 | private final PrintStream original;
90 |
91 | private final OutputStream copy;
92 |
93 | CaptureOutputStream(PrintStream original, OutputStream copy) {
94 | this.original = original;
95 | this.copy = copy;
96 | }
97 |
98 | @Override
99 | public void write(int b) throws IOException {
100 | this.copy.write(b);
101 | this.original.write(b);
102 | this.original.flush();
103 | }
104 |
105 | @Override
106 | public void write(byte[] b) throws IOException {
107 | write(b, 0, b.length);
108 | }
109 |
110 | @Override
111 | public void write(byte[] b, int off, int len) throws IOException {
112 | this.copy.write(b, off, len);
113 | this.original.write(b, off, len);
114 | }
115 |
116 | public PrintStream getOriginal() {
117 | return this.original;
118 | }
119 |
120 | @Override
121 | public void flush() throws IOException {
122 | this.copy.flush();
123 | this.original.flush();
124 | }
125 | }
126 |
127 | }
128 |
--------------------------------------------------------------------------------
/spring-cloud-cli-integration-tests/src/test/java/org/springframework/cloud/cli/SampleIntegrationTests.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2013-2015 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.cloud.cli;
17 |
18 | import java.io.File;
19 | import java.net.URI;
20 |
21 | import org.junit.BeforeClass;
22 | import org.junit.Ignore;
23 | import org.junit.Rule;
24 | import org.junit.Test;
25 |
26 | import static org.junit.Assert.assertTrue;
27 |
28 | /**
29 | * @author Dave Syer
30 | *
31 | */
32 | public class SampleIntegrationTests {
33 |
34 | @Rule
35 | public CliTester cli = new CliTester("samples/");
36 |
37 | @BeforeClass
38 | public static void setup() {
39 | System.setProperty("spring.main.allow-bean-definition-overriding", "true");
40 | }
41 |
42 | @Test
43 | @Ignore // FIXME: 3.0.0
44 | public void appSample() throws Exception {
45 | String output = this.cli.run("app.groovy");
46 | URI scriptUri = new File("samples/app.groovy").toURI();
47 | assertTrue("Wrong output: " + output,
48 | output.contains("Hello World! From " + scriptUri));
49 | }
50 |
51 | @Test
52 | @Ignore // FIXME: 3.0.0
53 | public void eurekaSample() throws Exception {
54 | String output = this.cli.run("eureka.groovy");
55 | assertTrue("Wrong output: " + output,
56 | output.contains("Setting initial instance status as: STARTING"));
57 | }
58 |
59 | @Test
60 | @Ignore // FIXME: 3.0.0
61 | public void eurekaServerSample() throws Exception {
62 | String output = this.cli.run("eurekaserver.groovy", "--", "--debug");
63 | assertTrue("Wrong output: " + output,
64 | output.contains("Setting the eureka configuration.."));
65 | }
66 |
67 | @Test
68 | @Ignore // FIXME: 3.0.0
69 | public void rabbitSample() throws Exception {
70 | String output = this.cli.run("rabbit.groovy");
71 | assertTrue("Wrong output: " + output,
72 | output.contains("subscriber to the 'errorChannel' channel"));
73 | }
74 |
75 | @Test
76 | @Ignore // FIXME: 3.0.0
77 | public void configServerSample() throws Exception {
78 | String output = this.cli.run("configserver.groovy", "--",
79 | "--spring.config.name=configserver", "--logging.level.org.springframework=DEBUG");
80 | assertTrue("Wrong output: " + output,
81 | output.contains("ConfigServerAutoConfiguration matched"));
82 | }
83 |
84 | @Test
85 | @Ignore // FIXME: 3.0.0
86 | public void stubRunnerSample() throws Exception {
87 | String output = this.cli.run("stubrunner.groovy");
88 | assertTrue("Wrong output: " + output,
89 | output.contains("No stubs to download have been passed"));
90 | }
91 |
92 | }
93 |
--------------------------------------------------------------------------------
/spring-cloud-cli/.gitignore:
--------------------------------------------------------------------------------
1 | /target/
2 |
--------------------------------------------------------------------------------
/spring-cloud-cli/README.md:
--------------------------------------------------------------------------------
1 | Spring Boot command line features for
2 | [Spring Cloud](https://github.com/spring-cloud). To install, make
3 | sure you have
4 | [Spring Boot CLI](https://github.com/spring-projects/spring-boot)
5 | (1.1.x with x>=5):
6 |
7 | $ spring version
8 | Spring CLI v1.1.5.RELEASE
9 |
10 |
--------------------------------------------------------------------------------
/spring-cloud-cli/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | spring-cloud-cli
7 | jar
8 |
9 | spring-cloud-cli
10 | Spring Patform Cli integration project
11 |
12 |
13 | org.springframework.cloud
14 | spring-cloud-cli-parent
15 | 3.1.2-SNAPSHOT
16 |
17 |
18 |
19 |
20 |
21 | src/main/resources
22 | true
23 |
24 |
25 |
26 |
27 |
28 |
29 | org.springframework.cloud.launcher
30 | spring-cloud-launcher-cli
31 | ${project.version}
32 |
33 |
34 | org.springframework.cloud
35 | spring-cloud-stream
36 | provided
37 |
38 |
39 | net.sf.jopt-simple
40 | jopt-simple
41 | provided
42 |
43 |
44 | org.springframework.security
45 | spring-security-rsa
46 |
47 |
48 | org.springframework
49 | spring-core
50 |
51 |
52 |
53 |
54 | org.springframework.security
55 | spring-security-crypto
56 |
57 |
58 | org.springframework.boot
59 | spring-boot-cli
60 | ${spring-boot.version}
61 | provided
62 |
63 |
64 | org.codehaus.groovy
65 | groovy
66 | provided
67 |
68 |
69 | org.springframework.boot
70 | spring-boot-starter-test
71 | test
72 |
73 |
74 | org.junit.vintage
75 | junit-vintage-engine
76 | test
77 |
78 |
79 |
80 |
81 |
82 | org.springframework.boot
83 | spring-boot-parent
84 | ${spring-boot.version}
85 | pom
86 | import
87 |
88 |
89 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/spring-cloud-cli/src/main/java/org/springframework/boot/groovy/cloud/EnableBinding.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.boot.groovy.cloud;
18 |
19 | import java.lang.annotation.Documented;
20 | import java.lang.annotation.ElementType;
21 | import java.lang.annotation.Retention;
22 | import java.lang.annotation.RetentionPolicy;
23 | import java.lang.annotation.Target;
24 |
25 | import org.springframework.cloud.cli.compiler.StreamRabbitCompilerAutoConfiguration;
26 | import org.springframework.core.annotation.AliasFor;
27 |
28 | /**
29 | * Pseudo annotation used to trigger {@link StreamRabbitCompilerAutoConfiguration} and
30 | * Redis.
31 | */
32 | @Target(ElementType.TYPE)
33 | @Documented
34 | @Retention(RetentionPolicy.RUNTIME)
35 | @org.springframework.cloud.stream.annotation.EnableBinding
36 | public @interface EnableBinding {
37 |
38 | @AliasFor(annotation = org.springframework.cloud.stream.annotation.EnableBinding.class, attribute = "value")
39 | Class>[] value() default {};
40 |
41 | String transport() default "rabbit";
42 | }
43 |
--------------------------------------------------------------------------------
/spring-cloud-cli/src/main/java/org/springframework/cloud/cli/command/CloudCommandFactory.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2013-2014 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.cloud.cli.command;
17 |
18 | import java.util.Arrays;
19 | import java.util.Collection;
20 |
21 | import org.springframework.boot.cli.command.Command;
22 | import org.springframework.boot.cli.command.CommandFactory;
23 | import org.springframework.cloud.cli.command.encrypt.DecryptCommand;
24 | import org.springframework.cloud.cli.command.encrypt.EncryptCommand;
25 | import org.springframework.cloud.cli.command.url.UrlDecodeCommand;
26 | import org.springframework.cloud.cli.command.url.UrlEncodeCommand;
27 | import org.springframework.cloud.launcher.cli.LauncherCommand;
28 |
29 | /**
30 | * @author Dave Syer
31 | *
32 | */
33 | public class CloudCommandFactory implements CommandFactory {
34 |
35 | @Override
36 | public Collection getCommands() {
37 | return Arrays.asList(new EncryptCommand(), new DecryptCommand(), new UrlEncodeCommand(), new UrlDecodeCommand(), new LauncherCommand());
38 | }
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/spring-cloud-cli/src/main/java/org/springframework/cloud/cli/command/encrypt/BaseEncryptOptionHandler.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2013-2014 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.cloud.cli.command.encrypt;
17 |
18 | import java.io.File;
19 | import java.io.FileInputStream;
20 | import java.nio.charset.Charset;
21 |
22 | import org.springframework.boot.cli.command.options.OptionHandler;
23 | import org.springframework.boot.cli.util.Log;
24 | import org.springframework.core.io.FileSystemResource;
25 | import org.springframework.security.crypto.encrypt.TextEncryptor;
26 | import org.springframework.security.rsa.crypto.KeyStoreKeyFactory;
27 | import org.springframework.security.rsa.crypto.RsaSecretEncryptor;
28 | import org.springframework.util.StreamUtils;
29 |
30 | import static java.util.Arrays.asList;
31 |
32 | import joptsimple.OptionSet;
33 | import joptsimple.OptionSpec;
34 |
35 | class BaseEncryptOptionHandler extends OptionHandler {
36 |
37 | private OptionSpec keyOption;
38 |
39 | private OptionSpec aliasOption;
40 |
41 | private OptionSpec passwordOption;
42 |
43 | private OptionSpec keyPassOption;
44 |
45 | private Charset charset;
46 |
47 | {
48 | charset = Charset.forName("UTF-8");
49 | }
50 |
51 | @Override
52 | protected final void options() {
53 | this.keyOption = option(asList("key", "k"),
54 | "Specify key (symmetric secret, or pem-encoded key). If the value starts with @ it is interpreted as a file location.")
55 | .withRequiredArg();
56 | this.passwordOption = option("password",
57 | "A password for the keyfile (assuming the --key option is a KeyStore file).")
58 | .withRequiredArg();
59 | this.keyPassOption = option("keypass",
60 | "A password for the key, defaults to the same as the store password (assuming the --key option is a KeyStore file).")
61 | .withRequiredArg();
62 | this.aliasOption = option("alias",
63 | "An alias for the the key in a keyfile (assuming the --key option is a KeyStore file).")
64 | .withRequiredArg();
65 | doOptions();
66 | }
67 |
68 | protected void doOptions() {
69 | }
70 |
71 | protected TextEncryptor createEncryptor(OptionSet options) {
72 | String value = keyOption.value(options);
73 | if (value == null) {
74 | throw new MissingKeyException();
75 | }
76 | if (options.has(passwordOption)) { // it's a keystore
77 | String password = options.valueOf(passwordOption);
78 | String alias = options.valueOf(aliasOption);
79 | KeyStoreKeyFactory factory = new KeyStoreKeyFactory(
80 | new FileSystemResource(value), password.toCharArray());
81 | if (options.has(keyPassOption)) {
82 | String keypass = options.valueOf(keyPassOption);
83 | RsaSecretEncryptor encryptor = new RsaSecretEncryptor(
84 | factory.getKeyPair(alias, keypass.toCharArray()));
85 | return encryptor;
86 | }
87 | else {
88 | RsaSecretEncryptor encryptor = new RsaSecretEncryptor(
89 | factory.getKeyPair(alias));
90 | return encryptor;
91 | }
92 | }
93 | boolean verbose = Boolean.getBoolean("debug");
94 | if (value.startsWith("@")) {
95 | value = readFile(value.substring(1));
96 | }
97 | try {
98 | value = readFile(value);
99 | if (verbose) {
100 | int len = Math.min(100, Math.max(value.length(), value.indexOf("\n")));
101 | Log.info("File contents:\n" + value.substring(0, len) + "...");
102 | }
103 | }
104 | catch (Exception e) {
105 | // not a file
106 | }
107 | return new EncryptorFactory(verbose).create(value.trim().replaceAll("\n", ""));
108 | }
109 |
110 | private String readFile(String filename) {
111 | try {
112 | return StreamUtils.copyToString(new FileInputStream(new File(filename)),
113 | charset);
114 | }
115 | catch (RuntimeException e) {
116 | throw e;
117 | }
118 | catch (Exception e) {
119 | throw new IllegalStateException(e);
120 | }
121 | }
122 |
123 | }
--------------------------------------------------------------------------------
/spring-cloud-cli/src/main/java/org/springframework/cloud/cli/command/encrypt/DecryptCommand.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2013-2014 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.cloud.cli.command.encrypt;
17 |
18 | import joptsimple.OptionSet;
19 |
20 | import org.springframework.boot.cli.command.OptionParsingCommand;
21 | import org.springframework.boot.cli.command.status.ExitStatus;
22 | import org.springframework.security.crypto.encrypt.TextEncryptor;
23 | import org.springframework.util.StringUtils;
24 |
25 | /**
26 | * @author Dave Syer
27 | *
28 | */
29 | public class DecryptCommand extends OptionParsingCommand {
30 |
31 | public DecryptCommand() {
32 | super("decrypt", "Decrypt a string previsouly encrypted with the same key (or key pair)",
33 | new DecryptOptionHandler());
34 | }
35 |
36 | @Override
37 | public String getUsageHelp() {
38 | return "[options] ";
39 | }
40 |
41 | private static class DecryptOptionHandler extends BaseEncryptOptionHandler {
42 |
43 | @Override
44 | protected synchronized ExitStatus run(OptionSet options) throws Exception {
45 | TextEncryptor encryptor = createEncryptor(options);
46 | String text = StringUtils.collectionToDelimitedString(
47 | options.nonOptionArguments(), " ");
48 | if (text.startsWith("{cipher}")) {
49 | text = text.substring("{cipher}".length());
50 | }
51 | System.out.println(encryptor.decrypt(text));
52 | return ExitStatus.OK;
53 | }
54 |
55 | }
56 |
57 | }
58 |
--------------------------------------------------------------------------------
/spring-cloud-cli/src/main/java/org/springframework/cloud/cli/command/encrypt/EncryptCommand.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2013-2014 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.cloud.cli.command.encrypt;
17 |
18 | import static java.util.Arrays.asList;
19 | import joptsimple.OptionSet;
20 | import joptsimple.OptionSpec;
21 |
22 | import org.springframework.boot.cli.command.OptionParsingCommand;
23 | import org.springframework.boot.cli.command.status.ExitStatus;
24 | import org.springframework.security.crypto.encrypt.TextEncryptor;
25 | import org.springframework.util.StringUtils;
26 |
27 | /**
28 | * @author Dave Syer
29 | *
30 | */
31 | public class EncryptCommand extends OptionParsingCommand {
32 |
33 | public EncryptCommand() {
34 | super("encrypt",
35 | "Encrypt a string so, for instance, it can be added to source control",
36 | new EncryptOptionHandler());
37 | }
38 |
39 | @Override
40 | public String getUsageHelp() {
41 | return "[options] ";
42 | }
43 |
44 | private static class EncryptOptionHandler extends BaseEncryptOptionHandler {
45 |
46 | private OptionSpec propertyOption;
47 |
48 | @Override
49 | protected void doOptions() {
50 | this.propertyOption = option(
51 | asList("property", "p"),
52 | "A name for the encrypted value. Output will be in a form that can be pasted in to a properties file.")
53 | .withRequiredArg();
54 | }
55 |
56 | @Override
57 | protected synchronized ExitStatus run(OptionSet options) throws Exception {
58 | TextEncryptor encryptor = createEncryptor(options);
59 | String text = StringUtils.collectionToDelimitedString(
60 | options.nonOptionArguments(), " ");
61 | System.out.println(formatCipher(options, encryptor.encrypt(text)));
62 | return ExitStatus.OK;
63 | }
64 |
65 | protected String formatCipher(OptionSet options, String output) {
66 | if (options.has(propertyOption)) {
67 | output = options.valueOf(propertyOption).replace(":", "\\:")
68 | .replace("=", "\\=").replace(" ", "\\ ")
69 | + "={cipher}" + output;
70 | }
71 | return output;
72 | }
73 |
74 | }
75 |
76 | }
77 |
--------------------------------------------------------------------------------
/spring-cloud-cli/src/main/java/org/springframework/cloud/cli/command/encrypt/EncryptorFactory.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2013-2014 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.cloud.cli.command.encrypt;
17 |
18 | import org.springframework.boot.cli.util.Log;
19 | import org.springframework.security.crypto.encrypt.Encryptors;
20 | import org.springframework.security.crypto.encrypt.TextEncryptor;
21 | import org.springframework.security.rsa.crypto.RsaSecretEncryptor;
22 |
23 | /**
24 | * @author Dave Syer
25 | *
26 | */
27 | public class EncryptorFactory {
28 |
29 | // TODO: expose as config property
30 | private static final String SALT = "deadbeef";
31 |
32 | private final boolean verbose;
33 |
34 | public EncryptorFactory() {
35 | this(false);
36 | }
37 |
38 | public EncryptorFactory(boolean verbose) {
39 | this.verbose = verbose;
40 | }
41 |
42 | public TextEncryptor create(String data) {
43 |
44 | TextEncryptor encryptor = null;
45 | try {
46 | encryptor = new RsaSecretEncryptor(data);
47 | }
48 | catch (IllegalArgumentException e) {
49 | if (verbose) {
50 | Log.info("Could not create RSA Encryptor (" + e.getMessage() + ")");
51 | }
52 | }
53 | if (encryptor == null) {
54 | if (verbose) {
55 | Log.info("Trying public key");
56 | }
57 | try {
58 | encryptor = new RsaSecretEncryptor(data);
59 | }
60 | catch (IllegalArgumentException e) {
61 | if (verbose) {
62 | Log.info("Could not create public key RSA Encryptor ("
63 | + e.getMessage() + ")");
64 | }
65 | }
66 | }
67 | if (encryptor == null) {
68 | if (verbose) {
69 | Log.info("Trying symmetric key");
70 | }
71 | encryptor = Encryptors.text(data, SALT);
72 | }
73 | if (encryptor == null) {
74 | if (verbose) {
75 | Log.error("Could not create any Encryptor");
76 | }
77 | throw new KeyFormatException();
78 | }
79 |
80 | return encryptor;
81 | }
82 |
83 | }
84 |
--------------------------------------------------------------------------------
/spring-cloud-cli/src/main/java/org/springframework/cloud/cli/command/encrypt/KeyFormatException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2013-2014 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.cloud.cli.command.encrypt;
17 |
18 | @SuppressWarnings("serial")
19 | public class KeyFormatException extends RuntimeException {
20 | }
--------------------------------------------------------------------------------
/spring-cloud-cli/src/main/java/org/springframework/cloud/cli/command/encrypt/MissingKeyException.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012-2014 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.cloud.cli.command.encrypt;
17 |
18 | import org.springframework.boot.cli.command.CommandException;
19 |
20 | @SuppressWarnings("serial")
21 | public class MissingKeyException extends CommandException {
22 |
23 | public MissingKeyException() {
24 | super("Error: missing key (please use --key)");
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/spring-cloud-cli/src/main/java/org/springframework/cloud/cli/command/url/BaseEncodeOptionHandler.java:
--------------------------------------------------------------------------------
1 | package org.springframework.cloud.cli.command.url;
2 |
3 | import static java.util.Arrays.asList;
4 |
5 | import joptsimple.OptionSpec;
6 | import org.springframework.boot.cli.command.options.OptionHandler;
7 |
8 |
9 | public class BaseEncodeOptionHandler extends OptionHandler {
10 | OptionSpec charsetOption;
11 |
12 | @Override
13 | protected final void options() {
14 | this.charsetOption = option(asList("charset", "c"),
15 | "Character set (defaults to UTF-8)").withRequiredArg();
16 | doOptions();
17 | }
18 |
19 | protected void doOptions(){
20 |
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/spring-cloud-cli/src/main/java/org/springframework/cloud/cli/command/url/UrlDecodeCommand.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2013-2014 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.cloud.cli.command.url;
17 |
18 | import java.io.UnsupportedEncodingException;
19 | import java.net.URLDecoder;
20 | import java.net.URLEncoder;
21 | import java.nio.charset.Charset;
22 | import java.nio.charset.UnsupportedCharsetException;
23 |
24 | import org.springframework.boot.cli.command.OptionParsingCommand;
25 | import org.springframework.boot.cli.command.options.OptionHandler;
26 | import org.springframework.boot.cli.command.status.ExitStatus;
27 | import org.springframework.util.StringUtils;
28 |
29 | import joptsimple.OptionSet;
30 |
31 | /**
32 | * @author William Witt
33 | */
34 | public class UrlDecodeCommand extends OptionParsingCommand {
35 |
36 | public UrlDecodeCommand() {
37 | super("urlDecode", "URL decodes the subsequent string",
38 | new UrlDecodeOptionHandler());
39 | }
40 |
41 | @Override
42 | public String getUsageHelp() {
43 | return "";
44 | }
45 |
46 | private static class UrlDecodeOptionHandler extends BaseEncodeOptionHandler {
47 |
48 | @Override
49 | protected synchronized ExitStatus run(OptionSet options) throws Exception {
50 | String charset = "UTF-8";
51 | if(options.has(charsetOption)){
52 | charset = options.valueOf(charsetOption);
53 | }
54 | String text = StringUtils
55 | .collectionToDelimitedString(options.nonOptionArguments(), " ");
56 | try {
57 | Charset.forName(charset);
58 | String outText = URLDecoder.decode(text, charset);
59 | System.out.println(outText);
60 | return ExitStatus.OK;
61 | } catch (UnsupportedCharsetException e){
62 | System.out.println("Unsupported Character Set");
63 | return ExitStatus.ERROR;
64 | }
65 | }
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/spring-cloud-cli/src/main/java/org/springframework/cloud/cli/command/url/UrlEncodeCommand.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2013-2014 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.cloud.cli.command.url;
17 |
18 | import joptsimple.OptionSet;
19 | import org.springframework.boot.cli.command.OptionParsingCommand;
20 | import org.springframework.boot.cli.command.status.ExitStatus;
21 | import org.springframework.util.StringUtils;
22 |
23 | import java.io.UnsupportedEncodingException;
24 | import java.net.URLEncoder;
25 | import java.nio.charset.Charset;
26 | import java.nio.charset.UnsupportedCharsetException;
27 |
28 | /**
29 | * @author William Witt
30 | */
31 | public class UrlEncodeCommand extends OptionParsingCommand {
32 |
33 | public UrlEncodeCommand() {
34 | super("urlEncode", "URL encodes the subsequent string",
35 | new UrlEncodeOptionHandler());
36 | }
37 |
38 | @Override
39 | public String getUsageHelp() {
40 | return "[options] ";
41 | }
42 |
43 | private static class UrlEncodeOptionHandler extends BaseEncodeOptionHandler{
44 |
45 | @Override
46 | protected synchronized ExitStatus run(OptionSet options) throws Exception {
47 | String charset = "UTF-8";
48 | if(options.has(charsetOption)){
49 | charset = options.valueOf(charsetOption);
50 | }
51 | String text = StringUtils
52 | .collectionToDelimitedString(options.nonOptionArguments(), " ");
53 | try {
54 | Charset.forName(charset);
55 | String outText = URLEncoder.encode(text, charset);
56 | System.out.println(outText);
57 | return ExitStatus.OK;
58 | } catch (UnsupportedCharsetException e){
59 | System.out.println("Unsupported Character Set");
60 | return ExitStatus.ERROR;
61 | }
62 | }
63 | }
64 | }
65 |
66 |
--------------------------------------------------------------------------------
/spring-cloud-cli/src/main/java/org/springframework/cloud/cli/compiler/BaseStreamCompilerAutoConfiguration.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2013-2014 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.cloud.cli.compiler;
17 |
18 | import org.codehaus.groovy.ast.AnnotationNode;
19 | import org.codehaus.groovy.ast.ClassNode;
20 | import org.codehaus.groovy.ast.expr.Expression;
21 | import org.codehaus.groovy.control.CompilationFailedException;
22 | import org.codehaus.groovy.control.customizers.ImportCustomizer;
23 | import org.springframework.boot.cli.compiler.AstUtils;
24 | import org.springframework.boot.cli.compiler.CompilerAutoConfiguration;
25 | import org.springframework.boot.cli.compiler.autoconfigure.SpringIntegrationCompilerAutoConfiguration;
26 | import org.springframework.util.PatternMatchUtils;
27 | import org.springframework.util.SystemPropertyUtils;
28 |
29 | /**
30 | * @author Dave Syer
31 | *
32 | */
33 | public abstract class BaseStreamCompilerAutoConfiguration
34 | extends CompilerAutoConfiguration {
35 |
36 | private SpringIntegrationCompilerAutoConfiguration integration = new SpringIntegrationCompilerAutoConfiguration();
37 |
38 | @Override
39 | public boolean matches(ClassNode classNode) {
40 | boolean annotated = AstUtils.hasAtLeastOneAnnotation(classNode, "EnableBinding");
41 | return annotated && isTransport(classNode, getTransport());
42 | }
43 |
44 | protected abstract String getTransport();
45 |
46 | static boolean isTransport(ClassNode node, String type) {
47 | for (AnnotationNode annotationNode : node.getAnnotations()) {
48 | String annotation = "EnableBinding";
49 | if (PatternMatchUtils.simpleMatch(annotation,
50 | annotationNode.getClassNode().getName())) {
51 | Expression expression = annotationNode.getMembers().get("transport");
52 | String transport = expression == null ? "rabbit" : expression.getText();
53 | if (transport != null) {
54 | transport = SystemPropertyUtils.resolvePlaceholders(transport);
55 | }
56 | return transport.equals(type);
57 | }
58 | }
59 | return false;
60 | }
61 |
62 | @Override
63 | public void applyImports(ImportCustomizer imports) throws CompilationFailedException {
64 | this.integration.applyImports(imports);
65 | imports.addImports("org.springframework.boot.groovy.cloud.EnableBinding");
66 | imports.addImport("IntegrationMessageSource",
67 | "org.springframework.integration.core.MessageSource");
68 | imports.addStarImports("org.springframework.cloud.stream.annotation",
69 | "org.springframework.cloud.stream.messaging");
70 | }
71 |
72 | }
73 |
--------------------------------------------------------------------------------
/spring-cloud-cli/src/main/java/org/springframework/cloud/cli/compiler/ConfigServerCompilerAutoConfiguration.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2013-2014 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.cloud.cli.compiler;
17 |
18 | import org.codehaus.groovy.ast.ClassNode;
19 | import org.codehaus.groovy.control.CompilationFailedException;
20 | import org.codehaus.groovy.control.customizers.ImportCustomizer;
21 | import org.springframework.boot.cli.compiler.AstUtils;
22 | import org.springframework.boot.cli.compiler.CompilerAutoConfiguration;
23 | import org.springframework.boot.cli.compiler.DependencyCustomizer;
24 |
25 | /**
26 | * @author Dave Syer
27 | *
28 | */
29 | public class ConfigServerCompilerAutoConfiguration extends CompilerAutoConfiguration {
30 |
31 | @Override
32 | public boolean matches(ClassNode classNode) {
33 | return AstUtils.hasAtLeastOneAnnotation(classNode, "EnableConfigServer");
34 | }
35 |
36 | @Override
37 | public void applyDependencies(DependencyCustomizer dependencies) {
38 | dependencies
39 | .ifAnyMissingClasses("org.springframework.cloud.config.server.EnableConfigServer")
40 | .add("spring-cloud-config-server");
41 | }
42 |
43 | @Override
44 | public void applyImports(ImportCustomizer imports) throws CompilationFailedException {
45 | imports.addImports("org.springframework.cloud.config.server.EnableConfigServer");
46 | }
47 |
48 | }
49 |
--------------------------------------------------------------------------------
/spring-cloud-cli/src/main/java/org/springframework/cloud/cli/compiler/EurekaClientCompilerAutoConfiguration.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2013-2014 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.cloud.cli.compiler;
17 |
18 | import org.codehaus.groovy.ast.ClassNode;
19 | import org.codehaus.groovy.control.CompilationFailedException;
20 | import org.codehaus.groovy.control.customizers.ImportCustomizer;
21 | import org.springframework.boot.cli.compiler.AstUtils;
22 | import org.springframework.boot.cli.compiler.CompilerAutoConfiguration;
23 | import org.springframework.boot.cli.compiler.DependencyCustomizer;
24 |
25 | /**
26 | * @author Dave Syer
27 | *
28 | */
29 | public class EurekaClientCompilerAutoConfiguration extends CompilerAutoConfiguration {
30 |
31 | @Override
32 | public boolean matches(ClassNode classNode) {
33 | return AstUtils.hasAtLeastOneAnnotation(classNode, "EnableDiscoveryClient");
34 | }
35 |
36 | @Override
37 | public void applyDependencies(DependencyCustomizer dependencies) {
38 | dependencies.ifAnyMissingClasses(
39 | "org.springframework.cloud.client.discovery.EnableDiscoveryClient").add(
40 | "spring-cloud-starter-netflix-eureka-client");
41 | }
42 |
43 | @Override
44 | public void applyImports(ImportCustomizer imports) throws CompilationFailedException {
45 | imports.addImports(
46 | "org.springframework.cloud.client.discovery.EnableDiscoveryClient",
47 | "org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean",
48 | "org.springframework.cloud.netflix.eureka.EurekaClientConfigBean",
49 | "org.springframework.cloud.client.discovery.DiscoveryClient",
50 | "org.springframework.cloud.client.ServiceInstance");
51 | }
52 |
53 | }
54 |
--------------------------------------------------------------------------------
/spring-cloud-cli/src/main/java/org/springframework/cloud/cli/compiler/EurekaServerCompilerAutoConfiguration.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2013-2014 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.cloud.cli.compiler;
17 |
18 | import org.codehaus.groovy.ast.ClassNode;
19 | import org.codehaus.groovy.control.CompilationFailedException;
20 | import org.codehaus.groovy.control.customizers.ImportCustomizer;
21 | import org.springframework.boot.cli.compiler.AstUtils;
22 | import org.springframework.boot.cli.compiler.CompilerAutoConfiguration;
23 | import org.springframework.boot.cli.compiler.DependencyCustomizer;
24 |
25 | /**
26 | * @author Dave Syer
27 | *
28 | */
29 | public class EurekaServerCompilerAutoConfiguration extends CompilerAutoConfiguration {
30 |
31 | @Override
32 | public boolean matches(ClassNode classNode) {
33 | return AstUtils.hasAtLeastOneAnnotation(classNode, "EnableEurekaServer");
34 | }
35 |
36 | @Override
37 | public void applyDependencies(DependencyCustomizer dependencies) {
38 | dependencies.ifAnyMissingClasses(
39 | "org.springframework.cloud.netflix.eureka.server.EnableEurekaServer")
40 | .add("spring-cloud-starter-netflix-eureka-server");
41 | if (JavaVersion.current().isJava11Compatible()) {
42 | dependencies.add("jaxb-api")
43 | .add("javax.activation-api")
44 | .add("jaxb-runtime");
45 | }
46 | }
47 |
48 | @Override
49 | public void applyImports(ImportCustomizer imports) throws CompilationFailedException {
50 | imports.addImports("org.springframework.cloud.netflix.eureka.server.EnableEurekaServer",
51 | "org.springframework.cloud.client.discovery.EnableDiscoveryClient",
52 | "org.springframework.cloud.netflix.eureka.server.EurekaServerConfigBean",
53 | "org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean",
54 | "org.springframework.cloud.netflix.eureka.EurekaClientConfigBean",
55 | "com.netflix.discovery.DiscoveryClient",
56 | "com.netflix.appinfo.InstanceInfo");
57 | }
58 |
59 | }
60 |
--------------------------------------------------------------------------------
/spring-cloud-cli/src/main/java/org/springframework/cloud/cli/compiler/JavaVersion.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2013-2014 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.cloud.cli.compiler;
17 |
18 | import java.util.ArrayList;
19 | import java.util.List;
20 |
21 | /**
22 | * TAKEN FROM GRADLE (https://github.com/gradle/gradle/blob/master/subprojects/base-services/src/main/java/org/gradle/api/JavaVersion.java)
23 | *
24 | * An enumeration of Java versions.
25 | * Before 9: https://www.oracle.com/technetwork/java/javase/versioning-naming-139433.html
26 | * 9+: https://openjdk.java.net/jeps/223
27 | */
28 | enum JavaVersion {
29 | VERSION_1_1, VERSION_1_2, VERSION_1_3, VERSION_1_4,
30 | VERSION_1_5, VERSION_1_6, VERSION_1_7, VERSION_1_8,
31 | VERSION_1_9, VERSION_1_10,
32 | /**
33 | * Java 11 major version.
34 | *
35 | * @since 4.7
36 | */
37 | VERSION_11,
38 |
39 | /**
40 | * Java 12 major version.
41 | *
42 | * @since 5.0
43 | */
44 | VERSION_12,
45 |
46 | /**
47 | * Higher version of Java.
48 | * @since 4.7
49 | */
50 | VERSION_HIGHER;
51 | // Since Java 9, version should be X instead of 1.X
52 | // However, to keep backward compatibility, we change from 11
53 | private static final int FIRST_MAJOR_VERSION_ORDINAL = 10;
54 | private static JavaVersion currentJavaVersion;
55 | private final String versionName;
56 |
57 | JavaVersion() {
58 | this.versionName = ordinal() >= FIRST_MAJOR_VERSION_ORDINAL ? getMajorVersion() : "1." + getMajorVersion();
59 | }
60 |
61 | /**
62 | * Converts the given object into a {@code JavaVersion}.
63 | *
64 | * @param value An object whose toString() value is to be converted. May be null.
65 | * @return The version, or null if the provided value is null.
66 | * @throws IllegalArgumentException when the provided value cannot be converted.
67 | */
68 | public static JavaVersion toVersion(Object value) throws IllegalArgumentException {
69 | if (value == null) {
70 | return null;
71 | }
72 | if (value instanceof JavaVersion) {
73 | return (JavaVersion) value;
74 | }
75 | String name = value.toString();
76 | int firstNonVersionCharIndex = findFirstNonVersionCharIndex(name);
77 | String[] versionStrings = name.substring(0, firstNonVersionCharIndex)
78 | .split("\\.");
79 | List versions = convertToNumber(name, versionStrings);
80 | if (isLegacyVersion(versions)) {
81 | assertTrue(name, versions.get(1) > 0);
82 | return getVersionForMajor(versions.get(1));
83 | }
84 | else {
85 | return getVersionForMajor(versions.get(0));
86 | }
87 | }
88 |
89 | /**
90 | * Returns the version of the current JVM.
91 | *
92 | * @return The version of the current JVM.
93 | */
94 | public static JavaVersion current() {
95 | if (currentJavaVersion == null) {
96 | currentJavaVersion = toVersion(System.getProperty("java.version"));
97 | }
98 | return currentJavaVersion;
99 | }
100 |
101 | private static JavaVersion getVersionForMajor(int major) {
102 | return major >= values().length ? JavaVersion.VERSION_HIGHER : values()[major - 1];
103 | }
104 |
105 | private static void assertTrue(String value, boolean condition) {
106 | if (!condition) {
107 | throw new IllegalArgumentException("Could not determine java version from '" + value + "'.");
108 | }
109 | }
110 |
111 | private static boolean isLegacyVersion(List versions) {
112 | return 1 == versions.get(0) && versions.size() > 1;
113 | }
114 |
115 | private static List convertToNumber(String value, String[] versionStrs) {
116 | List result = new ArrayList();
117 | for (String s : versionStrs) {
118 | assertTrue(value, !isNumberStartingWithZero(s));
119 | try {
120 | result.add(Integer.parseInt(s));
121 | }
122 | catch (NumberFormatException e) {
123 | assertTrue(value, false);
124 | }
125 | }
126 | assertTrue(value, !result.isEmpty() && result.get(0) > 0);
127 | return result;
128 | }
129 |
130 | private static boolean isNumberStartingWithZero(String number) {
131 | return number.length() > 1 && number.startsWith("0");
132 | }
133 |
134 | private static int findFirstNonVersionCharIndex(String s) {
135 | assertTrue(s, s.length() != 0);
136 |
137 | for (int i = 0; i < s.length(); ++i) {
138 | if (!isDigitOrPeriod(s.charAt(i))) {
139 | assertTrue(s, i != 0);
140 | return i;
141 | }
142 | }
143 |
144 | return s.length();
145 | }
146 |
147 | private static boolean isDigitOrPeriod(char c) {
148 | return (c >= '0' && c <= '9') || c == '.';
149 | }
150 |
151 | /**
152 | * Returns if the version is Java 11 compatible.
153 | *
154 | * @since 4.7
155 | */
156 | public boolean isJava11Compatible() {
157 | return this.compareTo(VERSION_11) >= 0;
158 | }
159 |
160 | @Override
161 | public String toString() {
162 | return this.versionName;
163 | }
164 |
165 |
166 | public String getMajorVersion() {
167 | return String.valueOf(ordinal() + 1);
168 | }
169 | }
--------------------------------------------------------------------------------
/spring-cloud-cli/src/main/java/org/springframework/cloud/cli/compiler/OAuth2LoadBalancedCompilerAutoConfiguration.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2013-2014 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.cloud.cli.compiler;
17 |
18 | import org.codehaus.groovy.ast.ClassNode;
19 | import org.springframework.boot.cli.compiler.AstUtils;
20 | import org.springframework.boot.cli.compiler.CompilerAutoConfiguration;
21 | import org.springframework.boot.cli.compiler.DependencyCustomizer;
22 |
23 | /**
24 | * @author Dave Syer
25 | *
26 | */
27 | public class OAuth2LoadBalancedCompilerAutoConfiguration extends CompilerAutoConfiguration {
28 |
29 | @Override
30 | public boolean matches(ClassNode classNode) {
31 | return AstUtils.hasAtLeastOneAnnotation(classNode, "EnableOAuth2Sso");
32 | }
33 |
34 | @Override
35 | public void applyDependencies(DependencyCustomizer dependencies) {
36 | dependencies
37 | .ifAnyMissingClasses(
38 | "org.springframework.cloud.security.oauth2.client.OAuth2LoadBalancerClientAutoConfiguration")
39 | .add("spring-cloud-starter-oauth2");
40 | }
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/spring-cloud-cli/src/main/java/org/springframework/cloud/cli/compiler/SpringCloudBomAstTransformation.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2015 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cloud.cli.compiler;
18 |
19 | import java.io.IOException;
20 | import java.io.InputStream;
21 | import java.nio.charset.StandardCharsets;
22 |
23 | import org.codehaus.groovy.control.CompilePhase;
24 | import org.codehaus.groovy.transform.GroovyASTTransformation;
25 | import org.springframework.boot.cli.compiler.DependencyManagementBomTransformation;
26 | import org.springframework.boot.cli.compiler.GenericBomAstTransformation;
27 | import org.springframework.core.io.ClassPathResource;
28 | import org.springframework.util.ReflectionUtils;
29 | import org.springframework.util.StreamUtils;
30 | import org.springframework.util.StringUtils;
31 |
32 | /**
33 | * @author Dave Syer
34 | *
35 | */
36 | @GroovyASTTransformation(phase = CompilePhase.CONVERSION)
37 | public class SpringCloudBomAstTransformation extends GenericBomAstTransformation {
38 |
39 | @Override
40 | protected String getBomModule() {
41 | return "org.springframework.cloud:spring-cloud-starter-parent:" + getBomVersion();
42 | }
43 |
44 | @Override
45 | public int getOrder() {
46 | return DependencyManagementBomTransformation.ORDER - 50;
47 | }
48 |
49 | String getBomVersion() {
50 | try (InputStream in = new ClassPathResource("META-INF/springcloudbom-version.txt").getInputStream()) {
51 | String version = StreamUtils.copyToString(in, StandardCharsets.UTF_8);
52 | if (StringUtils.hasText(version)) {
53 | version = version.trim();
54 | }
55 | return version;
56 | }
57 | catch (IOException e) {
58 | ReflectionUtils.rethrowRuntimeException(e);
59 | }
60 | // not reachable since exception rethrown at runtime
61 | return null;
62 | }
63 |
64 | }
65 |
--------------------------------------------------------------------------------
/spring-cloud-cli/src/main/java/org/springframework/cloud/cli/compiler/SpringCloudCompilerAutoConfiguration.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2013-2014 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.cloud.cli.compiler;
17 |
18 | import org.codehaus.groovy.control.CompilationFailedException;
19 | import org.codehaus.groovy.control.customizers.ImportCustomizer;
20 | import org.springframework.boot.cli.compiler.CompilerAutoConfiguration;
21 | import org.springframework.boot.cli.compiler.DependencyCustomizer;
22 |
23 | /**
24 | * @author Dave Syer
25 | *
26 | */
27 | public class SpringCloudCompilerAutoConfiguration extends
28 | CompilerAutoConfiguration {
29 |
30 | @Override
31 | public void applyDependencies(DependencyCustomizer dependencies) {
32 | dependencies
33 | .ifAnyMissingClasses(
34 | "org.springframework.boot.actuate.endpoint.EnvironmentEndpoint")
35 | .add("spring-boot-starter-actuator");
36 | dependencies.ifAnyMissingClasses(
37 | "org.springframework.cloud.config.Environment").add(
38 | "spring-cloud-starter-config");
39 | }
40 |
41 | @Override
42 | public void applyImports(ImportCustomizer imports)
43 | throws CompilationFailedException {
44 | imports.addImports("org.springframework.cloud.context.config.annotation.RefreshScope");
45 | }
46 |
47 | }
48 |
--------------------------------------------------------------------------------
/spring-cloud-cli/src/main/java/org/springframework/cloud/cli/compiler/StreamKafkaCompilerAutoConfiguration.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2013-2014 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.cloud.cli.compiler;
17 |
18 | import org.springframework.boot.cli.compiler.DependencyCustomizer;
19 |
20 | /**
21 | * @author Dave Syer
22 | *
23 | */
24 | public class StreamKafkaCompilerAutoConfiguration
25 | extends BaseStreamCompilerAutoConfiguration {
26 |
27 | @Override
28 | protected String getTransport() {
29 | return "kafka";
30 | }
31 |
32 | @Override
33 | public void applyDependencies(DependencyCustomizer dependencies) {
34 | dependencies
35 | .ifAnyMissingClasses(
36 | "org.springframework.cloud.stream.binder.kafka.config.KafkaServiceAutoConfiguration")
37 | .add("spring-cloud-starter-stream-kafka");
38 | }
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/spring-cloud-cli/src/main/java/org/springframework/cloud/cli/compiler/StreamRabbitCompilerAutoConfiguration.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2013-2014 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.cloud.cli.compiler;
17 |
18 | import org.springframework.boot.cli.compiler.DependencyCustomizer;
19 |
20 | /**
21 | * @author Dave Syer
22 | *
23 | */
24 | public class StreamRabbitCompilerAutoConfiguration
25 | extends BaseStreamCompilerAutoConfiguration {
26 |
27 | @Override
28 | protected String getTransport() {
29 | return "rabbit";
30 | }
31 |
32 | @Override
33 | public void applyDependencies(DependencyCustomizer dependencies) {
34 | dependencies
35 | .ifAnyMissingClasses(
36 | "org.springframework.cloud.stream.binder.rabbit.config.RabbitServiceAutoConfiguration")
37 | .add("spring-cloud-starter-stream-rabbit");
38 | }
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/spring-cloud-cli/src/main/java/org/springframework/cloud/cli/compiler/StubRunnerCompilerAutoConfiguration.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2013-2014 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.cloud.cli.compiler;
17 |
18 | import org.codehaus.groovy.ast.ClassNode;
19 | import org.codehaus.groovy.control.CompilationFailedException;
20 | import org.codehaus.groovy.control.customizers.ImportCustomizer;
21 | import org.springframework.boot.cli.compiler.AstUtils;
22 | import org.springframework.boot.cli.compiler.CompilerAutoConfiguration;
23 | import org.springframework.boot.cli.compiler.DependencyCustomizer;
24 |
25 | /**
26 | * @author Marcin Grzejszczak
27 | *
28 | */
29 | public class StubRunnerCompilerAutoConfiguration extends CompilerAutoConfiguration {
30 |
31 | @Override
32 | public boolean matches(ClassNode classNode) {
33 | return AstUtils.hasAtLeastOneAnnotation(classNode, "EnableStubRunnerServer");
34 | }
35 |
36 | @Override
37 | public void applyDependencies(DependencyCustomizer dependencies) {
38 | dependencies
39 | .ifAnyMissingClasses("org.springframework.cloud.contract.stubrunner.server.EnableStubRunnerServer")
40 | .add("spring-cloud-contract-stub-runner-boot");
41 | }
42 |
43 | @Override
44 | public void applyImports(ImportCustomizer imports) throws CompilationFailedException {
45 | imports.addImports("org.springframework.cloud.contract.stubrunner.server.EnableStubRunnerServer");
46 | }
47 |
48 | }
49 |
--------------------------------------------------------------------------------
/spring-cloud-cli/src/main/resources/META-INF/services/org.springframework.boot.cli.command.CommandFactory:
--------------------------------------------------------------------------------
1 | org.springframework.cloud.cli.command.CloudCommandFactory
2 |
--------------------------------------------------------------------------------
/spring-cloud-cli/src/main/resources/META-INF/services/org.springframework.boot.cli.compiler.CompilerAutoConfiguration:
--------------------------------------------------------------------------------
1 | org.springframework.cloud.cli.compiler.SpringCloudCompilerAutoConfiguration
2 | org.springframework.cloud.cli.compiler.ConfigServerCompilerAutoConfiguration
3 | org.springframework.cloud.cli.compiler.EurekaClientCompilerAutoConfiguration
4 | org.springframework.cloud.cli.compiler.EurekaServerCompilerAutoConfiguration
5 | org.springframework.cloud.cli.compiler.OAuth2LoadBalancedCompilerAutoConfiguration
6 | org.springframework.cloud.cli.compiler.StreamKafkaCompilerAutoConfiguration
7 | org.springframework.cloud.cli.compiler.StreamRabbitCompilerAutoConfiguration
8 | org.springframework.cloud.cli.compiler.StubRunnerCompilerAutoConfiguration
9 |
--------------------------------------------------------------------------------
/spring-cloud-cli/src/main/resources/META-INF/services/org.springframework.boot.cli.compiler.SpringBootAstTransformation:
--------------------------------------------------------------------------------
1 | org.springframework.cloud.cli.compiler.SpringCloudBomAstTransformation
--------------------------------------------------------------------------------
/spring-cloud-cli/src/main/resources/META-INF/springcloudbom-version.txt:
--------------------------------------------------------------------------------
1 | @spring-cloud.version@
2 |
--------------------------------------------------------------------------------
/spring-cloud-cli/src/test/java/org/springframework/cloud/cli/command/encrypt/DecryptCommandTests.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2013-2014 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.cloud.cli.command.encrypt;
17 |
18 | import java.nio.charset.Charset;
19 |
20 | import org.junit.Test;
21 |
22 | import org.springframework.boot.cli.command.status.ExitStatus;
23 | import org.springframework.core.io.ClassPathResource;
24 | import org.springframework.security.rsa.crypto.KeyStoreKeyFactory;
25 | import org.springframework.security.rsa.crypto.RsaSecretEncryptor;
26 | import org.springframework.util.StreamUtils;
27 |
28 | import static org.junit.Assert.assertEquals;
29 |
30 | /**
31 | * @author Dave Syer
32 | *
33 | */
34 | public class DecryptCommandTests {
35 |
36 | private DecryptCommand command = new DecryptCommand();
37 |
38 | @Test
39 | public void decryptsFromSymmetricKey() throws Exception {
40 | assertEquals(ExitStatus.OK, command.run("-k", "deadbeef",
41 | "68b7f624de187e79cebfdc9e2e869189b981d7e976385839506de265bb892a5d"));
42 | }
43 |
44 | @Test
45 | public void decryptsFromRsaKey() throws Exception {
46 | RsaSecretEncryptor encryptor = new RsaSecretEncryptor(StreamUtils
47 | .copyToString(new ClassPathResource("private.pem").getInputStream(),
48 | Charset.forName("UTF-8"))
49 | .replaceAll("\n", ""));
50 | String cipher = encryptor.encrypt("foo");
51 | assertEquals(ExitStatus.OK,
52 | command.run("-k", "@src/test/resources/private.pem", cipher));
53 | }
54 |
55 | @Test
56 | public void decryptsFromRsaKeyWithKeyStore() throws Exception {
57 | KeyStoreKeyFactory factory = new KeyStoreKeyFactory(
58 | new ClassPathResource("keystore.jks"), "letmein".toCharArray());
59 | RsaSecretEncryptor encryptor = new RsaSecretEncryptor(
60 | factory.getKeyPair("mytestkey", "changeme".toCharArray()));
61 | String cipher = encryptor.encrypt("foo");
62 | assertEquals(ExitStatus.OK,
63 | command.run("-k", "src/test/resources/keystore.jks", "--password",
64 | "letmein", "--keypass", "changeme", "--alias", "mytestkey",
65 | cipher));
66 | }
67 |
68 | @Test(expected = IllegalArgumentException.class)
69 | public void failsWithPlainText() throws Exception {
70 | assertEquals(ExitStatus.OK, command.run("-k", "deadbeef", "foo"));
71 | }
72 |
73 | @Test(expected = IllegalStateException.class)
74 | public void failsWithBadFile() throws Exception {
75 | assertEquals(ExitStatus.OK, command.run("-k", "@nosuchfile", "foo"));
76 | }
77 |
78 | }
79 |
--------------------------------------------------------------------------------
/spring-cloud-cli/src/test/java/org/springframework/cloud/cli/command/encrypt/EncryptCommandTests.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2013-2014 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.cloud.cli.command.encrypt;
17 |
18 | import static org.junit.Assert.*;
19 |
20 | import org.junit.Test;
21 | import org.springframework.boot.cli.command.status.ExitStatus;
22 |
23 |
24 | /**
25 | * @author Dave Syer
26 | *
27 | */
28 | public class EncryptCommandTests {
29 |
30 | private EncryptCommand command = new EncryptCommand();
31 |
32 | @Test
33 | public void encryptsFromSymmetricKey() throws Exception {
34 | assertEquals(ExitStatus.OK, command.run("-k", "deadbeef", "foo"));
35 | }
36 |
37 | @Test(expected=MissingKeyException.class)
38 | public void errorOnNoKey() throws Exception {
39 | assertEquals(ExitStatus.ERROR, command.run("foo"));
40 | }
41 |
42 | @Test(expected=IllegalStateException.class)
43 | public void failsWithBadFile() throws Exception {
44 | assertEquals(ExitStatus.OK, command.run("-k", "@nosuchfile", "foo"));
45 | }
46 |
47 | }
48 |
--------------------------------------------------------------------------------
/spring-cloud-cli/src/test/java/org/springframework/cloud/cli/command/url/OutputCapture.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012-2014 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cloud.cli.command.url;
18 |
19 | import java.io.ByteArrayOutputStream;
20 | import java.io.IOException;
21 | import java.io.OutputStream;
22 | import java.io.PrintStream;
23 |
24 | import org.junit.rules.TestRule;
25 | import org.junit.runner.Description;
26 | import org.junit.runners.model.Statement;
27 |
28 | /**
29 | * Capture output from System.out and System.err.
30 | *
31 | * @author Phillip Webb
32 | */
33 | public class OutputCapture implements TestRule {
34 |
35 | private CaptureOutputStream captureOut;
36 |
37 | private CaptureOutputStream captureErr;
38 |
39 | private ByteArrayOutputStream copy;
40 |
41 | @Override
42 | public Statement apply(final Statement base, Description description) {
43 | return new Statement() {
44 | @Override
45 | public void evaluate() throws Throwable {
46 | captureOutput();
47 | try {
48 | base.evaluate();
49 | }
50 | finally {
51 | releaseOutput();
52 | }
53 | }
54 | };
55 | }
56 |
57 | protected void captureOutput() {
58 | this.copy = new ByteArrayOutputStream();
59 | this.captureOut = new CaptureOutputStream(System.out, this.copy);
60 | this.captureErr = new CaptureOutputStream(System.err, this.copy);
61 | System.setOut(new PrintStream(this.captureOut));
62 | System.setErr(new PrintStream(this.captureErr));
63 | }
64 |
65 | protected void releaseOutput() {
66 | System.setOut(this.captureOut.getOriginal());
67 | System.setErr(this.captureErr.getOriginal());
68 | this.copy = null;
69 | }
70 |
71 | public void flush() {
72 | try {
73 | this.captureOut.flush();
74 | this.captureErr.flush();
75 | }
76 | catch (IOException ex) {
77 | // ignore
78 | }
79 | }
80 |
81 | @Override
82 | public String toString() {
83 | flush();
84 | return this.copy.toString();
85 | }
86 |
87 | private static class CaptureOutputStream extends OutputStream {
88 |
89 | private final PrintStream original;
90 |
91 | private final OutputStream copy;
92 |
93 | CaptureOutputStream(PrintStream original, OutputStream copy) {
94 | this.original = original;
95 | this.copy = copy;
96 | }
97 |
98 | @Override
99 | public void write(int b) throws IOException {
100 | this.copy.write(b);
101 | this.original.write(b);
102 | this.original.flush();
103 | }
104 |
105 | @Override
106 | public void write(byte[] b) throws IOException {
107 | write(b, 0, b.length);
108 | }
109 |
110 | @Override
111 | public void write(byte[] b, int off, int len) throws IOException {
112 | this.copy.write(b, off, len);
113 | this.original.write(b, off, len);
114 | }
115 |
116 | public PrintStream getOriginal() {
117 | return this.original;
118 | }
119 |
120 | @Override
121 | public void flush() throws IOException {
122 | this.copy.flush();
123 | this.original.flush();
124 | }
125 | }
126 |
127 | }
128 |
--------------------------------------------------------------------------------
/spring-cloud-cli/src/test/java/org/springframework/cloud/cli/command/url/UrlDecodeCommandTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2013-2014 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.cloud.cli.command.url;
17 |
18 | import org.junit.Rule;
19 | import org.junit.Test;
20 |
21 | import org.springframework.boot.cli.command.Command;
22 | import org.springframework.boot.cli.command.status.ExitStatus;
23 | import org.springframework.boot.test.system.OutputCaptureRule;
24 |
25 | import static org.junit.Assert.assertEquals;
26 |
27 | /**
28 | * @author William Witt
29 | */
30 | public class UrlDecodeCommandTest {
31 | Command command = new UrlDecodeCommand();
32 |
33 | @Rule
34 | public OutputCaptureRule capture = new OutputCaptureRule();
35 |
36 | @Test
37 | public void urlDecodeNoSpecialChars() throws Exception {
38 | command.run("abcdefg");
39 | assertEquals("abcdefg\n", capture.toString());
40 | }
41 |
42 | @Test
43 | public void urlDecodeSpecialChars() throws Exception {
44 | command.run("a+b+c%26d%25efg%2B");
45 | assertEquals("a b c&d%efg+\n", capture.toString());
46 | }
47 |
48 | @Test
49 | public void urlDecodeNoSpecialCharsWithCharset() throws Exception {
50 | command.run("-c", "UTF-8", "abcdefg");
51 | assertEquals("abcdefg\n", capture.toString());
52 | }
53 |
54 | @Test
55 | public void urlDecodeSpecialCharsWithCharset() throws Exception {
56 | command.run("-c", "UTF-8", "a+b+c%26d%25efg%2B");
57 | assertEquals("a b c&d%efg+\n", capture.toString());
58 | }
59 |
60 | @Test
61 | public void urlDecodeNoSpecialCharsWithUnsupportedCharset() throws Exception {
62 | assertEquals(ExitStatus.ERROR, command.run("-c", "UTF-9", "abcdefg"));
63 | }
64 |
65 | @Test
66 | public void urlDecodeSpecialCharsWithUnsupportedCharset() throws Exception {
67 | assertEquals(ExitStatus.ERROR, command.run("-c", "UTF-9", "a b c&d%efg+"));
68 | }
69 | }
--------------------------------------------------------------------------------
/spring-cloud-cli/src/test/java/org/springframework/cloud/cli/command/url/UrlEncodeCommandTest.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2013-2014 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 | package org.springframework.cloud.cli.command.url;
17 |
18 | import org.junit.Rule;
19 | import org.junit.Test;
20 |
21 | import org.springframework.boot.cli.command.Command;
22 | import org.springframework.boot.cli.command.status.ExitStatus;
23 | import org.springframework.boot.test.system.OutputCaptureRule;
24 |
25 | import static org.junit.Assert.assertEquals;
26 |
27 | /**
28 | * @author William Witt
29 | */
30 | public class UrlEncodeCommandTest {
31 | Command command = new UrlEncodeCommand();
32 |
33 | @Rule
34 | public OutputCaptureRule capture = new OutputCaptureRule();
35 |
36 | @Test
37 | public void urlEncodeNoSpecialChars() throws Exception {
38 | command.run("abcdefg");
39 | assertEquals("abcdefg\n", capture.toString());
40 | }
41 |
42 | @Test
43 | public void urlEncodeSpecialChars() throws Exception {
44 | command.run("a b c&d%efg+");
45 | assertEquals("a+b+c%26d%25efg%2B\n", capture.toString());
46 | }
47 |
48 | @Test
49 | public void urlEncodeNoSpecialCharsWithCharset() throws Exception {
50 | command.run("-c", "UTF-8", "abcdefg");
51 | assertEquals("abcdefg\n", capture.toString());
52 | }
53 |
54 | @Test
55 | public void urlEncodeSpecialCharsWithCharset() throws Exception {
56 | command.run("-c", "UTF-8", "a b c&d%efg+");
57 | assertEquals("a+b+c%26d%25efg%2B\n", capture.toString());
58 | }
59 |
60 | @Test
61 | public void urlEncodeNoSpecialCharsWithUnsupportedCharset() throws Exception {
62 | assertEquals(ExitStatus.ERROR, command.run("-c", "UTF-9", "abcdefg"));
63 | }
64 |
65 | @Test
66 | public void urlEncodeSpecialCharsWithUnsupportedCharset() throws Exception {
67 | assertEquals(ExitStatus.ERROR, command.run("-c", "UTF-9", "a b c&d%efg+"));
68 | }
69 | }
--------------------------------------------------------------------------------
/spring-cloud-cli/src/test/java/org/springframework/cloud/cli/compiler/SpringCloudBomAstTransformationTests.java:
--------------------------------------------------------------------------------
1 | package org.springframework.cloud.cli.compiler;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.assertj.core.api.Assertions.assertThat;
6 |
7 | public class SpringCloudBomAstTransformationTests {
8 |
9 | @Test
10 | public void defaultVersionReadFromFile() {
11 | String version = new SpringCloudBomAstTransformation().getBomVersion();
12 | // starts with one or more digits then a .
13 | assertThat(version).isNotBlank().doesNotContainAnyWhitespaces().containsPattern("^\\d+\\..*");
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/spring-cloud-cli/src/test/resources/application.yml:
--------------------------------------------------------------------------------
1 | debug: true
2 | spring:
3 | application:
4 | name: eureka
5 | management:
6 | context-path: /admin
7 | eureka:
8 | server:
9 | waitTimeInMsWhenSyncEmpty: 1000
10 | client:
11 | serviceUrl:
12 | defaultZone: http://localhost:8080/eureka/
13 | default.defaultZone: http://localhost:8080/eureka/
14 | registerWithEureka: false
15 | fetchRegistry: false
--------------------------------------------------------------------------------
/spring-cloud-cli/src/test/resources/keystore.jks:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/spring-cloud/spring-cloud-cli/e240bea402c09921cbcfee84bc9d9d74ce87bf4d/spring-cloud-cli/src/test/resources/keystore.jks
--------------------------------------------------------------------------------
/spring-cloud-cli/src/test/resources/private.pem:
--------------------------------------------------------------------------------
1 | -----BEGIN RSA PRIVATE KEY-----
2 | MIICXAIBAAKBgQDQ835BXnZ7WU6SJd39rpl/qjm97W+i2K2fSMBzbCtbC3Z733tc
3 | TJH20nb0n97V6/ItKx0YcI3McHVH0PcqlxVRMO78RtvBuSOJZfddNaafKAEm7YFW
4 | FWs2OVGRj497T+/QpSlV9zAbtHUusJWHdu6mSaPMhJwY5Gm0kMUBQnMZuQIDAQAB
5 | AoGAEkTXyxtZPJuoVPrel+mGHjVh6wsxcYmEVKLlwLG6cLFl4Jq/jGhdcrkgEW9Q
6 | 6l9Aw1Y7qwFcRH2oo2jP03d2M4SMcJeAf5nC9lnNmXnEXurJvjNDuP6GihTQBMFZ
7 | R35IXKRjwPDobG76INySu3dbpdCj3HZIozdgpGIS4uKL/WkCQQD3gsmdvfOcsXtz
8 | t/BswnuZoeqOJjoHr+6Sr5AWI1FXitTeAWvupKBbLscpGdk8/AsfK9E96xCPk1N3
9 | ws+AG/NvAkEA2B4kAlUnz6pA2BG1MKNqc6Am+MfXmOCDdTcoSEav17KAb3tPx0FY
10 | 4n+CTd4lsGG13rXxtXETxKA9xVD2RkcRVwJABIofjIcZWrxemUa8YCJJBg5UMPs+
11 | gTmW1JXnvKA1M7fWI6Q/CId4cXOwL27L7zRoN9Aj7FDNYvS+ySmHiL/6fQJBANZN
12 | 1RFHFeoz/ocD0DNB6L5tchfCO0VKZLDoGBbLmXT/eaKSmcKRRy2amUDT53Wm/qyw
13 | qNVuItcYuwgdx4ha0pMCQDZfzYIH//t0K+jW5N7+pdLP1KsnSuHZOPn3uQaSXhWr
14 | 5JupxP9s5r6DMztLpcFHN/fQRCYVg+5KOCWDgZYTamE=
15 | -----END RSA PRIVATE KEY-----
16 |
--------------------------------------------------------------------------------
/spring-cloud-launcher/README.md:
--------------------------------------------------------------------------------
1 | ## Spring Cloud Launcher
2 |
3 | ### Building
4 |
5 | `./mvnw clean install` from parent directory
6 |
7 | ### Installing
8 |
9 | [Install Spring CLI first](../docs/src/main/asciidoc/install.adoc)
10 |
11 | ### Running
12 |
13 | ```
14 | $ spring cloud
15 | ```
16 |
17 | Currently starts configserver, dataflow, eureka, h2 (db server) and kafka. [Here](spring-cloud-launcher-deployer/src/main/resources/cloud.yml) is the full configuration.
18 |
19 | ### Configuring
20 |
21 | Spring Cloud Launcher uses normal Spring Boot configuration mechanisms. The config name is `cloud`, so configuration can go in `cloud.yml` or `cloud.properties`.
22 |
23 | For example, to run configserver and eureka, create a `cloud.yml` that looks like:
24 | ```yaml
25 | spring:
26 | cloud:
27 | launcher:
28 | deployables:
29 | - name: configserver
30 | coordinates: maven://org.springframework.cloud.launcher:spring-cloud-launcher-configserver:1.2.1.RELEASE
31 | port: 8888
32 | waitUntilStarted: true
33 | order: -10
34 | - name: eureka
35 | coordinates: maven://org.springframework.cloud.launcher:spring-cloud-launcher-eureka:1.2.1.RELEASE
36 | port: 8761
37 | ```
38 |
39 | The `name` attribute is required. If `waitUntilStarted` is true, Launcher will block until the application has reached the `deployed` state. Before commands are deployed, the list is sorted using Spring's `OrderComparator`. In the above case, `configserver` is deployed before any other app is deployed. Currently only `maven:` coordinates and standard Spring Resources (`file:`, etc...) are supported.
40 |
41 | You can also select from the [predefined deployables](spring-cloud-launcher-deployer/src/main/resources/cloud.yml). For example to run Spring Cloud Data Flow execute:
42 | ```
43 | spring cloud dataflow
44 | ```
45 |
46 | ### Config Server git uri
47 |
48 | To run configserver with a git repo set the following in `./configserver.yml`:
49 | ```yaml
50 | spring:
51 | profiles.active: git
52 | cloud.config.server.git.uri: https://mygitserver/myrepo.git
53 | ```
54 |
55 | ### Stopping
56 |
57 | `Ctrl-C` in the same terminal `spring cloud` was run.
58 |
59 | ### TODO
60 |
61 | - [X] Eureka
62 | - [X] Configserver
63 | - [X] Kafka Broker
64 | - [X] Kafka Bus
65 | - [X] Easy inclusion of default deployables
66 | - [X] H2 Database
67 | - [X] Spring Cloud Dataflow server
68 | - [X] Launcher landing page (Eureka Dashboard works for now)
69 | - [X] Sleuth/Zipkin
70 | - [ ] Support external rabbit
71 | - [ ] Speedup startup (parallel start?, retry for config server, db and kafka?)
72 | - [ ] Cassandra Database
73 | - [ ] Client Side Library
74 | - [ ] Spring Boot Admin (Not compatible with Brixton)
75 |
--------------------------------------------------------------------------------
/spring-cloud-launcher/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | org.springframework.cloud
7 | spring-cloud-launcher
8 | 3.1.2-SNAPSHOT
9 | pom
10 |
11 | spring-cloud-launcher
12 | Spring Cloud Launcher
13 |
14 |
15 | org.springframework.cloud
16 | spring-cloud-cli-parent
17 | 3.1.2-SNAPSHOT
18 |
19 |
20 |
21 | 1.0.27.RELEASE
22 |
23 |
24 |
25 | spring-cloud-launcher-deployer
26 | spring-cloud-launcher-cli
27 | spring-cloud-launcher-configserver
28 |
29 |
30 | spring-cloud-launcher-eureka
31 | spring-cloud-launcher-h2
32 |
33 | spring-cloud-launcher-stubrunner
34 |
35 |
36 |
37 |
38 | org.springframework.boot
39 | spring-boot-configuration-processor
40 | true
41 | provided
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 | org.springframework.boot
50 | spring-boot-maven-plugin
51 |
52 |
53 | org.springframework.boot.experimental
54 | spring-boot-thin-layout
55 | ${thin-jar.version}
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
--------------------------------------------------------------------------------
/spring-cloud-launcher/spring-cloud-launcher-cli/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | org.springframework.cloud.launcher
7 | spring-cloud-launcher-cli
8 | jar
9 |
10 | spring-cloud-launcher-cli
11 | Spring Cloud Launcher CLI
12 |
13 |
14 | org.springframework.cloud
15 | spring-cloud-launcher
16 | 3.1.2-SNAPSHOT
17 |
18 |
19 |
20 | 3.6.3
21 |
22 |
23 |
24 |
25 |
26 | org.apache.maven
27 | maven-settings-builder
28 | ${maven.version}
29 |
30 |
31 |
32 |
33 |
34 |
35 | org.springframework
36 | spring-core
37 | provided
38 |
39 |
40 | org.springframework.boot
41 | spring-boot-cli
42 | ${spring-boot.version}
43 | provided
44 |
45 |
46 | org.codehaus.groovy
47 | groovy
48 | provided
49 |
50 |
51 | net.sf.jopt-simple
52 | jopt-simple
53 |
54 |
55 |
56 | org.codehaus.plexus
57 | plexus-utils
58 |
59 | 3.2.1
60 |
61 |
62 |
81 |
82 | commons-logging
83 | commons-logging
84 | 1.2
85 | provided
86 |
87 |
88 | org.springframework.boot
89 | spring-boot-starter-test
90 | test
91 |
92 |
93 | junit
94 | junit
95 | test
96 |
97 |
98 |
99 |
100 |
--------------------------------------------------------------------------------
/spring-cloud-launcher/spring-cloud-launcher-cli/src/test/java/org/springframework/cloud/launcher/cli/LauncherCommandTests.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2013-2016 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cloud.launcher.cli;
18 |
19 | import org.junit.Ignore;
20 | import org.junit.Rule;
21 | import org.junit.Test;
22 |
23 | import org.springframework.boot.test.system.OutputCaptureRule;
24 |
25 | import static org.hamcrest.CoreMatchers.containsString;
26 | import static org.hamcrest.CoreMatchers.startsWith;
27 | import static org.junit.Assert.assertThat;
28 |
29 | /**
30 | * @author Spencer Gibb
31 | */
32 | public class LauncherCommandTests {
33 |
34 | @Rule
35 | public OutputCaptureRule output = new OutputCaptureRule();
36 |
37 | @Test
38 | @Ignore // FIXME: 3.0.0
39 | public void testCreateClassLoaderAndListDeployables() throws Exception {
40 | new LauncherCommand().run("--list");
41 | assertThat(output.toString(), containsString("configserver"));
42 | }
43 |
44 | @Test
45 | @Ignore // FIXME: 3.0.0
46 | public void testNonOptionArgsPassedDown() throws Exception {
47 | new LauncherCommand().run("--list", "--", "--spring.profiles.active=test",
48 | "--spring.config.location=file:./src/test/resources/");
49 | assertThat(output.toString(), containsString("foo"));
50 | }
51 |
52 | @Test
53 | @Ignore // FIXME: 3.0.0
54 | public void testVersion() throws Exception {
55 | new LauncherCommand().run("--version");
56 | assertThat(output.toString(), startsWith("Spring Cloud CLI v"));
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/spring-cloud-launcher/spring-cloud-launcher-cli/src/test/java/org/springframework/cloud/launcher/cli/OutputCapture.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012-2014 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cloud.launcher.cli;
18 |
19 | import java.io.ByteArrayOutputStream;
20 | import java.io.IOException;
21 | import java.io.OutputStream;
22 | import java.io.PrintStream;
23 |
24 | import org.junit.rules.TestRule;
25 | import org.junit.runner.Description;
26 | import org.junit.runners.model.Statement;
27 |
28 | /**
29 | * Capture output from System.out and System.err.
30 | *
31 | * @author Phillip Webb
32 | */
33 | public class OutputCapture implements TestRule {
34 |
35 | private CaptureOutputStream captureOut;
36 |
37 | private CaptureOutputStream captureErr;
38 |
39 | private ByteArrayOutputStream copy;
40 |
41 | @Override
42 | public Statement apply(final Statement base, Description description) {
43 | return new Statement() {
44 | @Override
45 | public void evaluate() throws Throwable {
46 | captureOutput();
47 | try {
48 | base.evaluate();
49 | }
50 | finally {
51 | releaseOutput();
52 | }
53 | }
54 | };
55 | }
56 |
57 | protected void captureOutput() {
58 | this.copy = new ByteArrayOutputStream();
59 | this.captureOut = new CaptureOutputStream(System.out, this.copy);
60 | this.captureErr = new CaptureOutputStream(System.err, this.copy);
61 | System.setOut(new PrintStream(this.captureOut));
62 | System.setErr(new PrintStream(this.captureErr));
63 | }
64 |
65 | protected void releaseOutput() {
66 | System.setOut(this.captureOut.getOriginal());
67 | System.setErr(this.captureErr.getOriginal());
68 | this.copy = null;
69 | }
70 |
71 | public void flush() {
72 | try {
73 | this.captureOut.flush();
74 | this.captureErr.flush();
75 | }
76 | catch (IOException ex) {
77 | // ignore
78 | }
79 | }
80 |
81 | @Override
82 | public String toString() {
83 | flush();
84 | return this.copy.toString();
85 | }
86 |
87 | private static class CaptureOutputStream extends OutputStream {
88 |
89 | private final PrintStream original;
90 |
91 | private final OutputStream copy;
92 |
93 | CaptureOutputStream(PrintStream original, OutputStream copy) {
94 | this.original = original;
95 | this.copy = copy;
96 | }
97 |
98 | @Override
99 | public void write(int b) throws IOException {
100 | this.copy.write(b);
101 | this.original.write(b);
102 | this.original.flush();
103 | }
104 |
105 | @Override
106 | public void write(byte[] b) throws IOException {
107 | write(b, 0, b.length);
108 | }
109 |
110 | @Override
111 | public void write(byte[] b, int off, int len) throws IOException {
112 | this.copy.write(b, off, len);
113 | this.original.write(b, off, len);
114 | }
115 |
116 | public PrintStream getOriginal() {
117 | return this.original;
118 | }
119 |
120 | @Override
121 | public void flush() throws IOException {
122 | this.copy.flush();
123 | this.original.flush();
124 | }
125 | }
126 |
127 | }
128 |
--------------------------------------------------------------------------------
/spring-cloud-launcher/spring-cloud-launcher-cli/src/test/resources/cloud-test.yml:
--------------------------------------------------------------------------------
1 | debug: true
2 | spring:
3 | cloud:
4 | launcher:
5 | deployables:
6 | foo:
7 | coordinates: com.example:foo:0.0.1-SNAPSHOT
8 | port: 8000
9 | waitUntilStarted: true
10 | order: -200
11 |
--------------------------------------------------------------------------------
/spring-cloud-launcher/spring-cloud-launcher-configserver/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | org.springframework.cloud.launcher
7 | spring-cloud-launcher-configserver
8 | jar
9 |
10 | spring-cloud-launcher-configserver
11 | Spring Cloud Launcher ConfigServer
12 |
13 |
14 | org.springframework.cloud
15 | spring-cloud-launcher
16 | 3.1.2-SNAPSHOT
17 |
18 |
19 |
20 |
21 | org.springframework.boot
22 | spring-boot-starter-actuator
23 |
24 |
25 | org.springframework.cloud
26 | spring-cloud-starter-netflix-eureka-client
27 |
28 |
29 | org.springframework.cloud
30 | spring-cloud-starter-bus-kafka
31 |
32 |
33 | org.springframework.cloud
34 | spring-cloud-config-server
35 |
36 |
37 | org.springframework.cloud
38 | spring-cloud-config-monitor
39 |
40 |
41 | org.springframework.boot
42 | spring-boot-starter-test
43 | test
44 |
45 |
46 | org.junit.vintage
47 | junit-vintage-engine
48 | test
49 |
50 |
51 |
52 |
53 |
54 |
55 | org.springframework.boot
56 | spring-boot-maven-plugin
57 |
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/spring-cloud-launcher/spring-cloud-launcher-configserver/src/main/java/org/springframework/cloud/launcher/configserver/ConfigServerApplication.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2013-2016 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cloud.launcher.configserver;
18 |
19 | import java.io.IOException;
20 |
21 | import org.springframework.boot.SpringApplication;
22 | import org.springframework.boot.autoconfigure.SpringBootApplication;
23 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
24 | import org.springframework.cloud.config.server.EnableConfigServer;
25 |
26 | /**
27 | * @author Spencer Gibb
28 | */
29 | @EnableConfigServer
30 | @EnableDiscoveryClient
31 | @SpringBootApplication
32 | public class ConfigServerApplication {
33 |
34 | public static void main(String[] args) throws IOException {
35 | SpringApplication.run(ConfigServerApplication.class, args);
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/spring-cloud-launcher/spring-cloud-launcher-configserver/src/main/resources/META-INF/thin-rabbit.properties:
--------------------------------------------------------------------------------
1 | exclusions.spring-cloud-starter-bus-kafka: org.springframework.cloud:spring-cloud-starter-bus-kafka
2 | exclusions.servlet-api: javax.servlet:servlet-api
3 | dependencies.spring-cloud-starter-bus-amqp: org.springframework.cloud:spring-cloud-starter-bus-amqp
4 |
--------------------------------------------------------------------------------
/spring-cloud-launcher/spring-cloud-launcher-configserver/src/main/resources/META-INF/thin.properties:
--------------------------------------------------------------------------------
1 | exclusions.servlet-api: javax.servlet:servlet-api
2 |
--------------------------------------------------------------------------------
/spring-cloud-launcher/spring-cloud-launcher-configserver/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | application:
3 | name: configserver
4 | profiles:
5 | active: native
6 | cloud:
7 | config:
8 | server:
9 | bootstrap: true
10 | native:
11 | search-locations: classpath:/launcher/, file:./launcher/
12 |
13 | server:
14 | port: 8888
15 |
16 | info:
17 | artifactId: "@project.artifactId@"
18 | description: "@project.description@"
19 | version: "@project.version@"
--------------------------------------------------------------------------------
/spring-cloud-launcher/spring-cloud-launcher-configserver/src/main/resources/launcher/application.yml:
--------------------------------------------------------------------------------
1 | info:
2 | description: Spring Cloud Launcher
3 |
4 | eureka:
5 | client:
6 | instance-info-replication-interval-seconds: 5
7 | initial-instance-info-replication-interval-seconds: 5
8 | serviceUrl:
9 | defaultZone: http://localhost:8761/eureka/
10 |
11 | endpoints:
12 | restart:
13 | enabled: true
14 |
15 | ribbon:
16 | ConnectTimeout: 3000
17 | ReadTimeout: 60000
18 |
19 | h2.datasource.url: jdbc:h2:tcp://localhost:9096/./target/test
20 | #spring:
21 | # datasource:
22 | # url: ${h2.datasource.url}
23 |
24 | logging:
25 | level:
26 | kafka: WARN
27 | org.apache.zookeeper: WARN
28 | org.apache.zookeeper.ClientCnxn: ERROR
29 | org.apache.kafka: WARN
30 | org.I0Itec: WARN
31 |
--------------------------------------------------------------------------------
/spring-cloud-launcher/spring-cloud-launcher-configserver/src/test/java/org/springframework/cloud/launcher/configserver/DeployerApplicationTests.java:
--------------------------------------------------------------------------------
1 | package org.springframework.cloud.launcher.configserver;
2 |
3 | import org.junit.Test;
4 | import org.junit.runner.RunWith;
5 |
6 | import org.springframework.boot.test.context.SpringBootTest;
7 | import org.springframework.test.context.junit4.SpringRunner;
8 |
9 | @RunWith(SpringRunner.class)
10 | @SpringBootTest({ "spring.cloud.config.server.git.uri=file:./target",
11 | "spring.cloud.bus.enabled=false" })
12 | public class DeployerApplicationTests {
13 |
14 | @Test
15 | public void contextLoads() {
16 | }
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/spring-cloud-launcher/spring-cloud-launcher-dataflow/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | 4.0.0
5 |
6 | org.springframework.cloud.launcher
7 | spring-cloud-launcher-dataflow
8 | jar
9 |
10 | spring-cloud-launcher-dataflow
11 | Spring Cloud Launcher Data Flow
12 |
13 |
14 | org.springframework.cloud
15 | spring-cloud-launcher
16 | 3.1.2-SNAPSHOT
17 |
18 |
19 |
20 | 1.2.3.RELEASE
21 |
22 |
23 |
24 |
25 |
26 | org.springframework.cloud
27 | spring-cloud-dataflow-dependencies
28 | ${spring-cloud-dataflow.version}
29 | pom
30 | import
31 |
32 |
33 |
34 |
35 |
36 |
37 | org.springframework.boot
38 | spring-boot-starter-actuator
39 |
40 |
41 | org.springframework.cloud
42 | spring-cloud-starter-config
43 |
44 |
45 | org.springframework.cloud
46 | spring-cloud-starter-netflix-eureka-client
47 |
48 |
49 | org.springframework.cloud
50 | spring-cloud-starter-dataflow-server-local
51 |
52 |
53 | org.springframework.boot
54 | spring-boot-starter-test
55 | test
56 |
57 |
58 |
59 |
60 |
61 |
62 | org.springframework.boot
63 | spring-boot-maven-plugin
64 |
65 |
66 |
67 |
68 |
--------------------------------------------------------------------------------
/spring-cloud-launcher/spring-cloud-launcher-dataflow/src/main/java/org/springframework/cloud/launcher/dataflow/DataFlowApplication.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2013-2016 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cloud.launcher.dataflow;
18 |
19 | import org.springframework.boot.SpringApplication;
20 | import org.springframework.boot.autoconfigure.SpringBootApplication;
21 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
22 | import org.springframework.cloud.dataflow.server.EnableDataFlowServer;
23 |
24 | /**
25 | * @author Spencer Gibb
26 | */
27 | @EnableDataFlowServer
28 | @EnableDiscoveryClient
29 | @SpringBootApplication
30 | public class DataFlowApplication {
31 |
32 | public static void main(String[] args) {
33 | SpringApplication.run(DataFlowApplication.class, args);
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/spring-cloud-launcher/spring-cloud-launcher-dataflow/src/main/resources/META-INF/thin-rabbit.properties:
--------------------------------------------------------------------------------
1 | exclusions.spring-cloud-starter-bus-kafka: org.springframework.cloud:spring-cloud-starter-bus-kafka
2 | dependencies.spring-cloud-starter-bus-amqp: org.springframework.cloud:spring-cloud-starter-bus-amqp
3 |
--------------------------------------------------------------------------------
/spring-cloud-launcher/spring-cloud-launcher-dataflow/src/main/resources/application.yml:
--------------------------------------------------------------------------------
1 | server:
2 | port: 9393
3 |
4 | # debug: true
5 |
6 | eureka:
7 | instance:
8 | status-page-url-path: /dashboard #allows you to click on the link in eureka dashboard
9 |
10 | info:
11 | artifactId: "@project.artifactId@"
12 | description: "@project.description@"
13 | version: "@project.version@"
14 |
15 | security:
16 | basic:
17 | enabled: false
18 |
19 | management:
20 | security:
21 | enabled: false
22 |
23 | spring.cloud.dataflow.applicationProperties.stream.spring.cloud.deployer.JAVA_OPTS: -Xmx128m
24 | # app.time.spring.cloud.deployer.JAVA_OPTS: -Xmx128m
25 | # app.log.spring.cloud.deployer.JAVA_OPTS: -Xmx128m
--------------------------------------------------------------------------------
/spring-cloud-launcher/spring-cloud-launcher-dataflow/src/main/resources/bootstrap.yml:
--------------------------------------------------------------------------------
1 | spring:
2 | application:
3 | name: dataflow
4 |
--------------------------------------------------------------------------------
/spring-cloud-launcher/spring-cloud-launcher-dataflow/src/test/java/org/springframework/cloud/launcher/dataflow/DeployerApplicationTests.java:
--------------------------------------------------------------------------------
1 | package org.springframework.cloud.launcher.dataflow;
2 |
3 | import org.junit.Ignore;
4 | import org.junit.Test;
5 | import org.junit.runner.RunWith;
6 |
7 | import org.springframework.boot.test.context.SpringBootTest;
8 | import org.springframework.test.context.junit4.SpringRunner;
9 |
10 | @RunWith(SpringRunner.class)
11 | @SpringBootTest({ "spring.cloud.bus.enabled=false", "eureka.client.enabled=false" })
12 | public class DeployerApplicationTests {
13 |
14 | @Test
15 | public void contextLoads() {
16 | }
17 |
18 | }
19 |
--------------------------------------------------------------------------------
/spring-cloud-launcher/spring-cloud-launcher-deployer/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | org.springframework.cloud.launcher
8 | spring-cloud-launcher-deployer
9 | jar
10 |
11 | spring-cloud-launcher-deployer
12 | Spring Cloud Launcher Deployer
13 |
14 |
15 | org.springframework.cloud
16 | spring-cloud-launcher
17 | 3.1.2-SNAPSHOT
18 |
19 |
20 |
21 | 2.0.6.RELEASE
22 | 2.0.3.RELEASE
23 | 1.0.24.RELEASE
24 | 3.3.9
25 |
26 |
27 |
28 |
29 |
30 | org.springframework.cloud
31 | spring-cloud-deployer-local
32 | ${spring-cloud-deployer.version}
33 |
34 |
35 | org.springframework.cloud
36 | spring-cloud-deployer-thin
37 | ${spring-cloud-deployer-thin.version}
38 |
39 |
40 | org.springframework.boot
41 | spring-boot-test-support
42 |
43 |
44 |
45 |
46 | org.springframework.cloud
47 | spring-cloud-deployer-resource-support
48 | ${spring-cloud-deployer-resource-support.version}
49 |
50 |
51 | org.apache.maven
52 | maven-aether-provider
53 | ${maven.version}
54 |
55 |
56 | org.apache.maven
57 | maven-settings-builder
58 | ${maven.version}
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 | org.springframework.boot
67 | spring-boot-loader
68 | 2.1.9.RELEASE
69 |
70 |
71 | org.springframework.cloud
72 | spring-cloud-deployer-thin
73 |
74 |
75 | org.springframework.cloud
76 | spring-cloud-deployer-resource-support
77 |
78 |
79 | org.springframework.boot
80 | spring-boot-starter-validation
81 |
82 |
83 | org.springframework.boot
84 | spring-boot-starter-test
85 | test
86 |
87 |
88 | org.junit.vintage
89 | junit-vintage-engine
90 | test
91 |
92 |
93 |
94 |
95 |
96 |
97 | src/main/resources
98 | true
99 |
100 |
101 |
102 |
103 | org.springframework.boot
104 | spring-boot-maven-plugin
105 |
106 |
107 | org.apache.maven.plugins
108 | maven-surefire-plugin
109 |
110 |
111 | ${project.version}
112 |
113 |
114 |
115 |
116 |
117 |
118 |
--------------------------------------------------------------------------------
/spring-cloud-launcher/spring-cloud-launcher-deployer/src/main/java/org/springframework/cloud/launcher/deployer/DeployerApplication.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2013-2016 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cloud.launcher.deployer;
18 |
19 | import java.io.IOException;
20 | import java.io.InputStream;
21 | import java.nio.charset.StandardCharsets;
22 | import java.util.ArrayList;
23 | import java.util.Arrays;
24 | import java.util.Collection;
25 | import java.util.List;
26 |
27 | import org.slf4j.Logger;
28 | import org.slf4j.LoggerFactory;
29 |
30 | import org.springframework.boot.Banner.Mode;
31 | import org.springframework.boot.WebApplicationType;
32 | import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration;
33 | import org.springframework.boot.builder.SpringApplicationBuilder;
34 | import org.springframework.boot.logging.LogLevel;
35 | import org.springframework.boot.logging.logback.LogbackLoggingSystem;
36 | import org.springframework.context.ConfigurableApplicationContext;
37 | import org.springframework.core.io.ClassPathResource;
38 | import org.springframework.util.ClassUtils;
39 | import org.springframework.util.ReflectionUtils;
40 | import org.springframework.util.StreamUtils;
41 | import org.springframework.util.StringUtils;
42 |
43 | /**
44 | * @author Spencer Gibb
45 | */
46 | public class DeployerApplication {
47 |
48 | private static final Logger logger = LoggerFactory
49 | .getLogger(DeployerApplication.class);
50 |
51 | private String[] args;
52 |
53 | public DeployerApplication(String... args) {
54 | this.args = args;
55 | }
56 |
57 | public static void main(String[] args) {
58 | new DeployerApplication(args).run();
59 | }
60 |
61 | void run() {
62 | List list = Arrays.asList(this.args);
63 | if (list.contains("--launcher.list=true")) {
64 | quiet();
65 | list();
66 | }
67 | else {
68 | launch();
69 | }
70 | }
71 |
72 | private void quiet() {
73 | try {
74 | LogbackLoggingSystem.get(ClassUtils.getDefaultClassLoader())
75 | .setLogLevel("ROOT", LogLevel.OFF);
76 | }
77 | catch (Exception e) {
78 | logger.error("Unable to turn of ROOT logger for quiet()", e);
79 | }
80 | }
81 |
82 | private void list() {
83 | DeployerProperties properties = loadCloudProperties();
84 | if (!properties.getDeployables().isEmpty()) {
85 | Collection names = new ArrayList<>(
86 | properties.getDeployables().keySet());
87 | System.out.println(StringUtils.collectionToDelimitedString(names, " "));
88 | }
89 | }
90 |
91 | private DeployerProperties loadCloudProperties() {
92 |
93 | final ConfigurableApplicationContext context = new SpringApplicationBuilder(
94 | PropertyPlaceholderAutoConfiguration.class, DeployerConfiguration.class)
95 | .bannerMode(Mode.OFF).logStartupInfo(false).web(WebApplicationType.NONE)
96 | .properties("spring.config.name=cloud", "logging.level.ROOT=OFF",
97 | "spring.cloud.launcher.list=true",
98 | "launcher.version=" + getVersion())
99 | .run(this.args);
100 | try {
101 | return context.getBean(DeployerProperties.class);
102 | }
103 | finally {
104 | context.close();
105 | }
106 | }
107 |
108 | String getVersion() {
109 | Package pkg = DeployerApplication.class.getPackage();
110 | return (pkg != null ? pkg.getImplementationVersion() == null ? getDefaultVersion()
111 | : pkg.getImplementationVersion() : getDefaultVersion());
112 | }
113 |
114 | String getDefaultVersion() {
115 | try (InputStream in = new ClassPathResource("META-INF/cli-version.txt").getInputStream()) {
116 | String version = StreamUtils.copyToString(in, StandardCharsets.UTF_8);
117 | if (StringUtils.hasText(version)) {
118 | version = version.trim();
119 | }
120 | return version;
121 | }
122 | catch (IOException e) {
123 | ReflectionUtils.rethrowRuntimeException(e);
124 | }
125 | // not reachable since exception rethrown at runtime
126 | return null;
127 | }
128 |
129 | private void launch() {
130 |
131 | final ConfigurableApplicationContext context = new SpringApplicationBuilder(
132 | PropertyPlaceholderAutoConfiguration.class, DeployerConfiguration.class)
133 | .web(WebApplicationType.NONE)
134 | .properties("spring.config.name=cloud",
135 | "banner.location=launcher-banner.txt",
136 | "launcher.version=" + getVersion())
137 | .run(this.args);
138 |
139 | final Deployer deployer = context.getBean(Deployer.class);
140 | deployer.deploy();
141 |
142 | }
143 |
144 | }
145 |
--------------------------------------------------------------------------------
/spring-cloud-launcher/spring-cloud-launcher-deployer/src/main/java/org/springframework/cloud/launcher/deployer/DeployerConfiguration.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2013-2016 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cloud.launcher.deployer;
18 |
19 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
20 | import org.springframework.boot.context.properties.ConfigurationProperties;
21 | import org.springframework.boot.context.properties.EnableConfigurationProperties;
22 | import org.springframework.cloud.deployer.resource.maven.MavenProperties;
23 | import org.springframework.cloud.deployer.resource.maven.MavenResourceLoader;
24 | import org.springframework.cloud.deployer.resource.support.DelegatingResourceLoader;
25 | import org.springframework.cloud.deployer.spi.app.AppDeployer;
26 | import org.springframework.context.annotation.Bean;
27 | import org.springframework.context.annotation.Configuration;
28 | import org.springframework.core.env.ConfigurableEnvironment;
29 | import org.springframework.core.io.ResourceLoader;
30 |
31 | import java.util.HashMap;
32 |
33 | /**
34 | * @author Spencer Gibb
35 | */
36 | @Configuration
37 | @EnableAutoConfiguration
38 | @EnableConfigurationProperties({ DeployerProperties.class })
39 | public class DeployerConfiguration {
40 |
41 | @Bean
42 | public Deployer deployer(AppDeployer deployer, MavenResourceLoader resourceLoader,
43 | DeployerProperties properties, ConfigurableEnvironment environment) {
44 | return new Deployer(deployer, resourceLoader, properties, environment);
45 | }
46 |
47 | @ConfigurationProperties(prefix = "spring.cloud.maven")
48 | @Bean
49 | public MavenProperties mavenProperties() {
50 | return new MavenProperties();
51 | }
52 |
53 | @Bean
54 | public MavenResourceLoader mavenResourceLoader(MavenProperties mavenProperties) {
55 | return new MavenResourceLoader(mavenProperties);
56 | }
57 |
58 | @Bean
59 | public DelegatingResourceLoader delegatingResourceLoader(MavenResourceLoader mavenResourceLoader) {
60 | HashMap map = new HashMap<>();
61 | map.put("maven", mavenResourceLoader);
62 | return new DelegatingResourceLoader(map);
63 | }
64 | }
65 |
--------------------------------------------------------------------------------
/spring-cloud-launcher/spring-cloud-launcher-deployer/src/main/java/org/springframework/cloud/launcher/deployer/DeployerProperties.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2013-2016 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cloud.launcher.deployer;
18 |
19 | import java.util.ArrayList;
20 | import java.util.LinkedHashMap;
21 | import java.util.List;
22 | import java.util.Map;
23 |
24 | import javax.annotation.PostConstruct;
25 | import javax.validation.constraints.NotNull;
26 |
27 | import org.hibernate.validator.constraints.NotEmpty;
28 |
29 | import org.springframework.boot.context.properties.ConfigurationProperties;
30 | import org.springframework.core.Ordered;
31 |
32 | /**
33 | * @author Spencer Gibb
34 | */
35 | @ConfigurationProperties(prefix = "spring.cloud.launcher")
36 | public class DeployerProperties {
37 |
38 | /**
39 | * A set of deployable applications.
40 | */
41 | @NotNull
42 | private Map deployables = new LinkedHashMap<>();
43 |
44 | /**
45 | * The names of the deployable applications to actually deploy.
46 | */
47 | @NotNull
48 | private List deploy = new ArrayList<>();
49 |
50 | /**
51 | * Flag to say that user only requests a list of deployables.
52 | */
53 | private boolean list = false;
54 |
55 | /**
56 | * Time to sleep in a tight loop while waiting for an app to start.
57 | */
58 | private int statusSleepMillis = 300;
59 |
60 | public boolean isList() {
61 | return this.list;
62 | }
63 |
64 | public void setList(boolean list) {
65 | this.list = list;
66 | }
67 |
68 | public Map getDeployables() {
69 | return this.deployables;
70 | }
71 |
72 | public void setDeployables(Map deployables) {
73 | this.deployables = deployables;
74 | }
75 |
76 | public List getDeploy() {
77 | return this.deploy;
78 | }
79 |
80 | public void setDeploy(List deploy) {
81 | this.deploy = deploy;
82 | }
83 |
84 | public int getStatusSleepMillis() {
85 | return this.statusSleepMillis;
86 | }
87 |
88 | public void setStatusSleepMillis(int statusSleepMillis) {
89 | this.statusSleepMillis = statusSleepMillis;
90 | }
91 |
92 | @PostConstruct
93 | public void init() {
94 | for (String name : deployables.keySet()) {
95 | Deployable deployable = deployables.get(name);
96 | if (deployable.getName() == null) {
97 | deployable.setName(name);
98 | }
99 | }
100 | }
101 |
102 | @Override
103 | public String toString() {
104 | final StringBuffer sb = new StringBuffer("DeployerProperties{");
105 | sb.append("deployables=").append(this.deployables);
106 | sb.append(", deploy=").append(this.deploy);
107 | sb.append(", statusSleepMillis=").append(this.statusSleepMillis);
108 | sb.append('}');
109 | return sb.toString();
110 | }
111 |
112 | public static class Deployable implements Ordered {
113 | /**
114 | * Maven (grab-style) co-ordinates of the deployable application artifact in the
115 | * form "group:artifact[:classifer]:version" (classifer defaults to "jar").
116 | */
117 | @NotEmpty
118 | private String coordinates;
119 | /**
120 | * Name of the deployable application.
121 | */
122 | @NotEmpty
123 | private String name;
124 | /**
125 | * Port to listen on.
126 | */
127 | private int port = 0;
128 | /**
129 | * Flag to say that this application must be running before any with higher order
130 | * are launched.
131 | */
132 | private boolean waitUntilStarted;
133 | /**
134 | * The order to deploy this application. Default is unordered (so last).
135 | */
136 | private int order = 0;
137 | /**
138 | * A message to print when the application starts.
139 | */
140 | private String message;
141 | /**
142 | * A map of "negative" properties that apply to all apps when this one is
143 | * disabled. E.g. when eureka is disabled you might want
144 | * "eureka.client.enabled=false".
145 | */
146 | private Map disabled = new LinkedHashMap<>();
147 | /**
148 | * A map of "positive" properties that apply to all apps when this one is enabled.
149 | * E.g. when h2 is disabled you might want the JDBC URL to be used everywhere.
150 | */
151 | private Map enabled = new LinkedHashMap<>();
152 | /**
153 | * A map of "deployment" properties passed to the deployer (not the app) when an
154 | * app is launched. E.g. you can use
155 | * spring.cloud.deployer.local.javaOpts
here to pass JVM args to a
156 | * local deployer.
157 | */
158 | private Map properties = new LinkedHashMap<>();
159 |
160 | /**
161 | * A map of properties passed to the app (not the deployer) when an app is
162 | * launched.
163 | */
164 | private Map applicationProperties;
165 |
166 | public String getCoordinates() {
167 | return this.coordinates;
168 | }
169 |
170 | public void setCoordinates(String coordinates) {
171 | this.coordinates = coordinates;
172 | }
173 |
174 | public String getName() {
175 | return this.name;
176 | }
177 |
178 | public void setName(String name) {
179 | this.name = name;
180 | }
181 |
182 | public int getPort() {
183 | return this.port;
184 | }
185 |
186 | public void setPort(int port) {
187 | this.port = port;
188 | }
189 |
190 | public boolean isWaitUntilStarted() {
191 | return this.waitUntilStarted;
192 | }
193 |
194 | public void setWaitUntilStarted(boolean waitUntilStarted) {
195 | this.waitUntilStarted = waitUntilStarted;
196 | }
197 |
198 | @Override
199 | public int getOrder() {
200 | return this.order;
201 | }
202 |
203 | public void setOrder(int order) {
204 | this.order = order;
205 | }
206 |
207 | public String getMessage() {
208 | return this.message;
209 | }
210 |
211 | public void setMessage(String message) {
212 | this.message = message;
213 | }
214 |
215 | public void setDisabled(Map disabled) {
216 | this.disabled = disabled;
217 | }
218 |
219 | public Map getDisabled() {
220 | return disabled;
221 | }
222 |
223 | public Map getEnabled() {
224 | return enabled;
225 | }
226 |
227 | public void setEnabled(Map enabled) {
228 | this.enabled = enabled;
229 | }
230 |
231 | public Map getProperties() {
232 | return properties;
233 | }
234 |
235 | public void setProperties(Map properties) {
236 | this.properties = properties;
237 | }
238 |
239 | public Map getApplicationProperties() {
240 | return applicationProperties;
241 | }
242 |
243 | public void setApplicationProperties(Map applicationProperties) {
244 | this.applicationProperties = applicationProperties;
245 | }
246 |
247 | @Override
248 | public String toString() {
249 | final StringBuffer sb = new StringBuffer("Deployable{");
250 | sb.append("coordinates='").append(this.coordinates).append('\'');
251 | sb.append(", name='").append(this.name).append('\'');
252 | sb.append(", port=").append(this.port);
253 | sb.append(", waitUntilStarted=").append(this.waitUntilStarted);
254 | sb.append(", order=").append(this.order);
255 | sb.append(", disabled=").append(this.disabled);
256 | sb.append(", enabled=").append(this.disabled);
257 | sb.append(", properties=").append(this.properties);
258 | sb.append(", message=").append(this.message);
259 | sb.append('}');
260 | return sb.toString();
261 | }
262 |
263 | }
264 | }
265 |
--------------------------------------------------------------------------------
/spring-cloud-launcher/spring-cloud-launcher-deployer/src/main/resources/META-INF/cli-version.txt:
--------------------------------------------------------------------------------
1 | @project.version@
2 |
--------------------------------------------------------------------------------
/spring-cloud-launcher/spring-cloud-launcher-deployer/src/main/resources/META-INF/thin-local.properties:
--------------------------------------------------------------------------------
1 | exclusions.spring-cloud-deployer-local: org.springframework.cloud:spring-cloud-deployer-thin
2 | dependencies.spring-cloud-deplyer-thin: org.springframework.cloud:spring-cloud-deployer-local
3 |
--------------------------------------------------------------------------------
/spring-cloud-launcher/spring-cloud-launcher-deployer/src/main/resources/META-INF/thin-rabbit.properties:
--------------------------------------------------------------------------------
1 | exclusions.spring-cloud-starter-bus-kafka: org.springframework.cloud:spring-cloud-starter-bus-kafka
2 | dependencies.spring-cloud-starter-bus-amqp: org.springframework.cloud:spring-cloud-starter-bus-amqp
3 |
--------------------------------------------------------------------------------
/spring-cloud-launcher/spring-cloud-launcher-deployer/src/main/resources/META-INF/thin-thin.properties:
--------------------------------------------------------------------------------
1 | exclusions.spring-cloud-deployer-local: org.springframework.cloud:spring-cloud-deployer-local
2 | dependencies.spring-cloud-deplyer-thin: org.springframework.cloud:spring-cloud-deployer-thin
3 |
--------------------------------------------------------------------------------
/spring-cloud-launcher/spring-cloud-launcher-deployer/src/main/resources/cloud.yml:
--------------------------------------------------------------------------------
1 | dt:
2 | pre: maven://org.springframework.cloud.launcher:spring-cloud-launcher-
3 | ver: ${launcher.version}
4 | mem: 128m
5 | opts: -XX:TieredStopAtLevel=1 -noverify
6 |
7 | spring:
8 | cloud:
9 | maven:
10 | remote-repositories:
11 | central:
12 | url: https://repo1.maven.org/maven2
13 | spring-milestone:
14 | url: https://repo.spring.io/milestone
15 | spring-snapshot:
16 | url: https://repo.spring.io/snapshot
17 | launcher:
18 | deployables:
19 | configserver:
20 | coordinates: ${dt.pre}configserver:${dt.ver}
21 | port: 8888
22 | waitUntilStarted: true
23 | order: -100
24 | properties:
25 | spring.cloud.deployer.memory: ${dt.mem}
26 | spring.cloud.deployer.local.javaOpts: ${dt.opts}
27 | application-properties:
28 | management.security.enabled: false
29 | dataflow:
30 | coordinates: ${dt.pre}dataflow:${dt.ver}
31 | port: 9393
32 | properties:
33 | spring.cloud.deployer.memory: ${dt.mem}
34 | spring.cloud.deployer.local.javaOpts: ${dt.opts}
35 | application-properties:
36 | management.security.enabled: false
37 | eureka:
38 | coordinates: ${dt.pre}eureka:${dt.ver}
39 | port: 8761
40 | message: To see the dashboard open http://localhost:8761
41 | disabled:
42 | eureka.client.enabled: false
43 | properties:
44 | spring.cloud.deployer.memory: ${dt.mem}
45 | spring.cloud.deployer.local.javaOpts: ${dt.opts}
46 | application-properties:
47 | management.security.enabled: false
48 | h2:
49 | coordinates: ${dt.pre}h2:${dt.ver}
50 | port: 9095
51 | message: Connect on jdbc:h2:tcp://localhost:9096/mem:test, web console at http://localhost:9095
52 | waitUntilStarted: true
53 | order: -50
54 | enabled:
55 | spring.datasource.url: jdbc:h2:tcp://localhost:9096/mem:test
56 | spring.dataflow.embedded.database.enabled: false
57 | properties:
58 | spring.cloud.deployer.memory: ${dt.mem}
59 | spring.cloud.deployer.local.javaOpts: ${dt.opts}
60 | application-properties:
61 | management.security.enabled: false
62 | kafka:
63 | coordinates: ${dt.pre}kafka:${dt.ver}
64 | port: 9091
65 | waitUntilStarted: true
66 | order: -200
67 | disabled:
68 | spring.cloud.bus.enabled: false
69 | properties:
70 | spring.cloud.deployer.memory: ${dt.mem}
71 | spring.cloud.deployer.local.javaOpts: ${dt.opts}
72 | application-properties:
73 | management.security.enabled: false
74 | stubrunner:
75 | coordinates: ${dt.pre}stubrunner:${dt.ver}
76 | port: 8750
77 | message: To see the registered stubs open http://localhost:8750/stubs
78 | order: 0
79 | properties:
80 | spring.cloud.deployer.memory: ${dt.mem}
81 | spring.cloud.deployer.local.javaOpts: ${dt.opts}
82 | application-properties:
83 | management.security.enabled: false
84 | zipkin:
85 | coordinates: io.zipkin.java:zipkin-server:jar:exec:2.8.2
86 | port: 9411
87 | order: 0
88 | properties:
89 | spring.cloud.deployer.memory: ${dt.mem}
90 | spring.cloud.deployer.local.javaOpts: ${dt.opts}
91 | application-properties:
92 | management.security.enabled: false
93 | deploy: ${launcher.deploy:configserver,eureka}
94 |
95 | ---
96 | spring:
97 | profiles: rabbit
98 | cloud:
99 | launcher:
100 | deployables:
101 | configserver:
102 | properties:
103 | spring.cloud.deployer.thin.profile: rabbit
104 | application-properties:
105 | spring.cloud.bus.enabled: true
106 | eureka:
107 | properties:
108 | spring.cloud.deployer.thin.profile: rabbit
109 | application-properties:
110 | spring.cloud.bus.enabled: true
111 | h2:
112 | properties:
113 | spring.cloud.deployer.thin.profile: rabbit
114 | application-properties:
115 | spring.cloud.bus.enabled: true
116 | dataflow:
117 | properties:
118 | spring.cloud.deployer.thin.profile: rabbit
119 | application-properties:
120 | spring.cloud.bus.enabled: true
121 | stubrunner:
122 | properties:
123 | spring.cloud.deployer.thin.profile: rabbit
124 | application-properties:
125 | spring.cloud.bus.enabled: true
126 | zipkin:
127 | properties:
128 | spring.cloud.deployer.thin.profile: rabbit
129 | application-properties:
130 | spring.cloud.bus.enabled: true
131 |
--------------------------------------------------------------------------------
/spring-cloud-launcher/spring-cloud-launcher-deployer/src/main/resources/launcher-banner.txt:
--------------------------------------------------------------------------------
1 | ${Ansi.GREEN}
2 | ███████╗██████╗ ██████╗ ██╗███╗ ██╗ ██████╗ ██████╗██╗ ██████╗ ██╗ ██╗██████╗
3 | ██╔════╝██╔══██╗██╔══██╗██║████╗ ██║██╔════╝ ██╔════╝██║ ██╔═══██╗██║ ██║██╔══██╗
4 | ███████╗██████╔╝██████╔╝██║██╔██╗ ██║██║ ███╗ ██║ ██║ ██║ ██║██║ ██║██║ ██║
5 | ╚════██║██╔═══╝ ██╔══██╗██║██║╚██╗██║██║ ██║ ██║ ██║ ██║ ██║██║ ██║██║ ██║
6 | ███████║██║ ██║ ██║██║██║ ╚████║╚██████╔╝ ╚██████╗███████╗╚██████╔╝╚██████╔╝██████╔╝
7 | ╚══════╝╚═╝ ╚═╝ ╚═╝╚═╝╚═╝ ╚═══╝ ╚═════╝ ╚═════╝╚══════╝ ╚═════╝ ╚═════╝ ╚═════╝
8 | ${Ansi.WHITE}
9 | -- Spring Cloud Launcher --
10 |
--------------------------------------------------------------------------------
/spring-cloud-launcher/spring-cloud-launcher-deployer/src/test/java/org/springframework/cloud/launcher/deployer/DeployerApplicationTests.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2013-2016 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cloud.launcher.deployer;
18 |
19 | import org.junit.Ignore;
20 | import org.junit.Rule;
21 | import org.junit.Test;
22 |
23 | import org.springframework.boot.test.system.OutputCaptureRule;
24 |
25 | import static org.assertj.core.api.Assertions.assertThat;
26 |
27 | /**
28 | * @author Spencer Gibb
29 | */
30 | public class DeployerApplicationTests {
31 |
32 | @Rule
33 | public OutputCaptureRule output = new OutputCaptureRule();
34 |
35 | @Test
36 | @Ignore("I don't know how to change the stored deployer version")
37 | public void testDefaultLibrary() throws Exception {
38 | DeployerApplication wrapper = new DeployerApplication();
39 | if (System.getProperty("project.version") != null) {
40 | assertThat(wrapper.getVersion())
41 | .contains(System.getProperty("project.version"));
42 | }
43 | }
44 |
45 | @Test
46 | public void testCreateClassLoaderAndListDeployables() throws Exception {
47 | new DeployerApplication("--launcher.list=true").run();
48 | assertThat(output.toString()).contains("configserver");
49 | }
50 |
51 | @Test
52 | public void testNonOptionArgsPassedDown() throws Exception {
53 | new DeployerApplication("--launcher.list=true", "--spring.profiles.active=test")
54 | .run();
55 | assertThat(output.toString()).contains("foo");
56 | }
57 |
58 | @Test
59 | public void testInvalidDeployableFails() throws Exception {
60 | new DeployerApplication("--launcher.deploy=foo,bar").run();
61 | assertThat(output.toString())
62 | .contains("The following are not valid: 'foo,bar'");
63 | }
64 |
65 | @Test
66 | public void defaultVersionReadFromFile() {
67 | String defaultVersion = new DeployerApplication("--launcher.deploy=foo,bar").getDefaultVersion();
68 | // starts with one or more digits then a .
69 | assertThat(defaultVersion).isNotBlank().doesNotContainAnyWhitespaces().containsPattern("^\\d+\\..*");
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/spring-cloud-launcher/spring-cloud-launcher-deployer/src/test/java/org/springframework/cloud/launcher/deployer/LauncherAppDeployerTests.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012-2015 the original author or authors.
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package org.springframework.cloud.launcher.deployer;
18 |
19 | import java.util.Arrays;
20 | import java.util.LinkedHashMap;
21 | import java.util.List;
22 | import java.util.Map;
23 | import java.util.Properties;
24 |
25 | import org.junit.Assume;
26 | import org.junit.BeforeClass;
27 | import org.junit.Ignore;
28 | import org.junit.Test;
29 | import org.junit.runner.RunWith;
30 | import org.junit.runners.Parameterized;
31 | import org.springframework.boot.loader.thin.ArchiveUtils;
32 | import org.springframework.boot.loader.tools.LogbackInitializer;
33 | import org.springframework.cloud.deployer.spi.app.DeploymentState;
34 | import org.springframework.cloud.deployer.spi.core.AppDefinition;
35 | import org.springframework.cloud.deployer.spi.core.AppDeploymentRequest;
36 | import org.springframework.cloud.deployer.thin.ThinJarAppDeployer;
37 | import org.springframework.core.io.FileSystemResource;
38 | import org.springframework.core.io.Resource;
39 | import org.springframework.util.StringUtils;
40 |
41 | import static org.assertj.core.api.Assertions.assertThat;
42 |
43 | /**
44 | * @author Dave Syer
45 | */
46 | @RunWith(Parameterized.class)
47 | public class LauncherAppDeployerTests {
48 |
49 | static {
50 | LogbackInitializer.initialize();
51 | }
52 |
53 | private static ThinJarAppDeployer deployer = new ThinJarAppDeployer();
54 | private static String resource;
55 |
56 | @BeforeClass
57 | public static void skip() {
58 | try {
59 | resource = "maven://org.springframework.cloud.launcher:spring-cloud-launcher-configserver:"
60 | + new DeployerApplication().getVersion();
61 | ArchiveUtils.getArchiveRoot(ArchiveUtils.getArchive(resource));
62 | }
63 | catch (Exception e) {
64 | Assume.assumeNoException(
65 | "Could not locate jar for tests. Please build spring-cloud-cli locally first.",
66 | e);
67 | }
68 | }
69 |
70 | @Parameterized.Parameters
71 | public static List