├── .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 data() { 72 | // Repeat a couple of times to ensure it's consistent 73 | return Arrays.asList(new Object[2][0]); 74 | } 75 | 76 | @Test 77 | @Ignore //FIXME: 2.0.x 78 | public void rabbit() throws Exception { 79 | String first = deploy(resource, "spring.cloud.deployer.thin.profile=rabbit", ""); 80 | // Deployment is blocking so it either failed or succeeded. 81 | assertThat(deployer.status(first).getState()).isEqualTo(DeploymentState.deployed); 82 | deployer.undeploy(first); 83 | } 84 | 85 | private String deploy(String jarName, String deployment, String application, String... args) 86 | throws Exception { 87 | Resource resource = new FileSystemResource( 88 | ArchiveUtils.getArchiveRoot(ArchiveUtils.getArchive(jarName))); 89 | AppDefinition definition = new AppDefinition(resource.getFilename(), 90 | properties(application)); 91 | AppDeploymentRequest request = new AppDeploymentRequest(definition, resource, 92 | properties(deployment), Arrays.asList(args)); 93 | String deployed = deployer.deploy(request); 94 | return deployed; 95 | } 96 | 97 | private Map properties(String properties) { 98 | Map map = new LinkedHashMap<>(); 99 | Properties props = StringUtils.splitArrayElementsIntoProperties( 100 | StringUtils.commaDelimitedListToStringArray(properties), "="); 101 | if (props != null) { 102 | for (Object name : props.keySet()) { 103 | String key = (String) name; 104 | map.put(key, props.getProperty(key)); 105 | } 106 | } 107 | return map; 108 | } 109 | 110 | } 111 | -------------------------------------------------------------------------------- /spring-cloud-launcher/spring-cloud-launcher-deployer/src/test/resources/cloud-test.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | cloud: 3 | launcher: 4 | deployables: 5 | foo: 6 | coordinates: com.example:foo:0.0.1-SNAPSHOT 7 | port: 8000 8 | waitUntilStarted: true 9 | order: -200 10 | properties: 11 | JAVA_OPTS: -Xmx64m 12 | -------------------------------------------------------------------------------- /spring-cloud-launcher/spring-cloud-launcher-eureka/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | org.springframework.cloud.launcher 8 | spring-cloud-launcher-eureka 9 | jar 10 | 11 | spring-cloud-launcher-eureka 12 | Spring Cloud Launcher Eureka 13 | 14 | 15 | org.springframework.cloud 16 | spring-cloud-launcher 17 | 3.1.2-SNAPSHOT 18 | 19 | 20 | 21 | 22 | org.springframework.boot 23 | spring-boot-starter-actuator 24 | 25 | 26 | org.springframework.cloud 27 | spring-cloud-starter-config 28 | 29 | 30 | org.springframework.cloud 31 | spring-cloud-starter-bus-kafka 32 | 33 | 34 | org.springframework.cloud 35 | spring-cloud-netflix-eureka-server 36 | 37 | 38 | javax.xml.bind 39 | jaxb-api 40 | 41 | 42 | org.glassfish.jaxb 43 | jaxb-runtime 44 | 45 | 46 | javax.activation 47 | javax.activation-api 48 | 49 | 50 | org.springframework.boot 51 | spring-boot-starter-test 52 | test 53 | 54 | 55 | org.junit.vintage 56 | junit-vintage-engine 57 | test 58 | 59 | 60 | 61 | 62 | 63 | 64 | org.springframework.boot 65 | spring-boot-maven-plugin 66 | 67 | 68 | 69 | 70 | -------------------------------------------------------------------------------- /spring-cloud-launcher/spring-cloud-launcher-eureka/src/main/java/org/springframework/cloud/launcher/eureka/EurekaApplication.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.eureka; 18 | 19 | import org.springframework.boot.SpringApplication; 20 | import org.springframework.boot.autoconfigure.SpringBootApplication; 21 | import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; 22 | 23 | /** 24 | * @author Spencer Gibb 25 | */ 26 | @EnableEurekaServer 27 | @SpringBootApplication 28 | public class EurekaApplication { 29 | public static void main(String[] args) { 30 | SpringApplication.run(EurekaApplication.class, args); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /spring-cloud-launcher/spring-cloud-launcher-eureka/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-eureka/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8761 3 | 4 | eureka: 5 | client: 6 | registerWithEureka: false 7 | fetchRegistry: false 8 | server: 9 | renewal-percent-threshold: 0.01 10 | waitTimeInMsWhenSyncEmpty: 0 11 | 12 | info: 13 | artifactId: "@project.artifactId@" 14 | description: "@project.description@" 15 | version: "@project.version@" -------------------------------------------------------------------------------- /spring-cloud-launcher/spring-cloud-launcher-eureka/src/main/resources/bootstrap.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: eurekaserver 4 | -------------------------------------------------------------------------------- /spring-cloud-launcher/spring-cloud-launcher-eureka/src/test/java/org/springframework/cloud/launcher/eureka/DeployerApplicationTests.java: -------------------------------------------------------------------------------- 1 | package org.springframework.cloud.launcher.eureka; 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.bus.enabled=false", "spring.cloud.config.enabled=false"}) 11 | public class DeployerApplicationTests { 12 | 13 | @Test 14 | public void contextLoads() { 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /spring-cloud-launcher/spring-cloud-launcher-h2/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | org.springframework.cloud.launcher 8 | spring-cloud-launcher-h2 9 | jar 10 | 11 | spring-cloud-launcher-h2 12 | Spring Cloud Launcher H2 13 | 14 | 15 | org.springframework.cloud 16 | spring-cloud-launcher 17 | 3.1.2-SNAPSHOT 18 | 19 | 20 | 21 | 22 | com.h2database 23 | h2 24 | 25 | 26 | org.springframework.boot 27 | spring-boot-starter-web 28 | 29 | 30 | org.springframework.boot 31 | spring-boot-starter-actuator 32 | 33 | 34 | org.springframework.cloud 35 | spring-cloud-starter-config 36 | 37 | 38 | org.springframework.cloud 39 | spring-cloud-starter-bus-kafka 40 | 41 | 42 | org.springframework.cloud 43 | spring-cloud-netflix-eureka-client 44 | 45 | 46 | com.netflix.eureka 47 | eureka-client 48 | 49 | 50 | com.sun.jersey 51 | jersey-client 52 | 53 | 54 | com.sun.jersey 55 | jersey-core 56 | 57 | 58 | com.sun.jersey.contribs 59 | jersey-apache-client4 60 | 61 | 62 | com.netflix.archaius 63 | archaius-core 64 | 65 | 66 | 67 | 68 | org.springframework.boot 69 | spring-boot-starter-test 70 | test 71 | 72 | 73 | org.junit.vintage 74 | junit-vintage-engine 75 | test 76 | 77 | 78 | 79 | 80 | 81 | 82 | org.springframework.boot 83 | spring-boot-maven-plugin 84 | 85 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /spring-cloud-launcher/spring-cloud-launcher-h2/src/main/java/org/springframework/cloud/launcher/h2/H2Application.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.h2; 18 | 19 | import org.apache.commons.logging.Log; 20 | import org.apache.commons.logging.LogFactory; 21 | import org.h2.server.web.WebServlet; 22 | import org.h2.tools.Console; 23 | import org.springframework.beans.factory.annotation.Value; 24 | import org.springframework.boot.SpringApplication; 25 | import org.springframework.boot.autoconfigure.SpringBootApplication; 26 | import org.springframework.boot.web.servlet.ServletRegistrationBean; 27 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 28 | import org.springframework.context.SmartLifecycle; 29 | import org.springframework.context.annotation.Bean; 30 | import org.springframework.stereotype.Controller; 31 | import org.springframework.stereotype.Service; 32 | import org.springframework.util.Assert; 33 | import org.springframework.util.ReflectionUtils; 34 | import org.springframework.util.StringUtils; 35 | 36 | import java.util.concurrent.atomic.AtomicBoolean; 37 | 38 | /** 39 | * @author Spencer Gibb 40 | */ 41 | @EnableDiscoveryClient 42 | @SpringBootApplication 43 | @Controller 44 | public class H2Application { 45 | 46 | private static final Log log = LogFactory.getLog(H2Application.class); 47 | 48 | public static void main(String[] args) { 49 | SpringApplication.run(H2Application.class, args); 50 | } 51 | 52 | @Bean 53 | public ServletRegistrationBean h2Console() { 54 | String urlMapping = "/*"; 55 | ServletRegistrationBean registration = new ServletRegistrationBean(new WebServlet(), urlMapping); 56 | registration.addInitParameter("-webAllowOthers", ""); 57 | return registration; 58 | } 59 | @Service 60 | static class H2Server implements SmartLifecycle { 61 | private AtomicBoolean running = new AtomicBoolean(false); 62 | 63 | private Console console; 64 | 65 | @Value("${spring.datasource.url:jdbc:h2:tcp://localhost:9096/./target/test}") 66 | private String dataSourceUrl; 67 | 68 | @Override 69 | public boolean isAutoStartup() { 70 | return true; 71 | } 72 | 73 | @Override 74 | public void stop(Runnable callback) { 75 | stop(); 76 | callback.run(); 77 | } 78 | 79 | @Override 80 | public void start() { 81 | if (this.running.compareAndSet(false, true)) { 82 | try { 83 | log.info("Starting H2 Server"); 84 | this.console = new Console(); 85 | this.console.runTool("-tcp", "-tcpAllowOthers", "-tcpPort", getH2Port(this.dataSourceUrl)); 86 | } catch (Exception e) { 87 | ReflectionUtils.rethrowRuntimeException(e); 88 | } 89 | } 90 | } 91 | 92 | private String getH2Port(String url) { 93 | String[] tokens = StringUtils.tokenizeToStringArray(url, ":"); 94 | Assert.isTrue(tokens.length >= 5, "URL not properly formatted"); 95 | return tokens[4].substring(0, tokens[4].indexOf("/")); 96 | } 97 | 98 | @Override 99 | public void stop() { 100 | if (this.running.compareAndSet(true, false)) { 101 | log.info("Stopping H2 Server"); 102 | this.console.shutdown(); 103 | } 104 | } 105 | 106 | @Override 107 | public boolean isRunning() { 108 | return this.running.get(); 109 | } 110 | 111 | @Override 112 | public int getPhase() { 113 | return 0; 114 | } 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /spring-cloud-launcher/spring-cloud-launcher-h2/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-h2/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 9095 3 | 4 | info: 5 | artifactId: "@project.artifactId@" 6 | description: "@project.description@" 7 | version: "@project.version@" 8 | 9 | eureka: 10 | instance: 11 | # port of the h2 console 12 | non-secure-port: 9095 13 | status-page-url-path: / #allows you to click on the link in eureka dashboard 14 | 15 | -------------------------------------------------------------------------------- /spring-cloud-launcher/spring-cloud-launcher-h2/src/main/resources/bootstrap.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: h2server 4 | -------------------------------------------------------------------------------- /spring-cloud-launcher/spring-cloud-launcher-h2/src/test/java/org/springframework/cloud/launcher/h2/DeployerApplicationTests.java: -------------------------------------------------------------------------------- 1 | package org.springframework.cloud.launcher.h2; 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.bus.enabled=false", "spring.cloud.config.enabled=false"}) 11 | public class DeployerApplicationTests { 12 | 13 | @Test 14 | public void contextLoads() { 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /spring-cloud-launcher/spring-cloud-launcher-kafka/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.cloud.launcher 7 | spring-cloud-launcher-kafka 8 | jar 9 | 10 | spring-cloud-launcher-kafka 11 | Spring Cloud Launcher Kafka 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-web 23 | 24 | 25 | org.springframework.boot 26 | spring-boot-starter-actuator 27 | 28 | 29 | org.springframework.cloud 30 | spring-cloud-starter-config 31 | 32 | 33 | org.springframework.kafka 34 | spring-kafka-test 35 | 36 | 37 | org.springframework.boot 38 | spring-boot-starter-test 39 | test 40 | 41 | 42 | 43 | 44 | 45 | 46 | org.springframework.boot 47 | spring-boot-maven-plugin 48 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /spring-cloud-launcher/spring-cloud-launcher-kafka/src/main/java/org/springframework/cloud/launcher/kafka/KafkaApplication.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.kafka; 18 | 19 | import java.io.File; 20 | import java.net.InetSocketAddress; 21 | import java.util.Properties; 22 | import java.util.concurrent.atomic.AtomicBoolean; 23 | 24 | import org.I0Itec.zkclient.ZkClient; 25 | import org.I0Itec.zkclient.exception.ZkInterruptedException; 26 | import org.apache.commons.logging.Log; 27 | import org.apache.commons.logging.LogFactory; 28 | import org.apache.kafka.common.utils.Time; 29 | import org.apache.kafka.common.utils.Utils; 30 | import org.apache.zookeeper.server.NIOServerCnxnFactory; 31 | import org.apache.zookeeper.server.ZooKeeperServer; 32 | 33 | import org.springframework.beans.factory.annotation.Value; 34 | import org.springframework.boot.autoconfigure.SpringBootApplication; 35 | import org.springframework.boot.builder.SpringApplicationBuilder; 36 | import org.springframework.context.SmartLifecycle; 37 | import org.springframework.stereotype.Service; 38 | import org.springframework.util.ReflectionUtils; 39 | 40 | import kafka.server.KafkaConfig; 41 | import kafka.server.KafkaServer; 42 | import kafka.server.NotRunning; 43 | import kafka.utils.CoreUtils; 44 | import kafka.utils.TestUtils; 45 | import kafka.utils.ZKStringSerializer$; 46 | 47 | /** 48 | * @author Spencer Gibb 49 | * 50 | * see https://github.com/spring-projects/spring-kafka/blob/2.0.x/spring-kafka-test/src/main/java/org/springframework/kafka/test/rule/KafkaEmbedded.java 51 | */ 52 | @SpringBootApplication 53 | public class KafkaApplication { 54 | 55 | private static final Log log = LogFactory.getLog(KafkaApplication.class); 56 | 57 | public static void main(String[] args) { 58 | new SpringApplicationBuilder(KafkaApplication.class).run(args); 59 | } 60 | 61 | @Service 62 | static class KafkaDevServer implements SmartLifecycle { 63 | private AtomicBoolean running = new AtomicBoolean(false); 64 | private ZkClient zkClient; 65 | 66 | private EmbeddedZookeeper zookeeper; 67 | 68 | private KafkaServer kafkaServer; 69 | 70 | @Value("${kafka.port:${KAFKA_PORT:9092}}") 71 | private int port; 72 | 73 | @Value("${zk.port:${ZK_PORT:2181}}") 74 | private int zkPort; 75 | 76 | @Override 77 | public boolean isAutoStartup() { 78 | return true; 79 | } 80 | 81 | @Override 82 | public void stop(Runnable callback) { 83 | stop(); 84 | callback.run(); 85 | } 86 | 87 | @Override 88 | public void start() { 89 | if (this.running.compareAndSet(false, true)) { 90 | try { 91 | log.info("Starting Zookeeper"); 92 | this.zookeeper = new EmbeddedZookeeper(this.zkPort); 93 | String zkConnectString = "127.0.0.1:" + this.zookeeper.getPort(); 94 | log.info("Started Zookeeper at " + zkConnectString); 95 | try { 96 | int zkConnectionTimeout = 10000; 97 | int zkSessionTimeout = 10000; 98 | zkClient = new ZkClient(zkConnectString, zkSessionTimeout, 99 | zkConnectionTimeout, ZKStringSerializer$.MODULE$); 100 | } 101 | catch (Exception e) { 102 | zookeeper.shutdown(); 103 | throw e; 104 | } 105 | try { 106 | log.info("Creating Kafka server"); 107 | // TODO: move to properties? 108 | int nodeId = 0; 109 | boolean enableControlledShutdown = true; 110 | Properties brokerConfigProperties = TestUtils.createBrokerConfig( 111 | nodeId, zkConnectString, enableControlledShutdown, true, 112 | port, scala.Option.apply(null), 113 | scala.Option.apply(null), 114 | scala.Option.apply(null), true, false, 0, 115 | false, 0, false, 0, scala.Option.apply(null), 1, false); 116 | brokerConfigProperties.setProperty("replica.socket.timeout.ms", 117 | "1000"); 118 | brokerConfigProperties.setProperty("controller.socket.timeout.ms", 119 | "1000"); 120 | brokerConfigProperties 121 | .setProperty("offsets.topic.replication.factor", "1"); 122 | brokerConfigProperties.put("zookeeper.connect", zkConnectString); 123 | kafkaServer = TestUtils.createServer( 124 | new KafkaConfig(brokerConfigProperties), 125 | Time.SYSTEM); 126 | log.info("Created Kafka server at " 127 | + kafkaServer.config().hostName() + ":" 128 | + kafkaServer.config().port()); 129 | } 130 | catch (Exception e) { 131 | zookeeper.shutdown(); 132 | zkClient.close(); 133 | throw e; 134 | } 135 | } 136 | catch (Exception e) { 137 | ReflectionUtils.rethrowRuntimeException(e); 138 | } 139 | } 140 | } 141 | 142 | @Override 143 | public void stop() { 144 | if (this.running.compareAndSet(true, false)) { 145 | log.info("Stopping Kafka"); 146 | try { 147 | if (kafkaServer.brokerState() 148 | .currentState() != (NotRunning.state())) { 149 | kafkaServer.shutdown(); 150 | kafkaServer.awaitShutdown(); 151 | } 152 | } 153 | catch (Exception e) { 154 | // do nothing 155 | } 156 | try { 157 | CoreUtils.delete(kafkaServer.config().logDirs()); 158 | } 159 | catch (Exception e) { 160 | // do nothing 161 | } 162 | log.info("Stopping Zookeeper"); 163 | try { 164 | this.zkClient.close(); 165 | } 166 | catch (ZkInterruptedException e) { 167 | // do nothing 168 | } 169 | try { 170 | this.zookeeper.shutdown(); 171 | } 172 | catch (Exception e) { 173 | // do nothing 174 | } 175 | } 176 | } 177 | 178 | @Override 179 | public boolean isRunning() { 180 | return this.running.get(); 181 | } 182 | 183 | @Override 184 | public int getPhase() { 185 | return 0; 186 | } 187 | } 188 | 189 | static class EmbeddedZookeeper { 190 | private File snapshotDir = TestUtils.tempDir(); 191 | private File logDir = TestUtils.tempDir(); 192 | private int tickTime = 500; 193 | private NIOServerCnxnFactory factory = new NIOServerCnxnFactory(); 194 | private ZooKeeperServer zookeeper; 195 | private InetSocketAddress addr; 196 | private int port; 197 | 198 | public EmbeddedZookeeper(int port) throws Exception { 199 | this.port = port; 200 | zookeeper = new ZooKeeperServer(snapshotDir, logDir, tickTime); 201 | addr = new InetSocketAddress("127.0.0.1", port); 202 | factory.configure(addr, 0); 203 | factory.startup(zookeeper); 204 | } 205 | 206 | public int getPort() { 207 | return port; 208 | } 209 | 210 | void shutdown() throws Exception { 211 | zookeeper.shutdown(); 212 | factory.shutdown(); 213 | Utils.delete(logDir); 214 | Utils.delete(snapshotDir); 215 | } 216 | } 217 | } 218 | -------------------------------------------------------------------------------- /spring-cloud-launcher/spring-cloud-launcher-kafka/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 9091 3 | 4 | kafka: 5 | port: 9092 6 | 7 | zk: 8 | port: 2181 9 | 10 | info: 11 | artifactId: "@project.artifactId@" 12 | description: "@project.description@" 13 | version: "@project.version@" -------------------------------------------------------------------------------- /spring-cloud-launcher/spring-cloud-launcher-kafka/src/main/resources/bootstrap.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: kafka 4 | -------------------------------------------------------------------------------- /spring-cloud-launcher/spring-cloud-launcher-kafka/src/test/java/org/springframework/cloud/launcher/kafka/DeployerApplicationTests.java: -------------------------------------------------------------------------------- 1 | package org.springframework.cloud.launcher.kafka; 2 | 3 | import org.junit.AfterClass; 4 | import org.junit.BeforeClass; 5 | import org.junit.Test; 6 | import org.junit.runner.RunWith; 7 | import org.springframework.boot.test.context.SpringBootTest; 8 | import org.springframework.test.context.junit4.SpringRunner; 9 | import org.springframework.util.SocketUtils; 10 | 11 | @RunWith(SpringRunner.class) 12 | @SpringBootTest 13 | public class DeployerApplicationTests { 14 | 15 | @BeforeClass 16 | public static void before() { 17 | System.setProperty("kafka.port", String.valueOf(SocketUtils.findAvailableTcpPort())); 18 | System.setProperty("zk.port", String.valueOf(SocketUtils.findAvailableTcpPort())); 19 | } 20 | 21 | @AfterClass 22 | public static void after() { 23 | System.clearProperty("kafka.port"); 24 | System.clearProperty("zk.port"); 25 | } 26 | 27 | @Test 28 | public void contextLoads() { 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /spring-cloud-launcher/spring-cloud-launcher-stubrunner/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.cloud.launcher 7 | spring-cloud-launcher-stubrunner 8 | jar 9 | 10 | spring-cloud-launcher-stubrunner 11 | Spring Cloud Launcher Stub Runner 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.boot 26 | spring-boot-starter-web 27 | 28 | 29 | org.springframework.cloud 30 | spring-cloud-starter-contract-stub-runner 31 | 32 | 33 | org.springframework.boot 34 | spring-boot-starter-test 35 | 36 | 37 | 38 | 39 | org.springframework.boot 40 | spring-boot-starter-test 41 | ${spring-boot.version} 42 | test 43 | 44 | 45 | org.junit.vintage 46 | junit-vintage-engine 47 | test 48 | 49 | 50 | 51 | 52 | 53 | 54 | org.springframework.boot 55 | spring-boot-maven-plugin 56 | 57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /spring-cloud-launcher/spring-cloud-launcher-stubrunner/src/main/java/org/springframework/cloud/launcher/stubrunner/StubRunnerApplication.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.stubrunner; 18 | 19 | import org.springframework.boot.SpringApplication; 20 | import org.springframework.boot.autoconfigure.SpringBootApplication; 21 | import org.springframework.cloud.contract.stubrunner.server.EnableStubRunnerServer; 22 | 23 | /** 24 | * @author Marcin Grzejszczak 25 | */ 26 | @EnableStubRunnerServer 27 | @SpringBootApplication 28 | public class StubRunnerApplication { 29 | public static void main(String[] args) { 30 | SpringApplication.run(StubRunnerApplication.class, args); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /spring-cloud-launcher/spring-cloud-launcher-stubrunner/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-stubrunner/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: stubrunner 4 | 5 | server: 6 | port: 8750 7 | 8 | info: 9 | artifactId: "@project.artifactId@" 10 | description: "@project.description@" 11 | version: "@project.version@" -------------------------------------------------------------------------------- /spring-cloud-launcher/spring-cloud-launcher-stubrunner/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-stubrunner/src/test/java/org/springframework/cloud/launcher/stubrunner/DeployerApplicationTests.java: -------------------------------------------------------------------------------- 1 | package org.springframework.cloud.launcher.stubrunner; 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 11 | public class DeployerApplicationTests { 12 | 13 | @Test 14 | public void contextLoads() { 15 | } 16 | 17 | } 18 | --------------------------------------------------------------------------------