├── .springformat ├── .mvn ├── maven.config ├── jvm.config └── wrapper │ ├── maven-wrapper.jar │ └── maven-wrapper.properties ├── docs ├── src │ └── main │ │ ├── asciidoc │ │ ├── images │ │ │ └── .gitkeep │ │ ├── sagan-boot.adoc │ │ ├── sagan-index.adoc │ │ └── README.adoc │ │ └── antora │ │ └── resources │ │ └── antora-resources │ │ └── antora.yml ├── modules │ └── ROOT │ │ ├── assets │ │ └── images │ │ │ └── .gitkeep │ │ ├── pages │ │ ├── index.adoc │ │ ├── _attributes.adoc │ │ ├── bus.adoc │ │ ├── intro.adoc │ │ ├── appendix.adoc │ │ ├── install.adoc │ │ └── retry.adoc │ │ ├── partials │ │ ├── _spans.adoc │ │ ├── _metrics.adoc │ │ └── _conventions.adoc │ │ └── nav.adoc ├── package.json ├── antora.yml └── antora-playbook.yml ├── .github ├── dco.yml ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md ├── ISSUE_TEMPLATE.md ├── workflows │ ├── deploy-docs.yml │ └── maven.yml ├── dependabot.yml └── CONTRIBUTING.md ├── src ├── test │ └── resources │ │ ├── empty_config │ │ └── .do-not-delete.txt │ │ ├── consul_ui │ │ └── static │ │ │ ├── favicon.png │ │ │ ├── consul-logo.png │ │ │ └── loading-cylon-purple.svg │ │ ├── etc │ │ └── configserver.json │ │ ├── consul_config │ │ └── acl_config.json │ │ └── consul_acl │ │ ├── consul_discovery_client_acl.json │ │ └── consul_anonymous_acl.json └── checkstyle │ └── checkstyle-suppressions.xml ├── scripts ├── build.sh ├── compileOnly.sh └── runAcceptanceTests.sh ├── config └── releaser.yml ├── .sdkmanrc ├── spring-cloud-consul-integration-tests ├── spring-cloud-consul-configdata-tests │ ├── src │ │ ├── test │ │ │ ├── resources │ │ │ │ ├── orderingtest.properties │ │ │ │ └── orderingtest-dev.properties │ │ │ └── java │ │ │ │ └── org │ │ │ │ └── springframework │ │ │ │ └── cloud │ │ │ │ └── consul │ │ │ │ └── configdatatests │ │ │ │ └── ConsulConfigDataApplicationTests.java │ │ └── main │ │ │ ├── resources │ │ │ └── application.yml │ │ │ └── java │ │ │ └── org │ │ │ └── springframework │ │ │ └── cloud │ │ │ └── consul │ │ │ └── configdatatests │ │ │ ├── ConsulConfigDataApplication.java │ │ │ └── SampleProperties.java │ └── pom.xml ├── spring-cloud-consul-bootstrap-tests │ ├── src │ │ └── main │ │ │ ├── resources │ │ │ ├── bootstrap.yml │ │ │ └── application.yml │ │ │ └── java │ │ │ └── org │ │ │ └── springframework │ │ │ └── cloud │ │ │ └── consul │ │ │ └── bootstraptests │ │ │ └── SampleProperties.java │ └── pom.xml ├── spring-cloud-consul-configdata-retry-tests │ ├── src │ │ └── main │ │ │ ├── resources │ │ │ └── application.yml │ │ │ └── java │ │ │ └── org │ │ │ └── springframework │ │ │ └── cloud │ │ │ └── consul │ │ │ └── configdatatests │ │ │ └── ConsulConfigDataRetryApplication.java │ └── pom.xml └── pom.xml ├── SECURITY.md ├── spring-cloud-consul-binder ├── src │ ├── main │ │ ├── resources │ │ │ └── META-INF │ │ │ │ ├── spring.binders │ │ │ │ └── spring-cloud-stream │ │ │ │ └── consul-binder.properties │ │ └── java │ │ │ └── org │ │ │ └── springframework │ │ │ └── cloud │ │ │ └── consul │ │ │ └── binder │ │ │ ├── config │ │ │ ├── ConsulBinderProperties.java │ │ │ └── ConsulBinderConfiguration.java │ │ │ ├── ConsulSendingHandler.java │ │ │ └── ConsulBinder.java │ └── test │ │ ├── resources │ │ └── application.yml │ │ └── java │ │ └── org │ │ └── springframework │ │ └── cloud │ │ └── consul │ │ └── binder │ │ ├── ConsulInboundMessageProducerTests.java │ │ └── config │ │ └── ConsulBinderConfigurationTests.java └── pom.xml ├── spring-cloud-consul-core └── src │ ├── test │ ├── resources │ │ ├── server.jks │ │ └── trustStore.jks │ └── java │ │ └── org │ │ └── springframework │ │ └── cloud │ │ └── consul │ │ ├── ConsulHealthIndicatorUpTest.java │ │ ├── ConsulHealthIndicatorLightweightUpTest.java │ │ └── ConsulHealthIndicatorDownTest.java │ └── main │ ├── resources │ └── META-INF │ │ └── spring │ │ └── org.springframework.boot.autoconfigure.AutoConfiguration.imports │ └── java │ └── org │ └── springframework │ └── cloud │ └── consul │ ├── ConsulException.java │ ├── model │ └── http │ │ ├── KeyStoreInstanceType.java │ │ ├── format │ │ ├── WaitTimeFormat.java │ │ ├── WaitTimeFormatter.java │ │ └── WaitTimeAnnotationFormatterFactory.java │ │ ├── kv │ │ └── GetValue.java │ │ ├── ConsulHeaders.java │ │ └── catalog │ │ └── Node.java │ ├── ConditionalOnConsulEnabled.java │ ├── ConsulHealthIndicator.java │ ├── ConsulHealthIndicatorProperties.java │ └── RetryProperties.java ├── docker-compose.yml ├── spring-cloud-consul-config └── src │ ├── main │ ├── resources │ │ └── META-INF │ │ │ ├── spring │ │ │ └── org.springframework.boot.autoconfigure.AutoConfiguration.imports │ │ │ └── spring.factories │ └── java │ │ └── org │ │ └── springframework │ │ └── cloud │ │ └── consul │ │ └── config │ │ ├── ConsulConfigIndexes.java │ │ ├── PropertySourcesLocatedEvent.java │ │ ├── ConsulFilesPropertySource.java │ │ ├── ConsulRetryBootstrapper.java │ │ ├── ConsulConfigBootstrapConfiguration.java │ │ └── ConsulConfigAutoConfiguration.java │ └── test │ └── java │ └── org │ └── springframework │ └── cloud │ └── consul │ └── config │ ├── ConsulConfigPropertiesTests.java │ ├── ConsulPropertySourceLocatorFailFastTests.java │ ├── ConsulPropertySourceLocatorRetryTests.java │ ├── ConsulPropertyPrefixTests.java │ └── ConsulConfigBootstrapConfigurationTests.java ├── spring-cloud-consul-discovery └── src │ ├── test │ ├── resources │ │ ├── META-INF │ │ │ └── spring.factories │ │ └── bootstrapper.yaml │ └── java │ │ └── org │ │ └── springframework │ │ └── cloud │ │ └── consul │ │ ├── discovery │ │ ├── ConsulCatalogWatchTests.java │ │ ├── ConsulServerUtilsTest.java │ │ ├── HeartbeatPropertiesTests.java │ │ ├── configclient │ │ │ ├── TestConsulDiscoveryClientBootstrapConfiguration.java │ │ │ ├── ConsulConfigServerBootstrapperNoConfigClientTests.java │ │ │ └── ConsulConfigServerAutoConfigurationTests.java │ │ ├── ConsulDiscoveryClientProbeTests.java │ │ ├── ConsulLoadbalancerClientTests.java │ │ └── ConsulDiscoveryClientHttpsTests.java │ │ └── serviceregistry │ │ ├── ConsulAutoServiceRegistrationIntegrationTestConfig.java │ │ ├── ConsulAutoServiceRegistrationFailFastTests.java │ │ ├── ConsulAutoServiceRegistrationNonWebTests.java │ │ ├── ConsulServiceRegistryDisabledTests.java │ │ ├── ConsulAutoRegistrationCheckTtlDeregisterCriticalServiceTests.java │ │ ├── ConsulAutoServiceRegistrationRetryTests.java │ │ ├── ConsulAutoServiceRegistrationDefaultPortTests.java │ │ ├── ConsulAutoServiceRegistrationCustomizedServletContextTests.java │ │ └── ConsulAutoRegistrationHealthCheckTlsSkipVerifyTests.java │ └── main │ ├── resources │ └── META-INF │ │ ├── spring.factories │ │ ├── spring │ │ └── org.springframework.boot.autoconfigure.AutoConfiguration.imports │ │ └── additional-spring-configuration-metadata.json │ └── java │ └── org │ └── springframework │ └── cloud │ └── consul │ ├── serviceregistry │ ├── ConsulRegistrationCustomizer.java │ ├── ConsulManagementRegistrationCustomizer.java │ ├── ApplicationStatusProvider.java │ ├── ConsulServletRegistrationCustomizer.java │ ├── ConsulRegistration.java │ └── ConsulAutoServiceRegistrationListener.java │ └── discovery │ ├── ReregistrationPredicate.java │ ├── ConditionalOnConsulDiscoveryEnabled.java │ ├── configclient │ ├── ConsulDiscoveryClientConfigServiceBootstrapConfiguration.java │ └── ConsulConfigServerAutoConfiguration.java │ ├── ConsulServerUtils.java │ ├── ConsulCatalogWatchAutoConfiguration.java │ └── ConsulDiscoveryClientConfiguration.java ├── .gitignore ├── .editorconfig ├── spring-cloud-starter-consul-config └── pom.xml ├── spring-cloud-starter-consul-bus └── pom.xml ├── spring-cloud-starter-consul-all └── pom.xml ├── spring-cloud-starter-consul-discovery └── pom.xml ├── .settings.xml ├── spring-cloud-starter-consul └── pom.xml └── README.adoc /.springformat: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.mvn/maven.config: -------------------------------------------------------------------------------- 1 | -P spring 2 | -------------------------------------------------------------------------------- /docs/src/main/asciidoc/images/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/src/main/asciidoc/sagan-boot.adoc: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/modules/ROOT/assets/images/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.github/dco.yml: -------------------------------------------------------------------------------- 1 | require: 2 | members: false 3 | -------------------------------------------------------------------------------- /src/test/resources/empty_config/.do-not-delete.txt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /docs/modules/ROOT/pages/index.adoc: -------------------------------------------------------------------------------- 1 | include::intro.adoc[] -------------------------------------------------------------------------------- /scripts/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ./mvnw clean install -B -Pdocs ${@} 4 | -------------------------------------------------------------------------------- /scripts/compileOnly.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | ./mvnw clean install -B -Pdocs -DskipTests -fae 4 | -------------------------------------------------------------------------------- /config/releaser.yml: -------------------------------------------------------------------------------- 1 | releaser: 2 | maven: 3 | buildCommand: ./scripts/build.sh {{systemProps}} 4 | -------------------------------------------------------------------------------- /.mvn/jvm.config: -------------------------------------------------------------------------------- 1 | -Xmx1024m -XX:CICompilerCount=1 -XX:TieredStopAtLevel=1 -Djava.security.egd=file:/dev/./urandom -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-cloud/spring-cloud-consul/HEAD/.mvn/wrapper/maven-wrapper.jar -------------------------------------------------------------------------------- /.sdkmanrc: -------------------------------------------------------------------------------- 1 | # Enable auto-env through the sdkman_auto_env config 2 | # Add key=value pairs of SDKs to use below 3 | java=17.0.1-tem 4 | -------------------------------------------------------------------------------- /spring-cloud-consul-integration-tests/spring-cloud-consul-configdata-tests/src/test/resources/orderingtest.properties: -------------------------------------------------------------------------------- 1 | spring.config.import=consul: 2 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | ## Reporting a Vulnerability 4 | 5 | To report security vulnerabilities, please go to https://pivotal.io/security. 6 | -------------------------------------------------------------------------------- /spring-cloud-consul-binder/src/main/resources/META-INF/spring.binders: -------------------------------------------------------------------------------- 1 | consul:\ 2 | org.springframework.cloud.consul.binder.config.ConsulBinderConfiguration 3 | -------------------------------------------------------------------------------- /src/test/resources/consul_ui/static/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-cloud/spring-cloud-consul/HEAD/src/test/resources/consul_ui/static/favicon.png -------------------------------------------------------------------------------- /spring-cloud-consul-integration-tests/spring-cloud-consul-bootstrap-tests/src/main/resources/bootstrap.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | application: 3 | name: testConsulApp 4 | -------------------------------------------------------------------------------- /spring-cloud-consul-integration-tests/spring-cloud-consul-configdata-tests/src/test/resources/orderingtest-dev.properties: -------------------------------------------------------------------------------- 1 | my.prop=my value from local dev profile 2 | -------------------------------------------------------------------------------- /src/test/resources/etc/configserver.json: -------------------------------------------------------------------------------- 1 | { 2 | "service": { 3 | "name": "configserver", 4 | "address": "127.0.0.1", 5 | "port": 8888 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/test/resources/consul_ui/static/consul-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-cloud/spring-cloud-consul/HEAD/src/test/resources/consul_ui/static/consul-logo.png -------------------------------------------------------------------------------- /spring-cloud-consul-core/src/test/resources/server.jks: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-cloud/spring-cloud-consul/HEAD/spring-cloud-consul-core/src/test/resources/server.jks -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | # Work in Progress 2 | consul: 3 | image: library/consul 4 | ports: 5 | - "8300:8300" 6 | - "8400:8400" 7 | - "8500:8500" 8 | - "8600:8600" 9 | -------------------------------------------------------------------------------- /docs/modules/ROOT/partials/_spans.adoc: -------------------------------------------------------------------------------- 1 | [[observability-spans]] 2 | === Observability - Spans 3 | 4 | Below you can find a list of all spans declared by this project. 5 | 6 | 7 | -------------------------------------------------------------------------------- /docs/modules/ROOT/partials/_metrics.adoc: -------------------------------------------------------------------------------- 1 | [[observability-metrics]] 2 | === Observability - Metrics 3 | 4 | Below you can find a list of all metrics declared by this project. 5 | 6 | 7 | -------------------------------------------------------------------------------- /spring-cloud-consul-core/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports: -------------------------------------------------------------------------------- 1 | org.springframework.cloud.consul.ConsulAutoConfiguration 2 | -------------------------------------------------------------------------------- /spring-cloud-consul-core/src/test/resources/trustStore.jks: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/spring-cloud/spring-cloud-consul/HEAD/spring-cloud-consul-core/src/test/resources/trustStore.jks -------------------------------------------------------------------------------- /spring-cloud-consul-config/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports: -------------------------------------------------------------------------------- 1 | org.springframework.cloud.consul.config.ConsulConfigAutoConfiguration 2 | -------------------------------------------------------------------------------- /src/test/resources/consul_config/acl_config.json: -------------------------------------------------------------------------------- 1 | { 2 | "datacenter": "local", 3 | "acl_datacenter": "local", 4 | "acl_master_token": "2ee647bd-bd69-4118-9f34-b9a6e9e60746", 5 | "acl_default_policy": "deny" 6 | } 7 | -------------------------------------------------------------------------------- /docs/modules/ROOT/nav.adoc: -------------------------------------------------------------------------------- 1 | * xref:index.adoc[Introduction] 2 | * xref:quickstart.adoc[] 3 | * xref:install.adoc[] 4 | * xref:discovery.adoc[] 5 | * xref:config.adoc[] 6 | * xref:retry.adoc[] 7 | * xref:bus.adoc[] 8 | * xref:appendix.adoc[] 9 | -------------------------------------------------------------------------------- /docs/modules/ROOT/partials/_conventions.adoc: -------------------------------------------------------------------------------- 1 | [[observability-conventions]] 2 | === Observability - Conventions 3 | 4 | Below you can find a list of all `GlobalObservationConvention` and `ObservationConvention` declared by this project. 5 | 6 | 7 | -------------------------------------------------------------------------------- /spring-cloud-consul-discovery/src/test/resources/META-INF/spring.factories: -------------------------------------------------------------------------------- 1 | org.springframework.cloud.bootstrap.BootstrapConfiguration=\ 2 | org.springframework.cloud.consul.discovery.configclient.TestConsulDiscoveryClientBootstrapConfiguration 3 | 4 | -------------------------------------------------------------------------------- /spring-cloud-consul-discovery/src/test/resources/bootstrapper.yaml: -------------------------------------------------------------------------------- 1 | spring: 2 | config: 3 | import: "optional:configserver:" 4 | cloud: 5 | config: 6 | discovery: 7 | service-id: consul-configserver 8 | enabled: true 9 | -------------------------------------------------------------------------------- /.mvn/wrapper/maven-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.9.0/apache-maven-3.9.0-bin.zip 2 | wrapperUrl=https://repo.maven.apache.org/maven2/org/apache/maven/wrapper/maven-wrapper/3.1.1/maven-wrapper-3.1.1.jar 3 | -------------------------------------------------------------------------------- /spring-cloud-consul-binder/src/test/resources/application.yml: -------------------------------------------------------------------------------- 1 | spring: 2 | cloud: 3 | stream: 4 | binders: 5 | purchases: 6 | type: consul 7 | consul: 8 | binder: 9 | management: 10 | security: 11 | enabled: false 12 | # host: localhost 13 | # port: 18500 14 | -------------------------------------------------------------------------------- /docs/modules/ROOT/pages/_attributes.adoc: -------------------------------------------------------------------------------- 1 | :doctype: book 2 | :idprefix: 3 | :idseparator: - 4 | :tabsize: 4 5 | :numbered: 6 | :sectanchors: 7 | :sectnums: 8 | :icons: font 9 | :hide-uri-scheme: 10 | :docinfo: shared,private 11 | 12 | :sc-ext: java 13 | :project-full-name: Spring Cloud Consul 14 | :all: {asterisk}{asterisk} 15 | -------------------------------------------------------------------------------- /docs/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "antora": "3.2.0-alpha.11", 4 | "@antora/atlas-extension": "1.0.0-alpha.2", 5 | "@antora/collector-extension": "1.0.2", 6 | "@asciidoctor/tabs": "1.0.0-beta.6", 7 | "@springio/antora-extensions": "1.14.7", 8 | "@springio/asciidoctor-extensions": "1.0.0-alpha.17" 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *~ 2 | #* 3 | *# 4 | .#* 5 | .classpath 6 | .project 7 | .settings/ 8 | .springBeans 9 | target/ 10 | _site/ 11 | .idea 12 | *.iml 13 | *.ipr 14 | .factorypath 15 | *.swp 16 | /consul 17 | consul_*.zip 18 | consul_*.zip.* 19 | .vscode/ 20 | .flattened-pom.xml 21 | 22 | node 23 | node_modules 24 | build 25 | /package.json 26 | package-lock.json 27 | -------------------------------------------------------------------------------- /spring-cloud-consul-integration-tests/spring-cloud-consul-configdata-tests/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 0 3 | 4 | spring: 5 | application: 6 | name: testConsulConfigDataIntegrationTestApp 7 | 8 | logging: 9 | level: 10 | org.springframework.cloud.consul: DEBUG 11 | org.springframework.boot.context.config: TRACE 12 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome: https://EditorConfig.org 2 | 3 | # top-most EditorConfig file 4 | root = true 5 | 6 | [*] 7 | indent_style = tab 8 | indent_size = 4 9 | end_of_line = lf 10 | insert_final_newline = true 11 | 12 | [*.yml] 13 | indent_style = space 14 | indent_size = 2 15 | 16 | [*.yaml] 17 | indent_style = space 18 | indent_size = 2 19 | -------------------------------------------------------------------------------- /spring-cloud-consul-integration-tests/spring-cloud-consul-configdata-retry-tests/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 0 3 | 4 | spring: 5 | application: 6 | name: testConsulConfigDataIntegrationTestApp 7 | 8 | logging: 9 | level: 10 | org.springframework.cloud.consul: DEBUG 11 | org.springframework.boot.context.config: TRACE 12 | -------------------------------------------------------------------------------- /spring-cloud-consul-discovery/src/main/resources/META-INF/spring.factories: -------------------------------------------------------------------------------- 1 | org.springframework.cloud.bootstrap.BootstrapConfiguration=\ 2 | org.springframework.cloud.consul.discovery.configclient.ConsulDiscoveryClientConfigServiceBootstrapConfiguration 3 | 4 | org.springframework.boot.bootstrap.BootstrapRegistryInitializer=\ 5 | org.springframework.cloud.consul.discovery.configclient.ConsulConfigServerBootstrapper 6 | -------------------------------------------------------------------------------- /spring-cloud-consul-integration-tests/spring-cloud-consul-bootstrap-tests/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8080 3 | 4 | endpoints: 5 | health: 6 | sensitive: false 7 | restart: 8 | enabled: true 9 | shutdown: 10 | enabled: true 11 | 12 | management: 13 | security: 14 | enabled: false 15 | 16 | logging: 17 | level: 18 | org.springframework.cloud.consul: DEBUG 19 | -------------------------------------------------------------------------------- /src/test/resources/consul_acl/consul_discovery_client_acl.json: -------------------------------------------------------------------------------- 1 | { 2 | "ID": "2d2e6b3b-1c82-40ab-8171-54609d8ad304", 3 | "Name": "discover_client_test_acl", 4 | "Type": "client", 5 | "Rules": "{ 6 | \"service\": { 7 | \"\": { 8 | \"policy\": \"write\" 9 | }, 10 | \"testConsulDiscoveryAcl\": { 11 | \"policy\": \"write\" 12 | }, 13 | \"testSecondServiceAcl\": { 14 | \"policy\": \"write\" 15 | } 16 | } 17 | }" 18 | } 19 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | Please provide details of the problem, including the version of Spring Cloud that you 12 | are using. 13 | 14 | **Sample** 15 | If possible, please provide a test case or sample application that reproduces 16 | the problem. This makes it much easier for us to diagnose the problem and to verify that 17 | we have fixed it. 18 | -------------------------------------------------------------------------------- /scripts/runAcceptanceTests.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -o errexit 4 | 5 | mkdir -p target 6 | 7 | SCRIPT_URL="https://raw.githubusercontent.com/spring-cloud-samples/brewery/2021.0.x/runAcceptanceTests.sh" 8 | AT_WHAT_TO_TEST="CONSUL" 9 | 10 | cd target 11 | 12 | curl "${SCRIPT_URL}" --output runAcceptanceTests.sh 13 | 14 | chmod +x runAcceptanceTests.sh 15 | 16 | echo "Killing all running apps" 17 | ./runAcceptanceTests.sh -t "${AT_WHAT_TO_TEST}" -n 18 | 19 | ./runAcceptanceTests.sh --whattotest "${AT_WHAT_TO_TEST}" --killattheend 20 | -------------------------------------------------------------------------------- /docs/antora.yml: -------------------------------------------------------------------------------- 1 | name: cloud-consul 2 | version: true 3 | title: Spring Cloud Consul 4 | nav: 5 | - modules/ROOT/nav.adoc 6 | ext: 7 | collector: 8 | run: 9 | command: ./mvnw --no-transfer-progress -B process-resources -Pdocs -pl docs -Dantora-maven-plugin.phase=none -Dgenerate-docs.phase=none -Dgenerate-readme.phase=none -Dgenerate-cloud-resources.phase=none -Dmaven-dependency-plugin-for-docs.phase=none -Dmaven-dependency-plugin-for-docs-classes.phase=none -DskipTests -DdisableConfigurationProperties 10 | local: true 11 | scan: 12 | dir: ./target/classes/antora-resources/ 13 | -------------------------------------------------------------------------------- /docs/modules/ROOT/pages/bus.adoc: -------------------------------------------------------------------------------- 1 | [[spring-cloud-consul-bus]] 2 | = Spring Cloud Bus with Consul 3 | 4 | [[how-to-activate]] 5 | == How to activate 6 | 7 | To get started with the Consul Bus use the starter with group `org.springframework.cloud` and artifact id `spring-cloud-starter-consul-bus`. See the https://projects.spring.io/spring-cloud/[Spring Cloud Project page] for details on setting up your build system with the current Spring Cloud Release Train. 8 | 9 | See the https://cloud.spring.io/spring-cloud-bus/[Spring Cloud Bus] documentation for the available actuator endpoints and howto send custom messages. 10 | 11 | -------------------------------------------------------------------------------- /src/test/resources/consul_acl/consul_anonymous_acl.json: -------------------------------------------------------------------------------- 1 | { 2 | "ID": "anonymous", 3 | "Name": "anonymous", 4 | "Type": "client", 5 | "Rules": "{ 6 | \"key\": { 7 | \"\": { 8 | \"policy\": \"write\" 9 | } 10 | }, 11 | \"event\": { 12 | \"\": { 13 | \"policy\": \"write\" 14 | } 15 | }, 16 | \"service\": { 17 | \"\": { 18 | \"policy\": \"write\" 19 | }, 20 | \"testConsulDiscoveryAcl\": { 21 | \"policy\": \"deny\" 22 | }, 23 | \"testConsulDiscoveryAcl\": { 24 | \"policy\": \"deny\" 25 | } 26 | } 27 | }" 28 | } 29 | -------------------------------------------------------------------------------- /docs/modules/ROOT/pages/intro.adoc: -------------------------------------------------------------------------------- 1 | [[introduction]] 2 | = Spring Cloud Consul 3 | 4 | This project provides Consul integrations for Spring Boot apps through autoconfiguration 5 | and binding to the Spring Environment and other Spring programming model idioms. With a few 6 | simple annotations you can quickly enable and configure the common patterns inside your 7 | application and build large distributed systems with Consul based components. The 8 | patterns provided include Service Discovery, Control Bus and Configuration. 9 | Intelligent Routing and Client Side Load Balancing, Circuit Breaker 10 | are provided by integration with other Spring Cloud projects. 11 | 12 | -------------------------------------------------------------------------------- /docs/modules/ROOT/pages/appendix.adoc: -------------------------------------------------------------------------------- 1 | :numbered!: 2 | [appendix] 3 | [[common-application-properties]] 4 | = Common application properties 5 | :page-section-summary-toc: 1 6 | 7 | 8 | Various properties can be specified inside your `application.properties` file, inside your `application.yml` file, or as command line switches. 9 | This appendix provides a list of common Spring Cloud Consul properties and references to the underlying classes that consume them. 10 | 11 | NOTE: Property contributions can come from additional jar files on your classpath, so you should not consider this an exhaustive list. 12 | Also, you can define your own properties. 13 | 14 | include::partial$_configprops.adoc[] -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /spring-cloud-consul-discovery/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports: -------------------------------------------------------------------------------- 1 | org.springframework.cloud.consul.discovery.configclient.ConsulConfigServerAutoConfiguration 2 | org.springframework.cloud.consul.serviceregistry.ConsulAutoServiceRegistrationAutoConfiguration 3 | org.springframework.cloud.consul.serviceregistry.ConsulServiceRegistryAutoConfiguration 4 | org.springframework.cloud.consul.discovery.ConsulDiscoveryClientConfiguration 5 | org.springframework.cloud.consul.discovery.reactive.ConsulReactiveDiscoveryClientConfiguration 6 | org.springframework.cloud.consul.discovery.ConsulCatalogWatchAutoConfiguration 7 | org.springframework.cloud.consul.support.ConsulHeartbeatAutoConfiguration -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 21 | -------------------------------------------------------------------------------- /spring-cloud-consul-binder/src/main/resources/META-INF/spring-cloud-stream/consul-binder.properties: -------------------------------------------------------------------------------- 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 | spring.cloud.stream.binder.consul.default.host=localhost 17 | spring.cloud.stream.binder.consul.default.port=8500 18 | -------------------------------------------------------------------------------- /docs/modules/ROOT/pages/install.adoc: -------------------------------------------------------------------------------- 1 | [[spring-cloud-consul-install]] 2 | = Install Consul 3 | 4 | // TODO: document using Testcontainers and SpringApplication.from() 5 | 6 | Please see the https://www.consul.io/intro/getting-started/install.html[installation documentation] for instructions on how to install Consul. 7 | 8 | [[spring-cloud-consul-agent]] 9 | == Consul Agent 10 | 11 | A Consul Agent client must be available to all Spring Cloud Consul applications. By default, the Agent client is expected to be at `localhost:8500`. See the https://consul.io/docs/agent/basics.html[Agent documentation] for specifics on how to start an Agent client and how to connect to a cluster of Consul Agent Servers. Start a development agent according to the documentation above. 12 | 13 | This will start an agent in server mode on port 8500, with the ui available at http://localhost:8500 14 | 15 | -------------------------------------------------------------------------------- /docs/modules/ROOT/pages/retry.adoc: -------------------------------------------------------------------------------- 1 | [[spring-cloud-consul-retry]] 2 | = Consul Retry 3 | 4 | If you expect that the consul agent may occasionally be unavailable when 5 | your app starts, you can ask it to keep trying after a failure. You need to add 6 | `spring-retry` and `spring-boot-starter-aspectj` to your classpath. The default 7 | behaviour is to retry 6 times with an initial backoff interval of 1000ms and an 8 | exponential multiplier of 1.1 for subsequent backoffs. You can configure these 9 | properties (and others) using `spring.cloud.consul.retry.*` configuration properties. 10 | This works with both Spring Cloud Consul Config and Discovery registration. 11 | 12 | TIP: To take full control of the retry add a `@Bean` of type 13 | `RetryOperationsInterceptor` with id "consulRetryInterceptor". Spring 14 | Retry has a `RetryInterceptorBuilder` that makes it easy to create one. 15 | 16 | -------------------------------------------------------------------------------- /docs/antora-playbook.yml: -------------------------------------------------------------------------------- 1 | antora: 2 | extensions: 3 | - require: '@springio/antora-extensions' 4 | root_component_name: 'cloud-consul' 5 | site: 6 | title: Spring Cloud Consul 7 | url: https://docs.spring.io/spring-cloud-consul/reference/ 8 | content: 9 | sources: 10 | - url: ./.. 11 | branches: HEAD 12 | start_path: docs 13 | worktrees: true 14 | asciidoc: 15 | attributes: 16 | page-stackoverflow-url: https://stackoverflow.com/tags/spring-cloud 17 | page-pagination: '' 18 | hide-uri-scheme: '@' 19 | tabs-sync-option: '@' 20 | chomp: 'all' 21 | extensions: 22 | - '@asciidoctor/tabs' 23 | - '@springio/asciidoctor-extensions' 24 | sourcemap: true 25 | urls: 26 | latest_version_segment: '' 27 | runtime: 28 | log: 29 | failure_level: warn 30 | format: pretty 31 | ui: 32 | bundle: 33 | url: https://github.com/spring-io/antora-ui-spring/releases/download/v0.4.15/ui-bundle.zip 34 | -------------------------------------------------------------------------------- /spring-cloud-consul-config/src/main/java/org/springframework/cloud/consul/config/ConsulConfigIndexes.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-present 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.consul.config; 18 | 19 | import java.util.LinkedHashMap; 20 | 21 | public interface ConsulConfigIndexes { 22 | 23 | LinkedHashMap getIndexes(); 24 | 25 | } 26 | -------------------------------------------------------------------------------- /docs/src/main/antora/resources/antora-resources/antora.yml: -------------------------------------------------------------------------------- 1 | version: @antora-component.version@ 2 | prerelease: @antora-component.prerelease@ 3 | 4 | asciidoc: 5 | attributes: 6 | attribute-missing: 'warn' 7 | chomp: 'all' 8 | project-root: @maven.multiModuleProjectDirectory@ 9 | github-repo: @docs.main@ 10 | github-raw: https://raw.githubusercontent.com/spring-cloud/@docs.main@/@github-tag@ 11 | github-code: https://github.com/spring-cloud/@docs.main@/tree/@github-tag@ 12 | github-issues: https://github.com/spring-cloud/@docs.main@/issues/ 13 | github-wiki: https://github.com/spring-cloud/@docs.main@/wiki 14 | spring-cloud-version: @project.version@ 15 | github-tag: @github-tag@ 16 | version-type: @version-type@ 17 | docs-url: https://docs.spring.io/@docs.main@/docs/@project.version@ 18 | raw-docs-url: https://raw.githubusercontent.com/spring-cloud/@docs.main@/@github-tag@ 19 | project-version: @project.version@ 20 | project-name: @docs.main@ 21 | -------------------------------------------------------------------------------- /spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/serviceregistry/ConsulRegistrationCustomizer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013-present 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.consul.serviceregistry; 18 | 19 | /** 20 | * @author Piotr Wielgolaski 21 | */ 22 | public interface ConsulRegistrationCustomizer { 23 | 24 | void customize(ConsulRegistration registration); 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/checkstyle/checkstyle-suppressions.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 9 | 11 | 12 | 13 | 15 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/test/resources/consul_ui/static/loading-cylon-purple.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /spring-cloud-consul-core/src/main/java/org/springframework/cloud/consul/ConsulException.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013-present 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.consul; 18 | 19 | public class ConsulException extends RuntimeException { 20 | 21 | public ConsulException() { 22 | } 23 | 24 | public ConsulException(Throwable cause) { 25 | super(cause); 26 | } 27 | 28 | public ConsulException(String message) { 29 | super(message); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /.github/workflows/deploy-docs.yml: -------------------------------------------------------------------------------- 1 | name: Deploy Docs 2 | on: 3 | push: 4 | branches-ignore: [ gh-pages ] 5 | tags: '**' 6 | repository_dispatch: 7 | types: request-build-reference # legacy 8 | #schedule: 9 | #- cron: '0 10 * * *' # Once per day at 10am UTC 10 | workflow_dispatch: 11 | permissions: 12 | actions: write 13 | jobs: 14 | build: 15 | runs-on: ubuntu-latest 16 | # if: github.repository_owner == 'spring-cloud' 17 | steps: 18 | - name: Checkout 19 | uses: actions/checkout@v6 20 | with: 21 | ref: docs-build 22 | fetch-depth: 1 23 | - name: Dispatch (partial build) 24 | if: github.ref_type == 'branch' 25 | env: 26 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 27 | run: gh workflow run deploy-docs.yml -r $(git rev-parse --abbrev-ref HEAD) -f build-refname=${{ github.ref_name }} 28 | - name: Dispatch (full build) 29 | if: github.ref_type == 'tag' 30 | env: 31 | GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} 32 | run: gh workflow run deploy-docs.yml -r $(git rev-parse --abbrev-ref HEAD) 33 | -------------------------------------------------------------------------------- /spring-cloud-consul-config/src/main/resources/META-INF/spring.factories: -------------------------------------------------------------------------------- 1 | # Bootstrap Configuration 2 | org.springframework.cloud.bootstrap.BootstrapConfiguration=\ 3 | org.springframework.cloud.consul.config.ConsulConfigBootstrapConfiguration 4 | 5 | # Environment PostProcessor 6 | org.springframework.boot.EnvironmentPostProcessor=\ 7 | org.springframework.cloud.consul.config.ConsulConfigDataMissingEnvironmentPostProcessor 8 | 9 | org.springframework.boot.diagnostics.FailureAnalyzer=\ 10 | org.springframework.cloud.consul.config.ConsulConfigDataMissingEnvironmentPostProcessor.ImportExceptionFailureAnalyzer 11 | 12 | # ConfigData Location Resolvers 13 | org.springframework.boot.context.config.ConfigDataLocationResolver=\ 14 | org.springframework.cloud.consul.config.ConsulConfigDataLocationResolver 15 | 16 | # ConfigData Loaders 17 | org.springframework.boot.context.config.ConfigDataLoader=\ 18 | org.springframework.cloud.consul.config.ConsulConfigDataLoader 19 | 20 | # Spring Boot Bootstrappers 21 | org.springframework.boot.bootstrap.BootstrapRegistryInitializer=\ 22 | org.springframework.cloud.consul.config.ConsulRetryBootstrapper 23 | -------------------------------------------------------------------------------- /spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/serviceregistry/ConsulManagementRegistrationCustomizer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013-present 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.consul.serviceregistry; 18 | 19 | /** 20 | * @author Alexey Savchuk (devpreview) 21 | */ 22 | public interface ConsulManagementRegistrationCustomizer { 23 | 24 | /** 25 | * Customizes a registration. 26 | * @param managementRegistration registration to customize 27 | */ 28 | void customize(ConsulRegistration managementRegistration); 29 | 30 | } 31 | -------------------------------------------------------------------------------- /spring-cloud-consul-integration-tests/spring-cloud-consul-configdata-tests/src/main/java/org/springframework/cloud/consul/configdatatests/ConsulConfigDataApplication.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013-present 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.consul.configdatatests; 18 | 19 | import org.springframework.boot.autoconfigure.SpringBootApplication; 20 | import org.springframework.boot.context.properties.EnableConfigurationProperties; 21 | 22 | /** 23 | * @author Spencer Gibb 24 | */ 25 | @SpringBootApplication 26 | @EnableConfigurationProperties 27 | public class ConsulConfigDataApplication { 28 | 29 | } 30 | -------------------------------------------------------------------------------- /spring-cloud-consul-core/src/main/java/org/springframework/cloud/consul/model/http/KeyStoreInstanceType.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013-present 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.consul.model.http; 18 | 19 | /** 20 | * @author Matthew Whitaker 21 | */ 22 | public enum KeyStoreInstanceType { 23 | 24 | /** 25 | * Java Key Store. 26 | */ 27 | JKS, 28 | /** 29 | * TODO: Another Type. 30 | */ 31 | JCEKS, 32 | /** 33 | * TODO: Another Type. 34 | */ 35 | PKCS12, 36 | /** 37 | * TODO: Another Type. 38 | */ 39 | PKCS11, 40 | /** 41 | * TODO: Another Type. 42 | */ 43 | DKS; 44 | 45 | } 46 | -------------------------------------------------------------------------------- /.github/workflows/maven.yml: -------------------------------------------------------------------------------- 1 | # This workflow will build a Java project with Maven 2 | # For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven 3 | 4 | name: Build 5 | 6 | on: 7 | push: 8 | branches: [ main, 4.2.x, 4.1.x ] 9 | pull_request: 10 | branches: [ main, 4.2.x, 4.1.x ] 11 | 12 | jobs: 13 | build: 14 | 15 | runs-on: ubuntu-latest 16 | 17 | steps: 18 | - uses: actions/checkout@v6 19 | - name: Set up JDK 20 | uses: actions/setup-java@v4 21 | with: 22 | distribution: 'temurin' 23 | java-version: '17' 24 | - name: Cache local Maven repository 25 | uses: actions/cache@v5 26 | with: 27 | path: ~/.m2/repository 28 | key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }} 29 | restore-keys: | 30 | ${{ runner.os }}-maven- 31 | - name: Build with Maven 32 | run: ./mvnw clean install -B -U -Pspring -Dmaven.test.redirectTestOutputToFile=true 33 | - name: Publish Test Report 34 | uses: mikepenz/action-junit-report@v5 35 | if: always() # always run even if the previous step fails 36 | with: 37 | report_paths: '**/surefire-reports/TEST-*.xml' 38 | -------------------------------------------------------------------------------- /spring-cloud-consul-config/src/test/java/org/springframework/cloud/consul/config/ConsulConfigPropertiesTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013-present 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.consul.config; 18 | 19 | import org.junit.jupiter.api.Test; 20 | 21 | import static org.assertj.core.api.Assertions.assertThat; 22 | 23 | public class ConsulConfigPropertiesTests { 24 | 25 | @Test 26 | public void aclTokenToStringMasked() { 27 | ConsulConfigProperties properties = new ConsulConfigProperties(); 28 | properties.setAclToken("myAclToken"); 29 | assertThat(properties.toString()).doesNotContain("myAclToken").contains("******"); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /spring-cloud-consul-core/src/main/java/org/springframework/cloud/consul/model/http/format/WaitTimeFormat.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013-present 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.consul.model.http.format; 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 | @Documented 26 | @Retention(RetentionPolicy.RUNTIME) 27 | @Target({ ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER, ElementType.ANNOTATION_TYPE }) 28 | public @interface WaitTimeFormat { 29 | 30 | } 31 | -------------------------------------------------------------------------------- /spring-cloud-consul-integration-tests/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | org.springframework.cloud 8 | spring-cloud-consul 9 | 5.0.1-SNAPSHOT 10 | .. 11 | 12 | spring-cloud-consul-integration-tests 13 | spring-cloud-consul-integration-tests 14 | spring-cloud-consul-integration-tests 15 | pom 16 | 17 | 18 | spring-cloud-consul-bootstrap-tests 19 | spring-cloud-consul-configdata-tests 20 | spring-cloud-consul-configdata-retry-tests 21 | 22 | 23 | 24 | 25 | 26 | maven-deploy-plugin 27 | 28 | true 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /spring-cloud-consul-integration-tests/spring-cloud-consul-bootstrap-tests/src/main/java/org/springframework/cloud/consul/bootstraptests/SampleProperties.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013-present 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.consul.bootstraptests; 18 | 19 | import org.springframework.boot.context.properties.ConfigurationProperties; 20 | 21 | /** 22 | * @author Spencer Gibb 23 | */ 24 | @ConfigurationProperties("sample") 25 | public class SampleProperties { 26 | 27 | private String prop = "default value"; 28 | 29 | public String getProp() { 30 | return prop; 31 | } 32 | 33 | public void setProp(String prop) { 34 | this.prop = prop; 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /spring-cloud-consul-integration-tests/spring-cloud-consul-configdata-tests/src/main/java/org/springframework/cloud/consul/configdatatests/SampleProperties.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013-present 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.consul.configdatatests; 18 | 19 | import org.springframework.boot.context.properties.ConfigurationProperties; 20 | 21 | /** 22 | * @author Spencer Gibb 23 | */ 24 | @ConfigurationProperties("sample") 25 | public class SampleProperties { 26 | 27 | private String prop = "default value"; 28 | 29 | public String getProp() { 30 | return prop; 31 | } 32 | 33 | public void setProp(String prop) { 34 | this.prop = prop; 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /spring-cloud-consul-integration-tests/spring-cloud-consul-configdata-retry-tests/src/main/java/org/springframework/cloud/consul/configdatatests/ConsulConfigDataRetryApplication.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013-present 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.consul.configdatatests; 18 | 19 | import org.springframework.boot.SpringApplication; 20 | import org.springframework.boot.autoconfigure.SpringBootApplication; 21 | 22 | /** 23 | * @author Spencer Gibb 24 | */ 25 | @SpringBootApplication 26 | public class ConsulConfigDataRetryApplication { 27 | 28 | public static void main(String[] args) { 29 | SpringApplication.run(ConsulConfigDataRetryApplication.class, args); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/serviceregistry/ApplicationStatusProvider.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013-present 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.consul.serviceregistry; 18 | 19 | import org.springframework.cloud.consul.model.http.health.Check.CheckStatus; 20 | 21 | /** 22 | * Provides the current health of the application represented in Consul's 23 | * {@link CheckStatus} so that it can then be sent to Consul TTL checks. 24 | * 25 | * @author Chris Bono 26 | */ 27 | @FunctionalInterface 28 | public interface ApplicationStatusProvider { 29 | 30 | /** 31 | * @return the current health of the application 32 | */ 33 | CheckStatus currentStatus(); 34 | 35 | } 36 | -------------------------------------------------------------------------------- /spring-cloud-starter-consul-config/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | org.springframework.cloud 8 | spring-cloud-consul 9 | 5.0.1-SNAPSHOT 10 | .. 11 | 12 | spring-cloud-starter-consul-config 13 | Spring Cloud Starter Consul Config 14 | Spring Cloud Starter Consul Config 15 | https://projects.spring.io/spring-cloud 16 | 17 | Pivotal Software, Inc. 18 | https://www.spring.io 19 | 20 | 21 | ${basedir}/../.. 22 | 23 | 24 | 25 | org.springframework.cloud 26 | spring-cloud-starter-consul 27 | 28 | 29 | org.springframework.cloud 30 | spring-cloud-consul-config 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /spring-cloud-consul-core/src/main/java/org/springframework/cloud/consul/ConditionalOnConsulEnabled.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013-present 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.consul; 18 | 19 | import java.lang.annotation.ElementType; 20 | import java.lang.annotation.Retention; 21 | import java.lang.annotation.RetentionPolicy; 22 | import java.lang.annotation.Target; 23 | 24 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 25 | 26 | /** 27 | * When both property and consul classes are on the classpath. 28 | * 29 | * @author Spencer Gibb 30 | */ 31 | @Retention(RetentionPolicy.RUNTIME) 32 | @Target({ ElementType.TYPE, ElementType.METHOD }) 33 | @ConditionalOnProperty(value = "spring.cloud.consul.enabled", matchIfMissing = true) 34 | public @interface ConditionalOnConsulEnabled { 35 | 36 | } 37 | -------------------------------------------------------------------------------- /spring-cloud-starter-consul-bus/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | org.springframework.cloud 8 | spring-cloud-consul 9 | 5.0.1-SNAPSHOT 10 | .. 11 | 12 | spring-cloud-starter-consul-bus 13 | Spring Cloud Starter Consul Bus 14 | Spring Cloud Starter Consul Bus 15 | https://projects.spring.io/spring-cloud 16 | 17 | Pivotal Software, Inc. 18 | https://www.spring.io 19 | 20 | 21 | ${basedir}/../.. 22 | 23 | 24 | 25 | org.springframework.cloud 26 | spring-cloud-starter-consul 27 | 28 | 29 | org.springframework.cloud 30 | spring-cloud-consul-binder 31 | 32 | 33 | org.springframework.cloud 34 | spring-cloud-bus 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /spring-cloud-starter-consul-all/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | org.springframework.cloud 8 | spring-cloud-consul 9 | 5.0.1-SNAPSHOT 10 | .. 11 | 12 | spring-cloud-starter-consul-all 13 | Spring Cloud Starter Consul All 14 | Spring Cloud Starter Consul All 15 | https://projects.spring.io/spring-cloud 16 | 17 | Pivotal Software, Inc. 18 | https://www.spring.io 19 | 20 | 21 | ${basedir}/../.. 22 | 23 | 24 | 25 | org.springframework.cloud 26 | spring-cloud-starter-consul-bus 27 | 28 | 29 | org.springframework.cloud 30 | spring-cloud-starter-consul-config 31 | 32 | 33 | org.springframework.cloud 34 | spring-cloud-starter-consul-discovery 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /spring-cloud-starter-consul-discovery/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | org.springframework.cloud 8 | spring-cloud-consul 9 | 5.0.1-SNAPSHOT 10 | .. 11 | 12 | spring-cloud-starter-consul-discovery 13 | Spring Cloud Starter Consul Discovery 14 | Spring Cloud Starter Consul Discovery 15 | https://projects.spring.io/spring-cloud 16 | 17 | Pivotal Software, Inc. 18 | https://www.spring.io 19 | 20 | 21 | ${basedir}/../.. 22 | 23 | 24 | 25 | org.springframework.cloud 26 | spring-cloud-starter-consul 27 | 28 | 29 | org.springframework.cloud 30 | spring-cloud-consul-discovery 31 | 32 | 33 | org.springframework.cloud 34 | spring-cloud-starter-loadbalancer 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /spring-cloud-consul-core/src/main/java/org/springframework/cloud/consul/model/http/format/WaitTimeFormatter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013-present 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.consul.model.http.format; 18 | 19 | import java.text.ParseException; 20 | import java.util.Locale; 21 | 22 | import org.springframework.format.Formatter; 23 | 24 | public class WaitTimeFormatter implements Formatter { 25 | 26 | @Override 27 | public Long parse(String text, Locale locale) throws ParseException { 28 | try { 29 | if (text.endsWith("s")) { 30 | return Long.parseLong(text.substring(0, text.length() - 1)); 31 | } 32 | else { 33 | return Long.parseLong(text); 34 | } 35 | } 36 | catch (NumberFormatException e) { 37 | throw new ParseException(e.getMessage(), 0); 38 | } 39 | 40 | } 41 | 42 | @Override 43 | public String print(Long object, Locale locale) { 44 | return object + "s"; 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/ReregistrationPredicate.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013-present 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.consul.discovery; 18 | 19 | import org.springframework.web.client.HttpStatusCodeException; 20 | 21 | /** 22 | * Predicate on whether to re-register service. 23 | * 24 | * @author Toshiaki Maki 25 | */ 26 | public interface ReregistrationPredicate { 27 | 28 | /** 29 | * test if the exception is eligible for re-registration. 30 | * @param e OperationException 31 | * @return if the exception is eligible for re-registration 32 | */ 33 | boolean isEligible(HttpStatusCodeException e); 34 | 35 | /** 36 | * Default implementation that performs re-registration when the status code is either 37 | * 404 or 500. 38 | */ 39 | ReregistrationPredicate DEFAULT = e -> (e.getStatusCode().value() == 404 || e.getStatusCode().is5xxServerError()); 40 | 41 | } 42 | -------------------------------------------------------------------------------- /spring-cloud-consul-binder/src/main/java/org/springframework/cloud/consul/binder/config/ConsulBinderProperties.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013-present 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.consul.binder.config; 18 | 19 | import org.springframework.boot.context.properties.ConfigurationProperties; 20 | import org.springframework.core.style.ToStringCreator; 21 | 22 | /** 23 | * @author Spencer Gibb 24 | */ 25 | @ConfigurationProperties("spring.cloud.stream.consul.binder") 26 | public class ConsulBinderProperties { 27 | 28 | private int eventTimeout = 5; 29 | 30 | public ConsulBinderProperties() { 31 | } 32 | 33 | public int getEventTimeout() { 34 | return this.eventTimeout; 35 | } 36 | 37 | public void setEventTimeout(int eventTimeout) { 38 | this.eventTimeout = eventTimeout; 39 | } 40 | 41 | @Override 42 | public String toString() { 43 | return new ToStringCreator(this).append("eventTimeout", this.eventTimeout).toString(); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /spring-cloud-consul-binder/src/test/java/org/springframework/cloud/consul/binder/ConsulInboundMessageProducerTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013-present 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.consul.binder; 18 | 19 | import org.junit.Test; 20 | 21 | import static org.assertj.core.api.Assertions.fail; 22 | import static org.mockito.Mockito.mock; 23 | import static org.mockito.Mockito.when; 24 | 25 | /** 26 | * @author Spencer Gibb 27 | */ 28 | public class ConsulInboundMessageProducerTests { 29 | 30 | @Test 31 | public void getEventsShouldNotThrowException() { 32 | EventService eventService = mock(EventService.class); 33 | when(eventService.watch()).thenThrow(new RuntimeException("error")); 34 | 35 | ConsulInboundMessageProducer producer = new ConsulInboundMessageProducer(eventService); 36 | 37 | try { 38 | producer.getEvents(); 39 | } 40 | catch (Exception e) { 41 | fail("ConsulInboundMessageProducer threw unexpected exception: " + e); 42 | } 43 | 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /spring-cloud-consul-config/src/main/java/org/springframework/cloud/consul/config/PropertySourcesLocatedEvent.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013-present 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.consul.config; 18 | 19 | import java.util.LinkedHashMap; 20 | 21 | import org.springframework.context.ApplicationEvent; 22 | 23 | /** 24 | * @author Spencer Gibb 25 | */ 26 | public class PropertySourcesLocatedEvent extends ApplicationEvent { 27 | 28 | private final LinkedHashMap contextsToIndexes; 29 | 30 | /** 31 | * Create a new ApplicationEvent. 32 | * @param source the object on which the event initially occurred (never {@code null}) 33 | * @param contextsToIndexes contexts to indexes 34 | */ 35 | public PropertySourcesLocatedEvent(Object source, LinkedHashMap contextsToIndexes) { 36 | super(source); 37 | this.contextsToIndexes = contextsToIndexes; 38 | } 39 | 40 | public LinkedHashMap getContextsToIndexes() { 41 | return this.contextsToIndexes; 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /spring-cloud-consul-discovery/src/main/resources/META-INF/additional-spring-configuration-metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "properties": [ 3 | { 4 | "name": "spring.cloud.consul.ribbon.enabled", 5 | "type": "java.lang.Boolean", 6 | "description": "Enables Consul and Ribbon integration.", 7 | "defaultValue": "true" 8 | }, 9 | { 10 | "name": "spring.cloud.service-registry.enabled", 11 | "type": "java.lang.Boolean", 12 | "description": "Enables Service Registry functionality.", 13 | "defaultValue": "true" 14 | }, 15 | { 16 | "name": "spring.cloud.consul.service-registry.enabled", 17 | "type": "java.lang.Boolean", 18 | "description": "Enables Consul Service Registry functionality.", 19 | "defaultValue": "true" 20 | }, 21 | { 22 | "name": "spring.cloud.service-registry.auto-registration.enabled", 23 | "type": "java.lang.Boolean", 24 | "description": "Enables Service Registry Auto-registration.", 25 | "defaultValue": "true" 26 | }, 27 | { 28 | "name": "spring.cloud.consul.service-registry.auto-registration.enabled", 29 | "type": "java.lang.Boolean", 30 | "description": "Enables Consul Service Registry Auto-registration.", 31 | "defaultValue": "true" 32 | }, 33 | { 34 | "name": "spring.cloud.consul.discovery.heartbeat.use-actuator-health", 35 | "type": "java.lang.Boolean", 36 | "description": "Whether or not to take the current system health (as reported via the Actuator Health endpoint) into account when reporting the application status to the Consul TTL check. Actuator Health endpoint also has to be available to the application.", 37 | "defaultValue": "true" 38 | } 39 | ] 40 | } 41 | -------------------------------------------------------------------------------- /spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/ConsulCatalogWatchTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013-present 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.consul.discovery; 18 | 19 | import org.junit.jupiter.api.Test; 20 | 21 | import org.springframework.cloud.commons.util.InetUtils; 22 | import org.springframework.cloud.commons.util.InetUtilsProperties; 23 | 24 | import static org.assertj.core.api.Assertions.assertThat; 25 | 26 | /** 27 | * @author Spencer Gibb 28 | */ 29 | public class ConsulCatalogWatchTests { 30 | 31 | @Test 32 | public void isRunningReportsCorrectly() { 33 | ConsulDiscoveryProperties properties = new ConsulDiscoveryProperties(new InetUtils(new InetUtilsProperties())); 34 | ConsulCatalogWatch watch = new ConsulCatalogWatch(properties, null) { 35 | @Override 36 | public void catalogServicesWatch() { 37 | // do nothing 38 | } 39 | }; 40 | assertThat(watch.isRunning()).isFalse(); 41 | watch.start(); 42 | assertThat(watch.isRunning()).isTrue(); 43 | watch.stop(); 44 | assertThat(watch.isRunning()).isFalse(); 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/ConditionalOnConsulDiscoveryEnabled.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2019-present 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.consul.discovery; 18 | 19 | import java.lang.annotation.Documented; 20 | import java.lang.annotation.ElementType; 21 | import java.lang.annotation.Inherited; 22 | import java.lang.annotation.Retention; 23 | import java.lang.annotation.RetentionPolicy; 24 | import java.lang.annotation.Target; 25 | 26 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 27 | 28 | /** 29 | * Provides a more succinct conditional 30 | * spring.cloud.consul.discovery.enabled. 31 | * 32 | * @author Tim Ysewyn 33 | * @since 2.2.0 34 | */ 35 | @Target(ElementType.TYPE) 36 | @Retention(RetentionPolicy.RUNTIME) 37 | @Documented 38 | @Inherited 39 | @ConditionalOnProperty(value = ConditionalOnConsulDiscoveryEnabled.PROPERTY, matchIfMissing = true) 40 | public @interface ConditionalOnConsulDiscoveryEnabled { 41 | 42 | /** 43 | * Property key. 44 | */ 45 | String PROPERTY = "spring.cloud.consul.discovery.enabled"; 46 | 47 | } 48 | -------------------------------------------------------------------------------- /spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/ConsulServerUtilsTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013-present 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.consul.discovery; 18 | 19 | import org.junit.jupiter.api.Test; 20 | 21 | import static org.assertj.core.api.Assertions.assertThat; 22 | 23 | /** 24 | * @author Semenkov Alexey 25 | */ 26 | public class ConsulServerUtilsTest { 27 | 28 | @Test 29 | public void testAddressFormat() { 30 | String s1 = ConsulServerUtils.fixIPv6Address("fc00:ec:cd::242:ac11:c"); 31 | assertThat(s1).isEqualTo("[fc00:ec:cd:0:0:242:ac11:c]"); 32 | 33 | String s2 = ConsulServerUtils.fixIPv6Address("[fc00:ec:cd::242:ac11:c]"); 34 | assertThat(s2).isEqualTo("[fc00:ec:cd:0:0:242:ac11:c]"); 35 | 36 | String s3 = ConsulServerUtils.fixIPv6Address("192.168.0.1"); 37 | assertThat(s3).isEqualTo("192.168.0.1"); 38 | 39 | String s4 = ConsulServerUtils.fixIPv6Address("projects.spring.io"); 40 | assertThat(s4).isEqualTo("projects.spring.io"); 41 | 42 | String s5 = ConsulServerUtils.fixIPv6Address("veryLongHostName"); 43 | assertThat(s5).isEqualTo("veryLongHostName"); 44 | 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/HeartbeatPropertiesTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013-present 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.consul.discovery; 18 | 19 | import java.time.Duration; 20 | import java.time.temporal.ChronoUnit; 21 | 22 | import org.junit.jupiter.api.Test; 23 | 24 | import static org.assertj.core.api.Assertions.assertThat; 25 | 26 | /** 27 | * @author Spencer Gibb 28 | */ 29 | public class HeartbeatPropertiesTests { 30 | 31 | @Test 32 | public void computeHeartbeatIntervalWorks() { 33 | HeartbeatProperties properties = new HeartbeatProperties(); 34 | Duration period = properties.computeHeartbeatInterval(); 35 | 36 | assertThat(period).isNotNull(); 37 | assertThat(period.get(ChronoUnit.SECONDS)).isEqualTo(20); 38 | } 39 | 40 | @Test 41 | public void computeShortHeartbeat() { 42 | HeartbeatProperties properties = new HeartbeatProperties(); 43 | properties.setTtl(Duration.ofSeconds(2)); 44 | Duration period = properties.computeHeartbeatInterval(); 45 | 46 | assertThat(period).isNotNull(); 47 | assertThat(period.get(ChronoUnit.SECONDS)).isEqualTo(1); 48 | } 49 | 50 | } 51 | -------------------------------------------------------------------------------- /docs/src/main/asciidoc/sagan-index.adoc: -------------------------------------------------------------------------------- 1 | Spring Cloud Consul provides http://consul.io[Consul] integrations for Spring Boot apps through autoconfiguration and binding to the Spring Environment and other Spring programming model idioms. With a few simple annotations you can quickly enable and configure the common patterns inside your application and build large distributed systems with Hashicorp's Consul. The patterns provided include Service Discovery, Distributed Configuration and Control Bus. 2 | 3 | ## Features 4 | 5 | Spring Cloud Consul features: 6 | 7 | * Service Discovery: instances can be registered with the Consul agent and clients can discover the instances using Spring-managed beans 8 | * Supports Spring Cloud LoadBalancer - a client side load-balancer provided by the Spring Cloud project 9 | * Supports Spring Cloud Gateway, a dynamic router and filter 10 | * Distributed Configuration: using the Consul Key/Value store 11 | * Control Bus: Distributed control events using Consul Events 12 | 13 | ## Quick Start 14 | 15 | As long as Spring Cloud Consul and the Consul API are on the 16 | classpath any Spring Boot application with `@EnableDiscoveryClient` will try to contact a Consul 17 | agent on `localhost:8500` (the default values of 18 | `spring.cloud.consul.host` and `spring.cloud.consul.port` respectively): 19 | 20 | ```java 21 | @Configuration 22 | @EnableAutoConfiguration 23 | @EnableDiscoveryClient 24 | @RestController 25 | public class Application { 26 | 27 | @RequestMapping("/") 28 | public String home() { 29 | return "Hello World"; 30 | } 31 | 32 | public static void main(String[] args) { 33 | SpringApplication.run(Application.class, args); 34 | } 35 | 36 | } 37 | ``` 38 | 39 | A local Consul agent must be running. See the https://consul.io/docs/agent/basics.html[Consul agent documentation] on how to run an agent. 40 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "github-actions" 4 | directory: "/" 5 | target-branch: "4.2.x" 6 | schedule: 7 | interval: "weekly" 8 | - package-ecosystem: "github-actions" 9 | directory: "/" 10 | target-branch: "main" 11 | schedule: 12 | interval: "weekly" 13 | - package-ecosystem: maven 14 | directory: / 15 | schedule: 16 | interval: daily 17 | target-branch: 4.2.x 18 | ignore: 19 | # only upgrade patch versions for maintenance branch 20 | - dependency-name: "*" 21 | update-types: 22 | - version-update:semver-major 23 | - version-update:semver-minor 24 | - package-ecosystem: maven 25 | directory: / 26 | schedule: 27 | interval: daily 28 | target-branch: 4.3.x 29 | ignore: 30 | # only upgrade patch versions for maintenance branch 31 | - dependency-name: "*" 32 | update-types: 33 | - version-update:semver-major 34 | - version-update:semver-minor 35 | - package-ecosystem: maven 36 | directory: / 37 | schedule: 38 | interval: daily 39 | target-branch: main 40 | # ignore: 41 | # # only upgrade by minor or patch 42 | # - dependency-name: "*" 43 | # update-types: 44 | # - version-update:semver-major 45 | - package-ecosystem: npm 46 | target-branch: docs-build 47 | directory: / 48 | schedule: 49 | interval: weekly 50 | - package-ecosystem: npm 51 | target-branch: main 52 | directory: /docs 53 | schedule: 54 | interval: weekly 55 | - package-ecosystem: npm 56 | target-branch: 4.2.x 57 | directory: /docs 58 | schedule: 59 | interval: weekly 60 | - package-ecosystem: npm 61 | target-branch: 4.3.x 62 | directory: /docs 63 | schedule: 64 | interval: weekly 65 | -------------------------------------------------------------------------------- /.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 | spring 13 | 14 | true 15 | 16 | 17 | 18 | spring-snapshots 19 | Spring Snapshots 20 | https://repo.spring.io/libs-snapshot-local 21 | 22 | true 23 | 24 | 25 | 26 | spring-milestones 27 | Spring Milestones 28 | https://repo.spring.io/libs-milestone-local 29 | 30 | false 31 | 32 | 33 | 34 | spring-releases 35 | Spring Releases 36 | https://repo.spring.io/release 37 | 38 | false 39 | 40 | 41 | 42 | 43 | 44 | spring-snapshots 45 | Spring Snapshots 46 | https://repo.spring.io/libs-snapshot-local 47 | 48 | true 49 | 50 | 51 | 52 | spring-milestones 53 | Spring Milestones 54 | https://repo.spring.io/libs-milestone-local 55 | 56 | false 57 | 58 | 59 | 60 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /spring-cloud-consul-core/src/main/java/org/springframework/cloud/consul/model/http/kv/GetValue.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013-present 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.consul.model.http.kv; 18 | 19 | import java.nio.charset.Charset; 20 | import java.nio.charset.StandardCharsets; 21 | import java.util.Base64; 22 | 23 | import com.fasterxml.jackson.annotation.JsonProperty; 24 | 25 | public class GetValue { 26 | 27 | @JsonProperty("Key") 28 | private String key; 29 | 30 | @JsonProperty("Value") 31 | private String value; 32 | 33 | public String getKey() { 34 | return key; 35 | } 36 | 37 | public void setKey(String key) { 38 | this.key = key; 39 | } 40 | 41 | public String getValue() { 42 | return value; 43 | } 44 | 45 | public void setValue(String value) { 46 | this.value = value; 47 | } 48 | 49 | public String getDecodedValue(Charset charset) { 50 | if (this.value == null) { 51 | return null; 52 | } 53 | else { 54 | if (charset == null) { 55 | charset = StandardCharsets.UTF_8; 56 | } 57 | 58 | return new String(Base64.getDecoder().decode(this.value), charset); 59 | } 60 | } 61 | 62 | public String getDecodedValue() { 63 | return this.getDecodedValue(StandardCharsets.UTF_8); 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /spring-cloud-consul-core/src/main/java/org/springframework/cloud/consul/model/http/format/WaitTimeAnnotationFormatterFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013-present 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.consul.model.http.format; 18 | 19 | import java.util.Set; 20 | 21 | import org.springframework.format.AnnotationFormatterFactory; 22 | import org.springframework.format.Formatter; 23 | import org.springframework.format.Parser; 24 | import org.springframework.format.Printer; 25 | 26 | public class WaitTimeAnnotationFormatterFactory implements AnnotationFormatterFactory { 27 | 28 | private static final Set> FIELD_TYPES = Set.of(Long.class); 29 | 30 | @Override 31 | public Set> getFieldTypes() { 32 | return FIELD_TYPES; 33 | } 34 | 35 | @Override 36 | public Printer getPrinter(WaitTimeFormat annotation, Class fieldType) { 37 | return configureFormatterFrom(annotation, fieldType); 38 | } 39 | 40 | @Override 41 | public Parser getParser(WaitTimeFormat annotation, Class fieldType) { 42 | return configureFormatterFrom(annotation, fieldType); 43 | } 44 | 45 | private Formatter configureFormatterFrom(WaitTimeFormat annotation, Class fieldType) { 46 | return new WaitTimeFormatter(); 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /spring-cloud-starter-consul/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | org.springframework.cloud 8 | spring-cloud-consul 9 | 5.0.1-SNAPSHOT 10 | .. 11 | 12 | spring-cloud-starter-consul 13 | Spring Cloud Starter Consul 14 | Spring Cloud Starter Consul 15 | https://projects.spring.io/spring-cloud 16 | 17 | Pivotal Software, Inc. 18 | https://www.spring.io 19 | 20 | 21 | ${basedir}/../.. 22 | 23 | 24 | 25 | org.springframework.cloud 26 | spring-cloud-starter 27 | 28 | 29 | org.springframework.cloud 30 | spring-cloud-consul-core 31 | 32 | 33 | com.ecwid.consul 34 | consul-api 35 | 36 | 37 | 38 | com.google.code.gson 39 | gson 40 | 41 | 42 | org.apache.httpcomponents 43 | httpclient 44 | 45 | 46 | org.apache.httpcomponents 47 | httpcore 48 | 49 | 50 | 51 | -------------------------------------------------------------------------------- /spring-cloud-consul-config/src/main/java/org/springframework/cloud/consul/config/ConsulFilesPropertySource.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013-present 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.consul.config; 18 | 19 | import org.springframework.cloud.consul.ConsulClient; 20 | import org.springframework.cloud.consul.model.http.kv.GetValue; 21 | 22 | import static org.springframework.cloud.consul.config.ConsulConfigProperties.Format.PROPERTIES; 23 | import static org.springframework.cloud.consul.config.ConsulConfigProperties.Format.YAML; 24 | 25 | /** 26 | * @author Spencer Gibb 27 | */ 28 | public class ConsulFilesPropertySource extends ConsulPropertySource { 29 | 30 | public ConsulFilesPropertySource(String context, ConsulClient source, ConsulConfigProperties configProperties) { 31 | super(context, source, configProperties); 32 | } 33 | 34 | @Override 35 | public void init() { 36 | // noop 37 | } 38 | 39 | public void init(GetValue value) { 40 | if (this.getContext().endsWith(".yml") || this.getContext().endsWith(".yaml")) { 41 | parseValue(value, YAML); 42 | } 43 | else if (this.getContext().endsWith(".properties")) { 44 | parseValue(value, PROPERTIES); 45 | } 46 | else { 47 | throw new IllegalStateException("Unknown files extension for context " + this.getContext()); 48 | } 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationIntegrationTestConfig.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013-present 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.consul.serviceregistry; 18 | 19 | import java.lang.annotation.ElementType; 20 | import java.lang.annotation.Retention; 21 | import java.lang.annotation.RetentionPolicy; 22 | import java.lang.annotation.Target; 23 | 24 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 25 | import org.springframework.boot.autoconfigure.ImportAutoConfiguration; 26 | import org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationConfiguration; 27 | import org.springframework.cloud.consul.ConsulAutoConfiguration; 28 | import org.springframework.cloud.consul.support.ConsulHeartbeatAutoConfiguration; 29 | import org.springframework.context.annotation.Configuration; 30 | 31 | @Target(ElementType.TYPE) 32 | @Retention(RetentionPolicy.RUNTIME) 33 | @Configuration(proxyBeanMethods = false) 34 | @EnableAutoConfiguration 35 | @ImportAutoConfiguration({ AutoServiceRegistrationConfiguration.class, ConsulAutoConfiguration.class, 36 | ConsulAutoServiceRegistrationAutoConfiguration.class, ConsulHeartbeatAutoConfiguration.class }) 37 | public @interface ConsulAutoServiceRegistrationIntegrationTestConfig { 38 | 39 | } 40 | -------------------------------------------------------------------------------- /spring-cloud-consul-core/src/main/java/org/springframework/cloud/consul/ConsulHealthIndicator.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013-present 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.consul; 18 | 19 | import java.util.List; 20 | import java.util.Map; 21 | 22 | import org.springframework.boot.health.contributor.AbstractHealthIndicator; 23 | import org.springframework.boot.health.contributor.Health; 24 | import org.springframework.http.ResponseEntity; 25 | 26 | /** 27 | * @author Spencer Gibb 28 | */ 29 | public class ConsulHealthIndicator extends AbstractHealthIndicator { 30 | 31 | private ConsulClient consul; 32 | 33 | private ConsulHealthIndicatorProperties properties; 34 | 35 | public ConsulHealthIndicator(ConsulClient consul, ConsulHealthIndicatorProperties properties) { 36 | this.consul = consul; 37 | this.properties = properties; 38 | } 39 | 40 | @Override 41 | protected void doHealthCheck(Health.Builder builder) { 42 | final String leaderStatus = this.consul.getStatusLeader().getBody(); 43 | builder.up().withDetail("leader", leaderStatus); 44 | if (properties.isIncludeServicesQuery()) { 45 | ResponseEntity>> response = this.consul.getCatalogServices(); 46 | final Map> services = response.getBody(); 47 | builder.withDetail("services", services); 48 | } 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /spring-cloud-consul-core/src/main/java/org/springframework/cloud/consul/ConsulHealthIndicatorProperties.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013-present 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.consul; 18 | 19 | import org.springframework.boot.context.properties.ConfigurationProperties; 20 | import org.springframework.core.style.ToStringCreator; 21 | 22 | /** 23 | * Configuration properties for {@link ConsulHealthIndicator}. 24 | * 25 | * @author Chris Bono 26 | */ 27 | @ConfigurationProperties("spring.cloud.consul.health-indicator") 28 | public class ConsulHealthIndicatorProperties { 29 | 30 | /** 31 | * Whether or not the indicator should include a query for all registered services 32 | * during its execution. When set to {@code false} the indicator only uses the lighter 33 | * {@link ConsulClient#getStatusLeader()}. This can be helpful in large deployments 34 | * where the number of services returned makes the operation unnecessarily heavy. 35 | */ 36 | private boolean includeServicesQuery = true; 37 | 38 | boolean isIncludeServicesQuery() { 39 | return includeServicesQuery; 40 | } 41 | 42 | void setIncludeServicesQuery(boolean includeServicesQuery) { 43 | this.includeServicesQuery = includeServicesQuery; 44 | } 45 | 46 | @Override 47 | public String toString() { 48 | return new ToStringCreator(this).append("includeServicesQuery", this.includeServicesQuery).toString(); 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/serviceregistry/ConsulServletRegistrationCustomizer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013-present 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.consul.serviceregistry; 18 | 19 | import java.util.ArrayList; 20 | import java.util.List; 21 | 22 | import jakarta.servlet.ServletContext; 23 | 24 | import org.springframework.beans.factory.ObjectProvider; 25 | import org.springframework.util.StringUtils; 26 | 27 | /** 28 | * @author Piotr Wielgolaski 29 | */ 30 | public class ConsulServletRegistrationCustomizer implements ConsulRegistrationCustomizer { 31 | 32 | private ObjectProvider servletContext; 33 | 34 | public ConsulServletRegistrationCustomizer(ObjectProvider servletContext) { 35 | this.servletContext = servletContext; 36 | } 37 | 38 | @Override 39 | public void customize(ConsulRegistration registration) { 40 | if (this.servletContext == null) { 41 | return; 42 | } 43 | ServletContext sc = this.servletContext.getIfAvailable(); 44 | if (sc != null && StringUtils.hasText(sc.getContextPath()) 45 | && StringUtils.hasText(sc.getContextPath().replaceAll("/", ""))) { 46 | List tags = registration.getService().getTags(); 47 | if (tags == null) { 48 | tags = new ArrayList<>(); 49 | } 50 | tags.add("contextPath=" + sc.getContextPath()); 51 | registration.getService().setTags(tags); 52 | } 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /spring-cloud-consul-integration-tests/spring-cloud-consul-bootstrap-tests/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | spring-cloud-consul-bootstrap-tests 8 | jar 9 | Spring Cloud Consul Bootstrap Integration Tests 10 | Spring Cloud Consul Bootstrap Integration Tests 11 | 12 | 13 | org.springframework.cloud 14 | spring-cloud-consul-integration-tests 15 | 5.0.1-SNAPSHOT 16 | .. 17 | 18 | 19 | 20 | 21 | 22 | org.springframework.boot 23 | spring-boot-maven-plugin 24 | 25 | 26 | 27 | repackage 28 | 29 | 30 | 31 | 32 | 33 | 34 | maven-deploy-plugin 35 | 36 | true 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | org.springframework.boot 45 | spring-boot-starter-actuator 46 | 47 | 48 | org.springframework.cloud 49 | spring-cloud-starter-bootstrap 50 | 51 | 52 | org.springframework.cloud 53 | spring-cloud-starter-consul-all 54 | 55 | 56 | org.springframework.cloud 57 | spring-cloud-starter-openfeign 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /spring-cloud-consul-config/src/test/java/org/springframework/cloud/consul/config/ConsulPropertySourceLocatorFailFastTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013-present 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.consul.config; 18 | 19 | import org.junit.Test; 20 | import org.junit.runner.RunWith; 21 | 22 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 23 | import org.springframework.boot.test.context.SpringBootTest; 24 | import org.springframework.context.annotation.Configuration; 25 | import org.springframework.test.context.junit4.SpringRunner; 26 | 27 | import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; 28 | 29 | /** 30 | * @author Spencer Gibb 31 | */ 32 | @RunWith(SpringRunner.class) 33 | @SpringBootTest(classes = ConsulPropertySourceLocatorFailFastTests.Config.class, 34 | properties = { "spring.application.name=testConsulPropertySourceLocatorFailFast", 35 | "spring.config.use-legacy-processing=true", 36 | "spring.cloud.consul.host=53210a7c-4809-42cb-8b30-057d2db85fcc", "spring.cloud.consul.port=65530", 37 | "spring.cloud.consul.retry.enabled=false", "spring.cloud.consul.retry.maxAttempts=0", 38 | "spring.cloud.consul.config.failFast=false" }, 39 | webEnvironment = RANDOM_PORT) 40 | public class ConsulPropertySourceLocatorFailFastTests { 41 | 42 | @Test 43 | public void testFailFastFalse() { 44 | } 45 | 46 | @Configuration(proxyBeanMethods = false) 47 | @EnableAutoConfiguration 48 | static class Config { 49 | 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/configclient/ConsulDiscoveryClientConfigServiceBootstrapConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013-present 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.consul.discovery.configclient; 18 | 19 | import org.springframework.boot.autoconfigure.ImportAutoConfiguration; 20 | import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; 21 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 22 | import org.springframework.cloud.config.client.ConfigServicePropertySourceLocator; 23 | import org.springframework.cloud.consul.ConsulAutoConfiguration; 24 | import org.springframework.cloud.consul.discovery.ConsulDiscoveryClientConfiguration; 25 | import org.springframework.cloud.consul.discovery.reactive.ConsulReactiveDiscoveryClientConfiguration; 26 | import org.springframework.context.annotation.Configuration; 27 | 28 | /** 29 | * Helper for config client that wants to lookup the config server via discovery. 30 | * 31 | * @author Spencer Gibb 32 | * @author Tim Ysewyn 33 | */ 34 | @ConditionalOnClass(ConfigServicePropertySourceLocator.class) 35 | @ConditionalOnProperty("spring.cloud.config.discovery.enabled") 36 | @Configuration(proxyBeanMethods = false) 37 | @ImportAutoConfiguration({ ConsulAutoConfiguration.class, ConsulDiscoveryClientConfiguration.class, 38 | ConsulReactiveDiscoveryClientConfiguration.class }) 39 | public class ConsulDiscoveryClientConfigServiceBootstrapConfiguration { 40 | 41 | } 42 | -------------------------------------------------------------------------------- /spring-cloud-consul-binder/src/main/java/org/springframework/cloud/consul/binder/ConsulSendingHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013-present 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.consul.binder; 18 | 19 | import java.util.Arrays; 20 | 21 | import org.springframework.cloud.consul.ConsulClient; 22 | import org.springframework.cloud.consul.model.http.event.Event; 23 | import org.springframework.http.ResponseEntity; 24 | import org.springframework.integration.handler.AbstractMessageHandler; 25 | import org.springframework.messaging.Message; 26 | 27 | /** 28 | * Adapter that converts and sends Messages as Consul events. 29 | * 30 | * @author Spencer Gibb 31 | */ 32 | public class ConsulSendingHandler extends AbstractMessageHandler { 33 | 34 | private final ConsulClient consul; 35 | 36 | private final String eventName; 37 | 38 | public ConsulSendingHandler(ConsulClient consul, String eventName) { 39 | this.consul = consul; 40 | this.eventName = eventName; 41 | } 42 | 43 | @Override 44 | protected void handleMessageInternal(Message message) { 45 | if (this.logger.isTraceEnabled()) { 46 | this.logger.trace("Publishing message" + message); 47 | } 48 | 49 | Object payload = message.getPayload(); 50 | if (payload instanceof byte[]) { 51 | payload = Arrays.toString((byte[]) payload); 52 | } 53 | 54 | // TODO: support headers 55 | // TODO: support consul event filters: NodeFilter, ServiceFilter, TagFilter 56 | ResponseEntity event = this.consul.eventFire(this.eventName, (String) payload); 57 | // TODO: return event? 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/configclient/TestConsulDiscoveryClientBootstrapConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013-present 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.consul.discovery.configclient; 18 | 19 | import java.util.Arrays; 20 | 21 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 22 | import org.springframework.cloud.consul.discovery.ConsulDiscoveryClient; 23 | import org.springframework.cloud.consul.discovery.ConsulDiscoveryProperties; 24 | import org.springframework.cloud.consul.discovery.ConsulServiceInstance; 25 | import org.springframework.cloud.consul.model.http.health.HealthService; 26 | import org.springframework.context.annotation.Bean; 27 | import org.springframework.context.annotation.Configuration; 28 | 29 | import static org.mockito.BDDMockito.given; 30 | import static org.mockito.Mockito.mock; 31 | 32 | @ConditionalOnProperty("spring.cloud.consul.discovery.test.enabled") 33 | @Configuration(proxyBeanMethods = false) 34 | public class TestConsulDiscoveryClientBootstrapConfiguration { 35 | 36 | @Bean 37 | public ConsulDiscoveryClient consulDiscoveryClient(ConsulDiscoveryProperties properties) { 38 | ConsulDiscoveryClient client = mock(ConsulDiscoveryClient.class); 39 | ConsulServiceInstance instance = new ConsulServiceInstance("configserver1", "configserver", 40 | properties.getHostname(), properties.getPort(), false); 41 | instance.setHealthService(mock(HealthService.class)); 42 | given(client.getInstances("configserver")).willReturn(Arrays.asList(instance)); 43 | return client; 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/configclient/ConsulConfigServerBootstrapperNoConfigClientTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015-present 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.consul.discovery.configclient; 18 | 19 | import org.apache.catalina.webresources.TomcatURLStreamHandlerFactory; 20 | import org.junit.jupiter.api.BeforeEach; 21 | import org.junit.jupiter.api.Test; 22 | import org.junit.jupiter.api.extension.ExtendWith; 23 | 24 | import org.springframework.boot.SpringBootConfiguration; 25 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 26 | import org.springframework.boot.builder.SpringApplicationBuilder; 27 | import org.springframework.cloud.test.ClassPathExclusions; 28 | import org.springframework.cloud.test.ModifiedClassPathExtension; 29 | 30 | @ExtendWith(ModifiedClassPathExtension.class) 31 | @ClassPathExclusions({ "spring-cloud-config-client-*.jar", "spring-cloud-config-server-*.jar" }) 32 | public class ConsulConfigServerBootstrapperNoConfigClientTests { 33 | 34 | @BeforeEach 35 | public void init() { 36 | // FIXME: why do I need to do this? (fails in maven build without it. 37 | TomcatURLStreamHandlerFactory.disable(); 38 | } 39 | 40 | @Test 41 | public void enabledAddsInstanceProviderFn() { 42 | new SpringApplicationBuilder(TestConfig.class) 43 | .properties("--server.port=0", "spring.cloud.config.discovery.enabled=true", 44 | "spring.cloud.service-registry.auto-registration.enabled=false") 45 | .run() 46 | .close(); 47 | } 48 | 49 | @SpringBootConfiguration 50 | @EnableAutoConfiguration 51 | static class TestConfig { 52 | 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /docs/src/main/asciidoc/README.adoc: -------------------------------------------------------------------------------- 1 | image::https://github.com/spring-cloud/spring-cloud-consul/workflows/Build/badge.svg?style=svg["Actions Status", link="https://github.com/spring-cloud/spring-cloud-consul/actions"] 2 | image::https://codecov.io/gh/spring-cloud/spring-cloud-consul/branch/main/graph/badge.svg["Codecov", link="https://codecov.io/gh/spring-cloud/spring-cloud-consul/branch/main"] 3 | 4 | 5 | [[quick-start]] 6 | = Quick Start 7 | 8 | 9 | [[consul-overview]] 10 | = Consul overview 11 | 12 | Features of Consul 13 | 14 | * Distributed configuration 15 | * Service registration and discovery 16 | * Distributed events 17 | * Distributed locking and sessions 18 | * Supports multiple data centers 19 | * Built in, user-friendly user interface 20 | 21 | See the https://consul.io/intro/index.html[intro] for more information. 22 | 23 | [[spring-cloud-consul-features]] 24 | = Spring Cloud Consul Features 25 | 26 | * Spring Cloud `DiscoveryClient` implementation 27 | ** supports Spring Cloud Gateway 28 | ** supports Spring Cloud LoadBalancer 29 | * Consul based `PropertySource` loaded during the 'bootstrap' phase. 30 | * Spring Cloud Bus implementation based on Consul https://www.consul.io/docs/agent/http/event.html[events] 31 | 32 | [[running-the-sample]] 33 | = Running the sample 34 | 35 | 1. Run `docker-compose up` 36 | 2. Verify consul is running by visiting http://localhost:8500 37 | 3. Run `mvn package` this will bring in the required spring cloud maven repositories and build 38 | 4. Run `java -jar spring-cloud-consul-sample/target/spring-cloud-consul-sample-${VERSION}.jar` 39 | 5. visit http://localhost:8080, verify that `{"serviceId":":8080","host":"","port":8080}` results 40 | 6. run `java -jar spring-cloud-consul-sample/target/spring-cloud-consul-sample-${VERSION}.jar --server.port=8081` 41 | 7. visit http://localhost:8080 again, verify that `{"serviceId":":8081","host":"","port":8081}` eventually shows up in the results in a round robbin fashion (may take a minute or so). 42 | 43 | [[building]] 44 | = Building 45 | 46 | include::https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/main/docs/modules/ROOT/pages/building.adoc[] 47 | 48 | [[contributing]] 49 | = Contributing 50 | 51 | include::https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/main/docs/modules/ROOT/pages/contributing.adoc[] 52 | -------------------------------------------------------------------------------- /spring-cloud-consul-integration-tests/spring-cloud-consul-configdata-tests/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | spring-cloud-consul-configdata-tests 8 | jar 9 | Spring Cloud Consul ConfigData Integration Tests 10 | Spring Cloud Consul ConfigData Integration Tests 11 | 12 | 13 | org.springframework.cloud 14 | spring-cloud-consul-integration-tests 15 | 5.0.1-SNAPSHOT 16 | .. 17 | 18 | 19 | 20 | 21 | 22 | 23 | maven-deploy-plugin 24 | 25 | true 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | org.springframework.boot 34 | spring-boot-starter-actuator 35 | 36 | 37 | org.springframework.boot 38 | spring-boot-starter-web 39 | 40 | 41 | org.springframework.cloud 42 | spring-cloud-starter-consul-config 43 | 44 | 45 | org.springframework.boot 46 | spring-boot-starter-test 47 | test 48 | 49 | 50 | org.springframework.boot 51 | spring-boot-resttestclient 52 | test 53 | 54 | 55 | org.testcontainers 56 | consul 57 | test 58 | 59 | 60 | org.springframework.cloud 61 | spring-cloud-consul-core 62 | ${project.version} 63 | test-jar 64 | test 65 | 66 | 67 | 68 | 69 | -------------------------------------------------------------------------------- /spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/ConsulServerUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013-present 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.consul.discovery; 18 | 19 | import java.net.Inet6Address; 20 | import java.net.InetAddress; 21 | import java.net.UnknownHostException; 22 | 23 | import org.apache.commons.logging.Log; 24 | import org.apache.commons.logging.LogFactory; 25 | 26 | import org.springframework.cloud.consul.model.http.health.HealthService; 27 | import org.springframework.util.StringUtils; 28 | 29 | /** 30 | * @author Spencer Gibb 31 | * @author Semenkov Alexey 32 | */ 33 | public final class ConsulServerUtils { 34 | 35 | private static final Log log = LogFactory.getLog(ConsulServerUtils.class); 36 | 37 | private ConsulServerUtils() { 38 | throw new IllegalStateException("Can't instantiate a utility class"); 39 | } 40 | 41 | public static String findHost(HealthService healthService) { 42 | HealthService.Service service = healthService.getService(); 43 | HealthService.Node node = healthService.getNode(); 44 | 45 | if (StringUtils.hasText(service.getAddress())) { 46 | return fixIPv6Address(service.getAddress()); 47 | } 48 | else if (StringUtils.hasText(node.getAddress())) { 49 | return fixIPv6Address(node.getAddress()); 50 | } 51 | return node.getNode(); 52 | } 53 | 54 | public static String fixIPv6Address(String address) { 55 | try { 56 | InetAddress inetAdr = InetAddress.getByName(address); 57 | if (inetAdr instanceof Inet6Address) { 58 | return "[" + inetAdr.getHostAddress() + "]"; 59 | } 60 | return address; 61 | } 62 | catch (UnknownHostException e) { 63 | log.debug("Not InetAddress: " + address + " , resolved as is."); 64 | return address; 65 | } 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /spring-cloud-consul-integration-tests/spring-cloud-consul-configdata-tests/src/test/java/org/springframework/cloud/consul/configdatatests/ConsulConfigDataApplicationTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013-present 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.consul.configdatatests; 18 | 19 | import java.util.UUID; 20 | 21 | import org.junit.jupiter.api.AfterAll; 22 | import org.junit.jupiter.api.BeforeAll; 23 | import org.junit.jupiter.api.Test; 24 | 25 | import org.springframework.boot.SpringApplication; 26 | import org.springframework.cloud.consul.test.ConsulTestcontainers; 27 | import org.springframework.context.ConfigurableApplicationContext; 28 | import org.springframework.test.annotation.DirtiesContext; 29 | 30 | @DirtiesContext 31 | public class ConsulConfigDataApplicationTests { 32 | 33 | private static final String APP_NAME = "testConsulConfigDataIntegration"; 34 | 35 | private static final String PREFIX = "_configDataIntegrationTests_config__"; 36 | 37 | private static final String ROOT = PREFIX + UUID.randomUUID(); 38 | 39 | private static ConfigurableApplicationContext context; 40 | 41 | @BeforeAll 42 | public static void setup() { 43 | ConsulTestcontainers.start(); 44 | 45 | SpringApplication application = new SpringApplication(ConsulConfigDataApplication.class); 46 | context = application.run("--spring.application.name=" + APP_NAME, 47 | "--spring.config.import=optional:consul:" + ConsulTestcontainers.getHost() + ":" 48 | + ConsulTestcontainers.getPort(), 49 | "--spring.cloud.consul.config.prefix=" + ROOT, "--spring.cloud.consul.config.watch.delay=10"); 50 | 51 | } 52 | 53 | @AfterAll 54 | public static void teardown() { 55 | if (context != null) { 56 | context.close(); 57 | } 58 | } 59 | 60 | @Test 61 | public void contextLoads() { 62 | } 63 | 64 | } 65 | -------------------------------------------------------------------------------- /spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/ConsulDiscoveryClientProbeTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013-present 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.consul.discovery; 18 | 19 | import org.junit.jupiter.api.Test; 20 | import org.junit.jupiter.api.extension.ExtendWith; 21 | import org.mockito.InjectMocks; 22 | import org.mockito.Mock; 23 | import org.mockito.junit.jupiter.MockitoExtension; 24 | 25 | import org.springframework.cloud.consul.ConsulClient; 26 | import org.springframework.http.HttpStatus; 27 | import org.springframework.http.ResponseEntity; 28 | import org.springframework.web.client.HttpClientErrorException; 29 | 30 | import static org.assertj.core.api.Assertions.assertThatThrownBy; 31 | import static org.mockito.Mockito.verify; 32 | import static org.mockito.Mockito.when; 33 | 34 | /** 35 | * Unit tests for {@link ConsulDiscoveryClient} probe API. 36 | */ 37 | @ExtendWith(MockitoExtension.class) 38 | public class ConsulDiscoveryClientProbeTests { 39 | 40 | @Mock 41 | private ConsulClient consulClient; 42 | 43 | @Mock 44 | private ConsulDiscoveryProperties consulDiscoveryProperties; 45 | 46 | @InjectMocks 47 | private ConsulDiscoveryClient discoveryClient; 48 | 49 | @Test 50 | public void probeSucceeds() { 51 | when(consulClient.getStatusLeader()).thenReturn(ResponseEntity.ok("5150")); 52 | discoveryClient.probe(); 53 | verify(consulClient).getStatusLeader(); 54 | } 55 | 56 | @Test 57 | public void probeFails() { 58 | when(consulClient.getStatusLeader()) 59 | .thenThrow(new HttpClientErrorException(HttpStatus.INTERNAL_SERVER_ERROR, "No leader")); 60 | assertThatThrownBy(() -> discoveryClient.probe()).isInstanceOf(HttpClientErrorException.class) 61 | .hasMessageContaining("No leader"); 62 | verify(consulClient).getStatusLeader(); 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/serviceregistry/ConsulRegistration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013-present 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.consul.serviceregistry; 18 | 19 | import java.net.URI; 20 | import java.util.Map; 21 | 22 | import org.springframework.cloud.client.ServiceInstance; 23 | import org.springframework.cloud.client.serviceregistry.Registration; 24 | import org.springframework.cloud.consul.discovery.ConsulDiscoveryProperties; 25 | import org.springframework.cloud.consul.model.http.agent.NewService; 26 | 27 | /** 28 | * @author Spencer Gibb 29 | */ 30 | public class ConsulRegistration implements Registration { 31 | 32 | private final NewService service; 33 | 34 | private ConsulDiscoveryProperties properties; 35 | 36 | public ConsulRegistration(NewService service, ConsulDiscoveryProperties properties) { 37 | this.service = service; 38 | this.properties = properties; 39 | } 40 | 41 | public NewService getService() { 42 | return this.service; 43 | } 44 | 45 | protected ConsulDiscoveryProperties getProperties() { 46 | return this.properties; 47 | } 48 | 49 | public String getInstanceId() { 50 | return getService().getId(); 51 | } 52 | 53 | public String getServiceId() { 54 | return getService().getName(); 55 | } 56 | 57 | @Override 58 | public String getHost() { 59 | return getService().getAddress(); 60 | } 61 | 62 | @Override 63 | public int getPort() { 64 | return getService().getPort(); 65 | } 66 | 67 | @Override 68 | public boolean isSecure() { 69 | return this.properties.getScheme().equalsIgnoreCase("https"); 70 | } 71 | 72 | @Override 73 | public URI getUri() { 74 | return ServiceInstance.createUri(this); 75 | } 76 | 77 | @Override 78 | public Map getMetadata() { 79 | return getService().getMeta(); 80 | } 81 | 82 | } 83 | -------------------------------------------------------------------------------- /spring-cloud-consul-config/src/test/java/org/springframework/cloud/consul/config/ConsulPropertySourceLocatorRetryTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013-present 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.consul.config; 18 | 19 | import org.junit.Rule; 20 | import org.junit.Test; 21 | 22 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 23 | import org.springframework.boot.builder.SpringApplicationBuilder; 24 | import org.springframework.boot.test.system.OutputCaptureRule; 25 | import org.springframework.context.annotation.Configuration; 26 | import org.springframework.web.client.ResourceAccessException; 27 | 28 | import static org.assertj.core.api.Assertions.assertThat; 29 | import static org.assertj.core.api.Assertions.assertThatThrownBy; 30 | import static org.assertj.core.api.Assertions.fail; 31 | 32 | /** 33 | * @author Spencer Gibb 34 | */ 35 | public class ConsulPropertySourceLocatorRetryTests { 36 | 37 | @Rule 38 | public OutputCaptureRule output = new OutputCaptureRule(); 39 | 40 | @Test 41 | public void testRetry() { 42 | assertThatThrownBy(() -> { 43 | new SpringApplicationBuilder(Config.class) 44 | .properties("spring.application.name=testConsulPropertySourceLocatorRetry", 45 | "spring.config.use-legacy-processing=true", 46 | "spring.cloud.consul.host=53210a7c-4809-42cb-8b30-057d2db85fcc", 47 | "logging.level.org.springframework.retry=TRACE", "server.port=0", 48 | "spring.cloud.consul.port=65530", "spring.cloud.consul.retry.maxAttempts=1", 49 | "spring.cloud.consul.config.failFast=true") 50 | .run(); 51 | fail("Did not throw expected exception"); 52 | }).hasCauseInstanceOf(ResourceAccessException.class); 53 | assertThat(output).contains("RetryContext retrieved"); 54 | } 55 | 56 | @Configuration(proxyBeanMethods = false) 57 | @EnableAutoConfiguration 58 | static class Config { 59 | 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/configclient/ConsulConfigServerAutoConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013-present 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.consul.discovery.configclient; 18 | 19 | import jakarta.annotation.PostConstruct; 20 | 21 | import org.springframework.beans.factory.annotation.Autowired; 22 | import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; 23 | import org.springframework.boot.context.properties.EnableConfigurationProperties; 24 | import org.springframework.cloud.config.server.config.ConfigServerProperties; 25 | import org.springframework.cloud.consul.ConsulClient; 26 | import org.springframework.cloud.consul.discovery.ConsulDiscoveryProperties; 27 | import org.springframework.context.annotation.Configuration; 28 | import org.springframework.util.StringUtils; 29 | 30 | /** 31 | * Extra configuration for config server if it happens to be registered with Consul. 32 | * 33 | * @author Dave Syer 34 | */ 35 | @Configuration(proxyBeanMethods = false) 36 | @EnableConfigurationProperties 37 | @ConditionalOnClass({ ConsulDiscoveryProperties.class, ConsulClient.class, ConfigServerProperties.class }) 38 | public class ConsulConfigServerAutoConfiguration { 39 | 40 | /** 41 | * The metadata key for the path for config server. 42 | */ 43 | public static final String CONFIG_PATH_KEY = "configPath"; 44 | 45 | @Autowired(required = false) 46 | private ConsulDiscoveryProperties properties; 47 | 48 | @Autowired(required = false) 49 | private ConfigServerProperties server; 50 | 51 | @PostConstruct 52 | public void init() { 53 | if (this.properties == null || this.server == null) { 54 | return; 55 | } 56 | String prefix = this.server.getPrefix(); 57 | if (StringUtils.hasText(prefix)) { 58 | this.properties.getMetadata().put(CONFIG_PATH_KEY, prefix); 59 | } 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /spring-cloud-consul-core/src/test/java/org/springframework/cloud/consul/ConsulHealthIndicatorUpTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013-present 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.consul; 18 | 19 | import org.junit.Test; 20 | import org.junit.runner.RunWith; 21 | 22 | import org.springframework.beans.factory.annotation.Autowired; 23 | import org.springframework.boot.SpringBootConfiguration; 24 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 25 | import org.springframework.boot.health.actuate.endpoint.HealthEndpoint; 26 | import org.springframework.boot.health.contributor.Status; 27 | import org.springframework.boot.test.context.SpringBootTest; 28 | import org.springframework.cloud.consul.test.ConsulTestcontainers; 29 | import org.springframework.test.context.ContextConfiguration; 30 | import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; 31 | import org.springframework.test.context.junit4.SpringRunner; 32 | 33 | import static org.assertj.core.api.Assertions.assertThat; 34 | import static org.mockito.Mockito.verify; 35 | 36 | /** 37 | * Integration test for {@link ConsulHealthIndicator} when its in the UP status. 38 | * 39 | * @author Lomesh Patel (lomeshpatel) 40 | */ 41 | @RunWith(SpringRunner.class) 42 | @SpringBootTest 43 | @ContextConfiguration(initializers = ConsulTestcontainers.class) 44 | public class ConsulHealthIndicatorUpTest { 45 | 46 | @MockitoSpyBean 47 | private ConsulClient consulClient; 48 | 49 | @Autowired 50 | private HealthEndpoint healthEndpoint; 51 | 52 | @Test 53 | public void statusIsUp() { 54 | assertThat(this.healthEndpoint.health().getStatus()).as("health status was not UP").isEqualTo(Status.UP); 55 | verify(consulClient).getStatusLeader(); 56 | verify(consulClient).getCatalogServices(); 57 | } 58 | 59 | @EnableAutoConfiguration 60 | @SpringBootConfiguration 61 | protected static class TestConfig { 62 | 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /spring-cloud-consul-binder/src/test/java/org/springframework/cloud/consul/binder/config/ConsulBinderConfigurationTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013-present 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.consul.binder.config; 18 | 19 | import org.junit.Ignore; 20 | import org.junit.Rule; 21 | import org.junit.Test; 22 | import org.junit.rules.ExpectedException; 23 | 24 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 25 | import org.springframework.boot.builder.SpringApplicationBuilder; 26 | import org.springframework.cloud.consul.test.ConsulTestcontainers; 27 | import org.springframework.context.annotation.Configuration; 28 | import org.springframework.messaging.MessageChannel; 29 | 30 | import static org.hamcrest.Matchers.containsString; 31 | 32 | /** 33 | * @author Spencer Gibb 34 | */ 35 | public class ConsulBinderConfigurationTests { 36 | 37 | @Rule 38 | public ExpectedException exception = ExpectedException.none(); 39 | 40 | @Test 41 | @Ignore // FIXME 2.0.0 need stream fix 42 | public void consulBinderDisabledWorks() { 43 | this.exception.expectMessage(containsString("no proper implementation found")); 44 | new SpringApplicationBuilder(Application.class).initializers(new ConsulTestcontainers()) 45 | .properties("spring.cloud.consul.binder.enabled=false") 46 | .run(); 47 | } 48 | 49 | @Test 50 | @Ignore // FIXME 2.0.0 need stream fix 51 | public void consulDisabledDisablesBinder() { 52 | this.exception.expectMessage(containsString("no proper implementation found")); 53 | new SpringApplicationBuilder(Application.class).initializers(new ConsulTestcontainers()) 54 | .properties("spring.cloud.consul.enabled=false") 55 | .run(); 56 | } 57 | 58 | interface Events { 59 | 60 | // @Output 61 | MessageChannel purchases(); 62 | 63 | } 64 | 65 | @Configuration(proxyBeanMethods = false) 66 | @EnableAutoConfiguration 67 | // @EnableBinding(Events.class) 68 | public static class Application { 69 | 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /spring-cloud-consul-core/src/main/java/org/springframework/cloud/consul/model/http/ConsulHeaders.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013-present 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.consul.model.http; 18 | 19 | import org.springframework.http.HttpEntity; 20 | import org.springframework.util.StringUtils; 21 | 22 | /** 23 | * Custom Consul Defined Response Headers. 24 | * 25 | * @author Matthew Whitaker 26 | */ 27 | public final class ConsulHeaders { 28 | 29 | private ConsulHeaders() { 30 | } 31 | 32 | /** 33 | * Header name for Consul Index. 34 | */ 35 | public static String INDEX_HEADER = "X-Consul-Index"; 36 | 37 | /** 38 | * Header name for Consul Knownleader. 39 | */ 40 | public static String KNOWN_LEADER_HEADER = "X-Consul-Knownleader"; 41 | 42 | /** 43 | * Header name for Consul Lastcontact. 44 | */ 45 | public static String LAST_CONTACT_HEADER = "X-Consul-Lastcontact"; 46 | 47 | public static Long getConsulIndex(HttpEntity entity) { 48 | String header = entity.getHeaders().getFirst(INDEX_HEADER); 49 | return parseUnsignedLong(header); 50 | } 51 | 52 | public static Boolean getConsulKnownLeader(HttpEntity entity) { 53 | String header = entity.getHeaders().getFirst(KNOWN_LEADER_HEADER); 54 | return parseBoolean(header); 55 | } 56 | 57 | public static Long getConsulLastContact(HttpEntity entity) { 58 | String header = entity.getHeaders().getFirst(LAST_CONTACT_HEADER); 59 | return parseUnsignedLong(header); 60 | } 61 | 62 | private static Long parseUnsignedLong(String value) { 63 | if (StringUtils.hasText(value)) { 64 | try { 65 | return Long.parseUnsignedLong(value); 66 | } 67 | catch (Exception e) { 68 | } 69 | } 70 | 71 | return null; 72 | } 73 | 74 | private static Boolean parseBoolean(String value) { 75 | if (StringUtils.hasText(value)) { 76 | if ("true".equals(value)) { 77 | return true; 78 | } 79 | 80 | if ("false".equals(value)) { 81 | return false; 82 | } 83 | } 84 | 85 | return null; 86 | } 87 | 88 | } 89 | -------------------------------------------------------------------------------- /spring-cloud-consul-integration-tests/spring-cloud-consul-configdata-retry-tests/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | spring-cloud-consul-configdata-retry-tests 8 | jar 9 | Spring Cloud Consul ConfigData Retry Tests 10 | Spring Cloud Consul ConfigData Retry Tests 11 | 12 | 13 | org.springframework.cloud 14 | spring-cloud-consul-integration-tests 15 | 5.0.1-SNAPSHOT 16 | .. 17 | 18 | 19 | 20 | 21 | 22 | org.springframework.boot 23 | spring-boot-maven-plugin 24 | 25 | 26 | 27 | repackage 28 | 29 | 30 | 31 | 32 | 33 | 34 | maven-deploy-plugin 35 | 36 | true 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | org.springframework.boot 45 | spring-boot-starter-web 46 | 47 | 48 | org.springframework.boot 49 | spring-boot-starter-actuator 50 | 51 | 52 | org.springframework.cloud 53 | spring-cloud-starter-consul-config 54 | 55 | 56 | org.springframework.retry 57 | spring-retry 58 | 59 | 60 | org.springframework.boot 61 | spring-boot-starter-test 62 | test 63 | 64 | 65 | org.testcontainers 66 | consul 67 | test 68 | 69 | 70 | org.springframework.cloud 71 | spring-cloud-consul-core 72 | ${project.version} 73 | test-jar 74 | test 75 | 76 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /README.adoc: -------------------------------------------------------------------------------- 1 | //// 2 | DO NOT EDIT THIS FILE. IT WAS GENERATED. 3 | Manual changes to this file will be lost when it is generated again. 4 | Edit the files in the src/main/asciidoc/ directory instead. 5 | //// 6 | 7 | 8 | image::https://github.com/spring-cloud/spring-cloud-consul/workflows/Build/badge.svg?style=svg["Actions Status", link="https://github.com/spring-cloud/spring-cloud-consul/actions"] 9 | image::https://codecov.io/gh/spring-cloud/spring-cloud-consul/branch/main/graph/badge.svg["Codecov", link="https://codecov.io/gh/spring-cloud/spring-cloud-consul/branch/main"] 10 | 11 | 12 | [[quick-start]] 13 | = Quick Start 14 | 15 | 16 | [[consul-overview]] 17 | = Consul overview 18 | 19 | Features of Consul 20 | 21 | * Distributed configuration 22 | * Service registration and discovery 23 | * Distributed events 24 | * Distributed locking and sessions 25 | * Supports multiple data centers 26 | * Built in, user-friendly user interface 27 | 28 | See the https://consul.io/intro/index.html[intro] for more information. 29 | 30 | [[spring-cloud-consul-features]] 31 | = Spring Cloud Consul Features 32 | 33 | * Spring Cloud `DiscoveryClient` implementation 34 | ** supports Spring Cloud Gateway 35 | ** supports Spring Cloud LoadBalancer 36 | * Consul based `PropertySource` loaded during the 'bootstrap' phase. 37 | * Spring Cloud Bus implementation based on Consul https://www.consul.io/docs/agent/http/event.html[events] 38 | 39 | [[running-the-sample]] 40 | = Running the sample 41 | 42 | 1. Run `docker-compose up` 43 | 2. Verify consul is running by visiting http://localhost:8500 44 | 3. Run `mvn package` this will bring in the required spring cloud maven repositories and build 45 | 4. Run `java -jar spring-cloud-consul-sample/target/spring-cloud-consul-sample-${VERSION}.jar` 46 | 5. visit http://localhost:8080, verify that `{"serviceId":":8080","host":"","port":8080}` results 47 | 6. run `java -jar spring-cloud-consul-sample/target/spring-cloud-consul-sample-${VERSION}.jar --server.port=8081` 48 | 7. visit http://localhost:8080 again, verify that `{"serviceId":":8081","host":"","port":8081}` eventually shows up in the results in a round robbin fashion (may take a minute or so). 49 | 50 | [[building]] 51 | = Building 52 | 53 | [[building]] 54 | = Building 55 | 56 | Unresolved directive in https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/main/docs/modules/ROOT/pages/building.adoc - include::partial$building.adoc[] 57 | 58 | [[contributing]] 59 | = Contributing 60 | 61 | [[contributing]] 62 | = Contributing 63 | 64 | Unresolved directive in https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/main/docs/modules/ROOT/pages/contributing.adoc - include::partial$contributing.adoc[] 65 | -------------------------------------------------------------------------------- /spring-cloud-consul-core/src/test/java/org/springframework/cloud/consul/ConsulHealthIndicatorLightweightUpTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013-present 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.consul; 18 | 19 | import org.junit.Test; 20 | import org.junit.runner.RunWith; 21 | 22 | import org.springframework.beans.factory.annotation.Autowired; 23 | import org.springframework.boot.SpringBootConfiguration; 24 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 25 | import org.springframework.boot.health.actuate.endpoint.HealthEndpoint; 26 | import org.springframework.boot.health.contributor.Status; 27 | import org.springframework.boot.test.context.SpringBootTest; 28 | import org.springframework.cloud.consul.test.ConsulTestcontainers; 29 | import org.springframework.test.context.ContextConfiguration; 30 | import org.springframework.test.context.bean.override.mockito.MockitoSpyBean; 31 | import org.springframework.test.context.junit4.SpringRunner; 32 | 33 | import static org.assertj.core.api.Assertions.assertThat; 34 | import static org.mockito.Mockito.never; 35 | import static org.mockito.Mockito.verify; 36 | 37 | /** 38 | * Integration test for {@link ConsulHealthIndicator} using its lightweight check when its 39 | * in the UP status. 40 | * 41 | * @author Lomesh Patel (lomeshpatel) 42 | */ 43 | @RunWith(SpringRunner.class) 44 | @SpringBootTest(properties = "spring.cloud.consul.health-indicator.include-services-query=false") 45 | @ContextConfiguration(initializers = ConsulTestcontainers.class) 46 | public class ConsulHealthIndicatorLightweightUpTest { 47 | 48 | @MockitoSpyBean 49 | private ConsulClient consulClient; 50 | 51 | @Autowired 52 | private HealthEndpoint healthEndpoint; 53 | 54 | @Test 55 | public void statusIsUp() { 56 | assertThat(this.healthEndpoint.health().getStatus()).as("health status was not UP").isEqualTo(Status.UP); 57 | verify(consulClient).getStatusLeader(); 58 | verify(consulClient, never()).getCatalogServices(); 59 | } 60 | 61 | @EnableAutoConfiguration 62 | @SpringBootConfiguration 63 | protected static class TestConfig { 64 | 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013-present 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.consul.serviceregistry; 18 | 19 | import org.springframework.boot.web.server.context.ConfigurableWebServerApplicationContext; 20 | import org.springframework.boot.web.server.context.WebServerInitializedEvent; 21 | import org.springframework.context.ApplicationContext; 22 | import org.springframework.context.ApplicationEvent; 23 | import org.springframework.context.event.SmartApplicationListener; 24 | 25 | /** 26 | * Auto registers service upon web server initialization. 27 | * 28 | * @author Spencer Gibb 29 | */ 30 | public class ConsulAutoServiceRegistrationListener implements SmartApplicationListener { 31 | 32 | private final ConsulAutoServiceRegistration autoServiceRegistration; 33 | 34 | public ConsulAutoServiceRegistrationListener(ConsulAutoServiceRegistration autoServiceRegistration) { 35 | this.autoServiceRegistration = autoServiceRegistration; 36 | } 37 | 38 | @Override 39 | public boolean supportsEventType(Class eventType) { 40 | return WebServerInitializedEvent.class.isAssignableFrom(eventType); 41 | } 42 | 43 | @Override 44 | public boolean supportsSourceType(Class sourceType) { 45 | return true; 46 | } 47 | 48 | @Override 49 | public void onApplicationEvent(ApplicationEvent applicationEvent) { 50 | if (applicationEvent instanceof WebServerInitializedEvent) { 51 | WebServerInitializedEvent event = (WebServerInitializedEvent) applicationEvent; 52 | 53 | ApplicationContext context = event.getApplicationContext(); 54 | if (context instanceof ConfigurableWebServerApplicationContext) { 55 | if ("management".equals(((ConfigurableWebServerApplicationContext) context).getServerNamespace())) { 56 | return; 57 | } 58 | } 59 | this.autoServiceRegistration.setPortIfNeeded(event.getWebServer().getPort()); 60 | this.autoServiceRegistration.start(); 61 | } 62 | } 63 | 64 | @Override 65 | public int getOrder() { 66 | return 0; 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /spring-cloud-consul-binder/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | spring-cloud-consul-binder 8 | jar 9 | Spring Cloud Consul Binder 10 | Spring Cloud Consul Binder 11 | 12 | 13 | org.springframework.cloud 14 | spring-cloud-consul 15 | 5.0.1-SNAPSHOT 16 | .. 17 | 18 | 19 | 20 | 21 | org.springframework.boot 22 | spring-boot-starter-web 23 | true 24 | 25 | 26 | org.springframework.cloud 27 | spring-cloud-consul-core 28 | true 29 | 30 | 31 | org.springframework.cloud 32 | spring-cloud-stream 33 | 34 | 35 | org.springframework.cloud 36 | spring-cloud-deployer-local 37 | test 38 | 39 | 40 | org.springframework.cloud 41 | spring-cloud-test-support 42 | test 43 | 44 | 45 | org.springframework.boot 46 | spring-boot-starter-test 47 | test 48 | 49 | 50 | org.junit.vintage 51 | junit-vintage-engine 52 | test 53 | 54 | 55 | com.github.tomakehurst 56 | wiremock-jre8-standalone 57 | 2.35.2 58 | test 59 | 60 | 61 | org.awaitility 62 | awaitility 63 | 4.3.0 64 | test 65 | 66 | 67 | org.testcontainers 68 | consul 69 | test 70 | 71 | 72 | org.springframework.cloud 73 | spring-cloud-consul-core 74 | ${project.version} 75 | test-jar 76 | test 77 | 78 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/ConsulLoadbalancerClientTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013-present 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.consul.discovery; 18 | 19 | import org.junit.jupiter.api.Test; 20 | 21 | import org.springframework.beans.factory.annotation.Autowired; 22 | import org.springframework.boot.SpringBootConfiguration; 23 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 24 | import org.springframework.boot.test.context.SpringBootTest; 25 | import org.springframework.cloud.client.ServiceInstance; 26 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 27 | import org.springframework.cloud.client.loadbalancer.LoadBalancerClient; 28 | import org.springframework.cloud.consul.test.ConsulTestcontainers; 29 | import org.springframework.test.context.ContextConfiguration; 30 | 31 | import static org.assertj.core.api.Assertions.assertThat; 32 | import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; 33 | 34 | /** 35 | * @author Spencer Gibb 36 | */ 37 | @SpringBootTest(properties = { "spring.application.name=testConsulLoadBalancer", 38 | "spring.cloud.consul.discovery.prefer-ip-address=true", "spring.cloud.consul.discovery.metadata.foo=bar" }, 39 | webEnvironment = RANDOM_PORT) 40 | @ContextConfiguration(initializers = ConsulTestcontainers.class) 41 | public class ConsulLoadbalancerClientTests { 42 | 43 | @Autowired 44 | private LoadBalancerClient client; 45 | 46 | @Test 47 | public void chooseWorks() { 48 | ServiceInstance instance = this.client.choose("testConsulLoadBalancer"); 49 | assertThat(instance).isNotNull(); 50 | 51 | assertThat(instance.isSecure()).isFalse(); 52 | assertIpAddress(instance); 53 | assertThat(instance.getMetadata()).containsEntry("foo", "bar"); 54 | } 55 | 56 | private void assertIpAddress(ServiceInstance instance) { 57 | assertThat(Character.isDigit(instance.getHost().charAt(0))).as("host isn't an ip address").isTrue(); 58 | } 59 | 60 | @SpringBootConfiguration 61 | @EnableAutoConfiguration 62 | @EnableDiscoveryClient 63 | public static class MyTestConfig { 64 | 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/ConsulDiscoveryClientHttpsTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013-present 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.consul.discovery; 18 | 19 | import java.util.List; 20 | 21 | import org.junit.jupiter.api.Test; 22 | 23 | import org.springframework.beans.factory.annotation.Autowired; 24 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 25 | import org.springframework.boot.test.context.SpringBootTest; 26 | import org.springframework.cloud.client.ServiceInstance; 27 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 28 | import org.springframework.cloud.consul.test.ConsulTestcontainers; 29 | import org.springframework.context.annotation.Configuration; 30 | import org.springframework.test.context.ContextConfiguration; 31 | 32 | import static org.assertj.core.api.Assertions.assertThat; 33 | import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; 34 | 35 | /** 36 | * @author Glen Lockhart 37 | */ 38 | @SpringBootTest( 39 | properties = { "spring.application.name=testConsulDiscoveryHttps", 40 | "spring.cloud.consul.discovery.prefer-ip-address=true", "spring.cloud.consul.discovery.scheme=https" }, 41 | classes = ConsulDiscoveryClientHttpsTests.MyTestConfig.class, webEnvironment = RANDOM_PORT) 42 | @ContextConfiguration(initializers = ConsulTestcontainers.class) 43 | public class ConsulDiscoveryClientHttpsTests { 44 | 45 | @Autowired 46 | private ConsulDiscoveryClient discoveryClient; 47 | 48 | @Test 49 | public void getInstancesForServiceWorks() { 50 | List instances = this.discoveryClient.getInstances("testConsulDiscoveryHttps"); 51 | assertThat(instances).as("instances was null").isNotNull(); 52 | assertThat(instances.isEmpty()).as("instances was empty").isFalse(); 53 | 54 | ServiceInstance instance = instances.get(0); 55 | assertThat(instance.isSecure()).as("instance was not secure (https)").isTrue(); 56 | } 57 | 58 | @Configuration(proxyBeanMethods = false) 59 | @EnableAutoConfiguration 60 | @EnableDiscoveryClient 61 | public static class MyTestConfig { 62 | 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /spring-cloud-consul-config/src/main/java/org/springframework/cloud/consul/config/ConsulRetryBootstrapper.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013-present 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.consul.config; 18 | 19 | import org.springframework.boot.bootstrap.BootstrapRegistry; 20 | import org.springframework.boot.bootstrap.BootstrapRegistryInitializer; 21 | import org.springframework.boot.context.properties.bind.Binder; 22 | import org.springframework.cloud.consul.RetryProperties; 23 | import org.springframework.cloud.consul.config.ConsulBootstrapper.LoaderInterceptor; 24 | import org.springframework.retry.support.RetryTemplate; 25 | import org.springframework.util.ClassUtils; 26 | 27 | /** 28 | * Consul Retry Bootstrapper. 29 | * 30 | * @author Spencer Gibb 31 | * @since 3.0.2 32 | */ 33 | public class ConsulRetryBootstrapper implements BootstrapRegistryInitializer { 34 | 35 | static final boolean RETRY_IS_PRESENT = ClassUtils.isPresent("org.springframework.retry.annotation.Retryable", 36 | null); 37 | 38 | @Override 39 | public void initialize(BootstrapRegistry registry) { 40 | if (!RETRY_IS_PRESENT) { 41 | return; 42 | } 43 | 44 | registry.registerIfAbsent(RetryProperties.class, 45 | context -> context.get(Binder.class) 46 | .bind(RetryProperties.PREFIX, RetryProperties.class) 47 | .orElseGet(RetryProperties::new)); 48 | 49 | registry.registerIfAbsent(RetryTemplate.class, context -> { 50 | RetryProperties properties = context.get(RetryProperties.class); 51 | if (properties.isEnabled()) { 52 | return RetryTemplate.builder() 53 | .maxAttempts(properties.getMaxAttempts()) 54 | .exponentialBackoff(properties.getInitialInterval(), properties.getMultiplier(), 55 | properties.getMaxInterval()) 56 | .build(); 57 | } 58 | return null; 59 | }); 60 | registry.registerIfAbsent(LoaderInterceptor.class, context -> { 61 | RetryTemplate retryTemplate = context.get(RetryTemplate.class); 62 | if (retryTemplate != null) { 63 | return loadContext -> retryTemplate.execute(retryContext -> loadContext.getInvocation() 64 | .apply(loadContext.getLoaderContext(), loadContext.getResource())); 65 | } 66 | // disabled 67 | return null; 68 | }); 69 | 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /spring-cloud-consul-config/src/main/java/org/springframework/cloud/consul/config/ConsulConfigBootstrapConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013-present 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.consul.config; 18 | 19 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 20 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 21 | import org.springframework.boot.context.properties.EnableConfigurationProperties; 22 | import org.springframework.cloud.consul.ConditionalOnConsulEnabled; 23 | import org.springframework.cloud.consul.ConsulAutoConfiguration; 24 | import org.springframework.cloud.consul.ConsulClient; 25 | import org.springframework.context.annotation.Bean; 26 | import org.springframework.context.annotation.Configuration; 27 | import org.springframework.context.annotation.Import; 28 | import org.springframework.core.env.Environment; 29 | import org.springframework.util.ObjectUtils; 30 | 31 | /** 32 | * @author Spencer Gibb 33 | * @author Edvin Eriksson 34 | */ 35 | @Configuration(proxyBeanMethods = false) 36 | @ConditionalOnConsulEnabled 37 | public class ConsulConfigBootstrapConfiguration { 38 | 39 | @Configuration(proxyBeanMethods = false) 40 | @EnableConfigurationProperties 41 | @Import(ConsulAutoConfiguration.class) 42 | @ConditionalOnProperty(name = "spring.cloud.consul.config.enabled", matchIfMissing = true) 43 | protected static class ConsulPropertySourceConfiguration { 44 | 45 | private ConsulClient consul; 46 | 47 | public ConsulPropertySourceConfiguration(ConsulClient consul) { 48 | this.consul = consul; 49 | } 50 | 51 | @Bean 52 | @ConditionalOnMissingBean 53 | public ConsulConfigProperties consulConfigProperties(Environment env) { 54 | ConsulConfigProperties properties = new ConsulConfigProperties(); 55 | if (ObjectUtils.isEmpty(properties.getName())) { 56 | properties.setName(env.getProperty("spring.application.name", "application")); 57 | } 58 | return properties; 59 | } 60 | 61 | @Bean 62 | public ConsulPropertySourceLocator consulPropertySourceLocator(ConsulConfigProperties consulConfigProperties) { 63 | return new ConsulPropertySourceLocator(this.consul, consulConfigProperties); 64 | } 65 | 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /spring-cloud-consul-core/src/test/java/org/springframework/cloud/consul/ConsulHealthIndicatorDownTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013-present 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.consul; 18 | 19 | import org.junit.jupiter.api.Test; 20 | 21 | import org.springframework.beans.factory.annotation.Autowired; 22 | import org.springframework.boot.SpringBootConfiguration; 23 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 24 | import org.springframework.boot.health.actuate.endpoint.HealthEndpoint; 25 | import org.springframework.boot.health.contributor.Status; 26 | import org.springframework.boot.test.context.SpringBootTest; 27 | import org.springframework.http.ResponseEntity; 28 | import org.springframework.test.context.bean.override.mockito.MockitoBean; 29 | 30 | import static org.assertj.core.api.Assertions.assertThat; 31 | import static org.mockito.Mockito.verify; 32 | import static org.mockito.Mockito.when; 33 | 34 | /** 35 | * Integration test for {@link ConsulHealthIndicator} when it's in the DOWN status. 36 | * 37 | * @author Lomesh Patel (lomeshpatel) 38 | */ 39 | @SpringBootTest 40 | public class ConsulHealthIndicatorDownTest { 41 | 42 | @MockitoBean 43 | private ConsulClient consulClient; 44 | 45 | @Autowired 46 | private HealthEndpoint healthEndpoint; 47 | 48 | @Test 49 | public void statusIsDownWhenConsulClientFailsToGetLeaderStatus() { 50 | when(consulClient.getStatusLeader()).thenThrow(new RuntimeException("no leader")); 51 | assertThat(this.healthEndpoint.health().getStatus()).as("health status was not DOWN").isEqualTo(Status.DOWN); 52 | verify(consulClient).getStatusLeader(); 53 | } 54 | 55 | @Test 56 | public void statusIsDownWhenConsulClientFailsToGetServices() { 57 | String leaderStatus = "OK"; 58 | when(consulClient.getStatusLeader()).thenReturn(ResponseEntity.ok(leaderStatus)); 59 | when(consulClient.getCatalogServices()).thenThrow(new RuntimeException("no services")); 60 | assertThat(this.healthEndpoint.health().getStatus()).as("health status was not DOWN").isEqualTo(Status.DOWN); 61 | verify(consulClient).getCatalogServices(); 62 | } 63 | 64 | @EnableAutoConfiguration 65 | @SpringBootConfiguration 66 | protected static class TestConfig { 67 | 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /spring-cloud-consul-binder/src/main/java/org/springframework/cloud/consul/binder/config/ConsulBinderConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013-present 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.consul.binder.config; 18 | 19 | import tools.jackson.databind.ObjectMapper; 20 | 21 | import org.springframework.beans.factory.annotation.Autowired; 22 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 23 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 24 | import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; 25 | import org.springframework.cloud.consul.ConditionalOnConsulEnabled; 26 | import org.springframework.cloud.consul.ConsulClient; 27 | import org.springframework.cloud.consul.binder.ConsulBinder; 28 | import org.springframework.cloud.consul.binder.EventService; 29 | import org.springframework.cloud.stream.binder.Binder; 30 | import org.springframework.context.annotation.Bean; 31 | import org.springframework.context.annotation.Configuration; 32 | import org.springframework.context.annotation.Import; 33 | 34 | /** 35 | * Configures the Consul binder. 36 | * 37 | * @author Spencer Gibb 38 | */ 39 | @Configuration(proxyBeanMethods = false) 40 | @ConditionalOnMissingBean(Binder.class) 41 | @Import({ PropertyPlaceholderAutoConfiguration.class }) 42 | @ConditionalOnConsulEnabled 43 | @ConditionalOnProperty(name = "spring.cloud.consul.binder.enabled", matchIfMissing = true) 44 | // FIXME: boot 2.0.0 @EnableConfigurationProperties({ConsulBinderProperties.class}) 45 | public class ConsulBinderConfiguration { 46 | 47 | // @Autowired 48 | // private ConsulBinderProperties consulBinderProperties; 49 | 50 | @Autowired(required = false) 51 | protected ObjectMapper objectMapper = new ObjectMapper(); 52 | 53 | @Bean 54 | @ConditionalOnMissingBean 55 | public EventService eventService(ConsulClient consulClient) { 56 | return new EventService(null/* consulBinderProperties */, consulClient, this.objectMapper); 57 | } 58 | 59 | @Bean 60 | @ConditionalOnMissingBean 61 | public ConsulBinder consulClientBinder(EventService eventService) { 62 | return new ConsulBinder(eventService); 63 | } 64 | 65 | // TODO: create consul client if needed 66 | 67 | } 68 | -------------------------------------------------------------------------------- /spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationFailFastTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013-present 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.consul.serviceregistry; 18 | 19 | import org.assertj.core.api.Assertions; 20 | import org.junit.jupiter.api.Disabled; 21 | import org.junit.jupiter.api.Test; 22 | import org.mockito.Mockito; 23 | 24 | import org.springframework.boot.SpringBootConfiguration; 25 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 26 | import org.springframework.boot.autoconfigure.ImportAutoConfiguration; 27 | import org.springframework.boot.builder.SpringApplicationBuilder; 28 | import org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationConfiguration; 29 | import org.springframework.cloud.consul.ConsulAutoConfiguration; 30 | import org.springframework.cloud.consul.ConsulClient; 31 | import org.springframework.cloud.consul.test.ConsulTestcontainers; 32 | import org.springframework.context.annotation.Bean; 33 | import org.springframework.test.annotation.DirtiesContext; 34 | import org.springframework.test.context.ContextConfiguration; 35 | 36 | /** 37 | * @author Spencer Gibb 38 | * @author Venil Noronha 39 | */ 40 | @DirtiesContext 41 | @ContextConfiguration(initializers = ConsulTestcontainers.class) 42 | public class ConsulAutoServiceRegistrationFailFastTests { 43 | 44 | @Disabled 45 | @Test 46 | public void testFailFastEnabled() { 47 | Assertions.assertThatThrownBy(() -> { 48 | new SpringApplicationBuilder(TestConfig.class) 49 | .properties("spring.application.name=testregistrationfails-fast", 50 | "spring.jmx.default-domain=testautoregfailfast", "server.port=0", 51 | "spring.cloud.consul.discovery.failFast=true") 52 | .run(); 53 | }).isInstanceOf(IllegalStateException.class); 54 | } 55 | 56 | @SpringBootConfiguration 57 | @EnableAutoConfiguration 58 | @ImportAutoConfiguration({ AutoServiceRegistrationConfiguration.class, ConsulAutoConfiguration.class, 59 | ConsulAutoServiceRegistrationAutoConfiguration.class }) 60 | protected static class TestConfig { 61 | 62 | @Bean 63 | public ConsulClient consulClient() { 64 | return Mockito.mock(ConsulClient.class); 65 | } 66 | 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /.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 30 | [Spring 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 | -------------------------------------------------------------------------------- /spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/ConsulCatalogWatchAutoConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013-present 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.consul.discovery; 18 | 19 | import org.springframework.beans.factory.annotation.Qualifier; 20 | import org.springframework.boot.autoconfigure.AutoConfigureAfter; 21 | import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; 22 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 23 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 24 | import org.springframework.cloud.client.ConditionalOnDiscoveryEnabled; 25 | import org.springframework.cloud.consul.ConditionalOnConsulEnabled; 26 | import org.springframework.cloud.consul.ConsulClient; 27 | import org.springframework.context.annotation.Bean; 28 | import org.springframework.context.annotation.Configuration; 29 | import org.springframework.scheduling.TaskScheduler; 30 | import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; 31 | 32 | /** 33 | * Auto configuration for the catalog watcher. 34 | * 35 | * @author Tim Ysewyn 36 | */ 37 | @Configuration(proxyBeanMethods = false) 38 | @ConditionalOnConsulEnabled 39 | @ConditionalOnProperty(value = "spring.cloud.consul.discovery.catalog-services-watch.enabled", matchIfMissing = true) 40 | @ConditionalOnDiscoveryEnabled 41 | @AutoConfigureAfter({ ConsulDiscoveryClientConfiguration.class }) 42 | @ConditionalOnBean(ConsulDiscoveryProperties.class) 43 | public class ConsulCatalogWatchAutoConfiguration { 44 | 45 | /** 46 | * Name of the catalog watch task scheduler bean. 47 | */ 48 | public static final String CATALOG_WATCH_TASK_SCHEDULER_NAME = "catalogWatchTaskScheduler"; 49 | 50 | @Bean 51 | @ConditionalOnMissingBean 52 | public ConsulCatalogWatch consulCatalogWatch(ConsulDiscoveryProperties discoveryProperties, 53 | ConsulClient consulClient, @Qualifier(CATALOG_WATCH_TASK_SCHEDULER_NAME) TaskScheduler taskScheduler) { 54 | return new ConsulCatalogWatch(discoveryProperties, consulClient, taskScheduler); 55 | } 56 | 57 | @Bean(name = CATALOG_WATCH_TASK_SCHEDULER_NAME) 58 | public TaskScheduler catalogWatchTaskScheduler() { 59 | return new ThreadPoolTaskScheduler(); 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/discovery/configclient/ConsulConfigServerAutoConfigurationTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013-present 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.consul.discovery.configclient; 18 | 19 | import org.junit.jupiter.api.AfterEach; 20 | import org.junit.jupiter.api.Test; 21 | 22 | import org.springframework.boot.WebApplicationType; 23 | import org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration; 24 | import org.springframework.boot.builder.SpringApplicationBuilder; 25 | import org.springframework.cloud.config.server.config.ConfigServerProperties; 26 | import org.springframework.cloud.consul.discovery.ConsulDiscoveryProperties; 27 | import org.springframework.context.ConfigurableApplicationContext; 28 | import org.springframework.context.annotation.AnnotationConfigApplicationContext; 29 | 30 | import static org.assertj.core.api.Assertions.assertThat; 31 | 32 | /** 33 | * @author Dave Syer 34 | */ 35 | public class ConsulConfigServerAutoConfigurationTests { 36 | 37 | private ConfigurableApplicationContext context; 38 | 39 | @AfterEach 40 | public void close() { 41 | if (this.context != null) { 42 | this.context.close(); 43 | } 44 | } 45 | 46 | @Test 47 | public void offByDefault() { 48 | this.context = new AnnotationConfigApplicationContext(ConsulConfigServerAutoConfiguration.class); 49 | assertThat(this.context.getBeanNamesForType(ConsulDiscoveryProperties.class).length).isEqualTo(0); 50 | } 51 | 52 | @Test 53 | public void onWhenRequested() { 54 | setup("spring.cloud.config.server.prefix=/config", "spring.cloud.consul.discovery.tags-as-metadata=false"); 55 | assertThat(this.context.getBeanNamesForType(ConsulDiscoveryProperties.class).length).isEqualTo(1); 56 | ConsulDiscoveryProperties properties = this.context.getBean(ConsulDiscoveryProperties.class); 57 | assertThat(properties.getMetadata()).containsEntry("configPath", "/config"); 58 | } 59 | 60 | private void setup(String... env) { 61 | this.context = new SpringApplicationBuilder(PropertyPlaceholderAutoConfiguration.class, 62 | ConsulConfigServerAutoConfiguration.class, ConfigServerProperties.class, 63 | ConsulDiscoveryProperties.class) 64 | .web(WebApplicationType.NONE) 65 | .properties(env) 66 | .run(); 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /spring-cloud-consul-config/src/main/java/org/springframework/cloud/consul/config/ConsulConfigAutoConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013-present 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.consul.config; 18 | 19 | import org.springframework.beans.factory.annotation.Qualifier; 20 | import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; 21 | import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; 22 | import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; 23 | import org.springframework.boot.context.properties.EnableConfigurationProperties; 24 | import org.springframework.cloud.consul.ConditionalOnConsulEnabled; 25 | import org.springframework.cloud.consul.ConsulClient; 26 | import org.springframework.cloud.endpoint.RefreshEndpoint; 27 | import org.springframework.context.annotation.Bean; 28 | import org.springframework.context.annotation.Configuration; 29 | import org.springframework.scheduling.TaskScheduler; 30 | import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; 31 | 32 | /** 33 | * @author Spencer Gibb 34 | */ 35 | @Configuration(proxyBeanMethods = false) 36 | @ConditionalOnConsulEnabled 37 | @ConditionalOnProperty(name = "spring.cloud.consul.config.enabled", matchIfMissing = true) 38 | @EnableConfigurationProperties 39 | public class ConsulConfigAutoConfiguration { 40 | 41 | /** 42 | * Name of the config watch task scheduler bean. 43 | */ 44 | public static final String CONFIG_WATCH_TASK_SCHEDULER_NAME = "configWatchTaskScheduler"; 45 | 46 | @Configuration(proxyBeanMethods = false) 47 | @ConditionalOnClass(RefreshEndpoint.class) 48 | @ConditionalOnProperty(name = "spring.cloud.consul.config.watch.enabled", matchIfMissing = true) 49 | protected static class ConsulRefreshConfiguration { 50 | 51 | @Bean 52 | @ConditionalOnBean(ConsulConfigIndexes.class) 53 | public ConfigWatch configWatch(ConsulConfigProperties properties, ConsulConfigIndexes indexes, 54 | ConsulClient consul, @Qualifier(CONFIG_WATCH_TASK_SCHEDULER_NAME) TaskScheduler taskScheduler) { 55 | return new ConfigWatch(properties, consul, indexes.getIndexes(), taskScheduler); 56 | } 57 | 58 | @Bean(name = CONFIG_WATCH_TASK_SCHEDULER_NAME) 59 | public TaskScheduler configWatchTaskScheduler() { 60 | return new ThreadPoolTaskScheduler(); 61 | } 62 | 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /spring-cloud-consul-config/src/test/java/org/springframework/cloud/consul/config/ConsulPropertyPrefixTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013-present 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.consul.config; 18 | 19 | import java.io.IOException; 20 | import java.security.KeyStoreException; 21 | import java.security.NoSuchAlgorithmException; 22 | import java.security.cert.CertificateException; 23 | 24 | import org.junit.After; 25 | import org.junit.Before; 26 | import org.junit.Test; 27 | 28 | import org.springframework.cloud.consul.ConsulClient; 29 | import org.springframework.cloud.consul.test.ConsulTestcontainers; 30 | 31 | import static org.assertj.core.api.Assertions.assertThat; 32 | 33 | public class ConsulPropertyPrefixTests { 34 | 35 | private ConsulClient consulClient; 36 | 37 | @Before 38 | public void setup() throws CertificateException, KeyStoreException, IOException, NoSuchAlgorithmException { 39 | ConsulTestcontainers.start(); 40 | this.consulClient = ConsulTestcontainers.client(); 41 | } 42 | 43 | @After 44 | public void teardown() { 45 | this.consulClient.deleteKVValues(""); 46 | } 47 | 48 | @Test 49 | public void testEmptyPrefix() { 50 | // because prefix is empty, a leading forward slash is omitted 51 | String kvContext = "appname"; 52 | this.consulClient.setKVValue(kvContext + "/fooprop", "fookvval"); 53 | this.consulClient.setKVValue(kvContext + "/bar/prop", "8080"); 54 | 55 | ConsulPropertySource source = getConsulPropertySource(new ConsulConfigProperties(), kvContext); 56 | assertProperties(source, "fookvval", "8080"); 57 | } 58 | 59 | private void assertProperties(ConsulPropertySource source, Object fooval, Object barval) { 60 | assertThat(source.getProperty("fooprop")).as("fooprop was wrong").isEqualTo(fooval); 61 | assertThat(source.getProperty("bar.prop")).as("bar.prop was wrong").isEqualTo(barval); 62 | } 63 | 64 | @SuppressWarnings("Duplicates") 65 | private ConsulPropertySource getConsulPropertySource(ConsulConfigProperties configProperties, String context) { 66 | ConsulPropertySource source = new ConsulPropertySource(context, this.consulClient, configProperties); 67 | source.init(); 68 | String[] names = source.getPropertyNames(); 69 | assertThat(names).as("names was null").isNotNull(); 70 | assertThat(names.length).as("names was wrong size").isEqualTo(2); 71 | return source; 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationNonWebTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013-present 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.consul.serviceregistry; 18 | 19 | import java.util.Map; 20 | 21 | import org.junit.jupiter.api.Test; 22 | 23 | import org.springframework.beans.factory.annotation.Autowired; 24 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 25 | import org.springframework.boot.test.context.SpringBootTest; 26 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 27 | import org.springframework.cloud.consul.ConsulClient; 28 | import org.springframework.cloud.consul.model.http.agent.Service; 29 | import org.springframework.cloud.consul.test.ConsulTestcontainers; 30 | import org.springframework.context.annotation.Configuration; 31 | import org.springframework.http.ResponseEntity; 32 | import org.springframework.test.context.ContextConfiguration; 33 | 34 | import static org.assertj.core.api.Assertions.assertThat; 35 | import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.NONE; 36 | 37 | /** 38 | * @author Spencer Gibb 39 | */ 40 | @SpringBootTest(classes = ConsulAutoServiceRegistrationNonWebTests.TestConfig.class, 41 | properties = { "spring.application.name=consulNonWebTest", "server.port=32111" }, webEnvironment = NONE) 42 | @ContextConfiguration(initializers = ConsulTestcontainers.class) 43 | public class ConsulAutoServiceRegistrationNonWebTests { 44 | 45 | @Autowired 46 | private ConsulClient consul; 47 | 48 | @Autowired(required = false) 49 | private ConsulAutoServiceRegistration autoServiceRegistration; 50 | 51 | @Test 52 | public void contextLoads() { 53 | assertThat(this.autoServiceRegistration).as("ConsulAutoServiceRegistration was created").isNotNull(); 54 | 55 | ResponseEntity> response = this.consul.getAgentServices(); 56 | Map services = response.getBody(); 57 | Service service = services.get("consulNonWebTest"); 58 | assertThat(service).as("service was registered").isNull(); // no port to listen, 59 | // hence no 60 | // registration 61 | } 62 | 63 | @EnableDiscoveryClient 64 | @Configuration(proxyBeanMethods = false) 65 | @EnableAutoConfiguration 66 | public static class TestConfig { 67 | 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /spring-cloud-consul-core/src/main/java/org/springframework/cloud/consul/model/http/catalog/Node.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013-present 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.consul.model.http.catalog; 18 | 19 | import java.util.Map; 20 | 21 | import com.fasterxml.jackson.annotation.JsonProperty; 22 | 23 | public class Node { 24 | 25 | @JsonProperty("ID") 26 | private String id; 27 | 28 | @JsonProperty("Node") 29 | private String node; 30 | 31 | @JsonProperty("Address") 32 | private String address; 33 | 34 | @JsonProperty("Datacenter") 35 | private String datacenter; 36 | 37 | @JsonProperty("TaggedAddresses") 38 | private Map taggedAddresses; 39 | 40 | @JsonProperty("Meta") 41 | private Map meta; 42 | 43 | @JsonProperty("CreateIndex") 44 | private Long createIndex; 45 | 46 | @JsonProperty("ModifyIndex") 47 | private Long modifyIndex; 48 | 49 | public String getId() { 50 | return id; 51 | } 52 | 53 | public void setId(String id) { 54 | this.id = id; 55 | } 56 | 57 | public String getNode() { 58 | return node; 59 | } 60 | 61 | public void setNode(String node) { 62 | this.node = node; 63 | } 64 | 65 | public String getAddress() { 66 | return address; 67 | } 68 | 69 | public void setAddress(String address) { 70 | this.address = address; 71 | } 72 | 73 | public String getDatacenter() { 74 | return datacenter; 75 | } 76 | 77 | public void setDatacenter(String datacenter) { 78 | this.datacenter = datacenter; 79 | } 80 | 81 | public Map getTaggedAddresses() { 82 | return taggedAddresses; 83 | } 84 | 85 | public void setTaggedAddresses(Map taggedAddresses) { 86 | this.taggedAddresses = taggedAddresses; 87 | } 88 | 89 | public Map getMeta() { 90 | return meta; 91 | } 92 | 93 | public void setMeta(Map meta) { 94 | this.meta = meta; 95 | } 96 | 97 | public Long getCreateIndex() { 98 | return createIndex; 99 | } 100 | 101 | public void setCreateIndex(Long createIndex) { 102 | this.createIndex = createIndex; 103 | } 104 | 105 | public Long getModifyIndex() { 106 | return modifyIndex; 107 | } 108 | 109 | public void setModifyIndex(Long modifyIndex) { 110 | this.modifyIndex = modifyIndex; 111 | } 112 | 113 | } 114 | -------------------------------------------------------------------------------- /spring-cloud-consul-discovery/src/main/java/org/springframework/cloud/consul/discovery/ConsulDiscoveryClientConfiguration.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013-present 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.consul.discovery; 18 | 19 | import org.springframework.boot.autoconfigure.AutoConfigureAfter; 20 | import org.springframework.boot.autoconfigure.AutoConfigureBefore; 21 | import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 22 | import org.springframework.boot.context.properties.EnableConfigurationProperties; 23 | import org.springframework.cloud.client.CommonsClientAutoConfiguration; 24 | import org.springframework.cloud.client.ConditionalOnBlockingDiscoveryEnabled; 25 | import org.springframework.cloud.client.ConditionalOnDiscoveryEnabled; 26 | import org.springframework.cloud.client.discovery.simple.SimpleDiscoveryClientAutoConfiguration; 27 | import org.springframework.cloud.commons.util.InetUtils; 28 | import org.springframework.cloud.commons.util.UtilAutoConfiguration; 29 | import org.springframework.cloud.consul.ConditionalOnConsulEnabled; 30 | import org.springframework.cloud.consul.ConsulAutoConfiguration; 31 | import org.springframework.cloud.consul.ConsulClient; 32 | import org.springframework.context.annotation.Bean; 33 | import org.springframework.context.annotation.Configuration; 34 | 35 | /** 36 | * @author Spencer Gibb 37 | * @author Olga Maciaszek-Sharma 38 | * @author Tim Ysewyn 39 | */ 40 | @Configuration(proxyBeanMethods = false) 41 | @ConditionalOnDiscoveryEnabled 42 | @ConditionalOnBlockingDiscoveryEnabled 43 | @ConditionalOnConsulEnabled 44 | @ConditionalOnConsulDiscoveryEnabled 45 | @EnableConfigurationProperties 46 | @AutoConfigureBefore({ SimpleDiscoveryClientAutoConfiguration.class, CommonsClientAutoConfiguration.class }) 47 | @AutoConfigureAfter({ UtilAutoConfiguration.class, ConsulAutoConfiguration.class }) 48 | public class ConsulDiscoveryClientConfiguration { 49 | 50 | @Bean 51 | @ConditionalOnMissingBean 52 | public ConsulDiscoveryProperties consulDiscoveryProperties(InetUtils inetUtils) { 53 | return new ConsulDiscoveryProperties(inetUtils); 54 | } 55 | 56 | @Bean 57 | @ConditionalOnMissingBean 58 | public ConsulDiscoveryClient consulDiscoveryClient(ConsulClient consulClient, 59 | ConsulDiscoveryProperties discoveryProperties) { 60 | return new ConsulDiscoveryClient(consulClient, discoveryProperties); 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulServiceRegistryDisabledTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013-present 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.consul.serviceregistry; 18 | 19 | import java.util.Map; 20 | 21 | import org.junit.jupiter.api.Test; 22 | 23 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 24 | import org.springframework.boot.test.context.runner.WebApplicationContextRunner; 25 | import org.springframework.cloud.consul.ConsulClient; 26 | import org.springframework.cloud.consul.discovery.HeartbeatProperties; 27 | import org.springframework.cloud.consul.model.http.agent.Service; 28 | import org.springframework.cloud.consul.test.ConsulTestcontainers; 29 | import org.springframework.context.annotation.Configuration; 30 | import org.springframework.http.ResponseEntity; 31 | 32 | import static org.assertj.core.api.Assertions.assertThat; 33 | 34 | /** 35 | * @author Spencer Gibb 36 | */ 37 | public class ConsulServiceRegistryDisabledTests { 38 | 39 | @Test 40 | public void disabledViaSpringCloudProperty() { 41 | testAutoRegistrationDisabled("serviceRegistryDisabledTest1", "spring.cloud.service-registry.enabled"); 42 | } 43 | 44 | @Test 45 | public void disabledViaConsulProperty() { 46 | testAutoRegistrationDisabled("serviceRegistryDisabledTest2", "spring.cloud.consul.service-registry.enabled"); 47 | } 48 | 49 | private void testAutoRegistrationDisabled(String testName, String disableProperty) { 50 | new WebApplicationContextRunner().withUserConfiguration(TestConfig.class) 51 | .withPropertyValues("spring.application.name=" + testName, disableProperty + "=false", "server.port=0") 52 | .withInitializer(new ConsulTestcontainers()) 53 | .run(context -> { 54 | assertThat(context).doesNotHaveBean(ConsulServiceRegistry.class); 55 | assertThat(context).doesNotHaveBean(HeartbeatProperties.class); 56 | 57 | ConsulClient consul = context.getBean(ConsulClient.class); 58 | 59 | ResponseEntity> response = consul.getAgentServices(); 60 | Map services = response.getBody(); 61 | Service service = services.get(testName); 62 | assertThat(service).as("service was registered").isNull(); 63 | }); 64 | } 65 | 66 | @Configuration(proxyBeanMethods = false) 67 | @EnableAutoConfiguration 68 | public static class TestConfig { 69 | 70 | } 71 | 72 | } 73 | -------------------------------------------------------------------------------- /spring-cloud-consul-core/src/main/java/org/springframework/cloud/consul/RetryProperties.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013-present 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.consul; 18 | 19 | import org.springframework.boot.context.properties.ConfigurationProperties; 20 | import org.springframework.core.style.ToStringCreator; 21 | 22 | /** 23 | * @author Spencer Gibb 24 | */ 25 | @ConfigurationProperties(RetryProperties.PREFIX) 26 | public class RetryProperties { 27 | 28 | /** 29 | * Consul Retry Properties prefix. 30 | */ 31 | public static final String PREFIX = "spring.cloud.consul.retry"; 32 | 33 | /** If consul retry is enabled. */ 34 | private boolean enabled = true; 35 | 36 | /** Initial retry interval in milliseconds. */ 37 | private long initialInterval = 1000; 38 | 39 | /** Multiplier for next interval. */ 40 | private double multiplier = 1.1; 41 | 42 | /** Maximum interval for backoff. */ 43 | private long maxInterval = 2000; 44 | 45 | /** Maximum number of attempts. */ 46 | private int maxAttempts = 6; 47 | 48 | public RetryProperties() { 49 | } 50 | 51 | public boolean isEnabled() { 52 | return this.enabled; 53 | } 54 | 55 | public void setEnabled(boolean enabled) { 56 | this.enabled = enabled; 57 | } 58 | 59 | public long getInitialInterval() { 60 | return this.initialInterval; 61 | } 62 | 63 | public void setInitialInterval(long initialInterval) { 64 | this.initialInterval = initialInterval; 65 | } 66 | 67 | public double getMultiplier() { 68 | return this.multiplier; 69 | } 70 | 71 | public void setMultiplier(double multiplier) { 72 | this.multiplier = multiplier; 73 | } 74 | 75 | public long getMaxInterval() { 76 | return this.maxInterval; 77 | } 78 | 79 | public void setMaxInterval(long maxInterval) { 80 | this.maxInterval = maxInterval; 81 | } 82 | 83 | public int getMaxAttempts() { 84 | return this.maxAttempts; 85 | } 86 | 87 | public void setMaxAttempts(int maxAttempts) { 88 | this.maxAttempts = maxAttempts; 89 | } 90 | 91 | @Override 92 | public String toString() { 93 | return new ToStringCreator(this).append("enabled", this.enabled) 94 | .append("initialInterval", this.initialInterval) 95 | .append("multiplier", this.multiplier) 96 | .append("maxInterval", this.maxInterval) 97 | .append("maxAttempts", this.maxAttempts) 98 | .toString(); 99 | } 100 | 101 | } 102 | -------------------------------------------------------------------------------- /spring-cloud-consul-binder/src/main/java/org/springframework/cloud/consul/binder/ConsulBinder.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013-present 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.consul.binder; 18 | 19 | import org.springframework.cloud.stream.binder.AbstractBinder; 20 | import org.springframework.cloud.stream.binder.Binding; 21 | import org.springframework.cloud.stream.binder.ConsumerProperties; 22 | import org.springframework.cloud.stream.binder.DefaultBinding; 23 | import org.springframework.cloud.stream.binder.ProducerProperties; 24 | import org.springframework.integration.endpoint.EventDrivenConsumer; 25 | import org.springframework.messaging.MessageChannel; 26 | import org.springframework.messaging.SubscribableChannel; 27 | import org.springframework.util.Assert; 28 | 29 | /** 30 | * @author Spencer Gibb 31 | */ 32 | public class ConsulBinder extends AbstractBinder { 33 | 34 | private static final String BEAN_NAME_TEMPLATE = "outbound.%s"; 35 | 36 | private final EventService eventService; 37 | 38 | public ConsulBinder(EventService eventService) { 39 | this.eventService = eventService; 40 | } 41 | 42 | @Override 43 | protected Binding doBindConsumer(String name, String group, MessageChannel inputChannel, 44 | ConsumerProperties properties) { 45 | ConsulInboundMessageProducer messageProducer = new ConsulInboundMessageProducer(this.eventService); 46 | messageProducer.setOutputChannel(inputChannel); 47 | messageProducer.setBeanFactory(this.getBeanFactory()); 48 | messageProducer.afterPropertiesSet(); 49 | messageProducer.start(); 50 | 51 | return new DefaultBinding<>(name, group, inputChannel, messageProducer); 52 | } 53 | 54 | @Override 55 | protected Binding doBindProducer(String name, MessageChannel channel, 56 | ProducerProperties properties) { 57 | Assert.isInstanceOf(SubscribableChannel.class, channel); 58 | 59 | this.logger.debug("Binding Consul client to eventName " + name); 60 | ConsulSendingHandler sendingHandler = new ConsulSendingHandler(this.eventService.getConsulClient(), name); 61 | 62 | EventDrivenConsumer consumer = new EventDrivenConsumer((SubscribableChannel) channel, sendingHandler); 63 | consumer.setBeanFactory(getBeanFactory()); 64 | consumer.setBeanName(String.format(BEAN_NAME_TEMPLATE, name)); 65 | consumer.afterPropertiesSet(); 66 | consumer.start(); 67 | 68 | return new DefaultBinding<>(name, null, channel, consumer); 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoRegistrationCheckTtlDeregisterCriticalServiceTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013-present 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.consul.serviceregistry; 18 | 19 | import org.junit.jupiter.api.Test; 20 | 21 | import org.springframework.beans.factory.annotation.Autowired; 22 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 23 | import org.springframework.boot.autoconfigure.ImportAutoConfiguration; 24 | import org.springframework.boot.test.context.SpringBootTest; 25 | import org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationConfiguration; 26 | import org.springframework.cloud.consul.ConsulAutoConfiguration; 27 | import org.springframework.cloud.consul.model.http.agent.NewService; 28 | import org.springframework.cloud.consul.support.ConsulHeartbeatAutoConfiguration; 29 | import org.springframework.cloud.consul.test.ConsulTestcontainers; 30 | import org.springframework.context.annotation.Configuration; 31 | import org.springframework.test.context.ContextConfiguration; 32 | 33 | import static org.assertj.core.api.Assertions.assertThat; 34 | 35 | /** 36 | * @author Niko Tung 37 | */ 38 | @SpringBootTest(classes = ConsulAutoRegistrationCheckTtlDeregisterCriticalServiceTests.TestConfig.class, 39 | properties = { "spring.application.name=myConsulServiceRegistryHealthCheckTtlDeregisterCriticalServiceAfter-N", 40 | "spring.cloud.consul.discovery.health-check-critical-timeout=1m", 41 | "spring.cloud.consul.discovery.heartbeat.enabled=true" }, 42 | webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) 43 | @ContextConfiguration(initializers = ConsulTestcontainers.class) 44 | public class ConsulAutoRegistrationCheckTtlDeregisterCriticalServiceTests { 45 | 46 | @Autowired 47 | private ConsulRegistration registration; 48 | 49 | @Test 50 | public void contextLoads() { 51 | NewService service = registration.getService(); 52 | assertThat("1m".equals(service.getCheck().getDeregisterCriticalServiceAfter())) 53 | .as("Service with heartbeat check and deregister critical timeout registered") 54 | .isTrue(); 55 | } 56 | 57 | @Configuration(proxyBeanMethods = false) 58 | @EnableAutoConfiguration 59 | @ImportAutoConfiguration({ AutoServiceRegistrationConfiguration.class, ConsulAutoConfiguration.class, 60 | ConsulAutoServiceRegistrationAutoConfiguration.class, ConsulHeartbeatAutoConfiguration.class }) 61 | protected static class TestConfig { 62 | 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationRetryTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013-present 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.consul.serviceregistry; 18 | 19 | import org.junit.jupiter.api.Test; 20 | import org.junit.jupiter.api.extension.ExtendWith; 21 | 22 | import org.springframework.boot.SpringBootConfiguration; 23 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 24 | import org.springframework.boot.autoconfigure.ImportAutoConfiguration; 25 | import org.springframework.boot.builder.SpringApplicationBuilder; 26 | import org.springframework.boot.test.system.CapturedOutput; 27 | import org.springframework.boot.test.system.OutputCaptureExtension; 28 | import org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationConfiguration; 29 | import org.springframework.cloud.consul.ConsulAutoConfiguration; 30 | import org.springframework.cloud.consul.test.ConsulTestcontainers; 31 | import org.springframework.context.ConfigurableApplicationContext; 32 | import org.springframework.test.annotation.DirtiesContext; 33 | import org.springframework.test.context.ContextConfiguration; 34 | 35 | import static org.assertj.core.api.Assertions.assertThat; 36 | import static org.assertj.core.api.Assertions.assertThatThrownBy; 37 | 38 | /** 39 | * @author Spencer Gibb 40 | * @author Venil Noronha 41 | */ 42 | @DirtiesContext 43 | @ContextConfiguration(initializers = ConsulTestcontainers.class) 44 | @ExtendWith(OutputCaptureExtension.class) 45 | public class ConsulAutoServiceRegistrationRetryTests { 46 | 47 | // @Disabled 48 | @Test 49 | public void testRetry(CapturedOutput output) { 50 | assertThatThrownBy(() -> { 51 | try (ConfigurableApplicationContext context = new SpringApplicationBuilder(TestConfig.class) 52 | .properties("spring.application.name=testregistrationretry", 53 | "spring.jmx.default-domain=testautoregretry", "spring.cloud.consul.retry.max-attempts=2", 54 | "logging.level.org.springframework.retry=DEBUG", "server.port=0") 55 | .run()) { 56 | // try with resources 57 | } 58 | }).cause().hasMessageContaining("Connection refused"); 59 | assertThat(output).contains("Retry: count="); 60 | } 61 | 62 | @SpringBootConfiguration 63 | @EnableAutoConfiguration 64 | @ImportAutoConfiguration({ AutoServiceRegistrationConfiguration.class, ConsulAutoConfiguration.class, 65 | ConsulAutoServiceRegistrationAutoConfiguration.class }) 66 | protected static class TestConfig { 67 | 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationDefaultPortTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013-present 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.consul.serviceregistry; 18 | 19 | import java.util.Map; 20 | 21 | import org.junit.jupiter.api.Test; 22 | 23 | import org.springframework.beans.factory.annotation.Autowired; 24 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 25 | import org.springframework.boot.autoconfigure.ImportAutoConfiguration; 26 | import org.springframework.boot.test.context.SpringBootTest; 27 | import org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationConfiguration; 28 | import org.springframework.cloud.consul.ConsulAutoConfiguration; 29 | import org.springframework.cloud.consul.ConsulClient; 30 | import org.springframework.cloud.consul.model.http.agent.Service; 31 | import org.springframework.cloud.consul.test.ConsulTestcontainers; 32 | import org.springframework.context.annotation.Configuration; 33 | import org.springframework.http.ResponseEntity; 34 | import org.springframework.test.context.ContextConfiguration; 35 | 36 | import static org.assertj.core.api.Assertions.assertThat; 37 | import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; 38 | 39 | /** 40 | * @author Spencer Gibb 41 | */ 42 | @SpringBootTest(classes = ConsulAutoServiceRegistrationDefaultPortTests.TestConfig.class, 43 | properties = { "spring.application.name=myTestService2-DD", 44 | "spring.cloud.consul.discovery.instanceId=myTestService2-DD" }, 45 | webEnvironment = RANDOM_PORT) 46 | @ContextConfiguration(initializers = ConsulTestcontainers.class) 47 | public class ConsulAutoServiceRegistrationDefaultPortTests { 48 | 49 | @Autowired 50 | private ConsulClient consul; 51 | 52 | @Test 53 | public void contextLoads() { 54 | ResponseEntity> response = this.consul.getAgentServices(); 55 | Map services = response.getBody(); 56 | Service service = services.get("myTestService2-DD"); 57 | assertThat(service).as("service was null").isNotNull(); 58 | assertThat(service.getPort().intValue()).as("service port is 0").isNotEqualTo(0); 59 | } 60 | 61 | @Configuration(proxyBeanMethods = false) 62 | @EnableAutoConfiguration 63 | @ImportAutoConfiguration({ AutoServiceRegistrationConfiguration.class, ConsulAutoConfiguration.class, 64 | ConsulAutoServiceRegistrationAutoConfiguration.class }) 65 | public static class TestConfig { 66 | 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /spring-cloud-consul-config/src/test/java/org/springframework/cloud/consul/config/ConsulConfigBootstrapConfigurationTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013-present 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.consul.config; 18 | 19 | import java.util.Collections; 20 | 21 | import org.junit.Test; 22 | 23 | import org.springframework.boot.test.context.runner.ApplicationContextRunner; 24 | import org.springframework.cloud.consul.test.ConsulTestcontainers; 25 | import org.springframework.context.annotation.Bean; 26 | 27 | import static org.assertj.core.api.Assertions.assertThat; 28 | 29 | /** 30 | * @author Edvin Eriksson 31 | */ 32 | public class ConsulConfigBootstrapConfigurationTests { 33 | 34 | private final ApplicationContextRunner contextRunner = new ApplicationContextRunner(); 35 | 36 | /** 37 | * Tests that the auto-config bean backs off if a user provided their own. 38 | */ 39 | @Test 40 | public void testConfigPropsBeanBacksOff() { 41 | this.contextRunner.withUserConfiguration(TestConfig.class) 42 | .withInitializer(new ConsulTestcontainers()) 43 | .withUserConfiguration(ConsulConfigBootstrapConfiguration.class) 44 | .run(context -> { 45 | ConsulConfigProperties config = context.getBean(ConsulConfigProperties.class); 46 | assertThat(config.getPrefixes().get(0)).as("Prefix did not match").isEqualTo("platform-config"); 47 | assertThat(config.getDefaultContext()).as("Default context did not match").isEqualTo("defaults"); 48 | }); 49 | } 50 | 51 | /** 52 | * Tests that the auto-config bean kicks in if the user did not provide any custom 53 | * bean. 54 | */ 55 | @Test 56 | public void testConfigPropsBeanKicksIn() { 57 | this.contextRunner.withUserConfiguration(ConsulConfigBootstrapConfiguration.class) 58 | .withInitializer(new ConsulTestcontainers()) 59 | .run(context -> { 60 | ConsulConfigProperties config = context.getBean(ConsulConfigProperties.class); 61 | assertThat(config.getPrefixes().get(0)).as("Prefix did not match").isEqualTo("config"); 62 | assertThat(config.getDefaultContext()).as("Default context did not match").isEqualTo("application"); 63 | }); 64 | } 65 | 66 | /** 67 | * Test config that simulates a "user provided bean". 68 | */ 69 | private static final class TestConfig { 70 | 71 | @Bean 72 | public ConsulConfigProperties consulConfigProperties() { 73 | ConsulConfigProperties config = new ConsulConfigProperties(); 74 | config.setPrefixes(Collections.singletonList("platform-config")); 75 | config.setDefaultContext("defaults"); 76 | return config; 77 | } 78 | 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoServiceRegistrationCustomizedServletContextTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013-present 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.consul.serviceregistry; 18 | 19 | import java.util.Map; 20 | 21 | import org.junit.jupiter.api.Test; 22 | 23 | import org.springframework.beans.factory.annotation.Autowired; 24 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 25 | import org.springframework.boot.test.context.SpringBootTest; 26 | import org.springframework.cloud.client.discovery.EnableDiscoveryClient; 27 | import org.springframework.cloud.consul.ConsulClient; 28 | import org.springframework.cloud.consul.model.http.agent.Service; 29 | import org.springframework.cloud.consul.test.ConsulTestcontainers; 30 | import org.springframework.context.annotation.Configuration; 31 | import org.springframework.http.ResponseEntity; 32 | import org.springframework.test.context.ContextConfiguration; 33 | 34 | import static org.assertj.core.api.Assertions.assertThat; 35 | import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; 36 | 37 | /** 38 | * @author Piotr Wielgolaski 39 | */ 40 | @SpringBootTest(classes = ConsulAutoServiceRegistrationCustomizedServletContextTests.TestConfig.class, 41 | properties = { "spring.application.name=myTestService-WithServletContext", 42 | "spring.cloud.consul.discovery.instanceId=myTestService1-WithServletContext", 43 | "server.servlet.context-path=/customContext" }, 44 | webEnvironment = RANDOM_PORT) 45 | @ContextConfiguration(initializers = ConsulTestcontainers.class) 46 | public class ConsulAutoServiceRegistrationCustomizedServletContextTests { 47 | 48 | @Autowired 49 | private ConsulClient consul; 50 | 51 | @Test 52 | public void contextLoads() { 53 | ResponseEntity> response = this.consul.getAgentServices(); 54 | Map services = response.getBody(); 55 | Service service = services.get("myTestService1-WithServletContext"); 56 | assertThat(service).as("service was null").isNotNull(); 57 | assertThat(service.getPort().intValue()).as("service port is 0").isNotEqualTo(0); 58 | assertThat(service.getId()).as("service id was wrong").isEqualTo("myTestService1-WithServletContext"); 59 | assertThat(service.getTags()).as("contextPath tag missing").contains("contextPath=/customContext"); 60 | } 61 | 62 | @EnableDiscoveryClient 63 | @Configuration(proxyBeanMethods = false) 64 | @EnableAutoConfiguration 65 | public static class TestConfig { 66 | 67 | } 68 | 69 | } 70 | -------------------------------------------------------------------------------- /spring-cloud-consul-discovery/src/test/java/org/springframework/cloud/consul/serviceregistry/ConsulAutoRegistrationHealthCheckTlsSkipVerifyTests.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2013-present 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.consul.serviceregistry; 18 | 19 | import org.junit.jupiter.api.Test; 20 | 21 | import org.springframework.beans.factory.annotation.Autowired; 22 | import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 23 | import org.springframework.boot.autoconfigure.ImportAutoConfiguration; 24 | import org.springframework.boot.test.context.SpringBootTest; 25 | import org.springframework.cloud.client.serviceregistry.AutoServiceRegistrationConfiguration; 26 | import org.springframework.cloud.consul.ConsulAutoConfiguration; 27 | import org.springframework.cloud.consul.discovery.ConsulDiscoveryProperties; 28 | import org.springframework.cloud.consul.model.http.agent.NewService; 29 | import org.springframework.cloud.consul.test.ConsulTestcontainers; 30 | import org.springframework.context.annotation.Configuration; 31 | import org.springframework.test.context.ContextConfiguration; 32 | 33 | import static org.assertj.core.api.Assertions.assertThat; 34 | import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT; 35 | 36 | /** 37 | * @author Patrick Hi 38 | */ 39 | @SpringBootTest(classes = ConsulAutoRegistrationHealthCheckTlsSkipVerifyTests.TestConfig.class, 40 | properties = { "spring.application.name=myTestService-DiscoveryHealthCheckTlsSkipVerify", 41 | "spring.cloud.consul.discovery.health-check-tls-skip-verify=true" }, 42 | webEnvironment = RANDOM_PORT) 43 | @ContextConfiguration(initializers = ConsulTestcontainers.class) 44 | public class ConsulAutoRegistrationHealthCheckTlsSkipVerifyTests { 45 | 46 | @Autowired 47 | private ConsulAutoRegistration registration; 48 | 49 | @Autowired 50 | private ConsulDiscoveryProperties properties; 51 | 52 | @Test 53 | public void contextLoads() { 54 | NewService service = this.registration.getService(); 55 | assertThat(service).as("service was null").isNotNull(); 56 | 57 | NewService.Check check = service.getCheck(); 58 | assertThat(check).as("check was null").isNotNull(); 59 | assertThat(check.getTlsSkipVerify()).as("tls_skip_verify was wrong").isEqualTo(Boolean.TRUE); 60 | 61 | // unable to call consul api to get health check details 62 | } 63 | 64 | @Configuration(proxyBeanMethods = false) 65 | @EnableAutoConfiguration 66 | @ImportAutoConfiguration({ AutoServiceRegistrationConfiguration.class, ConsulAutoConfiguration.class, 67 | ConsulAutoServiceRegistrationAutoConfiguration.class }) 68 | public static class TestConfig { 69 | 70 | } 71 | 72 | } 73 | --------------------------------------------------------------------------------