Compare commits

...
121 Commits
Author SHA1 Message Date
spring-builds 08e02ad0c9 Update SNAPSHOT to 5.0.2 2026-06-11 15:33:23 +00:00
Ryan Baxter c0d9f1fa5c Using new PR workflow 2026-06-01 19:48:25 -04:00
Ryan Baxter daab658d8f Merge pull request #4573 from spring-cloud/dependabot/npm_and_yarn/docs/main/springio/antora-extensions-1.14.12
Bump @springio/antora-extensions from 1.14.11 to 1.14.12 in /docs
2026-06-01 09:11:44 -04:00
dependabot[bot] be1e756370 Bump @springio/antora-extensions from 1.14.11 to 1.14.12 in /docs
Bumps [@springio/antora-extensions](https://github.com/spring-io/antora-extensions) from 1.14.11 to 1.14.12.
- [Changelog](https://github.com/spring-io/antora-extensions/blob/main/CHANGELOG.adoc)
- [Commits](https://github.com/spring-io/antora-extensions/compare/v1.14.11...v1.14.12)

---
updated-dependencies:
- dependency-name: "@springio/antora-extensions"
  dependency-version: 1.14.12
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-28 18:52:27 +00:00
spring-builds 7878fb5f8a Bumping versions 2026-05-28 14:57:27 +00:00
Ryan Baxter 3f36565a36 Upgrading antora to 3.2.0-alpha.12 2026-05-17 17:20:25 -04:00
spring-builds 1a381ddc93 Bumping versions 2026-05-14 10:28:37 +00:00
Ryan Baxter b6353637c9 Merge pull request #4560 from spring-cloud/dependabot/maven/main/org.springframework.cloud-spring-cloud-config-dependencies-5.0.3
Bump org.springframework.cloud:spring-cloud-config-dependencies from 5.0.3-SNAPSHOT to 5.0.3
2026-05-06 14:08:43 -04:00
dependabot[bot] 253f9c1d18 Bump org.springframework.cloud:spring-cloud-config-dependencies
Bumps [org.springframework.cloud:spring-cloud-config-dependencies](https://github.com/spring-cloud/spring-cloud-build) from 5.0.3-SNAPSHOT to 5.0.3.
- [Release notes](https://github.com/spring-cloud/spring-cloud-build/releases)
- [Commits](https://github.com/spring-cloud/spring-cloud-build/commits)

---
updated-dependencies:
- dependency-name: org.springframework.cloud:spring-cloud-config-dependencies
  dependency-version: 5.0.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-05-06 16:44:36 +00:00
Ryan Baxter c1af2d65e9 Merge pull request #4558 from spring-cloud/dependabot/npm_and_yarn/docs/main/springio/antora-extensions-1.14.11 2026-04-09 13:27:23 -04:00
dependabot[bot] 49476de4c8 Bump @springio/antora-extensions from 1.14.10 to 1.14.11 in /docs
Bumps [@springio/antora-extensions](https://github.com/spring-io/antora-extensions) from 1.14.10 to 1.14.11.
- [Changelog](https://github.com/spring-io/antora-extensions/blob/main/CHANGELOG.adoc)
- [Commits](https://github.com/spring-io/antora-extensions/compare/v1.14.10...v1.14.11)

---
updated-dependencies:
- dependency-name: "@springio/antora-extensions"
  dependency-version: 1.14.11
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-09 16:44:41 +00:00
Ryan Baxter 77b73b65f9 Merge pull request #4553 from spring-cloud/dependabot/npm_and_yarn/docs/main/springio/antora-extensions-1.14.10 2026-04-02 13:01:44 -04:00
dependabot[bot] cfbaef0c50 Bump @springio/antora-extensions from 1.14.9 to 1.14.10 in /docs
Bumps [@springio/antora-extensions](https://github.com/spring-io/antora-extensions) from 1.14.9 to 1.14.10.
- [Changelog](https://github.com/spring-io/antora-extensions/blob/main/CHANGELOG.adoc)
- [Commits](https://github.com/spring-io/antora-extensions/compare/v1.14.9...v1.14.10)

---
updated-dependencies:
- dependency-name: "@springio/antora-extensions"
  dependency-version: 1.14.10
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-04-02 16:44:01 +00:00
Ryan Baxter 95441aef81 Merge branch '4.3.x' 2026-04-01 10:28:44 -04:00
Ryan Baxter 127f659c4c Merge pull request #4549 from ryanjbaxter/webclient-application-deregister
Use own connectionprovider and loopresources for WebClient
2026-04-01 10:27:04 -04:00
Ryan Baxter 79b7b91a03 Use own connectionprovider and loopresources for WebClient
When eureka.client.webclient.enabled=true is used with a reactive web server (Netty), the WebClient in WebClientEurekaHttpClient shares the same Reactor Netty event loop
  resources (LoopResources / ConnectionProvider) with the reactive web server, via Spring Boot's ReactorResourceFactory.
  During graceful shutdown, the sequence is:
  1. EurekaServiceRegistry.deregister() sets the instance status to DOWN (but doesn't send the actual DELETE)
  2. The reactive Netty web server shuts down, terminating its event loop
  3. Later, during bean destruction, DiscoveryClient.shutdown() calls WebClientEurekaHttpClient.cancel() to send the DELETE deregistration request
  4. cancel() calls Mono.block() on the WebClient, which tries to use the now-terminated Netty event loop → RejectedExecutionException: event executor terminated

Fixes #4488
2026-04-01 10:10:50 -04:00
spring-builds c225462df7 Bumping versions 2026-03-29 14:44:51 +00:00
Ryan Baxter 0855dd64ac Merge pull request #4547 from spring-cloud/dependabot/maven/main/eureka.version-2.0.6
Bump eureka.version from 2.0.5 to 2.0.6
2026-03-27 17:24:39 -04:00
Ryan Baxter 702705b430 Merge pull request #4548 from spring-cloud/dependabot/maven/4.3.x/eureka.version-2.0.6
Bump eureka.version from 2.0.5 to 2.0.6
2026-03-27 17:24:14 -04:00
spencergibb cae32c8d53 Merge branch '4.3.x' 2026-03-27 12:58:38 -04:00
spencergibb 1974458749 Exclude commons-configuration from eureka-client
Also removes libs-*-local bits from repositories

Fixes gh-4457
2026-03-27 12:55:33 -04:00
dependabot[bot] f43fbc9f7b Bump eureka.version from 2.0.5 to 2.0.6
Bumps `eureka.version` from 2.0.5 to 2.0.6.

Updates `com.netflix.eureka:eureka-client` from 2.0.5 to 2.0.6
- [Release notes](https://github.com/Netflix/eureka/releases)
- [Commits](https://github.com/Netflix/eureka/compare/v2.0.5...v2.0.6)

Updates `com.netflix.eureka:eureka-core` from 2.0.5 to 2.0.6
- [Release notes](https://github.com/Netflix/eureka/releases)
- [Commits](https://github.com/Netflix/eureka/compare/v2.0.5...v2.0.6)

Updates `com.netflix.eureka:eureka-core-jersey3` from 2.0.5 to 2.0.6
- [Release notes](https://github.com/Netflix/eureka/releases)
- [Commits](https://github.com/Netflix/eureka/compare/v2.0.5...v2.0.6)

Updates `com.netflix.eureka:eureka-client-jersey3` from 2.0.5 to 2.0.6
- [Release notes](https://github.com/Netflix/eureka/releases)
- [Commits](https://github.com/Netflix/eureka/compare/v2.0.5...v2.0.6)

---
updated-dependencies:
- dependency-name: com.netflix.eureka:eureka-client
  dependency-version: 2.0.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: com.netflix.eureka:eureka-core
  dependency-version: 2.0.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: com.netflix.eureka:eureka-core-jersey3
  dependency-version: 2.0.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: com.netflix.eureka:eureka-client-jersey3
  dependency-version: 2.0.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-27 16:44:38 +00:00
dependabot[bot] c0e31237f2 Bump eureka.version from 2.0.5 to 2.0.6
Bumps `eureka.version` from 2.0.5 to 2.0.6.

Updates `com.netflix.eureka:eureka-client` from 2.0.5 to 2.0.6
- [Release notes](https://github.com/Netflix/eureka/releases)
- [Commits](https://github.com/Netflix/eureka/compare/v2.0.5...v2.0.6)

Updates `com.netflix.eureka:eureka-core` from 2.0.5 to 2.0.6
- [Release notes](https://github.com/Netflix/eureka/releases)
- [Commits](https://github.com/Netflix/eureka/compare/v2.0.5...v2.0.6)

Updates `com.netflix.eureka:eureka-core-jersey3` from 2.0.5 to 2.0.6
- [Release notes](https://github.com/Netflix/eureka/releases)
- [Commits](https://github.com/Netflix/eureka/compare/v2.0.5...v2.0.6)

Updates `com.netflix.eureka:eureka-client-jersey3` from 2.0.5 to 2.0.6
- [Release notes](https://github.com/Netflix/eureka/releases)
- [Commits](https://github.com/Netflix/eureka/compare/v2.0.5...v2.0.6)

---
updated-dependencies:
- dependency-name: com.netflix.eureka:eureka-client
  dependency-version: 2.0.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: com.netflix.eureka:eureka-core
  dependency-version: 2.0.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: com.netflix.eureka:eureka-core-jersey3
  dependency-version: 2.0.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: com.netflix.eureka:eureka-client-jersey3
  dependency-version: 2.0.6
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-27 16:43:29 +00:00
Ryan Baxter ad03f7f924 Merge pull request #4546 from spring-cloud/dependabot/github_actions/4.3.x/codecov/codecov-action-6 2026-03-26 13:42:40 -04:00
dependabot[bot] 28402d65f7 Bump codecov/codecov-action from 5 to 6
Bumps [codecov/codecov-action](https://github.com/codecov/codecov-action) from 5 to 6.
- [Release notes](https://github.com/codecov/codecov-action/releases)
- [Changelog](https://github.com/codecov/codecov-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/codecov/codecov-action/compare/v5...v6)

---
updated-dependencies:
- dependency-name: codecov/codecov-action
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-26 16:44:24 +00:00
Ryan Baxter 0a8435a2b0 Update workflow to remove push trigger
Removed push trigger for specific branches.

Signed-off-by: Ryan Baxter <rbaxter85@gmail.com>
2026-03-25 16:21:55 -04:00
Ryan Baxter 7d8864c45b Add CI workflow for Spring Cloud Netflix
Signed-off-by: Ryan Baxter <rbaxter85@gmail.com>
2026-03-25 16:03:15 -04:00
Ryan Baxter 92e355543b Update spring-cloud-config.version to 5.0.3-SNAPSHOT
Signed-off-by: Ryan Baxter <rbaxter85@gmail.com>
2026-03-24 15:39:43 -04:00
Ryan Baxter 7818b881db Merge pull request #4539 from spring-cloud/dependabot/npm_and_yarn/docs/main/springio/antora-extensions-1.14.9
Bump @springio/antora-extensions from 1.14.7 to 1.14.9 in /docs
2026-03-19 14:37:35 -04:00
Ryan Baxter 5620205eaa Merge pull request #4542 from spring-cloud/dependabot/npm_and_yarn/docs/4.3.x/springio/antora-extensions-1.14.9
Bump @springio/antora-extensions from 1.14.7 to 1.14.9 in /docs
2026-03-19 14:37:23 -04:00
dependabot[bot] 7b6f8cb37c Bump @springio/antora-extensions from 1.14.7 to 1.14.9 in /docs
Bumps [@springio/antora-extensions](https://github.com/spring-io/antora-extensions) from 1.14.7 to 1.14.9.
- [Changelog](https://github.com/spring-io/antora-extensions/blob/main/CHANGELOG.adoc)
- [Commits](https://github.com/spring-io/antora-extensions/compare/v1.14.7...v1.14.9)

---
updated-dependencies:
- dependency-name: "@springio/antora-extensions"
  dependency-version: 1.14.9
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-19 18:32:17 +00:00
dependabot[bot] 6aa989eb18 Bump @springio/antora-extensions from 1.14.7 to 1.14.9 in /docs
Bumps [@springio/antora-extensions](https://github.com/spring-io/antora-extensions) from 1.14.7 to 1.14.9.
- [Changelog](https://github.com/spring-io/antora-extensions/blob/main/CHANGELOG.adoc)
- [Commits](https://github.com/spring-io/antora-extensions/compare/v1.14.7...v1.14.9)

---
updated-dependencies:
- dependency-name: "@springio/antora-extensions"
  dependency-version: 1.14.9
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-19 18:31:34 +00:00
Ryan Baxter e11f7d7621 Merge pull request #4543 from spring-cloud/dependabot/npm_and_yarn/docs/4.3.x/springio/asciidoctor-extensions-1.0.0-alpha.18
Bump @springio/asciidoctor-extensions from 1.0.0-alpha.17 to 1.0.0-alpha.18 in /docs
2026-03-19 14:30:55 -04:00
Ryan Baxter 55d1253d38 Merge pull request #4536 from spring-cloud/dependabot/maven/main/org.webjars.npm-jquery-3.6.4
Bump org.webjars.npm:jquery from 3.6.0 to 3.6.4
2026-03-19 14:30:36 -04:00
Ryan Baxter ced9207db9 Merge pull request #4541 from spring-cloud/dependabot/npm_and_yarn/docs/main/springio/asciidoctor-extensions-1.0.0-alpha.18
Bump @springio/asciidoctor-extensions from 1.0.0-alpha.17 to 1.0.0-alpha.18 in /docs
2026-03-19 14:30:28 -04:00
dependabot[bot] b1c4d9a2a5 Bump @springio/asciidoctor-extensions in /docs
Bumps [@springio/asciidoctor-extensions](https://github.com/spring-io/asciidoctor-extensions) from 1.0.0-alpha.17 to 1.0.0-alpha.18.
- [Changelog](https://github.com/spring-io/asciidoctor-extensions/blob/main/CHANGELOG.adoc)
- [Commits](https://github.com/spring-io/asciidoctor-extensions/compare/v1.0.0-alpha.17...v1.0.0-alpha.18)

---
updated-dependencies:
- dependency-name: "@springio/asciidoctor-extensions"
  dependency-version: 1.0.0-alpha.18
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-19 16:46:00 +00:00
dependabot[bot] 8060bd35a7 Bump @springio/asciidoctor-extensions in /docs
Bumps [@springio/asciidoctor-extensions](https://github.com/spring-io/asciidoctor-extensions) from 1.0.0-alpha.17 to 1.0.0-alpha.18.
- [Changelog](https://github.com/spring-io/asciidoctor-extensions/blob/main/CHANGELOG.adoc)
- [Commits](https://github.com/spring-io/asciidoctor-extensions/compare/v1.0.0-alpha.17...v1.0.0-alpha.18)

---
updated-dependencies:
- dependency-name: "@springio/asciidoctor-extensions"
  dependency-version: 1.0.0-alpha.18
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-19 16:45:10 +00:00
Ryan Baxter 9bb3eb87c9 Rename CI job to Spring Cloud Netflix
Signed-off-by: Ryan Baxter <rbaxter85@gmail.com>
2026-03-13 13:00:06 -04:00
Ryan Baxter e7a0ecbf78 Modify pull request branches for CI workflow
Updated pull request trigger branches in maven.yml

Signed-off-by: Ryan Baxter <rbaxter85@gmail.com>
2026-03-13 12:59:45 -04:00
Ryan Baxter 21f50f8a28 Add CI workflow for Spring Cloud Build
Signed-off-by: Ryan Baxter <rbaxter85@gmail.com>
2026-03-13 12:59:01 -04:00
Ryan Baxter 4a3ba2be64 Ignore updates to org.webjars.npm:glob as it conflicts with jshint version 2026-03-11 19:43:48 -04:00
dependabot[bot] 64ecafca42 Bump org.webjars.npm:jquery from 3.6.0 to 3.6.4
Bumps [org.webjars.npm:jquery](https://github.com/jquery/jquery) from 3.6.0 to 3.6.4.
- [Release notes](https://github.com/jquery/jquery/releases)
- [Changelog](https://github.com/jquery/jquery/blob/main/changelog.md)
- [Commits](https://github.com/jquery/jquery/compare/3.6.0...3.6.4)

---
updated-dependencies:
- dependency-name: org.webjars.npm:jquery
  dependency-version: 3.6.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-03-09 21:58:03 +00:00
Ryan Baxter dd1cb74e94 Revert "Bump org.webjars.npm:glob from 7.2.0 to 7.2.3 (#4451)"
This reverts commit 5234a4c095.
2026-03-09 17:43:34 -04:00
Ryan Baxter 8da42d23d7 Revert "Bump org.webjars.npm:bootstrap from 5.1.3 to 5.3.8 (#4487)"
This reverts commit 39bd9aa0c6.
2026-03-09 17:21:50 -04:00
Ryan Baxter 6b0c74b854 Revert "Bump ro.isdc.wro4j:wro4j-maven-plugin from 1.10.1 to 2.1.1 (#4449)"
This reverts commit 9601dc04fa.
2026-03-09 17:21:33 -04:00
Ryan Baxter dd2d5cd013 Update Dependabot configuration for GitHub Actions and Maven
Signed-off-by: Ryan Baxter <rbaxter85@gmail.com>
2026-03-09 17:18:16 -04:00
Ryan Baxter 5c080a48b3 Revert "Bump org.webjars.npm:glob from 7.2.0 to 11.0.3 (#4505)"
This reverts commit 1ee84b68b4.
2026-03-09 17:14:57 -04:00
dependabot[bot]andRyan Baxter 9601dc04fa Bump ro.isdc.wro4j:wro4j-maven-plugin from 1.10.1 to 2.1.1 (#4449)
Bumps [ro.isdc.wro4j:wro4j-maven-plugin](https://github.com/wro4j/wro4j) from 1.10.1 to 2.1.1.
- [Release notes](https://github.com/wro4j/wro4j/releases)
- [Changelog](https://github.com/wro4j/wro4j/blob/master/docs/ReleaseNotes.wiki)
- [Commits](https://github.com/wro4j/wro4j/compare/v1.10.1...v2.1.1)

---
updated-dependencies:
- dependency-name: ro.isdc.wro4j:wro4j-maven-plugin
  dependency-version: 2.1.1
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Ryan Baxter <ryan.baxter@broadcom.com>
2026-03-09 16:29:49 -04:00
dependabot[bot] ca7b068436 Bump org.webjars.npm:jquery from 3.6.0 to 3.6.4 (#4450)
Bumps [org.webjars.npm:jquery](https://github.com/jquery/jquery) from 3.6.0 to 3.6.4.
- [Release notes](https://github.com/jquery/jquery/releases)
- [Changelog](https://github.com/jquery/jquery/blob/main/changelog.md)
- [Commits](https://github.com/jquery/jquery/compare/3.6.0...3.6.4)

---
updated-dependencies:
- dependency-name: org.webjars.npm:jquery
  dependency-version: 3.6.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-09 16:29:15 -04:00
dependabot[bot] 5234a4c095 Bump org.webjars.npm:glob from 7.2.0 to 7.2.3 (#4451)
Bumps [org.webjars.npm:glob](https://github.com/isaacs/node-glob) from 7.2.0 to 7.2.3.
- [Changelog](https://github.com/isaacs/node-glob/blob/main/changelog.md)
- [Commits](https://github.com/isaacs/node-glob/compare/v7.2.0...v7.2.3)

---
updated-dependencies:
- dependency-name: org.webjars.npm:glob
  dependency-version: 7.2.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-09 16:29:12 -04:00
dependabot[bot] 39bd9aa0c6 Bump org.webjars.npm:bootstrap from 5.1.3 to 5.3.8 (#4487)
Bumps [org.webjars.npm:bootstrap](https://github.com/twbs/bootstrap) from 5.1.3 to 5.3.8.
- [Release notes](https://github.com/twbs/bootstrap/releases)
- [Commits](https://github.com/twbs/bootstrap/compare/v5.1.3...v5.3.8)

---
updated-dependencies:
- dependency-name: org.webjars.npm:bootstrap
  dependency-version: 5.3.8
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-09 16:29:09 -04:00
dependabot[bot] 1ee84b68b4 Bump org.webjars.npm:glob from 7.2.0 to 11.0.3 (#4505)
Bumps [org.webjars.npm:glob](https://github.com/isaacs/node-glob) from 7.2.0 to 11.0.3.
- [Changelog](https://github.com/isaacs/node-glob/blob/main/changelog.md)
- [Commits](https://github.com/isaacs/node-glob/compare/v7.2.0...v11.0.3)

---
updated-dependencies:
- dependency-name: org.webjars.npm:glob
  dependency-version: 11.0.3
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-09 16:29:06 -04:00
dependabot[bot] bdccd8d5bb Bump @antora/collector-extension from 1.0.2 to 1.0.3 in /docs (#4532)
---
updated-dependencies:
- dependency-name: "@antora/collector-extension"
  dependency-version: 1.0.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-09 16:29:03 -04:00
dependabot[bot] ab3de3d617 Bump @antora/collector-extension from 1.0.2 to 1.0.3 in /docs (#4535)
---
updated-dependencies:
- dependency-name: "@antora/collector-extension"
  dependency-version: 1.0.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-09 16:28:54 -04:00
dependabot[bot] bdaacaac28 Bump actions/upload-artifact from 6 to 7 (#4531)
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 6 to 7.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v6...v7)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-02 20:06:33 -05:00
Ryan Baxter 9e9785a1d9 Adding restclient test dependency 2026-03-02 19:40:37 -05:00
spring-builds 404fb89fe9 Bumping versions 2026-02-13 10:18:03 +00:00
dependabot[bot] 651c035fb4 Bump jersey.version from 4.0.1 to 4.0.2 (#4529)
Bumps `jersey.version` from 4.0.1 to 4.0.2.

Updates `org.glassfish.jersey.containers:jersey-container-servlet` from 4.0.1 to 4.0.2

Updates `org.glassfish.jersey.core:jersey-server` from 4.0.1 to 4.0.2

Updates `org.glassfish.jersey.core:jersey-client` from 4.0.1 to 4.0.2

Updates `org.glassfish.jersey.inject:jersey-hk2` from 4.0.1 to 4.0.2

---
updated-dependencies:
- dependency-name: org.glassfish.jersey.containers:jersey-container-servlet
  dependency-version: 4.0.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: org.glassfish.jersey.core:jersey-server
  dependency-version: 4.0.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: org.glassfish.jersey.core:jersey-client
  dependency-version: 4.0.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: org.glassfish.jersey.inject:jersey-hk2
  dependency-version: 4.0.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-30 12:17:31 -05:00
spring-builds d33aa03ff2 Bumping versions 2026-01-30 10:27:13 +00:00
spring-builds e7e265feba Bumping versions 2026-01-29 10:26:08 +00:00
spring-builds 45a6657800 Bumping dependency versions after release 2026-01-28 21:32:38 +00:00
spring-builds 4fdf471acd Bumping versions to 5.0.2-SNAPSHOT after release 2026-01-28 21:31:21 +00:00
spring-builds c318efa173 Going back to snapshots 2026-01-28 21:31:20 +00:00
spring-builds a607986345 Update SNAPSHOT to 5.0.1 2026-01-28 21:30:33 +00:00
dependabot[bot] 33215dc079 Bump jersey.version from 4.0.0 to 4.0.1 (#4528)
Bumps `jersey.version` from 4.0.0 to 4.0.1.

Updates `org.glassfish.jersey.containers:jersey-container-servlet` from 4.0.0 to 4.0.1

Updates `org.glassfish.jersey.core:jersey-server` from 4.0.0 to 4.0.1

Updates `org.glassfish.jersey.core:jersey-client` from 4.0.0 to 4.0.1

Updates `org.glassfish.jersey.inject:jersey-hk2` from 4.0.0 to 4.0.1

---
updated-dependencies:
- dependency-name: org.glassfish.jersey.containers:jersey-container-servlet
  dependency-version: 4.0.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: org.glassfish.jersey.core:jersey-server
  dependency-version: 4.0.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: org.glassfish.jersey.core:jersey-client
  dependency-version: 4.0.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
- dependency-name: org.glassfish.jersey.inject:jersey-hk2
  dependency-version: 4.0.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-01-23 11:57:03 -05:00
spring-builds b2bcfa2298 Bumping dependency versions after release 2025-12-16 21:11:15 +00:00
spring-builds a0e94fcd74 Bumping versions to 4.3.2-SNAPSHOT after release 2025-12-16 21:10:02 +00:00
spring-builds 1b67bb917d Going back to snapshots 2025-12-16 21:10:00 +00:00
spring-builds a660a7bf48 Update SNAPSHOT to 4.3.1 2025-12-16 21:09:07 +00:00
dependabot[bot] 866dfe1a83 Bump testcontainers.version from 1.21.3 to 1.21.4 (#4522)
Bumps `testcontainers.version` from 1.21.3 to 1.21.4.

Updates `org.testcontainers:mockserver` from 1.21.3 to 1.21.4
- [Release notes](https://github.com/testcontainers/testcontainers-java/releases)
- [Changelog](https://github.com/testcontainers/testcontainers-java/blob/main/CHANGELOG.md)
- [Commits](https://github.com/testcontainers/testcontainers-java/compare/1.21.3...1.21.4)

Updates `org.testcontainers:junit-jupiter` from 1.21.3 to 1.21.4
- [Release notes](https://github.com/testcontainers/testcontainers-java/releases)
- [Changelog](https://github.com/testcontainers/testcontainers-java/blob/main/CHANGELOG.md)
- [Commits](https://github.com/testcontainers/testcontainers-java/compare/1.21.3...1.21.4)

---
updated-dependencies:
- dependency-name: org.testcontainers:mockserver
  dependency-version: 1.21.4
  dependency-type: direct:development
  update-type: version-update:semver-patch
- dependency-name: org.testcontainers:junit-jupiter
  dependency-version: 1.21.4
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-16 14:27:51 -05:00
dependabot[bot] 3669e48fd3 Bump testcontainers.version from 1.21.3 to 1.21.4 (#4523)
Bumps `testcontainers.version` from 1.21.3 to 1.21.4.

Updates `org.testcontainers:mockserver` from 1.21.3 to 1.21.4
- [Release notes](https://github.com/testcontainers/testcontainers-java/releases)
- [Changelog](https://github.com/testcontainers/testcontainers-java/blob/main/CHANGELOG.md)
- [Commits](https://github.com/testcontainers/testcontainers-java/compare/1.21.3...1.21.4)

Updates `org.testcontainers:junit-jupiter` from 1.21.3 to 1.21.4
- [Release notes](https://github.com/testcontainers/testcontainers-java/releases)
- [Changelog](https://github.com/testcontainers/testcontainers-java/blob/main/CHANGELOG.md)
- [Commits](https://github.com/testcontainers/testcontainers-java/compare/1.21.3...1.21.4)

---
updated-dependencies:
- dependency-name: org.testcontainers:mockserver
  dependency-version: 1.21.4
  dependency-type: direct:development
  update-type: version-update:semver-patch
- dependency-name: org.testcontainers:junit-jupiter
  dependency-version: 1.21.4
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-16 14:27:22 -05:00
dependabot[bot] 47f989fa7b Bump actions/cache from 4 to 5 (#4520)
Bumps [actions/cache](https://github.com/actions/cache) from 4 to 5.
- [Release notes](https://github.com/actions/cache/releases)
- [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md)
- [Commits](https://github.com/actions/cache/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/cache
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-15 11:51:25 -05:00
dependabot[bot] 798d6ba29a Bump actions/upload-artifact from 5 to 6 (#4521)
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 5 to 6.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-15 11:50:55 -05:00
spencergibb 4f181b65e1 Merge branch '4.3.x' 2025-12-03 11:28:20 -05:00
spencergibb 0e2f9ed0c2 Merge branch '4.2.x' into 4.3.x 2025-12-03 11:28:06 -05:00
spencergibb ab66c66488 Exclude guava from eureka-client
Fixes gh-4467
2025-12-03 11:25:55 -05:00
spencergibb fda86f94f0 Merge branch '4.3.x' 2025-12-03 11:02:00 -05:00
spencergibb 41c38ef71c Merge remote-tracking branch 'origin/4.3.x' into 4.3.x
# Conflicts:
#	pom.xml
#	spring-cloud-netflix-dependencies/pom.xml
2025-12-03 10:59:27 -05:00
spencergibb a1569a6458 Merge branch '4.2.x' into 4.3.x 2025-12-03 10:49:30 -05:00
David Vana 8885663ff9 Switch remaining JUnit 4 tests to JUnit Jupiter #4011 (#4421)
* Migrate to JUnit 5 (#4011)

Signed-off-by: David Vana <developer@david-vana.cz>

* Removed unused JUnit 4 dependencies (#4011)

Signed-off-by: David Vana <developer@david-vana.cz>

---------

Signed-off-by: David Vana <developer@david-vana.cz>
2025-12-03 10:44:42 -05:00
dependabot[bot] aa49ce6171 Bump antora from 3.2.0-alpha.10 to 3.2.0-alpha.11 in /docs (#4517)
Bumps [antora](https://gitlab.com/antora/antora) from 3.2.0-alpha.10 to 3.2.0-alpha.11.
- [Changelog](https://gitlab.com/antora/antora/blob/main/CHANGELOG.adoc)
- [Commits](https://gitlab.com/antora/antora/compare/v3.2.0-alpha.10...v3.2.0-alpha.11)

---
updated-dependencies:
- dependency-name: antora
  dependency-version: 3.2.0-alpha.11
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-01 16:18:56 -05:00
dependabot[bot] fe385b62b3 Bump antora from 3.2.0-alpha.10 to 3.2.0-alpha.11 in /docs (#4518)
Bumps [antora](https://gitlab.com/antora/antora) from 3.2.0-alpha.10 to 3.2.0-alpha.11.
- [Changelog](https://gitlab.com/antora/antora/blob/main/CHANGELOG.adoc)
- [Commits](https://gitlab.com/antora/antora/compare/v3.2.0-alpha.10...v3.2.0-alpha.11)

---
updated-dependencies:
- dependency-name: antora
  dependency-version: 3.2.0-alpha.11
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-12-01 16:15:25 -05:00
dependabot[bot] bef6d5ccd3 Bump antora from 3.2.0-alpha.10 to 3.2.0-alpha.11 in /docs (#4519) 2025-12-01 14:24:07 -05:00
dependabot[bot] d455f9ef2a Bump actions/checkout from 5 to 6 (#4512)
Bumps [actions/checkout](https://github.com/actions/checkout) from 5 to 6.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-24 15:01:09 -05:00
dependabot[bot] 21ed3d99a3 Bump actions/checkout from 5 to 6 (#4513)
Bumps [actions/checkout](https://github.com/actions/checkout) from 5 to 6.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-24 15:00:25 -05:00
dependabot[bot] d83fbc8176 Bump actions/checkout from 5 to 6 (#4514)
Bumps [actions/checkout](https://github.com/actions/checkout) from 5 to 6.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](https://github.com/actions/checkout/compare/v5...v6)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-24 14:57:10 -05:00
spring-builds 41ef79beb8 Bumping dependency versions after release 2025-11-24 15:53:00 +00:00
spring-builds f01832b08d Bumping versions to 5.0.1-SNAPSHOT after release 2025-11-24 15:51:53 +00:00
spring-builds 25de83e70b Going back to snapshots 2025-11-24 15:51:51 +00:00
spring-builds 44bc8a0f26 Update SNAPSHOT to 5.0.0 2025-11-24 15:51:03 +00:00
spencergibb f722baa811 Updates for new method in ServiceInstance
See https://github.com/spring-cloud/spring-cloud-commons/pull/1604
2025-11-22 19:51:14 -05:00
spring-builds c935fd79ec Bumping versions 2025-11-19 10:31:59 +00:00
Ryan Baxter 1314715c19 Changes for Spring Boot 4 snapshots 2025-11-14 11:18:43 -05:00
spring-builds 34c1b9d9e2 Going back to snapshots 2025-11-12 12:23:38 +00:00
spring-builds d104c36968 Update SNAPSHOT to 5.0.0-RC1 2025-11-12 12:22:50 +00:00
spring-builds d8afd906c5 Bumping versions 2025-11-11 10:27:19 +00:00
Mohamed Macow 9be3229249 Implement tests for EurekaReactiveDiscoveryClient and EurekaDiscoveryClientTests (#4508)
* Implement probe() and reactiveProbe() and tests for Reactive client

Signed-off-by: Mohamed Macow <mmacovv@gmail.com>

* Implement test for probe()

Signed-off-by: Mohamed Macow <mmacovv@gmail.com>

* Correct year in copyright

Signed-off-by: Mohamed Macow <mmacovv@gmail.com>

* remove function override and correct tests

Signed-off-by: Mohamed Macow <mmacovv@gmail.com>

* revert override in reactive client

Signed-off-by: Mohamed Macow <mmacovv@gmail.com>

* revert format

Signed-off-by: Mohamed Macow <mmacovv@gmail.com>

---------

Signed-off-by: Mohamed Macow <mmacovv@gmail.com>
2025-11-10 15:50:26 -05:00
Ryan Baxter e570ec275b Use server customizer for Eureka Jackson mappings in mock server
Possible after Boot addressed https://github.com/spring-projects/spring-boot/issues/47798
2025-11-07 15:54:41 -05:00
Lê Nam Khánh 2122fa420c Fix typos in some files (#4511) 2025-11-06 09:29:38 -05:00
dependabot[bot] cb47274dc7 Bump jersey.version from 3.1.11 to 4.0.0 (#4510) 2025-11-05 13:54:54 -05:00
dependabot[bot] 3277e5558a Bump mikepenz/action-junit-report from 5 to 6 (#4509)
Bumps [mikepenz/action-junit-report](https://github.com/mikepenz/action-junit-report) from 5 to 6.
- [Release notes](https://github.com/mikepenz/action-junit-report/releases)
- [Commits](https://github.com/mikepenz/action-junit-report/compare/v5...v6)

---
updated-dependencies:
- dependency-name: mikepenz/action-junit-report
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-11-03 11:48:39 -05:00
spring-builds c3c43d14d8 Bumping versions 2025-10-29 00:19:46 +00:00
dependabot[bot] cc432a4c1a Bump actions/upload-artifact from 4 to 5 (#4507)
Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 4 to 5.
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](https://github.com/actions/upload-artifact/compare/v4...v5)

---
updated-dependencies:
- dependency-name: actions/upload-artifact
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-27 17:53:06 -04:00
Ryan Baxter ce229a7ac3 Changes for the latest Boot snapshots (#4506)
* Changes for the latest Boot snapshots

* Add Spring Boot Jackson 2 module
2025-10-24 12:35:04 -04:00
spring-builds 2796d5b64a Bumping versions 2025-10-24 03:22:53 +00:00
spring-builds eba4fa8cda Going back to snapshots 2025-10-17 12:35:24 +00:00
spring-builds a0368c39fa Update SNAPSHOT to 5.0.0-M4 2025-10-17 12:34:37 +00:00
spring-builds 3ad1ac3448 Bumping versions 2025-10-14 10:26:21 +00:00
Olga Maciaszek-Sharma a1fddaf139 Remove RestTemplate support. (#4504)
Signed-off-by: Olga Maciaszek-Sharma <olga.maciaszek-sharma@broadcom.com>
2025-10-09 14:55:03 -04:00
Olga Maciaszek-Sharma d429c7623f Merge remote-tracking branch 'origin/4.3.x' 2025-10-07 14:57:41 +02:00
Olga Maciaszek-Sharma 58f0adf43b Merge remote-tracking branch 'origin/4.2.x' into 4.3.x 2025-10-07 14:57:20 +02:00
dependabot[bot] 1f4b1444c4 Bump antora from 3.2.0-alpha.9 to 3.2.0-alpha.10 in /docs (#4502)
Bumps [antora](https://gitlab.com/antora/antora) from 3.2.0-alpha.9 to 3.2.0-alpha.10.
- [Changelog](https://gitlab.com/antora/antora/blob/main/CHANGELOG.adoc)
- [Commits](https://gitlab.com/antora/antora/compare/v3.2.0-alpha.9...v3.2.0-alpha.10)

---
updated-dependencies:
- dependency-name: antora
  dependency-version: 3.2.0-alpha.10
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-10-07 14:56:11 +02:00
spring-builds b6c087232c Going back to snapshots 2025-10-01 21:42:42 +00:00
spring-builds 37cb7d369b Update SNAPSHOT to 5.0.0-M3 2025-10-01 21:41:54 +00:00
Olga Maciaszek-Sharma ab76ec72e9 Apply workaround to enforce Jackson 2 decoder/ encoder use with WebClient. Remove unnecessary classpath exclusions.
Signed-off-by: Olga Maciaszek-Sharma <olga.maciaszek-sharma@broadcom.com>
2025-10-01 17:46:44 +02:00
Olga Maciaszek-Sharma 00ade3f8d3 Merge remote-tracking branch 'origin/main' 2025-10-01 15:33:01 +02:00
spring-builds 6ba1684ced Bumping versions 2025-10-01 10:18:33 +00:00
Olga Maciaszek-Sharma 9274d7cebe Merge remote-tracking branch 'origin/main' 2025-09-19 12:00:53 +02:00
Ryan Baxter 224e06856b Fixing new Bootstrap changes 2025-09-18 14:55:33 -04:00
Olga Maciaszek-Sharma 12f664ab76 Use Jackson 2.20.0 in Eureka Client (#4496)
* Revert "Disables WebClientEurekaHttpClientTests"

This reverts commit ad30b66f94.

Signed-off-by: Olga Maciaszek-Sharma <olga.maciaszek-sharma@broadcom.com>

* Use Jackson `2.20.0` in Client.

Signed-off-by: Olga Maciaszek-Sharma <olga.maciaszek-sharma@broadcom.com>

---------

Signed-off-by: Olga Maciaszek-Sharma <olga.maciaszek-sharma@broadcom.com>
2025-09-18 16:08:05 +02:00
Olga Maciaszek-Sharma 4f9d969a78 Revert "Disables WebClientEurekaHttpClientTests"
This reverts commit ad30b66f94.
2025-09-16 14:36:13 +02:00
67 changed files with 405 additions and 1465 deletions
+10 -21
View File
@@ -1,10 +1,5 @@
version: 2
updates:
- package-ecosystem: "github-actions"
directory: "/"
target-branch: "4.2.x"
schedule:
interval: "weekly"
- package-ecosystem: "github-actions"
directory: "/"
target-branch: "4.3.x"
@@ -15,23 +10,14 @@ updates:
target-branch: "main"
schedule:
interval: "weekly"
- package-ecosystem: maven
directory: /
schedule:
interval: daily
target-branch: 4.2.x
ignore:
# only upgrade patch versions for maintenance branch
- dependency-name: "*"
update-types:
- version-update:semver-major
- version-update:semver-minor
- package-ecosystem: maven
directory: /
schedule:
interval: daily
target-branch: 4.3.x
ignore:
# glob 7.2.3+ conflicts with jshint (minimatch) in wro4j-maven-plugin
- dependency-name: "org.webjars.npm:glob"
# only upgrade patch versions for maintenance branch
- dependency-name: "*"
update-types:
@@ -42,6 +28,14 @@ updates:
schedule:
interval: daily
target-branch: main
ignore:
# glob 7.2.3+ conflicts with jshint (minimatch) in wro4j-maven-plugin
- dependency-name: "org.webjars.npm:glob"
# only upgrade patch versions for maintenance branch
- dependency-name: "*"
update-types:
- version-update:semver-major
- version-update:semver-minor
- package-ecosystem: npm
target-branch: docs-build
directory: /
@@ -52,11 +46,6 @@ updates:
directory: /docs
schedule:
interval: weekly
- package-ecosystem: npm
target-branch: 4.2.x
directory: /docs
schedule:
interval: weekly
- package-ecosystem: npm
target-branch: 4.3.x
directory: /docs
+33
View File
@@ -0,0 +1,33 @@
name: Spring Cloud Netflix CI Job
on:
push:
branches:
- main
- 4.3.x
# Scheduled builds run daily at midnight UTC
schedule:
- cron: '0 0 * * *'
# Manual trigger with optional branch override
workflow_dispatch:
inputs:
branches:
description: "Which branch should be built (can be a comma-separated list of branches)"
required: true
default: 'main'
type: string
jobs:
deploy:
uses: spring-cloud/spring-cloud-github-actions/.github/workflows/deploy.yml@main
with:
branches: ${{ inputs.branches }}
secrets:
ARTIFACTORY_USERNAME: ${{ secrets.ARTIFACTORY_USERNAME }}
ARTIFACTORY_PASSWORD: ${{ secrets.ARTIFACTORY_PASSWORD }}
COMMERCIAL_ARTIFACTORY_USERNAME: ${{ secrets.COMMERCIAL_ARTIFACTORY_USERNAME }}
COMMERCIAL_ARTIFACTORY_PASSWORD: ${{ secrets.COMMERCIAL_ARTIFACTORY_PASSWORD }}
DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }}
+1 -1
View File
@@ -16,7 +16,7 @@ jobs:
# if: github.repository_owner == 'spring-cloud'
steps:
- name: Checkout
uses: actions/checkout@v5
uses: actions/checkout@v6
with:
ref: docs-build
fetch-depth: 1
-42
View File
@@ -1,42 +0,0 @@
# This workflow will build a Java project with Maven
# For more information see: https://help.github.com/actions/language-and-framework-guides/building-and-testing-java-with-maven
name: Build
on:
push:
branches: [ main, 4.3.x, 4.2.x ]
pull_request:
branches: [ main, 4.3.x, 4.2.x ]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v5
- name: Set up JDK
uses: actions/setup-java@v5
with:
distribution: 'temurin'
java-version: '17'
- name: Cache local Maven repository
uses: actions/cache@v4
with:
path: ~/.m2/repository
key: ${{ runner.os }}-maven-${{ hashFiles('**/pom.xml') }}
restore-keys: |
${{ runner.os }}-maven-
- name: Build with Maven
run: ./mvnw -s .settings.xml clean org.jacoco:jacoco-maven-plugin:prepare-agent install -U -P sonar -nsu --batch-mode -Dmaven.test.redirectTestOutputToFile=true -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn
- name: Publish Test Report
uses: mikepenz/action-junit-report@v5
if: always() # always run even if the previous step fails
with:
report_paths: '**/surefire-reports/TEST-*.xml'
- name: Archive code coverage results
uses: actions/upload-artifact@v4
with:
name: surefire-reports
path: '**/surefire-reports/*'
+9
View File
@@ -0,0 +1,9 @@
name: PR
on:
pull_request:
branches: [ main, 4.3.x ]
jobs:
build:
uses: spring-cloud/spring-cloud-github-actions/.github/workflows/pr.yml@main
+7
View File
@@ -65,6 +65,13 @@ parsing or rendering it, just copying it to `${main.basedir}`
any changes in the README it will then show up after a Maven build as
a modified file in the correct place. Just commit it and push the change.
You can generate the docs site using the following command:
[indent=0]
----
./mvnw -pl docs -P docs antora:antora
----
[[working-with-the-code]]
== Working with the code
If you don't have an IDE preference we would recommend that you use
@@ -96,9 +96,9 @@ The `eureka.client.tls.enabled` needs to be true to enable Eureka client side TL
NOTE: Because of a limitation in Eureka, it is not possible to support per-server basic auth credentials, so only the first set that are found is used.
If you want to customize the RestTemplate used by the Eureka HTTP Client you may want to create a bean of `EurekaClientHttpRequestFactorySupplier` and provide your own logic for generating a `ClientHttpRequestFactory` instance.
If you want to customize the `RestClient` used by the Eureka HTTP Client you may want to create a bean of `EurekaClientHttpRequestFactorySupplier` and provide your own logic for generating a `ClientHttpRequestFactory` instance.
All default timeout-related properties for RestTemplate and RestClient used by the Eureka HTTP Client are set to 3 minutes (in keeping with Apache HC5 default `RequestConfig` and `SocketConfig`). Therefore, to specify the timeout values, you must specify the value directly with the properties in `eureka.client.rest-template-timeout` or `eureka.client.restclient.timeout`. All timeout properties are in milliseconds.
All default timeout-related properties for `RestClient` used by the Eureka HTTP Client are set to 3 minutes (in keeping with Apache HC5 default `RequestConfig` and `SocketConfig`). Therefore, to specify the timeout values, you must specify the value directly with the properties in `eureka.client.timeout`. All timeout properties are in milliseconds.
.application.yml
[source,yaml]
@@ -290,11 +290,11 @@ It is initialized in a `SmartLifecycle` (with `phase=0`), so the earliest you ca
==== Underlying HTTP clients
`EurekaClient` uses either `RestClient`, `RestTemplate`, `WebClient` or `JerseyClient` under the hood. In order to use the `EurekaClient`, you need to have one of the supported HTTP clients on your classpath.
`EurekaClient` uses either `RestClient`, `WebClient` or `JerseyClient` under the hood. In order to use the `EurekaClient`, you need to have one of the supported HTTP clients on your classpath.
To use `RestTemplate` or `RestClient`, add `spring-boot-restclient` to your dependencies. To use `WebClient`, add `spring-boot-webclient` to your dependencies. If both `spring-boot-restclient`
To use `RestClient`, add `spring-boot-restclient` to your dependencies. To use `WebClient`, add `spring-boot-webclient` to your dependencies. If both `spring-boot-restclient`
and `spring-boot-webclient` are included in the dependencies and the `eureka.client.webclient.enabled` flag is set to `true`,
then `WebClient` will be used. If that's not the case and `eureka.client.restclient.enabled` is set to `true`, `RestClient` will be used. Otherwise, `RestTemplate` will be used.
then `WebClient` will be used. If that's not the case, `RestClient` will be used.
NOTE: For any of those client implementations, if there's a builder bean available, it will be used to create the underlying client.
@@ -591,7 +591,7 @@ Set `eureka.instance.preferIpAddress` to `true` and, when the application regist
[TIP]
====
If the hostname cannot be determined by Java, then the IP address is sent to Eureka.
Only explict way of setting the hostname is by setting `eureka.instance.hostname` property.
Only explicit way of setting the hostname is by setting `eureka.instance.hostname` property.
You can set your hostname at the run-time by using an environment variable -- for example, `eureka.instance.hostname=$\{HOST_NAME}`.
====
+15 -12
View File
@@ -46,16 +46,12 @@
|eureka.client.register-with-eureka | `+++true+++` | Indicates whether or not this instance should register its information with eureka server for discovery by others. In some cases, you do not want your instances to be discovered whereas you just want do discover other instances.
|eureka.client.registry-fetch-interval-seconds | `+++30+++` | Indicates how often(in seconds) to fetch the registry information from the eureka server.
|eureka.client.registry-refresh-single-vip-address | | Indicates whether the client is only interested in the registry information for a single VIP.
|eureka.client.rest-template-timeout.connect-request-timeout | `+++180000+++` |
|eureka.client.rest-template-timeout.connect-timeout | `+++180000+++` | Default values are set to 180000, in keeping with {@link RequestConfig} and {@link SocketConfig} defaults.
|eureka.client.rest-template-timeout.socket-timeout | `+++180000+++` |
|eureka.client.restclient.enabled | `+++false+++` | Enables the use of RestClient for Eureka HTTP Client.
|eureka.client.restclient.timeout.connect-request-timeout | `+++180000+++` |
|eureka.client.restclient.timeout.connect-timeout | `+++180000+++` | Default values are set to 180000, in keeping with {@link RequestConfig} and {@link SocketConfig} defaults.
|eureka.client.restclient.timeout.socket-timeout | `+++180000+++` |
|eureka.client.service-url | | Map of availability zone to list of fully qualified URLs to communicate with eureka server. Each value can be a single URL or a comma separated list of alternative locations. Typically the eureka server URLs carry protocol,host,port,context and version information if any. Example: https://ec2-256-156-243-129.compute-1.amazonaws.com:7001/eureka/ The changes are effective at runtime at the next service url refresh cycle as specified by eurekaServiceUrlPollIntervalSeconds.
|eureka.client.should-enforce-registration-at-init | `+++false+++` | Indicates whether the client should enforce registration during initialization. Defaults to false.
|eureka.client.should-unregister-on-shutdown | `+++true+++` | Indicates whether the client should explicitly unregister itself from the remote server on client shutdown.
|eureka.client.timeout.connect-request-timeout | `+++180000+++` |
|eureka.client.timeout.connect-timeout | `+++180000+++` | Default values are set to 180000, in keeping with {@link RequestConfig} and {@link SocketConfig} defaults.
|eureka.client.timeout.socket-timeout | `+++180000+++` |
|eureka.client.tls.enabled | |
|eureka.client.tls.key-password | |
|eureka.client.tls.key-store | |
@@ -78,15 +74,15 @@
|eureka.instance.default-address-resolution-order | `+++[]+++` |
|eureka.instance.environment | |
|eureka.instance.health-check-url | | Gets the absolute health check page URL for this instance. The users can provide the healthCheckUrlPath if the health check page resides in the same instance talking to eureka, else in the cases where the instance is a proxy for some other server, users can provide the full URL. If the full URL is provided it takes precedence. <p> It is normally used for making educated decisions based on the health of the instance - for example, it can be used to determine whether to proceed deployments to an entire farm or stop the deployments without causing further damage. The full URL should follow the format http://${eureka.hostname}:7001/ where the value ${eureka.hostname} is replaced at runtime.
|eureka.instance.health-check-url-path | | Gets the relative health check URL path for this instance. The health check page URL is then constructed out of the hostname and the type of communication - secure or unsecure as specified in securePort and nonSecurePort. It is normally used for making educated decisions based on the health of the instance - for example, it can be used to determine whether to proceed deployments to an entire farm or stop the deployments without causing further damage.
|eureka.instance.health-check-url-path | | Gets the relative health check URL path for this instance. The health check page URL is then constructed out of the hostname and the type of communication - secure or insecure as specified in securePort and nonSecurePort. It is normally used for making educated decisions based on the health of the instance - for example, it can be used to determine whether to proceed deployments to an entire farm or stop the deployments without causing further damage.
|eureka.instance.home-page-url | | Gets the absolute home page URL for this instance. The users can provide the homePageUrlPath if the home page resides in the same instance talking to eureka, else in the cases where the instance is a proxy for some other server, users can provide the full URL. If the full URL is provided it takes precedence. It is normally used for informational purposes for other services to use it as a landing page. The full URL should follow the format http://${eureka.hostname}:7001/ where the value ${eureka.hostname} is replaced at runtime.
|eureka.instance.home-page-url-path | `+++/+++` | Gets the relative home page URL Path for this instance. The home page URL is then constructed out of the hostName and the type of communication - secure or unsecure. It is normally used for informational purposes for other services to use it as a landing page.
|eureka.instance.home-page-url-path | `+++/+++` | Gets the relative home page URL Path for this instance. The home page URL is then constructed out of the hostName and the type of communication - secure or insecure. It is normally used for informational purposes for other services to use it as a landing page.
|eureka.instance.hostname | | The hostname if it can be determined at configuration time (otherwise it will be guessed from OS primitives).
|eureka.instance.initial-status | `+++up+++` | Initial status to register with remote Eureka server.
|eureka.instance.instance-enabled-onit | `+++false+++` | Indicates whether the instance should be enabled for taking traffic as soon as it is registered with eureka. Sometimes the application might need to do some pre-processing before it is ready to take traffic.
|eureka.instance.instance-id | | Get the unique Id (within the scope of the appName) of this instance to be registered with eureka.
|eureka.instance.ip-address | | Get the IPAdress of the instance. This information is for academic purposes only as the communication from other instances primarily happen using the information supplied in {@link #getHostName(boolean)}.
|eureka.instance.lease-expiration-duration-in-seconds | `+++90+++` | Indicates the time in seconds that the eureka server waits since it received the last heartbeat before it can remove this instance from its view and there by disallowing traffic to this instance. Setting this value too long could mean that the traffic could be routed to the instance even though the instance is not alive. Setting this value too small could mean, the instance may be taken out of traffic because of temporary network glitches.This value to be set to atleast higher than the value specified in leaseRenewalIntervalInSeconds.
|eureka.instance.lease-expiration-duration-in-seconds | `+++90+++` | Indicates the time in seconds that the eureka server waits since it received the last heartbeat before it can remove this instance from its view and there by disallowing traffic to this instance. Setting this value too long could mean that the traffic could be routed to the instance even though the instance is not alive. Setting this value too small could mean, the instance may be taken out of traffic because of temporary network glitches.This value to be set to at least higher than the value specified in leaseRenewalIntervalInSeconds.
|eureka.instance.lease-renewal-interval-in-seconds | `+++30+++` | Indicates how often (in seconds) the eureka client needs to send heartbeats to eureka server to indicate that it is still alive. If the heartbeats are not received for the period specified in leaseExpirationDurationInSeconds, eureka server will remove the instance from its view, there by disallowing traffic to this instance. Note that the instance could still not take traffic if it implements HealthCheckCallback and then decides to make itself unavailable.
|eureka.instance.metadata-map | | Gets the metadata name/value pairs associated with this instance. This information is sent to eureka server and can be used by other instances.
|eureka.instance.metadata-map.weight | `+++1+++` | The weight of service instance for weighted load balancing.
@@ -101,7 +97,7 @@
|eureka.instance.secure-port-enabled | `+++false+++` | Indicates whether the secure port should be enabled for traffic or not.
|eureka.instance.secure-virtual-host-name | `+++unknown+++` | Gets the secure virtual host name defined for this instance. This is typically the way other instance would find this instance by using the secure virtual host name.Think of this as similar to the fully qualified domain name, that the users of your services will need to find this instance.
|eureka.instance.status-page-url | | Gets the absolute status page URL path for this instance. The users can provide the statusPageUrlPath if the status page resides in the same instance talking to eureka, else in the cases where the instance is a proxy for some other server, users can provide the full URL. If the full URL is provided it takes precedence. It is normally used for informational purposes for other services to find about the status of this instance. Users can provide a simple HTML indicating what is the current status of the instance.
|eureka.instance.status-page-url-path | | Gets the relative status page URL path for this instance. The status page URL is then constructed out of the hostName and the type of communication - secure or unsecure as specified in securePort and nonSecurePort. It is normally used for informational purposes for other services to find about the status of this instance. Users can provide a simple HTML indicating what is the current status of the instance.
|eureka.instance.status-page-url-path | | Gets the relative status page URL path for this instance. The status page URL is then constructed out of the hostName and the type of communication - secure or insecure as specified in securePort and nonSecurePort. It is normally used for informational purposes for other services to find about the status of this instance. Users can provide a simple HTML indicating what is the current status of the instance.
|eureka.instance.virtual-host-name | `+++unknown+++` | Gets the virtual host name defined for this instance. This is typically the way other instance would find this instance by using the virtual host name.Think of this as similar to the fully qualified domain name, that the users of your services will need to find this instance.
|eureka.server.a-s-g-cache-expiry-timeout-ms | `+++600000+++` |
|eureka.server.a-s-g-query-timeout-ms | `+++300+++` |
@@ -180,7 +176,7 @@
|eureka.server.use-read-only-response-cache | `+++true+++` |
|eureka.server.wait-time-in-ms-when-sync-empty | `+++300000+++` |
|eureka.server.xml-codec-name | |
|spring.cloud.compatibility-verifier.compatible-boot-versions | `+++4.0.x+++` | Default accepted versions for the Spring Boot dependency. You can set {@code x} for the patch version if you don't want to specify a concrete value. Example: {@code 3.5.x}
|spring.cloud.compatibility-verifier.compatible-boot-versions | | Default accepted versions for the Spring Boot dependency. You can set {@code x} for the patch version if you don't want to specify a concrete value. Example: {@code 3.5.x}
|spring.cloud.compatibility-verifier.enabled | `+++false+++` | Enables creation of Spring Cloud compatibility verification.
|spring.cloud.config.allow-override | `+++true+++` | Flag to indicate that {@link #isOverrideSystemProperties() systemPropertiesOverride} can be used. Set to false to prevent users from changing the default accidentally. Default true.
|spring.cloud.config.initialize-on-context-refresh | `+++false+++` | Flag to initialize bootstrap configuration on context refresh event. Default false.
@@ -212,6 +208,13 @@
|spring.cloud.inetutils.preferred-networks | | List of Java regular expressions for network addresses that will be preferred.
|spring.cloud.inetutils.timeout-seconds | `+++1+++` | Timeout, in seconds, for calculating hostname.
|spring.cloud.inetutils.use-only-site-local-interfaces | `+++false+++` | Whether to use only interfaces with site local addresses. See {@link InetAddress#isSiteLocalAddress()} for more details.
|spring.cloud.loadbalancer.api-version.default | | Sets default version that should be used for each request.
|spring.cloud.loadbalancer.api-version.fallback-to-available-instances | `+++false+++` | Indicates whether all the available instances should be returned if no instances for the specified version are available.
|spring.cloud.loadbalancer.api-version.header | | Uses the HTTP header with the given name to obtain the version.
|spring.cloud.loadbalancer.api-version.media-type-parameters | | Uses the media type parameter with the given name to obtain the version.
|spring.cloud.loadbalancer.api-version.path-segment | | Uses the path segment at the given index to obtain the version.
|spring.cloud.loadbalancer.api-version.query-parameter | | Uses the query parameter with the given name to obtain the version.
|spring.cloud.loadbalancer.api-version.required | `+++false+++` | Indicates whether the API version is required with each request.
|spring.cloud.loadbalancer.cache.caffeine.spec | | The spec to use to create caches. See CaffeineSpec for more details on the spec format.
|spring.cloud.loadbalancer.cache.capacity | `+++256+++` | Initial cache capacity expressed as int.
|spring.cloud.loadbalancer.cache.enabled | `+++true+++` | Enables Spring Cloud LoadBalancer caching mechanism.
+4 -4
View File
@@ -1,10 +1,10 @@
{
"dependencies": {
"antora": "3.2.0-alpha.9",
"antora": "3.2.0-alpha.12",
"@antora/atlas-extension": "1.0.0-alpha.5",
"@antora/collector-extension": "1.0.2",
"@antora/collector-extension": "1.0.3",
"@asciidoctor/tabs": "1.0.0-beta.6",
"@springio/antora-extensions": "1.14.7",
"@springio/asciidoctor-extensions": "1.0.0-alpha.17"
"@springio/antora-extensions": "1.14.12",
"@springio/asciidoctor-extensions": "1.0.0-alpha.18"
}
}
+1 -1
View File
@@ -8,7 +8,7 @@
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix</artifactId>
<version>5.0.0-SNAPSHOT</version>
<version>5.0.2</version>
<relativePath>..</relativePath>
</parent>
<packaging>jar</packaging>
+10 -10
View File
@@ -3,7 +3,7 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>spring-cloud-netflix</artifactId>
<version>5.0.0-SNAPSHOT</version>
<version>5.0.2</version>
<packaging>pom</packaging>
<name>Spring Cloud Netflix</name>
<description>Spring Cloud Netflix</description>
@@ -11,7 +11,7 @@
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-build</artifactId>
<version>5.0.0-SNAPSHOT</version>
<version>5.0.2</version>
<relativePath />
</parent>
<scm>
@@ -80,9 +80,9 @@
</developers>
<properties>
<bintray.package>netflix</bintray.package>
<spring-cloud-commons.version>5.0.0-SNAPSHOT</spring-cloud-commons.version>
<spring-cloud-config.version>5.0.0-SNAPSHOT</spring-cloud-config.version>
<testcontainers.version>1.21.3</testcontainers.version>
<spring-cloud-commons.version>5.0.2</spring-cloud-commons.version>
<spring-cloud-config.version>5.0.4</spring-cloud-config.version>
<testcontainers.version>1.21.4</testcontainers.version>
<mockserverclient.version>5.15.0</mockserverclient.version>
<!-- Sonar -->
@@ -238,7 +238,7 @@
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/libs-snapshot-local</url>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
@@ -249,7 +249,7 @@
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/libs-milestone-local</url>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
@@ -267,7 +267,7 @@
<pluginRepository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/libs-snapshot-local</url>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
@@ -278,7 +278,7 @@
<pluginRepository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/libs-milestone-local</url>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
@@ -286,7 +286,7 @@
<pluginRepository>
<id>spring-releases</id>
<name>Spring Releases</name>
<url>https://repo.spring.io/libs-release-local</url>
<url>https://repo.spring.io/release</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
+15 -7
View File
@@ -5,16 +5,16 @@
<parent>
<artifactId>spring-cloud-dependencies-parent</artifactId>
<groupId>org.springframework.cloud</groupId>
<version>5.0.0-SNAPSHOT</version>
<version>5.0.2</version>
<relativePath/>
</parent>
<artifactId>spring-cloud-netflix-dependencies</artifactId>
<version>5.0.0-SNAPSHOT</version>
<version>5.0.2</version>
<packaging>pom</packaging>
<name>spring-cloud-netflix-dependencies</name>
<description>Spring Cloud Netflix Dependencies</description>
<properties>
<eureka.version>2.0.5</eureka.version>
<eureka.version>2.0.6</eureka.version>
</properties>
<dependencyManagement>
<dependencies>
@@ -43,6 +43,10 @@
<artifactId>eureka-client</artifactId>
<version>${eureka.version}</version>
<exclusions>
<exclusion>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
</exclusion>
<exclusion>
<groupId>com.netflix.archaius</groupId>
<artifactId>archaius-core</artifactId>
@@ -59,6 +63,10 @@
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
</exclusion>
<exclusion>
<artifactId>commons-configuration</artifactId>
<groupId>commons-configuration</groupId>
</exclusion>
<exclusion>
<artifactId>commons-logging</artifactId>
<groupId>commons-logging</groupId>
@@ -153,7 +161,7 @@
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/libs-snapshot-local</url>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
@@ -164,7 +172,7 @@
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/libs-milestone-local</url>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
@@ -182,7 +190,7 @@
<pluginRepository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/libs-snapshot-local</url>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
@@ -193,7 +201,7 @@
<pluginRepository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/libs-milestone-local</url>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
@@ -5,7 +5,7 @@
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix</artifactId>
<version>5.0.0-SNAPSHOT</version>
<version>5.0.2</version>
<relativePath>..</relativePath> <!-- lookup parent from repository -->
</parent>
<artifactId>spring-cloud-netflix-eureka-client-tls-tests</artifactId>
@@ -103,11 +103,6 @@
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.bouncycastle</groupId>
<artifactId>bcpkix-jdk15on</artifactId>
@@ -26,7 +26,7 @@ import org.junit.platform.suite.api.Suite;
* That means that when the new context starts we will fail cause the executor service is
* already shutdown.
*/
@SelectClasses({ EurekaClientTests.class, RestTemplateEurekaClientTests.class })
@SelectClasses({ EurekaClientTests.class, RestClientEurekaClientTests.class })
@Suite
public class EurekaClientSuite {
@@ -25,10 +25,11 @@ import org.junit.jupiter.api.BeforeAll;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.cloud.netflix.eureka.http.DefaultEurekaClientHttpRequestFactorySupplier;
import org.springframework.cloud.netflix.eureka.http.RestTemplateDiscoveryClientOptionalArgs;
import org.springframework.cloud.netflix.eureka.http.RestTemplateTransportClientFactories;
import org.springframework.cloud.netflix.eureka.http.RestClientDiscoveryClientOptionalArgs;
import org.springframework.cloud.netflix.eureka.http.RestClientTransportClientFactories;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestClient;
import static org.assertj.core.api.Assertions.assertThat;
@@ -44,7 +45,7 @@ public class EurekaClientTests extends BaseCertTests {
public static void setupAll() {
server = startEurekaServer(EurekaClientTests.TestEurekaServer.class);
service = startService(server, EurekaClientTests.TestApp.class);
assertThat(service.discoveryClientOptionalArgs()).isInstanceOf(RestTemplateDiscoveryClientOptionalArgs.class);
assertThat(service.discoveryClientOptionalArgs()).isInstanceOf(RestClientDiscoveryClientOptionalArgs.class);
LOG.info("Successfully asserted that Jersey will be used");
waitForRegistration(() -> new EurekaClientTests().createEurekaClient());
}
@@ -59,15 +60,16 @@ public class EurekaClientTests extends BaseCertTests {
public static class TestApp {
@Bean
public RestTemplateTransportClientFactories forceRestTemplateTransportClientFactories(
RestTemplateDiscoveryClientOptionalArgs discoveryClientOptionalArgs) {
return new RestTemplateTransportClientFactories(discoveryClientOptionalArgs);
public RestClientTransportClientFactories forceRestClientTransportClientFactories(
RestClientDiscoveryClientOptionalArgs discoveryClientOptionalArgs) {
return new RestClientTransportClientFactories(discoveryClientOptionalArgs);
}
@Bean
public RestTemplateDiscoveryClientOptionalArgs discoveryClientOptionalArgs() {
return new RestTemplateDiscoveryClientOptionalArgs(new DefaultEurekaClientHttpRequestFactorySupplier(
new RestTemplateTimeoutProperties(), Collections.emptySet()));
public RestClientDiscoveryClientOptionalArgs discoveryClientOptionalArgs() {
return new RestClientDiscoveryClientOptionalArgs(
new DefaultEurekaClientHttpRequestFactorySupplier(new TimeoutProperties(), Collections.emptySet()),
RestClient::builder);
}
}
@@ -18,6 +18,7 @@ package org.springframework.cloud.netflix.eureka;
import java.io.IOException;
import java.security.GeneralSecurityException;
import java.util.Collections;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -27,6 +28,7 @@ import org.junit.jupiter.api.BeforeAll;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.cloud.configuration.TlsProperties;
import org.springframework.cloud.netflix.eureka.http.DefaultEurekaClientHttpRequestFactorySupplier;
import org.springframework.cloud.netflix.eureka.http.EurekaClientHttpRequestFactorySupplier;
import org.springframework.cloud.netflix.eureka.http.RestClientDiscoveryClientOptionalArgs;
import org.springframework.cloud.netflix.eureka.http.RestClientTransportClientFactories;
@@ -94,6 +96,12 @@ public class RestClientEurekaClientTests extends BaseCertTests {
return new RestClientTransportClientFactories(discoveryClientOptionalArgs);
}
@Bean
EurekaClientHttpRequestFactorySupplier defaultEurekaClientHttpRequestFactorySupplier(
TimeoutProperties timeoutProperties) {
return new DefaultEurekaClientHttpRequestFactorySupplier(timeoutProperties, Collections.emptySet());
}
}
@SpringBootConfiguration
@@ -1,106 +0,0 @@
/*
* Copyright 2018-present the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.netflix.eureka;
import java.io.IOException;
import java.security.GeneralSecurityException;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.restclient.RestTemplateBuilder;
import org.springframework.cloud.configuration.TlsProperties;
import org.springframework.cloud.netflix.eureka.http.DefaultEurekaClientHttpRequestFactorySupplier;
import org.springframework.cloud.netflix.eureka.http.EurekaClientHttpRequestFactorySupplier;
import org.springframework.cloud.netflix.eureka.http.RestTemplateDiscoveryClientOptionalArgs;
import org.springframework.cloud.netflix.eureka.http.RestTemplateTransportClientFactories;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
import org.springframework.context.annotation.Bean;
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.cloud.netflix.eureka.config.DiscoveryClientOptionalArgsConfiguration.setupTLS;
public class RestTemplateEurekaClientTests extends BaseCertTests {
private static final Log log = LogFactory.getLog(RestTemplateEurekaClientTests.class);
private static EurekaServerRunner server;
private static EurekaClientRunner service;
@BeforeAll
public static void setupAll() {
server = startEurekaServer(TestEurekaServer.class);
service = startService(server, RestTemplateEurekaClientTests.RestTemplateTestApp.class);
// Will use RestTemplate
assertThat(service.discoveryClientOptionalArgs()).isInstanceOf(RestTemplateDiscoveryClientOptionalArgs.class);
log.info("Successfully asserted that RestTemplate will be used");
waitForRegistration(() -> new RestTemplateEurekaClientTests().createEurekaClient());
}
@AfterAll
public static void tearDownAll() {
stopService(service);
stopEurekaServer(server);
}
@Override
EurekaClientRunner createEurekaClient() {
return new EurekaClientRunner(RestTemplateTestApp.class, server);
}
@SpringBootConfiguration
@EnableAutoConfiguration
public static class RestTemplateTestApp {
@Bean
public RestTemplateDiscoveryClientOptionalArgs forceRestTemplateDiscoveryClientOptionalArgs(
TlsProperties tlsProperties,
EurekaClientHttpRequestFactorySupplier eurekaClientHttpRequestFactorySupplier)
throws GeneralSecurityException, IOException {
RestTemplateDiscoveryClientOptionalArgs result = new RestTemplateDiscoveryClientOptionalArgs(
eurekaClientHttpRequestFactorySupplier, RestTemplateBuilder::new);
setupTLS(result, tlsProperties);
return result;
}
@Bean
public RestTemplateTransportClientFactories forceRestTemplateTransportClientFactories(
RestTemplateDiscoveryClientOptionalArgs discoveryClientOptionalArgs) {
return new RestTemplateTransportClientFactories(discoveryClientOptionalArgs);
}
@Bean
EurekaClientHttpRequestFactorySupplier defaultEurekaClientHttpRequestFactorySupplier(
RestTemplateTimeoutProperties restTemplateTimeoutProperties) {
return new DefaultEurekaClientHttpRequestFactorySupplier(restTemplateTimeoutProperties);
}
}
@SpringBootConfiguration
@EnableAutoConfiguration
@EnableEurekaServer
public static class TestEurekaServer {
}
}
+5 -6
View File
@@ -6,7 +6,7 @@
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix</artifactId>
<version>5.0.0-SNAPSHOT</version>
<version>5.0.2</version>
<relativePath>..</relativePath> <!-- lookup parent from repository -->
</parent>
<artifactId>spring-cloud-netflix-eureka-client</artifactId>
@@ -18,6 +18,10 @@
<maven.javadoc.failOnError>false</maven.javadoc.failOnError>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-jackson2</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
@@ -97,11 +101,6 @@
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-test-support</artifactId>
@@ -21,12 +21,12 @@ import com.netflix.discovery.EurekaClient;
import com.netflix.discovery.EurekaClientConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.health.SimpleStatusAggregator;
import org.springframework.boot.actuate.health.StatusAggregator;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.health.actuate.endpoint.SimpleStatusAggregator;
import org.springframework.boot.health.actuate.endpoint.StatusAggregator;
import org.springframework.cloud.client.ConditionalOnBlockingDiscoveryEnabled;
import org.springframework.cloud.client.ConditionalOnDiscoveryEnabled;
import org.springframework.cloud.context.scope.refresh.RefreshScopeRefreshedEvent;
@@ -27,7 +27,7 @@ import com.netflix.appinfo.InstanceInfo.InstanceStatus;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.boot.actuate.health.StatusAggregator;
import org.springframework.boot.health.actuate.endpoint.StatusAggregator;
import org.springframework.boot.health.contributor.CompositeHealthContributor;
import org.springframework.boot.health.contributor.CompositeReactiveHealthContributor;
import org.springframework.boot.health.contributor.Health;
@@ -111,7 +111,7 @@ public class EurekaInstanceConfigBean implements CloudEurekaInstanceConfig, Envi
* Setting this value too long could mean that the traffic could be routed to the
* instance even though the instance is not alive. Setting this value too small could
* mean, the instance may be taken out of traffic because of temporary network
* glitches.This value to be set to atleast higher than the value specified in
* glitches.This value to be set to at least higher than the value specified in
* leaseRenewalIntervalInSeconds.
*/
private int leaseExpirationDurationInSeconds = 90;
@@ -169,7 +169,7 @@ public class EurekaInstanceConfigBean implements CloudEurekaInstanceConfig, Envi
/**
* Gets the relative status page URL path for this instance. The status page URL is
* then constructed out of the hostName and the type of communication - secure or
* unsecure as specified in securePort and nonSecurePort.
* insecure as specified in securePort and nonSecurePort.
*
* It is normally used for informational purposes for other services to find about the
* status of this instance. Users can provide a simple HTML indicating what is the
@@ -191,7 +191,7 @@ public class EurekaInstanceConfigBean implements CloudEurekaInstanceConfig, Envi
/**
* Gets the relative home page URL Path for this instance. The home page URL is then
* constructed out of the hostName and the type of communication - secure or unsecure.
* constructed out of the hostName and the type of communication - secure or insecure.
*
* It is normally used for informational purposes for other services to use it as a
* landing page.
@@ -213,7 +213,7 @@ public class EurekaInstanceConfigBean implements CloudEurekaInstanceConfig, Envi
/**
* Gets the relative health check URL path for this instance. The health check page
* URL is then constructed out of the hostname and the type of communication - secure
* or unsecure as specified in securePort and nonSecurePort.
* or insecure as specified in securePort and nonSecurePort.
*
* It is normally used for making educated decisions based on the health of the
* instance - for example, it can be used to determine whether to proceed deployments
@@ -22,7 +22,6 @@ import java.util.Objects;
import com.netflix.appinfo.InstanceInfo;
import org.springframework.cloud.client.DefaultServiceInstance;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.core.style.ToStringCreator;
import org.springframework.util.Assert;
@@ -81,7 +80,7 @@ public class EurekaServiceInstance implements ServiceInstance {
@Override
public URI getUri() {
return DefaultServiceInstance.getUri(this);
return ServiceInstance.createUri(this);
}
@Override
@@ -1,37 +0,0 @@
/*
* Copyright 2013-present the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.netflix.eureka;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.web.client.RestClient;
/**
* A {@link RestClient}-specific {@link TimeoutProperties} implementation.
*
* @author Olga Maciaszek-Sharma
* @since 4.2.0
*/
@ConfigurationProperties("eureka.client.restclient.timeout")
public class RestClientTimeoutProperties extends TimeoutProperties {
@Override
public String toString() {
return "RestClientTimeoutProperties{" + ", connectTimeout=" + connectTimeout + ", connectRequestTimeout="
+ connectRequestTimeout + ", socketTimeout=" + socketTimeout + '}';
}
}
@@ -1,43 +0,0 @@
/*
* Copyright 2013-present the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.netflix.eureka;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.web.client.RestClient;
import org.springframework.web.client.RestTemplate;
/**
* A {@link RestTemplate}-specific {@link TimeoutProperties} implementation.
*
* @author Jiwon Jeon
* @author Mooyong Lee
* @author Olga Maciaszek-Sharma
* @since 3.1.6
* @deprecated {@link RestTemplate}-based implementation to be removed in favour of
* {@link RestClient}-based implementation.
*/
@Deprecated(forRemoval = true)
@ConfigurationProperties("eureka.client.rest-template-timeout")
public class RestTemplateTimeoutProperties extends TimeoutProperties {
@Override
public String toString() {
return "RestTemplateTimeoutProperties{" + ", connectTimeout=" + connectTimeout + ", connectRequestTimeout="
+ connectRequestTimeout + ", socketTimeout=" + socketTimeout + '}';
}
}
@@ -22,10 +22,11 @@ import com.netflix.discovery.shared.transport.EurekaHttpClient;
import org.apache.hc.client5.http.config.RequestConfig;
import org.apache.hc.core5.http.io.SocketConfig;
import org.springframework.web.client.RestTemplate;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.web.client.RestClient;
/**
* Properties for configuring timeouts used in {@link RestTemplate} required by
* Properties for configuring timeouts used in {@link RestClient} required by
* {@link EurekaHttpClient}.
*
* @author Jiwon Jeon
@@ -33,7 +34,8 @@ import org.springframework.web.client.RestTemplate;
* @author Olga Maciaszek-Sharma
* @since 4.2.0
*/
public abstract class TimeoutProperties {
@ConfigurationProperties("eureka.client.timeout")
public class TimeoutProperties {
/**
* Default values are set to 180000, in keeping with {@link RequestConfig} and
@@ -78,7 +80,7 @@ public abstract class TimeoutProperties {
return false;
}
RestTemplateTimeoutProperties that = (RestTemplateTimeoutProperties) o;
TimeoutProperties that = (TimeoutProperties) o;
return connectTimeout == that.connectTimeout && connectRequestTimeout == that.connectRequestTimeout
&& socketTimeout == that.socketTimeout;
@@ -36,24 +36,19 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.SearchStrategy;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.restclient.RestTemplateBuilder;
import org.springframework.cloud.configuration.SSLContextFactory;
import org.springframework.cloud.configuration.TlsProperties;
import org.springframework.cloud.netflix.eureka.RestClientTimeoutProperties;
import org.springframework.cloud.netflix.eureka.RestTemplateTimeoutProperties;
import org.springframework.cloud.netflix.eureka.TimeoutProperties;
import org.springframework.cloud.netflix.eureka.http.DefaultEurekaClientHttpRequestFactorySupplier;
import org.springframework.cloud.netflix.eureka.http.EurekaClientHttpRequestFactorySupplier;
import org.springframework.cloud.netflix.eureka.http.RestClientDiscoveryClientOptionalArgs;
import org.springframework.cloud.netflix.eureka.http.RestClientTransportClientFactories;
import org.springframework.cloud.netflix.eureka.http.RestTemplateDiscoveryClientOptionalArgs;
import org.springframework.cloud.netflix.eureka.http.RestTemplateTransportClientFactories;
import org.springframework.cloud.netflix.eureka.http.WebClientDiscoveryClientOptionalArgs;
import org.springframework.cloud.netflix.eureka.http.WebClientTransportClientFactories;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestClient;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.reactive.function.client.WebClient;
/**
@@ -63,10 +58,10 @@ import org.springframework.web.reactive.function.client.WebClient;
* @author Wonchul Heo
*/
@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties({ RestTemplateTimeoutProperties.class, RestClientTimeoutProperties.class })
@EnableConfigurationProperties({ TimeoutProperties.class })
public class DiscoveryClientOptionalArgsConfiguration {
protected static final Log logger = LogFactory.getLog(DiscoveryClientOptionalArgsConfiguration.class);
protected static final Log LOG = LogFactory.getLog(DiscoveryClientOptionalArgsConfiguration.class);
@Bean
@ConfigurationProperties("eureka.client.tls")
@@ -83,49 +78,6 @@ public class DiscoveryClientOptionalArgsConfiguration {
}
}
/**
* @deprecated {@link RestTemplate}-based implementation to be removed in favour of
* {@link RestClient}-based implementation.
*/
@Configuration(proxyBeanMethods = false)
@Conditional(OnRestTemplatePresentAndEnabledCondition.class)
@Deprecated
static class RestTemplateConfiguration {
@Bean
@ConditionalOnMissingBean
EurekaClientHttpRequestFactorySupplier defaultEurekaClientHttpRequestFactorySupplier(
RestTemplateTimeoutProperties restTemplateTimeoutProperties,
Set<EurekaClientHttpRequestFactorySupplier.RequestConfigCustomizer> requestConfigCustomizers) {
return new DefaultEurekaClientHttpRequestFactorySupplier(restTemplateTimeoutProperties,
requestConfigCustomizers);
}
@Bean
@ConditionalOnMissingBean(value = { AbstractDiscoveryClientOptionalArgs.class },
search = SearchStrategy.CURRENT)
public RestTemplateDiscoveryClientOptionalArgs restTemplateDiscoveryClientOptionalArgs(
TlsProperties tlsProperties,
EurekaClientHttpRequestFactorySupplier eurekaClientHttpRequestFactorySupplier,
ObjectProvider<RestTemplateBuilder> restTemplateBuilders) throws GeneralSecurityException, IOException {
if (logger.isInfoEnabled()) {
logger.info("Eureka HTTP Client uses RestTemplate.");
}
RestTemplateDiscoveryClientOptionalArgs result = new RestTemplateDiscoveryClientOptionalArgs(
eurekaClientHttpRequestFactorySupplier, restTemplateBuilders::getIfAvailable);
setupTLS(result, tlsProperties);
return result;
}
@Bean
@ConditionalOnMissingBean(value = { TransportClientFactories.class }, search = SearchStrategy.CURRENT)
public RestTemplateTransportClientFactories restTemplateTransportClientFactories(
RestTemplateDiscoveryClientOptionalArgs optionalArgs) {
return new RestTemplateTransportClientFactories(optionalArgs);
}
}
@Configuration(proxyBeanMethods = false)
@Conditional(OnJerseyClientPresentAndEnabledCondition.class)
@ConditionalOnBean(value = AbstractDiscoveryClientOptionalArgs.class, search = SearchStrategy.CURRENT)
@@ -133,8 +85,8 @@ public class DiscoveryClientOptionalArgsConfiguration {
DiscoveryClientOptionalArgsTlsConfiguration(TlsProperties tlsProperties,
AbstractDiscoveryClientOptionalArgs optionalArgs) throws GeneralSecurityException, IOException {
if (logger.isInfoEnabled()) {
logger.info("Eureka HTTP Client uses Jersey");
if (LOG.isInfoEnabled()) {
LOG.info("Eureka HTTP Client uses Jersey");
}
setupTLS(optionalArgs, tlsProperties);
}
@@ -149,12 +101,12 @@ public class DiscoveryClientOptionalArgsConfiguration {
@Bean
@ConditionalOnMissingBean(
value = { AbstractDiscoveryClientOptionalArgs.class, RestTemplateDiscoveryClientOptionalArgs.class },
value = { AbstractDiscoveryClientOptionalArgs.class, RestClientDiscoveryClientOptionalArgs.class },
search = SearchStrategy.CURRENT)
public WebClientDiscoveryClientOptionalArgs webClientDiscoveryClientOptionalArgs(TlsProperties tlsProperties,
ObjectProvider<WebClient.Builder> builder) throws GeneralSecurityException, IOException {
if (logger.isInfoEnabled()) {
logger.info("Eureka HTTP Client uses WebClient.");
if (LOG.isInfoEnabled()) {
LOG.info("Eureka HTTP Client uses WebClient.");
}
WebClientDiscoveryClientOptionalArgs result = new WebClientDiscoveryClientOptionalArgs(
builder::getIfAvailable);
@@ -191,7 +143,7 @@ public class DiscoveryClientOptionalArgsConfiguration {
@Bean
@ConditionalOnMissingBean
EurekaClientHttpRequestFactorySupplier defaultEurekaClientHttpRequestFactorySupplier(
RestClientTimeoutProperties restClientTimeoutProperties,
TimeoutProperties restClientTimeoutProperties,
Set<EurekaClientHttpRequestFactorySupplier.RequestConfigCustomizer> requestConfigCustomizers) {
return new DefaultEurekaClientHttpRequestFactorySupplier(restClientTimeoutProperties,
requestConfigCustomizers);
@@ -204,8 +156,8 @@ public class DiscoveryClientOptionalArgsConfiguration {
EurekaClientHttpRequestFactorySupplier eurekaClientHttpRequestFactorySupplier,
ObjectProvider<RestClient.Builder> restClientBuilderProvider)
throws GeneralSecurityException, IOException {
if (logger.isInfoEnabled()) {
logger.info("Eureka HTTP Client uses RestClient.");
if (LOG.isInfoEnabled()) {
LOG.info("Eureka HTTP Client uses RestClient.");
}
RestClientDiscoveryClientOptionalArgs result = new RestClientDiscoveryClientOptionalArgs(
eurekaClientHttpRequestFactorySupplier,
@@ -259,46 +211,6 @@ public class DiscoveryClientOptionalArgsConfiguration {
}
/**
* @deprecated {@link RestTemplate}-based implementation to be removed in favour of
* {@link RestClient}-based implementation.
*/
@Deprecated(forRemoval = true)
static class OnRestTemplatePresentAndEnabledCondition extends AllNestedConditions {
OnRestTemplatePresentAndEnabledCondition() {
super(ConfigurationPhase.REGISTER_BEAN);
}
@ConditionalOnClass(name = "org.springframework.web.client.RestTemplate")
static class OnRestTemplatePresent {
}
@ConditionalOnClass(name = "org.springframework.boot.restclient.RestTemplateBuilder")
static class OnRestTemplateBuilderPresent {
}
@Conditional(OnJerseyClientNotPresentOrNotEnabledCondition.class)
static class OnJerseyClientNotPresentOrNotEnabled {
}
@ConditionalOnProperty(prefix = "eureka.client", name = "webclient.enabled", matchIfMissing = true,
havingValue = "false")
static class OnWebClientDisabled {
}
@ConditionalOnProperty(prefix = "eureka.client", name = "restclient.enabled", havingValue = "false",
matchIfMissing = true)
static class OnRestClientDisabled {
}
}
static class OnRestClientPresentAndEnabledCondition extends AllNestedConditions {
OnRestClientPresentAndEnabledCondition() {
@@ -321,11 +233,6 @@ public class DiscoveryClientOptionalArgsConfiguration {
}
@ConditionalOnProperty(prefix = "eureka.client", name = "restclient.enabled", havingValue = "true")
static class OnRestClientEnabled {
}
}
}
@@ -30,20 +30,16 @@ import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.SearchStrategy;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.boot.http.codec.autoconfigure.CodecsAutoConfiguration;
import org.springframework.boot.restclient.RestTemplateBuilder;
import org.springframework.boot.webclient.autoconfigure.WebClientAutoConfiguration;
import org.springframework.cloud.config.client.ConfigServerInstanceProvider;
import org.springframework.cloud.config.client.ConfigServicePropertySourceLocator;
import org.springframework.cloud.configuration.TlsProperties;
import org.springframework.cloud.netflix.eureka.EurekaClientConfigBean;
import org.springframework.cloud.netflix.eureka.RestClientTimeoutProperties;
import org.springframework.cloud.netflix.eureka.RestTemplateTimeoutProperties;
import org.springframework.cloud.netflix.eureka.TimeoutProperties;
import org.springframework.cloud.netflix.eureka.http.DefaultEurekaClientHttpRequestFactorySupplier;
import org.springframework.cloud.netflix.eureka.http.EurekaClientHttpRequestFactorySupplier;
import org.springframework.cloud.netflix.eureka.http.RestClientEurekaHttpClient;
import org.springframework.cloud.netflix.eureka.http.RestClientTransportClientFactory;
import org.springframework.cloud.netflix.eureka.http.RestTemplateEurekaHttpClient;
import org.springframework.cloud.netflix.eureka.http.RestTemplateTransportClientFactory;
import org.springframework.cloud.netflix.eureka.http.WebClientEurekaHttpClient;
import org.springframework.cloud.netflix.eureka.http.WebClientTransportClientFactory;
import org.springframework.context.annotation.Bean;
@@ -52,7 +48,6 @@ import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.lang.Nullable;
import org.springframework.web.client.RestClient;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.reactive.function.client.WebClient;
/**
@@ -67,7 +62,7 @@ import org.springframework.web.reactive.function.client.WebClient;
@ConditionalOnClass(ConfigServicePropertySourceLocator.class)
@Conditional(EurekaConfigServerBootstrapConfiguration.EurekaConfigServerBootstrapCondition.class)
@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties({ RestTemplateTimeoutProperties.class, RestClientTimeoutProperties.class })
@EnableConfigurationProperties({ TimeoutProperties.class })
public class EurekaConfigServerBootstrapConfiguration {
@Bean
@@ -82,67 +77,6 @@ public class EurekaConfigServerBootstrapConfiguration {
return new EurekaConfigServerInstanceProvider(client, config)::getInstances;
}
/**
* @deprecated {@link RestTemplate}-based implementation to be removed in favour of
* {@link RestClient}-based implementation.
*/
@Configuration(proxyBeanMethods = false)
@Conditional(RestTemplateConfiguration.OnRestTemplatePresentAndEnabledCondition.class)
@Deprecated
static class RestTemplateConfiguration {
@Bean
@ConditionalOnMissingBean(EurekaHttpClient.class)
public RestTemplateEurekaHttpClient configDiscoveryRestTemplateEurekaHttpClient(EurekaClientConfigBean config,
Environment env, @Nullable TlsProperties properties,
EurekaClientHttpRequestFactorySupplier eurekaClientHttpRequestFactorySupplier,
ObjectProvider<RestTemplateBuilder> restTemplateBuilders) {
return (RestTemplateEurekaHttpClient) new RestTemplateTransportClientFactory(properties,
eurekaClientHttpRequestFactorySupplier, restTemplateBuilders::getIfAvailable)
.newClient(HostnameBasedUrlRandomizer.randomEndpoint(config, env));
}
@Bean
@ConditionalOnMissingBean
EurekaClientHttpRequestFactorySupplier defaultEurekaClientHttpRequestFactorySupplier(
RestTemplateTimeoutProperties restTemplateTimeoutProperties,
Set<EurekaClientHttpRequestFactorySupplier.RequestConfigCustomizer> requestConfigCustomizers) {
return new DefaultEurekaClientHttpRequestFactorySupplier(restTemplateTimeoutProperties,
requestConfigCustomizers);
}
/**
* @deprecated {@link RestTemplate}-based implementation to be removed in favour
* of {@link RestClient}-based implementation.
*/
@Deprecated(forRemoval = true)
static class OnRestTemplatePresentAndEnabledCondition extends AllNestedConditions {
OnRestTemplatePresentAndEnabledCondition() {
super(ConfigurationPhase.REGISTER_BEAN);
}
@ConditionalOnClass(name = "org.springframework.web.client.RestTemplate")
static class OnRestTemplatePresent {
}
@ConditionalOnProperty(prefix = "eureka.client", name = "webclient.enabled", matchIfMissing = true,
havingValue = "false")
static class OnWebClientDisabled {
}
@ConditionalOnProperty(prefix = "eureka.client", name = "restclient.enabled", havingValue = "false",
matchIfMissing = true)
static class OnRestClientDisabled {
}
}
}
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass({ WebClient.class, WebClientAutoConfiguration.class, CodecsAutoConfiguration.class })
@ConditionalOnProperty(prefix = "eureka.client", name = "webclient.enabled", havingValue = "true")
@@ -178,10 +112,9 @@ public class EurekaConfigServerBootstrapConfiguration {
@Bean
@ConditionalOnMissingBean
EurekaClientHttpRequestFactorySupplier defaultEurekaClientHttpRequestFactorySupplier(
RestClientTimeoutProperties restClientTimeoutProperties,
TimeoutProperties timeoutProperties,
Set<EurekaClientHttpRequestFactorySupplier.RequestConfigCustomizer> requestConfigCustomizers) {
return new DefaultEurekaClientHttpRequestFactorySupplier(restClientTimeoutProperties,
requestConfigCustomizers);
return new DefaultEurekaClientHttpRequestFactorySupplier(timeoutProperties, requestConfigCustomizers);
}
static class OnRestClientPresentAndEnabledCondition extends AllNestedConditions {
@@ -201,11 +134,6 @@ public class EurekaConfigServerBootstrapConfiguration {
}
@ConditionalOnProperty(prefix = "eureka.client", name = "restclient.enabled", havingValue = "true")
static class OnRestClientEnabled {
}
}
}
@@ -20,9 +20,9 @@ import java.util.Collections;
import com.netflix.discovery.shared.transport.EurekaHttpClient;
import org.springframework.boot.BootstrapContext;
import org.springframework.boot.BootstrapRegistry;
import org.springframework.boot.BootstrapRegistryInitializer;
import org.springframework.boot.bootstrap.BootstrapContext;
import org.springframework.boot.bootstrap.BootstrapRegistry;
import org.springframework.boot.bootstrap.BootstrapRegistryInitializer;
import org.springframework.boot.context.properties.bind.BindHandler;
import org.springframework.boot.context.properties.bind.Binder;
import org.springframework.cloud.config.client.ConfigClientProperties;
@@ -30,7 +30,7 @@ import org.springframework.cloud.config.client.ConfigServerConfigDataLocationRes
import org.springframework.cloud.config.client.ConfigServerInstanceProvider;
import org.springframework.cloud.configuration.TlsProperties;
import org.springframework.cloud.netflix.eureka.EurekaClientConfigBean;
import org.springframework.cloud.netflix.eureka.RestClientTimeoutProperties;
import org.springframework.cloud.netflix.eureka.TimeoutProperties;
import org.springframework.cloud.netflix.eureka.http.DefaultEurekaClientHttpRequestFactorySupplier;
import org.springframework.cloud.netflix.eureka.http.EurekaClientHttpRequestFactorySupplier;
import org.springframework.cloud.netflix.eureka.http.RestClientTransportClientFactory;
@@ -61,7 +61,7 @@ public class EurekaConfigServerBootstrapper implements BootstrapRegistryInitiali
EurekaHttpClient httpClient = new RestClientTransportClientFactory(
context.getOrElse(TlsProperties.class, null),
context.getOrElse(EurekaClientHttpRequestFactorySupplier.class,
new DefaultEurekaClientHttpRequestFactorySupplier(new RestClientTimeoutProperties(),
new DefaultEurekaClientHttpRequestFactorySupplier(new TimeoutProperties(),
Collections.emptySet())))
.newClient(HostnameBasedUrlRandomizer.randomEndpoint(config, getPropertyResolver(context)));
return new EurekaConfigServerInstanceProvider(httpClient, config)::getInstances;
@@ -16,7 +16,6 @@
package org.springframework.cloud.netflix.eureka.http;
import java.util.Collections;
import java.util.Set;
import java.util.concurrent.TimeUnit;
@@ -34,7 +33,6 @@ import org.apache.hc.client5.http.ssl.SSLConnectionSocketFactoryBuilder;
import org.apache.hc.core5.http.io.SocketConfig;
import org.apache.hc.core5.util.Timeout;
import org.springframework.cloud.netflix.eureka.RestTemplateTimeoutProperties;
import org.springframework.cloud.netflix.eureka.TimeoutProperties;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
@@ -53,35 +51,7 @@ public class DefaultEurekaClientHttpRequestFactorySupplier implements EurekaClie
private final TimeoutProperties timeoutProperties;
// TODO: switch to final after removing deprecated interfaces
private Set<RequestConfigCustomizer> requestConfigCustomizers = Collections.emptySet();
/**
* @deprecated in favour of
* {@link DefaultEurekaClientHttpRequestFactorySupplier#DefaultEurekaClientHttpRequestFactorySupplier(TimeoutProperties, Set)}
*/
@Deprecated(forRemoval = true)
public DefaultEurekaClientHttpRequestFactorySupplier() {
this.timeoutProperties = new RestTemplateTimeoutProperties();
}
/**
* @deprecated in favour of
* {@link DefaultEurekaClientHttpRequestFactorySupplier#DefaultEurekaClientHttpRequestFactorySupplier(TimeoutProperties, Set)}
*/
@Deprecated(forRemoval = true)
public DefaultEurekaClientHttpRequestFactorySupplier(RestTemplateTimeoutProperties timeoutProperties) {
this.timeoutProperties = timeoutProperties;
}
/**
* @deprecated in favour of
* {@link DefaultEurekaClientHttpRequestFactorySupplier#DefaultEurekaClientHttpRequestFactorySupplier(TimeoutProperties, Set)}
*/
@Deprecated(forRemoval = true)
public DefaultEurekaClientHttpRequestFactorySupplier(TimeoutProperties timeoutProperties) {
this.timeoutProperties = timeoutProperties;
}
private final Set<RequestConfigCustomizer> requestConfigCustomizers;
public DefaultEurekaClientHttpRequestFactorySupplier(TimeoutProperties timeoutProperties,
Set<RequestConfigCustomizer> requestConfigCustomizers) {
@@ -24,8 +24,8 @@ import com.netflix.discovery.shared.Application;
import com.netflix.discovery.shared.Applications;
/**
* A simple wrapper class for {@link Applications} that insure proprer Jackson
* serialization through the JsonPropert overwrites.
* A simple wrapper class for {@link Applications} that insure proper Jackson
* serialization through the JsonProperties overwrites.
*
* @author Daniel Lavoie
*/
@@ -1,52 +0,0 @@
/*
* Copyright 2017-present the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.netflix.eureka.http;
import java.util.function.Supplier;
import com.netflix.discovery.AbstractDiscoveryClientOptionalArgs;
import org.springframework.boot.restclient.RestTemplateBuilder;
import org.springframework.web.client.RestClient;
import org.springframework.web.client.RestTemplate;
/**
* @author Daniel Lavoie
* @author Armin Krezovic
* @deprecated {@link RestTemplate}-based implementation to be removed in favour of
* {@link RestClient}-based implementation.
*/
@Deprecated
public class RestTemplateDiscoveryClientOptionalArgs extends AbstractDiscoveryClientOptionalArgs<Void> {
protected final EurekaClientHttpRequestFactorySupplier eurekaClientHttpRequestFactorySupplier;
protected final Supplier<RestTemplateBuilder> restTemplateBuilderSupplier;
public RestTemplateDiscoveryClientOptionalArgs(
EurekaClientHttpRequestFactorySupplier eurekaClientHttpRequestFactorySupplier) {
this(eurekaClientHttpRequestFactorySupplier, RestTemplateBuilder::new);
}
public RestTemplateDiscoveryClientOptionalArgs(
EurekaClientHttpRequestFactorySupplier eurekaClientHttpRequestFactorySupplier,
Supplier<RestTemplateBuilder> restTemplateBuilderSupplier) {
this.eurekaClientHttpRequestFactorySupplier = eurekaClientHttpRequestFactorySupplier;
this.restTemplateBuilderSupplier = restTemplateBuilderSupplier;
}
}
@@ -1,252 +0,0 @@
/*
* Copyright 2017-present the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.netflix.eureka.http;
import java.net.URI;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import com.netflix.appinfo.InstanceInfo;
import com.netflix.appinfo.InstanceInfo.InstanceStatus;
import com.netflix.discovery.shared.Application;
import com.netflix.discovery.shared.Applications;
import com.netflix.discovery.shared.transport.EurekaHttpClient;
import com.netflix.discovery.shared.transport.EurekaHttpResponse;
import com.netflix.discovery.shared.transport.EurekaHttpResponse.EurekaHttpResponseBuilder;
import com.netflix.discovery.util.StringUtil;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestClient;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;
import static com.netflix.discovery.shared.transport.EurekaHttpResponse.anEurekaHttpResponse;
/**
* @author Daniel Lavoie
* @author Václav Plic
* @deprecated {@link RestTemplate}-based implementation to be removed in favour of
* {@link RestClient}-based implementation.
*/
@Deprecated(forRemoval = true)
public class RestTemplateEurekaHttpClient implements EurekaHttpClient {
private final RestTemplate restTemplate;
private String serviceUrl;
public RestTemplateEurekaHttpClient(RestTemplate restTemplate, String serviceUrl) {
this.restTemplate = restTemplate;
this.serviceUrl = serviceUrl;
if (!serviceUrl.endsWith("/")) {
this.serviceUrl = this.serviceUrl + "/";
}
}
public String getServiceUrl() {
return this.serviceUrl;
}
public RestTemplate getRestTemplate() {
return restTemplate;
}
@Override
public EurekaHttpResponse<Void> register(InstanceInfo info) {
URI uri = UriComponentsBuilder.fromUriString(serviceUrl)
.path("apps/{appName}")
.buildAndExpand(info.getAppName())
.toUri();
HttpHeaders headers = new HttpHeaders();
headers.add(HttpHeaders.ACCEPT_ENCODING, "gzip");
headers.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE);
ResponseEntity<Void> response = restTemplate.exchange(uri, HttpMethod.POST, new HttpEntity<>(info, headers),
Void.class);
return anEurekaHttpResponse(response.getStatusCode().value()).headers(headersOf(response)).build();
}
@Override
public EurekaHttpResponse<Void> cancel(String appName, String id) {
URI uri = UriComponentsBuilder.fromUriString(serviceUrl)
.path("apps/{appName}/{id}")
.buildAndExpand(appName, id)
.toUri();
ResponseEntity<Void> response = restTemplate.exchange(uri, HttpMethod.DELETE, null, Void.class);
return anEurekaHttpResponse(response.getStatusCode().value()).headers(headersOf(response)).build();
}
@Override
public EurekaHttpResponse<InstanceInfo> sendHeartBeat(String appName, String id, InstanceInfo info,
InstanceStatus overriddenStatus) {
UriComponentsBuilder uriBuilder = UriComponentsBuilder.fromUriString(serviceUrl)
.path("apps/{appName}/{id}")
.queryParam("status", info.getStatus().toString())
.queryParam("lastDirtyTimestamp", info.getLastDirtyTimestamp().toString());
if (overriddenStatus != null) {
uriBuilder = uriBuilder.queryParam("overriddenstatus", overriddenStatus.name());
}
URI uri = uriBuilder.buildAndExpand(appName, id).toUri();
ResponseEntity<InstanceInfo> response = restTemplate.exchange(uri, HttpMethod.PUT, null, InstanceInfo.class);
EurekaHttpResponseBuilder<InstanceInfo> eurekaResponseBuilder = anEurekaHttpResponse(
response.getStatusCode().value(), InstanceInfo.class)
.headers(headersOf(response));
if (response.hasBody()) {
eurekaResponseBuilder.entity(response.getBody());
}
return eurekaResponseBuilder.build();
}
@Override
public EurekaHttpResponse<Void> statusUpdate(String appName, String id, InstanceStatus newStatus,
InstanceInfo info) {
URI uri = UriComponentsBuilder.fromUriString(serviceUrl)
.path("apps/{appName}/{id}/status")
.queryParam("value", newStatus.name())
.queryParam("lastDirtyTimestamp", info.getLastDirtyTimestamp().toString())
.buildAndExpand(appName, id)
.toUri();
ResponseEntity<Void> response = restTemplate.exchange(uri, HttpMethod.PUT, null, Void.class);
return anEurekaHttpResponse(response.getStatusCode().value()).headers(headersOf(response)).build();
}
@Override
public EurekaHttpResponse<Void> deleteStatusOverride(String appName, String id, InstanceInfo info) {
URI uri = UriComponentsBuilder.fromUriString(serviceUrl)
.path("apps/{appName}/{id}/status")
.queryParam("lastDirtyTimestamp", info.getLastDirtyTimestamp().toString())
.buildAndExpand(appName, id)
.toUri();
ResponseEntity<Void> response = restTemplate.exchange(uri, HttpMethod.DELETE, null, Void.class);
return anEurekaHttpResponse(response.getStatusCode().value()).headers(headersOf(response)).build();
}
@Override
public EurekaHttpResponse<Applications> getApplications(String... regions) {
return getApplicationsInternal("apps/", regions);
}
private EurekaHttpResponse<Applications> getApplicationsInternal(String urlPath, String[] regions) {
UriComponentsBuilder uriBuilder = UriComponentsBuilder.fromUriString(serviceUrl).path(urlPath);
if (regions != null && regions.length > 0) {
uriBuilder = uriBuilder.queryParam("regions", StringUtil.join(regions));
}
URI uri = uriBuilder.build().toUri();
ResponseEntity<EurekaApplications> response = restTemplate.exchange(uri, HttpMethod.GET, null,
EurekaApplications.class);
return anEurekaHttpResponse(response.getStatusCode().value(),
response.getStatusCode().value() == HttpStatus.OK.value() && response.hasBody()
? (Applications) response.getBody() : null)
.headers(headersOf(response))
.build();
}
@Override
public EurekaHttpResponse<Applications> getDelta(String... regions) {
return getApplicationsInternal("apps/delta", regions);
}
@Override
public EurekaHttpResponse<Applications> getVip(String vipAddress, String... regions) {
return getApplicationsInternal("vips/" + vipAddress, regions);
}
@Override
public EurekaHttpResponse<Applications> getSecureVip(String secureVipAddress, String... regions) {
return getApplicationsInternal("svips/" + secureVipAddress, regions);
}
@Override
public EurekaHttpResponse<Application> getApplication(String appName) {
URI uri = UriComponentsBuilder.fromUriString(serviceUrl).path("apps/{appName}").buildAndExpand(appName).toUri();
ResponseEntity<Application> response = restTemplate.exchange(uri, HttpMethod.GET, null, Application.class);
Application application = response.getStatusCode().value() == HttpStatus.OK.value() && response.hasBody()
? response.getBody() : null;
return anEurekaHttpResponse(response.getStatusCode().value(), application).headers(headersOf(response)).build();
}
@Override
public EurekaHttpResponse<InstanceInfo> getInstance(String appName, String id) {
return getInstanceInternal("apps", appName, id);
}
@Override
public EurekaHttpResponse<InstanceInfo> getInstance(String id) {
return getInstanceInternal("instances", id);
}
private EurekaHttpResponse<InstanceInfo> getInstanceInternal(String... pathSegments) {
URI uri = UriComponentsBuilder.fromUriString(serviceUrl).pathSegment(pathSegments).build().toUri();
ResponseEntity<InstanceInfo> response = restTemplate.exchange(uri, HttpMethod.GET, null, InstanceInfo.class);
return anEurekaHttpResponse(response.getStatusCode().value(),
response.getStatusCode().value() == HttpStatus.OK.value() && response.hasBody() ? response.getBody()
: null)
.headers(headersOf(response))
.build();
}
@Override
public void shutdown() {
// Nothing to do
}
private static Map<String, String> headersOf(ResponseEntity<?> response) {
HttpHeaders httpHeaders = response.getHeaders();
if (httpHeaders == null || httpHeaders.isEmpty()) {
return Collections.emptyMap();
}
Map<String, String> headers = new HashMap<>();
for (Entry<String, List<String>> entry : httpHeaders.headerSet()) {
if (!entry.getValue().isEmpty()) {
headers.put(entry.getKey(), entry.getValue().get(0));
}
}
return headers;
}
}
@@ -1,63 +0,0 @@
/*
* Copyright 2017-present the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.netflix.eureka.http;
import java.util.Collection;
import java.util.Optional;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import com.netflix.appinfo.InstanceInfo;
import com.netflix.discovery.EurekaClientConfig;
import com.netflix.discovery.shared.transport.TransportClientFactory;
import com.netflix.discovery.shared.transport.jersey.TransportClientFactories;
import org.springframework.web.client.RestClient;
import org.springframework.web.client.RestTemplate;
/**
* @author Daniel Lavoie
* @author Armin Krezovic
* @deprecated {@link RestTemplate}-based implementation to be removed in favour of
* {@link RestClient}-based implementation.
*/
@Deprecated(forRemoval = true)
public class RestTemplateTransportClientFactories implements TransportClientFactories<Void> {
private final RestTemplateDiscoveryClientOptionalArgs args;
public RestTemplateTransportClientFactories(RestTemplateDiscoveryClientOptionalArgs args) {
this.args = args;
}
@Override
public TransportClientFactory newTransportClientFactory(EurekaClientConfig clientConfig,
Collection<Void> additionalFilters, InstanceInfo myInstanceInfo) {
return new RestTemplateTransportClientFactory(args.getSSLContext(), args.getHostnameVerifier(),
args.eurekaClientHttpRequestFactorySupplier, args.restTemplateBuilderSupplier);
}
@Override
public TransportClientFactory newTransportClientFactory(final EurekaClientConfig clientConfig,
final Collection<Void> additionalFilters, final InstanceInfo myInstanceInfo,
final Optional<SSLContext> sslContext, final Optional<HostnameVerifier> hostnameVerifier) {
return new RestTemplateTransportClientFactory(args.getSSLContext(), args.getHostnameVerifier(),
args.eurekaClientHttpRequestFactorySupplier, args.restTemplateBuilderSupplier);
}
}
@@ -1,177 +0,0 @@
/*
* Copyright 2017-present the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.netflix.eureka.http;
import java.util.Optional;
import java.util.function.Supplier;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import com.netflix.discovery.shared.resolver.EurekaEndpoint;
import com.netflix.discovery.shared.transport.EurekaHttpClient;
import com.netflix.discovery.shared.transport.TransportClientFactory;
import org.springframework.boot.restclient.RestTemplateBuilder;
import org.springframework.cloud.configuration.TlsProperties;
import org.springframework.http.HttpStatus;
import org.springframework.http.HttpStatusCode;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.http.client.support.BasicAuthenticationInterceptor;
import org.springframework.web.client.DefaultResponseErrorHandler;
import org.springframework.web.client.RestClient;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;
import static org.springframework.cloud.netflix.eureka.http.EurekaHttpClientUtils.context;
import static org.springframework.cloud.netflix.eureka.http.EurekaHttpClientUtils.extractUserInfo;
import static org.springframework.cloud.netflix.eureka.http.EurekaHttpClientUtils.mappingJacksonHttpMessageConverter;
/**
* Provides the custom {@link RestTemplate} required by the
* {@link RestTemplateEurekaHttpClient}. Relies on Jackson for serialization and
* deserialization.
*
* @author Daniel Lavoie
* @author Armin Krezovic
* @author Wonchul Heo
* @author Olga Maciaszek-Sharma
* @deprecated {@link RestTemplate}-based implementation to be removed in favour of
* {@link RestClient}-based implementation.
*/
@Deprecated(forRemoval = true)
public class RestTemplateTransportClientFactory implements TransportClientFactory {
private final Optional<SSLContext> sslContext;
private final Optional<HostnameVerifier> hostnameVerifier;
private final EurekaClientHttpRequestFactorySupplier eurekaClientHttpRequestFactorySupplier;
private final Supplier<RestTemplateBuilder> restTemplateBuilderSupplier;
public RestTemplateTransportClientFactory(Optional<SSLContext> sslContext,
Optional<HostnameVerifier> hostnameVerifier,
EurekaClientHttpRequestFactorySupplier eurekaClientHttpRequestFactorySupplier,
Supplier<RestTemplateBuilder> restTemplateBuilderSupplier) {
this.sslContext = sslContext;
this.hostnameVerifier = hostnameVerifier;
this.eurekaClientHttpRequestFactorySupplier = eurekaClientHttpRequestFactorySupplier;
this.restTemplateBuilderSupplier = restTemplateBuilderSupplier;
}
public RestTemplateTransportClientFactory(TlsProperties tlsProperties,
EurekaClientHttpRequestFactorySupplier eurekaClientHttpRequestFactorySupplier,
Supplier<RestTemplateBuilder> restTemplateBuilderSupplier) {
this(context(tlsProperties), Optional.empty(), eurekaClientHttpRequestFactorySupplier,
restTemplateBuilderSupplier);
}
public RestTemplateTransportClientFactory(TlsProperties tlsProperties,
EurekaClientHttpRequestFactorySupplier eurekaClientHttpRequestFactorySupplier) {
this(tlsProperties, eurekaClientHttpRequestFactorySupplier, RestTemplateBuilder::new);
}
public RestTemplateTransportClientFactory(Optional<SSLContext> sslContext,
Optional<HostnameVerifier> hostnameVerifier,
EurekaClientHttpRequestFactorySupplier eurekaClientHttpRequestFactorySupplier) {
this(sslContext, hostnameVerifier, eurekaClientHttpRequestFactorySupplier, RestTemplateBuilder::new);
}
// Visible for testing
/**
* @deprecated pass the default values while initialising object in test classes.
*/
@Deprecated(forRemoval = true)
public RestTemplateTransportClientFactory() {
this(Optional.empty(), Optional.empty(), new DefaultEurekaClientHttpRequestFactorySupplier());
}
@Override
public EurekaHttpClient newClient(EurekaEndpoint serviceUrl) {
return new RestTemplateEurekaHttpClient(restTemplate(serviceUrl.getServiceUrl()),
stripUserInfo(serviceUrl.getServiceUrl()));
}
// apache http client 5.2 fails with non-null userinfo
// basic auth added in restTemplate() below
private String stripUserInfo(String serviceUrl) {
return UriComponentsBuilder.fromUriString(serviceUrl).userInfo(null).toUriString();
}
private RestTemplate restTemplate(String serviceUrl) {
ClientHttpRequestFactory requestFactory = this.eurekaClientHttpRequestFactorySupplier
.get(this.sslContext.orElse(null), this.hostnameVerifier.orElse(null));
RestTemplate restTemplate;
if (restTemplateBuilderSupplier != null && restTemplateBuilderSupplier.get() != null) {
// Avoid using RestTemplateBuilder.requestFactory(() -> requestFactory)
// when we have a concrete type, the reflective builder can throw errors if
// there is custom configuration (ie Redirects.DONT_FOLLOW) gh-4423
restTemplate = restTemplateBuilderSupplier.get().build();
restTemplate.setRequestFactory(requestFactory);
}
else {
restTemplate = new RestTemplate(requestFactory);
}
final EurekaHttpClientUtils.UserInfo userInfo = extractUserInfo(serviceUrl);
if (userInfo != null) {
restTemplate.getInterceptors()
.add(new BasicAuthenticationInterceptor(userInfo.username(), userInfo.password()));
}
restTemplate.getMessageConverters().add(0, mappingJacksonHttpMessageConverter());
restTemplate.setErrorHandler(new ErrorHandler());
restTemplate.getInterceptors().add((request, body, execution) -> {
ClientHttpResponse response = execution.execute(request, body);
if (!response.getStatusCode().equals(HttpStatus.NOT_FOUND)) {
return response;
}
return new NotFoundHttpResponse(response);
});
return restTemplate;
}
@Override
public void shutdown() {
}
class ErrorHandler extends DefaultResponseErrorHandler {
@Override
protected boolean hasError(HttpStatusCode statusCode) {
/**
* When the Eureka server restarts and a client tries to send a heartbeat the
* server will respond with a 404. By default, RestTemplate will throw an
* exception in this case. What we want is to return the 404 to the upstream
* code, so it will send another registration request to the server.
*/
if (statusCode.is4xxClientError()) {
return false;
}
return super.hasError(statusCode);
}
}
}
@@ -24,9 +24,13 @@ import com.netflix.discovery.shared.transport.EurekaHttpClient;
import com.netflix.discovery.shared.transport.TransportClientFactory;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
import reactor.netty.http.client.HttpClient;
import reactor.netty.resources.ConnectionProvider;
import reactor.netty.resources.LoopResources;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
import org.springframework.http.codec.ClientCodecConfigurer;
import org.springframework.http.codec.json.Jackson2JsonDecoder;
import org.springframework.http.codec.json.Jackson2JsonEncoder;
@@ -48,13 +52,20 @@ import static org.springframework.cloud.netflix.eureka.http.EurekaHttpClientUtil
* @author Haytham Mohamed
* @author Armin Krezovic
* @author Wonchul Heo
* @author Olga Maciaszek-Sharma
*/
public class WebClientTransportClientFactory implements TransportClientFactory {
private final Supplier<WebClient.Builder> builderSupplier;
private final ConnectionProvider connectionProvider;
private final LoopResources loopResources;
public WebClientTransportClientFactory(Supplier<WebClient.Builder> builderSupplier) {
this.builderSupplier = builderSupplier;
this.connectionProvider = ConnectionProvider.create("eureka-webclient");
this.loopResources = LoopResources.create("eureka-webclient");
}
@Override
@@ -64,6 +75,11 @@ public class WebClientTransportClientFactory implements TransportClientFactory {
setUrl(builder, endpoint.getServiceUrl());
setCodecs(builder);
builder.filter(http4XxErrorExchangeFilterFunction());
// Use dedicated Reactor Netty resources independent of the reactive web server
// to prevent RejectedExecutionException during graceful shutdown when the
// server's event loop terminates before DiscoveryClient deregisters.
builder.clientConnector(
new ReactorClientHttpConnector(HttpClient.create(this.connectionProvider).runOn(this.loopResources)));
return new WebClientEurekaHttpClient(builder.build());
}
@@ -81,6 +97,8 @@ public class WebClientTransportClientFactory implements TransportClientFactory {
ObjectMapper objectMapper = objectMapper();
builder.codecs(configurer -> {
ClientCodecConfigurer.ClientDefaultCodecs defaults = configurer.defaultCodecs();
defaults.jacksonJsonDecoder(new Jackson2JsonDecoder(objectMapper, MediaType.APPLICATION_JSON));
defaults.jacksonJsonEncoder(new Jackson2JsonEncoder(objectMapper, MediaType.APPLICATION_JSON));
defaults.jackson2JsonEncoder(new Jackson2JsonEncoder(objectMapper, MediaType.APPLICATION_JSON));
defaults.jackson2JsonDecoder(new Jackson2JsonDecoder(objectMapper, MediaType.APPLICATION_JSON));
@@ -110,6 +128,8 @@ public class WebClientTransportClientFactory implements TransportClientFactory {
@Override
public void shutdown() {
this.connectionProvider.dispose();
this.loopResources.dispose();
}
}
@@ -32,7 +32,7 @@ import org.apache.commons.logging.LogFactory;
import org.springframework.aop.framework.Advised;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.cloud.client.DefaultServiceInstance;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.serviceregistry.Registration;
import org.springframework.cloud.netflix.eureka.CloudEurekaClient;
import org.springframework.cloud.netflix.eureka.CloudEurekaInstanceConfig;
@@ -102,7 +102,7 @@ public class EurekaRegistration implements Registration {
@Override
public URI getUri() {
return DefaultServiceInstance.getUri(this);
return ServiceInstance.createUri(this);
}
@Override
@@ -12,12 +12,6 @@
"description": "Determines whether the EurekaClient instance can be refreshed or not(If disabled none of the Eureka client properties will be refreshable).",
"type": "java.lang.Boolean"
},
{
"defaultValue": false,
"name": "eureka.client.restclient.enabled",
"description": "Enables the use of RestClient for Eureka HTTP Client.",
"type": "java.lang.Boolean"
},
{
"defaultValue": false,
"name": "eureka.client.webclient.enabled",
@@ -1,5 +1,5 @@
org.springframework.cloud.bootstrap.BootstrapConfiguration=\
org.springframework.cloud.netflix.eureka.config.EurekaConfigServerBootstrapConfiguration
org.springframework.boot.BootstrapRegistryInitializer=\
org.springframework.boot.bootstrap.BootstrapRegistryInitializer=\
org.springframework.cloud.netflix.eureka.config.EurekaConfigServerBootstrapper
@@ -0,0 +1,59 @@
/*
* Copyright 2025-present the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.netflix.eureka;
import com.netflix.discovery.EurekaClient;
import com.netflix.discovery.shared.Applications;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import static org.assertj.core.api.Assertions.assertThatCode;
import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.mockito.Mockito.when;
/**
* @author Mohamed Macow
*/
@ExtendWith(MockitoExtension.class)
class EurekaDiscoveryClientTests {
@Mock
private EurekaClient eurekaClient;
@InjectMocks
private EurekaDiscoveryClient client;
@Test
void shouldCompleteProbeWhenClientHealthy() {
when(eurekaClient.getApplications()).thenReturn(new Applications());
assertThatCode(() -> client.probe()).doesNotThrowAnyException();
}
@Test
void shouldThrowProbeWhenClientThrows() {
RuntimeException eurekaException = new RuntimeException("exception");
when(eurekaClient.getApplications()).thenThrow(eurekaException);
assertThatExceptionOfType(eurekaException.getClass()).isThrownBy(() -> client.probe())
.withMessage(eurekaException.getMessage());
}
}
@@ -26,7 +26,7 @@ import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import reactor.core.publisher.Mono;
import org.springframework.boot.actuate.health.SimpleStatusAggregator;
import org.springframework.boot.health.actuate.endpoint.SimpleStatusAggregator;
import org.springframework.boot.health.contributor.AbstractHealthIndicator;
import org.springframework.boot.health.contributor.AbstractReactiveHealthIndicator;
import org.springframework.boot.health.contributor.CompositeHealthContributor;
@@ -24,7 +24,6 @@ import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.cloud.netflix.eureka.http.RestClientEurekaHttpClient;
import org.springframework.cloud.netflix.eureka.http.RestTemplateEurekaHttpClient;
import org.springframework.cloud.netflix.eureka.http.WebClientEurekaHttpClient;
import org.springframework.cloud.test.ClassPathExclusions;
@@ -36,27 +35,12 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy;
*/
class EurekaConfigServerBootstrapConfigurationClientTests {
@Test
void properBeansCreatedWhenRestTemplateEnabled() {
new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(EurekaConfigServerBootstrapConfiguration.class))
.withPropertyValues("spring.cloud.config.discovery.enabled=true")
.withPropertyValues("eureka.client.enabled=true")
.withPropertyValues("eureka.client.restclient.enabled=false")
.run(context -> {
assertThat(context).hasSingleBean(RestTemplateEurekaHttpClient.class);
assertThat(context).doesNotHaveBean(RestClientEurekaHttpClient.class);
assertThat(context).doesNotHaveBean(WebClientEurekaHttpClient.class);
});
}
@Test
void properBeansCreatedWhenRestClientEnabled() {
new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(EurekaConfigServerBootstrapConfiguration.class))
.withPropertyValues("spring.cloud.config.discovery.enabled=true")
.withPropertyValues("eureka.client.enabled=true")
.withPropertyValues("eureka.client.restclient.enabled=true")
.run(context -> {
assertThat(context).hasSingleBean(RestClientEurekaHttpClient.class);
assertThat(context).doesNotHaveBean(WebClientEurekaHttpClient.class);
@@ -80,21 +64,7 @@ class EurekaConfigServerBootstrapConfigurationClientTests {
@Nested
@ClassPathExclusions({ "spring-webflux-*" })
static class NoWebFlux {
@Test
void properBeansCreatedWhenRestTemplateEnabled() {
new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(EurekaConfigServerBootstrapConfiguration.class))
.withPropertyValues("spring.cloud.config.discovery.enabled=true")
.withPropertyValues("eureka.client.enabled=true")
.withPropertyValues("eureka.client.restclient.enabled=false")
.run(context -> {
assertThat(context).hasSingleBean(RestTemplateEurekaHttpClient.class);
assertThat(context).doesNotHaveBean(RestClientEurekaHttpClient.class);
assertThat(context).doesNotHaveBean(WebClientEurekaHttpClient.class);
});
}
class NoWebFlux {
@Test
void properBeansCreatedWhenRestClientEnabled() {
@@ -102,7 +72,6 @@ class EurekaConfigServerBootstrapConfigurationClientTests {
.withConfiguration(AutoConfigurations.of(EurekaConfigServerBootstrapConfiguration.class))
.withPropertyValues("spring.cloud.config.discovery.enabled=true")
.withPropertyValues("eureka.client.enabled=true")
.withPropertyValues("eureka.client.restclient.enabled=true")
.run(context -> {
assertThat(context).hasSingleBean(RestClientEurekaHttpClient.class);
assertThat(context).doesNotHaveBean(WebClientEurekaHttpClient.class);
@@ -22,7 +22,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.web.server.test.LocalServerPort;
import org.springframework.boot.test.web.server.LocalServerPort;
import org.springframework.cloud.netflix.eureka.http.RestClientEurekaHttpClient;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpStatus;
@@ -40,10 +40,8 @@ import static org.springframework.boot.test.context.SpringBootTest.WebEnvironmen
/**
* @author Wonchul Heo
*/
@SpringBootTest(
properties = { "spring.cloud.config.discovery.enabled=true", "eureka.client.enabled=true",
"spring.config.use-legacy-processing=true", "eureka.client.restclient.enabled=true" },
webEnvironment = RANDOM_PORT)
@SpringBootTest(properties = { "spring.cloud.config.discovery.enabled=true", "eureka.client.enabled=true",
"spring.config.use-legacy-processing=true" }, webEnvironment = RANDOM_PORT)
class EurekaConfigServerBootstrapConfigurationRestClientIntegrationTests {
@LocalServerPort
@@ -23,7 +23,6 @@ import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.cloud.config.client.ConfigServerInstanceProvider;
import org.springframework.cloud.netflix.eureka.EurekaClientConfigBean;
import org.springframework.cloud.netflix.eureka.http.RestClientEurekaHttpClient;
import org.springframework.cloud.netflix.eureka.http.RestTemplateEurekaHttpClient;
import static org.assertj.core.api.Assertions.assertThat;
@@ -33,11 +32,10 @@ import static org.assertj.core.api.Assertions.assertThat;
class EurekaConfigServerBootstrapConfigurationRestClientTests {
@Test
void properBeansCreatedWhenEnabled() {
void properBeansCreated() {
new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(EurekaConfigServerBootstrapConfiguration.class))
.withPropertyValues("spring.cloud.config.discovery.enabled=true", "eureka.client.enabled=true",
"eureka.client.restclient.enabled=true")
.withPropertyValues("spring.cloud.config.discovery.enabled=true", "eureka.client.enabled=true")
.run(context -> {
assertThat(context).hasSingleBean(EurekaClientConfigBean.class);
assertThat(context).hasSingleBean(RestClientEurekaHttpClient.class);
@@ -45,18 +43,4 @@ class EurekaConfigServerBootstrapConfigurationRestClientTests {
});
}
@Test
void properBeansCreatedWhenEnabledRestClientDisabled() {
new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(EurekaConfigServerBootstrapConfiguration.class))
.withPropertyValues("spring.cloud.config.discovery.enabled=true", "eureka.client.enabled=true",
"eureka.client.restclient.enabled=false")
.run(context -> {
assertThat(context).hasSingleBean(EurekaClientConfigBean.class);
assertThat(context).doesNotHaveBean(RestClientEurekaHttpClient.class);
assertThat(context).hasSingleBean(RestTemplateEurekaHttpClient.class);
assertThat(context).hasSingleBean(ConfigServerInstanceProvider.Function.class);
});
}
}
@@ -25,9 +25,8 @@ import com.netflix.discovery.shared.Applications;
import com.netflix.discovery.shared.transport.EurekaHttpClient;
import com.netflix.discovery.shared.transport.EurekaHttpResponse;
import org.apache.catalina.webresources.TomcatURLStreamHandlerFactory;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.AutoConfigurations;
@@ -35,13 +34,13 @@ import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.test.context.assertj.AssertableApplicationContext;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.boot.test.system.OutputCaptureRule;
import org.springframework.boot.test.system.CapturedOutput;
import org.springframework.boot.test.system.OutputCaptureExtension;
import org.springframework.cloud.config.client.ConfigServerInstanceProvider;
import org.springframework.cloud.netflix.eureka.CloudEurekaClient;
import org.springframework.cloud.netflix.eureka.EurekaClientConfigBean;
import org.springframework.cloud.netflix.eureka.http.RestTemplateEurekaHttpClient;
import org.springframework.cloud.netflix.eureka.http.RestClientEurekaHttpClient;
import org.springframework.cloud.test.ClassPathExclusions;
import org.springframework.cloud.test.ModifiedClassPathRunner;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -54,22 +53,19 @@ import static org.mockito.Mockito.when;
* @author Tang Xiong
*/
@SuppressWarnings("removal")
@RunWith(ModifiedClassPathRunner.class)
@ExtendWith(OutputCaptureExtension.class)
@ClassPathExclusions("spring-webflux-*")
public class EurekaConfigServerBootstrapConfigurationTests {
@Rule
public OutputCaptureRule output = new OutputCaptureRule();
class EurekaConfigServerBootstrapConfigurationTests {
@Test
public void offByDefault() {
void offByDefault() {
new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(EurekaConfigServerBootstrapConfiguration.class))
.run(this::assertEurekaBeansNotPresent);
}
@Test
public void properBeansCreatedWhenDiscoveryEnabled() {
void properBeansCreatedWhenDiscoveryEnabled() {
new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(EurekaConfigServerBootstrapConfiguration.class))
.withPropertyValues("spring.cloud.config.discovery.enabled=true")
@@ -77,7 +73,7 @@ public class EurekaConfigServerBootstrapConfigurationTests {
}
@Test
public void beansNotCreatedWhenDiscoveryNotEnabled() {
void beansNotCreatedWhenDiscoveryNotEnabled() {
new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(EurekaConfigServerBootstrapConfiguration.class))
.withPropertyValues("spring.cloud.config.discovery.enabled=false")
@@ -85,7 +81,7 @@ public class EurekaConfigServerBootstrapConfigurationTests {
}
@Test
public void beansNotCreatedWhenDiscoveryDisabled() {
void beansNotCreatedWhenDiscoveryDisabled() {
new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(EurekaConfigServerBootstrapConfiguration.class))
.withPropertyValues("spring.cloud.config.discovery.disabled")
@@ -93,7 +89,7 @@ public class EurekaConfigServerBootstrapConfigurationTests {
}
@Test
public void beansNotCreatedWhenEurekaClientEnabled() {
void beansNotCreatedWhenEurekaClientEnabled() {
new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(EurekaConfigServerBootstrapConfiguration.class))
.withPropertyValues("eureka.client.enabled=true")
@@ -101,7 +97,7 @@ public class EurekaConfigServerBootstrapConfigurationTests {
}
@Test
public void beansNotCreatedWhenEurekaClientNotEnabled() {
void beansNotCreatedWhenEurekaClientNotEnabled() {
new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(EurekaConfigServerBootstrapConfiguration.class))
.withPropertyValues("eureka.client.enabled=false")
@@ -109,7 +105,7 @@ public class EurekaConfigServerBootstrapConfigurationTests {
}
@Test
public void beansNotCreatedWhenEurekaClientDisabled() {
void beansNotCreatedWhenEurekaClientDisabled() {
new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(EurekaConfigServerBootstrapConfiguration.class))
.withPropertyValues("eureka.client.disabled")
@@ -117,7 +113,7 @@ public class EurekaConfigServerBootstrapConfigurationTests {
}
@Test
public void properBeansCreatedWhenDiscoveryEnabled_EurekaEnabled() {
void properBeansCreatedWhenDiscoveryEnabled_EurekaEnabled() {
new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(EurekaConfigServerBootstrapConfiguration.class))
.withPropertyValues("spring.cloud.config.discovery.enabled=true", "eureka.client.enabled=true")
@@ -125,7 +121,7 @@ public class EurekaConfigServerBootstrapConfigurationTests {
}
@Test
public void beansNotCreatedWhenDiscoveryEnabled_EurekaNotEnabled() {
void beansNotCreatedWhenDiscoveryEnabled_EurekaNotEnabled() {
new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(EurekaConfigServerBootstrapConfiguration.class))
.withPropertyValues("spring.cloud.config.discovery.enabled=true", "eureka.client.enabled=false")
@@ -133,7 +129,7 @@ public class EurekaConfigServerBootstrapConfigurationTests {
}
@Test
public void beansNotCreatedWhenDiscoveryNotEnabled_EurekaEnabled() {
void beansNotCreatedWhenDiscoveryNotEnabled_EurekaEnabled() {
new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(EurekaConfigServerBootstrapConfiguration.class))
.withPropertyValues("spring.cloud.config.discovery.enabled=false", "eureka.client.enabled=true")
@@ -141,7 +137,7 @@ public class EurekaConfigServerBootstrapConfigurationTests {
}
@Test
public void beansNotCreatedWhenDiscoveryNotEnabled_EurekaNotEnabled() {
void beansNotCreatedWhenDiscoveryNotEnabled_EurekaNotEnabled() {
new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(EurekaConfigServerBootstrapConfiguration.class))
.withPropertyValues("spring.cloud.config.discovery.enabled=false", "eureka.client.enabled=false")
@@ -149,7 +145,7 @@ public class EurekaConfigServerBootstrapConfigurationTests {
}
@Test
public void eurekaDnsConfigurationWorks() {
void eurekaDnsConfigurationWorks(CapturedOutput output) {
new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(EurekaConfigServerBootstrapConfiguration.class))
.withPropertyValues("spring.cloud.config.discovery.enabled=true", "eureka.client.enabled=true",
@@ -161,7 +157,7 @@ public class EurekaConfigServerBootstrapConfigurationTests {
}
@Test
public void eurekaConfigServerInstanceProviderCalled() {
void eurekaConfigServerInstanceProviderCalled(CapturedOutput output) {
// FIXME: why do I need to do this? (fails in maven build without it.
TomcatURLStreamHandlerFactory.disable();
new SpringApplicationBuilder(TestConfigDiscoveryConfiguration.class)
@@ -176,7 +172,7 @@ public class EurekaConfigServerBootstrapConfigurationTests {
}
@Test
public void eurekaConfigServerInstanceProviderCalledWithRemoteRegions() {
void eurekaConfigServerInstanceProviderCalledWithRemoteRegions(CapturedOutput output) {
TomcatURLStreamHandlerFactory.disable();
new SpringApplicationBuilder(TestConfigDiscoveryConfiguration.class)
.properties("spring.config.use-legacy-processing=true", "spring.cloud.config.discovery.enabled=true",
@@ -190,7 +186,7 @@ public class EurekaConfigServerBootstrapConfigurationTests {
}
@Test
public void eurekaConfigServerInstanceProviderCalledWithVipAddress() {
void eurekaConfigServerInstanceProviderCalledWithVipAddress(CapturedOutput output) {
TomcatURLStreamHandlerFactory.disable();
new SpringApplicationBuilder(TestConfigDiscoveryConfiguration.class)
.properties("spring.config.use-legacy-processing=true", "spring.cloud.config.discovery.enabled=true",
@@ -206,7 +202,7 @@ public class EurekaConfigServerBootstrapConfigurationTests {
private void assertEurekaBeansPresent(AssertableApplicationContext context) {
assertThat(context).hasSingleBean(EurekaClientConfigBean.class);
assertThat(context).hasSingleBean(RestTemplateEurekaHttpClient.class);
assertThat(context).hasSingleBean(RestClientEurekaHttpClient.class);
assertThat(context).hasSingleBean(ConfigServerInstanceProvider.Function.class);
}
@@ -22,7 +22,7 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringBootConfiguration;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.web.server.test.LocalServerPort;
import org.springframework.boot.test.web.server.LocalServerPort;
import org.springframework.cloud.netflix.eureka.http.WebClientEurekaHttpClient;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpStatus;
@@ -22,7 +22,7 @@ import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.cloud.config.client.ConfigServerInstanceProvider;
import org.springframework.cloud.netflix.eureka.EurekaClientConfigBean;
import org.springframework.cloud.netflix.eureka.http.RestTemplateEurekaHttpClient;
import org.springframework.cloud.netflix.eureka.http.RestClientEurekaHttpClient;
import org.springframework.cloud.netflix.eureka.http.WebClientEurekaHttpClient;
import static org.assertj.core.api.Assertions.assertThat;
@@ -54,7 +54,7 @@ class EurekaConfigServerBootstrapConfigurationWebClientTests {
.run(context -> {
assertThat(context).hasSingleBean(EurekaClientConfigBean.class);
assertThat(context).doesNotHaveBean(WebClientEurekaHttpClient.class);
assertThat(context).hasSingleBean(RestTemplateEurekaHttpClient.class);
assertThat(context).hasSingleBean(RestClientEurekaHttpClient.class);
assertThat(context).hasSingleBean(ConfigServerInstanceProvider.Function.class);
});
}
@@ -17,15 +17,11 @@
package org.springframework.cloud.netflix.eureka.config;
import org.apache.catalina.webresources.TomcatURLStreamHandlerFactory;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.jupiter.api.Test;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.cloud.netflix.eureka.sample.EurekaSampleApplication;
import org.springframework.cloud.test.ClassPathExclusions;
import org.springframework.cloud.test.ModifiedClassPathRunner;
import org.springframework.context.ConfigurableApplicationContext;
import static org.assertj.core.api.AssertionsForClassTypes.fail;
@@ -34,13 +30,11 @@ import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat;
/**
* @author Daniel Lavoie
*/
@RunWith(ModifiedClassPathRunner.class)
@ClassPathExclusions({ "jersey-client-*", "jersey-core-*", "jersey-apache-client4-*", "spring-webflux-*" })
@SpringBootTest(classes = EurekaSampleApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT)
public class EurekaHttpClientsOptionalArgsConfigurationNoWebFluxTests {
class EurekaHttpClientsOptionalArgsConfigurationNoWebFluxTests {
@Test
public void contextFailsWithoutWebClient() {
void contextFailsWithoutWebClient() {
ConfigurableApplicationContext ctx = null;
try {
@@ -16,18 +16,13 @@
package org.springframework.cloud.netflix.eureka.config;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.test.context.runner.WebApplicationContextRunner;
import org.springframework.cloud.netflix.eureka.http.RestClientDiscoveryClientOptionalArgs;
import org.springframework.cloud.netflix.eureka.http.RestTemplateDiscoveryClientOptionalArgs;
import org.springframework.cloud.netflix.eureka.http.WebClientDiscoveryClientOptionalArgs;
import org.springframework.cloud.netflix.eureka.sample.EurekaSampleApplication;
import org.springframework.cloud.test.ClassPathExclusions;
import org.springframework.cloud.test.ModifiedClassPathRunner;
import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat;
@@ -35,64 +30,26 @@ import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat;
* @author Daniel Lavoie
* @author Wonchul Heo
*/
@RunWith(ModifiedClassPathRunner.class)
@ClassPathExclusions({ "jersey-client-*", "jersey-core-*", "jersey-apache-client4-*" })
@SpringBootTest(classes = EurekaSampleApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT)
public class EurekaHttpClientsOptionalArgsConfigurationTests {
class EurekaHttpClientsOptionalArgsConfigurationTests {
@Test
public void contextLoadsWithRestTemplateWhenWebClientDisabled() {
public void contextLoadsWithRestClientWhenWebClientDisabled() {
new WebApplicationContextRunner().withUserConfiguration(EurekaSampleApplication.class)
.withPropertyValues("eureka.client.webclient.enabled=false")
.withPropertyValues("eureka.client.restclient.enabled=false")
.run(context -> {
assertThat(context).hasSingleBean(RestTemplateDiscoveryClientOptionalArgs.class);
assertThat(context).hasSingleBean(RestClientDiscoveryClientOptionalArgs.class);
assertThat(context).doesNotHaveBean(WebClientDiscoveryClientOptionalArgs.class);
assertThat(context).doesNotHaveBean(RestClientDiscoveryClientOptionalArgs.class);
});
}
@Test
public void contextLoadsWithRestTemplateWhenRestClientDisabled() {
new WebApplicationContextRunner().withUserConfiguration(EurekaSampleApplication.class)
.withPropertyValues("eureka.client.restclient.enabled=false")
.run(context -> {
assertThat(context).hasSingleBean(RestTemplateDiscoveryClientOptionalArgs.class);
assertThat(context).doesNotHaveBean(WebClientDiscoveryClientOptionalArgs.class);
assertThat(context).doesNotHaveBean(RestClientDiscoveryClientOptionalArgs.class);
});
}
@Test
public void contextLoadsWithWebClient() {
void contextLoadsWithWebClient() {
new WebApplicationContextRunner().withUserConfiguration(EurekaSampleApplication.class)
.withPropertyValues("eureka.client.webclient.enabled=true")
.run(context -> {
assertThat(context).doesNotHaveBean(RestTemplateDiscoveryClientOptionalArgs.class);
assertThat(context).doesNotHaveBean(RestClientDiscoveryClientOptionalArgs.class);
assertThat(context).hasSingleBean(WebClientDiscoveryClientOptionalArgs.class);
assertThat(context).doesNotHaveBean(RestClientDiscoveryClientOptionalArgs.class);
});
}
@Test
public void contextLoadsWithRestClient() {
new WebApplicationContextRunner().withUserConfiguration(EurekaSampleApplication.class)
.withPropertyValues("eureka.client.restclient.enabled=true")
.run(context -> {
assertThat(context).doesNotHaveBean(RestTemplateDiscoveryClientOptionalArgs.class);
assertThat(context).doesNotHaveBean(WebClientDiscoveryClientOptionalArgs.class);
assertThat(context).hasSingleBean(RestClientDiscoveryClientOptionalArgs.class);
});
}
@Test
public void contextLoadsWithRestTemplateAsDefault() {
new WebApplicationContextRunner().withUserConfiguration(EurekaSampleApplication.class)
.withPropertyValues("eureka.client.restclient.enabled=false")
.run(context -> {
assertThat(context).hasSingleBean(RestTemplateDiscoveryClientOptionalArgs.class);
assertThat(context).doesNotHaveBean(WebClientDiscoveryClientOptionalArgs.class);
assertThat(context).doesNotHaveBean(RestClientDiscoveryClientOptionalArgs.class);
});
}
@@ -21,7 +21,7 @@ import org.junit.jupiter.api.Test;
import org.springframework.boot.autoconfigure.AutoConfigurations;
import org.springframework.boot.test.context.runner.ApplicationContextRunner;
import org.springframework.cloud.netflix.eureka.http.RestTemplateDiscoveryClientOptionalArgs;
import org.springframework.cloud.netflix.eureka.http.RestClientDiscoveryClientOptionalArgs;
import static org.assertj.core.api.Assertions.assertThat;
@@ -30,12 +30,11 @@ import static org.assertj.core.api.Assertions.assertThat;
*
* @author Olga Maciaszek-Sharma
*/
@SuppressWarnings("deprecation")
public class JerseyClientOptionalArgsConfigurationTests {
@SuppressWarnings("OptionalGetWithoutIsPresent")
@Test
void shouldCreateRestTemplateDiscoveryClientOptionalArgsWhenJerseyClientDisabled() {
void shouldCreateRestClientDiscoveryClientOptionalArgsWhenJerseyClientDisabled() {
new ApplicationContextRunner()
.withConfiguration(AutoConfigurations.of(DiscoveryClientOptionalArgsConfiguration.class))
.withPropertyValues("eureka.client.jersey.enabled=false")
@@ -45,8 +44,8 @@ public class JerseyClientOptionalArgsConfigurationTests {
.values()
.stream()
.findFirst()
.get()).isInstanceOf(RestTemplateDiscoveryClientOptionalArgs.class);
assertThat(context).hasSingleBean(RestTemplateDiscoveryClientOptionalArgs.class);
.get()).isInstanceOf(RestClientDiscoveryClientOptionalArgs.class);
assertThat(context).hasSingleBean(RestClientDiscoveryClientOptionalArgs.class);
});
}
@@ -27,6 +27,7 @@ import com.netflix.discovery.shared.Application;
import com.netflix.discovery.shared.Applications;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.http.converter.autoconfigure.ServerHttpMessageConvertersCustomizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
@@ -34,7 +35,6 @@ import org.springframework.core.annotation.Order;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.security.config.Customizer;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.core.userdetails.User;
@@ -111,15 +111,6 @@ public class EurekaServerMockApplication {
.setNamespace("namespace1")
.build();
/**
* Simulates Eureka Server own's serialization.
* @return converter
*/
@Bean
public MappingJackson2HttpMessageConverter mappingJacksonHttpMessageConverter() {
return EurekaHttpClientUtils.mappingJacksonHttpMessageConverter();
}
@ResponseStatus(HttpStatus.OK)
@PostMapping("/apps/{appName}")
public void register(@PathVariable String appName, @RequestBody InstanceInfo instanceInfo) {
@@ -189,6 +180,17 @@ public class EurekaServerMockApplication {
return INFO;
}
/*
* Use this customizer to make sure we use the Jackson mappings for the Eureka server
*/
@Bean
@Order
ServerHttpMessageConvertersCustomizer customServerConvertersCustomizer() {
return builder -> {
builder.withJsonConverter(EurekaHttpClientUtils.mappingJacksonHttpMessageConverter());
};
}
@Configuration(proxyBeanMethods = false)
@Order(Ordered.HIGHEST_PRECEDENCE)
protected static class TestSecurityConfiguration {
@@ -32,7 +32,7 @@ import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.cloud.commons.util.InetUtils;
import org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean;
import org.springframework.cloud.netflix.eureka.RestClientTimeoutProperties;
import org.springframework.cloud.netflix.eureka.TimeoutProperties;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.web.client.RestClient;
@@ -46,7 +46,14 @@ import static org.assertj.core.api.AssertionsForClassTypes.assertThatExceptionOf
*/
@SpringBootTest(classes = EurekaServerMockApplication.class,
properties = { "debug=true", "security.basic.enabled=true", "eureka.client.fetch-registry=false",
"eureka.client.register-with-eureka=false", "logging.level.org.springframework=INFO" },
"eureka.client.register-with-eureka=false", "logging.level.org.springframework=INFO",
// spring.http.converters.preferred-json-mapper=jackson2 is only necessary
// to make the
// mock Eureka Server used in this test to work
// TODO we can likely remove this once this Boot issue is fixed post
// 2025.1.0-RC1:
// https://github.com/spring-projects/spring-boot/issues/47798
"spring.http.converters.preferred-json-mapper=jackson2" },
webEnvironment = WebEnvironment.RANDOM_PORT)
@DirtiesContext
class RestClientEurekaHttpClientTests extends AbstractEurekaHttpClientTests {
@@ -88,7 +95,7 @@ class RestClientEurekaHttpClientTests extends AbstractEurekaHttpClientTests {
private EurekaHttpClient buildEurekaHttpClient(
Set<EurekaClientHttpRequestFactorySupplier.RequestConfigCustomizer> customizers) {
return new RestClientTransportClientFactory(Optional.empty(), Optional.empty(),
new DefaultEurekaClientHttpRequestFactorySupplier(new RestClientTimeoutProperties(), customizers),
new DefaultEurekaClientHttpRequestFactorySupplier(new TimeoutProperties(), customizers),
RestClient::builder)
.newClient(new DefaultEndpoint(serviceUrl));
}
@@ -25,7 +25,7 @@ import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.cloud.netflix.eureka.RestClientTimeoutProperties;
import org.springframework.cloud.netflix.eureka.TimeoutProperties;
import org.springframework.web.client.RestClient;
import static org.assertj.core.api.Assertions.assertThat;
@@ -43,8 +43,7 @@ class RestClientTransportClientFactoryTests {
@BeforeEach
void setup() {
transportClientFactory = new RestClientTransportClientFactory(Optional.empty(), Optional.empty(),
new DefaultEurekaClientHttpRequestFactorySupplier(new RestClientTimeoutProperties(),
Collections.emptySet()),
new DefaultEurekaClientHttpRequestFactorySupplier(new TimeoutProperties(), Collections.emptySet()),
RestClient::builder);
}
@@ -1,85 +0,0 @@
/*
* Copyright 2017-present the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.netflix.eureka.http;
import java.util.List;
import com.netflix.appinfo.providers.EurekaConfigBasedInstanceInfoProvider;
import com.netflix.discovery.shared.resolver.DefaultEndpoint;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.cloud.commons.util.InetUtils;
import org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.support.BasicAuthenticationInterceptor;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.web.client.RestTemplate;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Daniel Lavoie
*/
@SpringBootTest(classes = EurekaServerMockApplication.class,
properties = { "debug=true", "security.basic.enabled=true", "eureka.client.fetch-registry=false",
"eureka.client.register-with-eureka=false", "logging.level.org.springframework=INFO" },
webEnvironment = WebEnvironment.RANDOM_PORT)
@DirtiesContext
class RestTemplateEurekaHttpClientTests extends AbstractEurekaHttpClientTests {
@Autowired
private InetUtils inetUtils;
@Value("http://${security.user.name}:${security.user.password}@localhost:${local.server.port}/eureka")
private String serviceUrl;
@BeforeEach
void setup() {
eurekaHttpClient = new RestTemplateTransportClientFactory().newClient(new DefaultEndpoint(serviceUrl));
EurekaInstanceConfigBean config = new EurekaInstanceConfigBean(inetUtils);
String appname = "customapp";
config.setIpAddress("127.0.0.1");
config.setHostname("localhost");
config.setAppname(appname);
config.setVirtualHostName(appname);
config.setSecureVirtualHostName(appname);
config.setNonSecurePort(4444);
config.setSecurePort(8443);
config.setInstanceId("127.0.0.1:customapp:4444");
info = new EurekaConfigBasedInstanceInfoProvider(config).get();
}
@Test
void basicAuth() {
assertThat(eurekaHttpClient).isInstanceOf(RestTemplateEurekaHttpClient.class);
RestTemplateEurekaHttpClient restTemplateEurekaHttpClient = (RestTemplateEurekaHttpClient) eurekaHttpClient;
RestTemplate restTemplate = restTemplateEurekaHttpClient.getRestTemplate();
List<ClientHttpRequestInterceptor> interceptors = restTemplate.getInterceptors();
boolean hasBasicAuth = interceptors.stream()
.anyMatch(interceptor -> interceptor instanceof BasicAuthenticationInterceptor);
assertThat(hasBasicAuth).as("Basic Auth not configured").isTrue();
}
}
@@ -1,94 +0,0 @@
/*
* Copyright 2017-present the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.netflix.eureka.http;
import java.util.Optional;
import com.netflix.discovery.shared.resolver.DefaultEndpoint;
import com.netflix.discovery.shared.transport.EurekaHttpClient;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.springframework.boot.http.client.ClientHttpRequestFactorySettings;
import org.springframework.boot.http.client.HttpRedirects;
import org.springframework.boot.restclient.RestTemplateBuilder;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.http.client.InterceptingClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Daniel Lavoie
* @author Wonchul Heo
*/
class RestTemplateTransportClientFactoryTests {
private RestTemplateTransportClientFactory transportClientFactory;
@BeforeEach
void setup() {
transportClientFactory = new RestTemplateTransportClientFactory();
}
@Test
void withoutUserInfo() {
EurekaHttpClient eurekaHttpClient = transportClientFactory
.newClient(new DefaultEndpoint("http://localhost:8761"));
assertThat(eurekaHttpClient).isInstanceOf(RestTemplateEurekaHttpClient.class);
}
@Test
void invalidUserInfo() {
EurekaHttpClient eurekaHttpClient = transportClientFactory
.newClient(new DefaultEndpoint("http://test@localhost:8761"));
assertThat(eurekaHttpClient).isInstanceOf(RestTemplateEurekaHttpClient.class);
}
@Test
void userInfo() {
EurekaHttpClient eurekaHttpClient = transportClientFactory
.newClient(new DefaultEndpoint("http://test:test@localhost:8761"));
assertThat(eurekaHttpClient).isInstanceOf(RestTemplateEurekaHttpClient.class);
}
@Test
void testRequestFactorySetWithRestTemplateBuilderSupplier() {
// Gateway Server WebMVC sets Redirects.DONT_FOLLOW, gh-4423
RestTemplateBuilder builder = new RestTemplateBuilder()
.requestFactorySettings(new ClientHttpRequestFactorySettings(HttpRedirects.DONT_FOLLOW, null, null, null));
transportClientFactory = new RestTemplateTransportClientFactory(Optional.empty(), Optional.empty(),
new DefaultEurekaClientHttpRequestFactorySupplier(), () -> builder);
EurekaHttpClient eurekaHttpClient = transportClientFactory
.newClient(new DefaultEndpoint("http://localhost:8761"));
RestTemplateEurekaHttpClient restTemplateEurekaHttpClient = (RestTemplateEurekaHttpClient) eurekaHttpClient;
RestTemplate restTemplate = restTemplateEurekaHttpClient.getRestTemplate();
ClientHttpRequestFactory requestFactory = restTemplate.getRequestFactory();
if (requestFactory instanceof InterceptingClientHttpRequestFactory interceptingClientHttpRequestFactory) {
requestFactory = interceptingClientHttpRequestFactory.getDelegate();
}
assertThat(requestFactory).isInstanceOf(HttpComponentsClientHttpRequestFactory.class);
}
@AfterEach
void shutdown() {
transportClientFactory.shutdown();
}
}
@@ -18,27 +18,33 @@ package org.springframework.cloud.netflix.eureka.http;
import com.netflix.appinfo.providers.EurekaConfigBasedInstanceInfoProvider;
import com.netflix.discovery.shared.resolver.DefaultEndpoint;
import com.netflix.discovery.shared.transport.EurekaHttpClient;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import reactor.netty.http.client.HttpClient;
import reactor.netty.resources.LoopResources;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.cloud.commons.util.InetUtils;
import org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean;
import org.springframework.http.HttpStatus;
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
import org.springframework.test.annotation.DirtiesContext;
import org.springframework.web.reactive.function.client.WebClient;
import static org.assertj.core.api.Assertions.assertThat;
/**
* @author Daniel Lavoie
*/
// @SpringBootTest(classes = EurekaServerMockApplication.class,
// properties = { "debug=true", "security.basic.enabled=true",
// "eureka.client.webclient.enabled=true",
// "eureka.client.fetch-registry=false", "eureka.client.register-with-eureka=false" },
// webEnvironment = WebEnvironment.RANDOM_PORT)
//
@SpringBootTest(classes = EurekaServerMockApplication.class,
properties = { "debug=true", "security.basic.enabled=true", "eureka.client.webclient.enabled=true",
"eureka.client.fetch-registry=false", "eureka.client.register-with-eureka=false" },
webEnvironment = WebEnvironment.RANDOM_PORT)
@DirtiesContext
@Disabled("https://github.com/spring-cloud/spring-cloud-netflix/issues/4495")
class WebClientEurekaHttpClientTests extends AbstractEurekaHttpClientTests {
@Autowired
@@ -67,4 +73,29 @@ class WebClientEurekaHttpClientTests extends AbstractEurekaHttpClientTests {
info = new EurekaConfigBasedInstanceInfoProvider(config).get();
}
@Test
void cancelSucceedsAfterSharedReactorResourcesDisposed() {
// Simulate the LoopResources shared between the reactive web server and a
// WebClient (as Spring Boot's ReactorResourceFactory provides by default)
LoopResources sharedResources = LoopResources.create("simulated-server");
WebClient.Builder sharedBuilder = WebClient.builder()
.clientConnector(new ReactorClientHttpConnector(HttpClient.create().runOn(sharedResources)));
WebClientTransportClientFactory factory = new WebClientTransportClientFactory(() -> sharedBuilder);
EurekaHttpClient client = factory.newClient(new DefaultEndpoint(serviceUrl));
// Simulate the reactive web server shutting down (terminates the shared event
// loop)
sharedResources.dispose();
// cancel() must succeed because the factory uses its own dedicated Reactor Netty
// resources that are independent of the shared (now disposed) web server
// resources.
// Without the fix this would throw RejectedExecutionException: event executor
// terminated
assertThat(client.cancel("test", "test").getStatusCode()).isEqualTo(HttpStatus.OK.value());
factory.shutdown();
}
}
@@ -39,6 +39,7 @@ import static org.mockito.Mockito.when;
/**
* @author Tim Ysewyn
* @author Mohamed Macow
*/
@ExtendWith(MockitoExtension.class)
class EurekaReactiveDiscoveryClientTests {
@@ -109,4 +110,21 @@ class EurekaReactiveDiscoveryClientTests {
StepVerifier.create(instances).expectNextCount(1).expectComplete().verify();
}
@Test
void shouldCompleteReactiveProbeWhenClientHealthy() {
when(eurekaClient.getApplications()).thenReturn(new Applications());
StepVerifier.create(client.reactiveProbe()).verifyComplete();
}
@Test
void shouldErrorReactiveProbeWhenClientThrows() {
RuntimeException eurekaException = new RuntimeException("exception");
when(eurekaClient.getApplications()).thenThrow(eurekaException);
StepVerifier.create(client.reactiveProbe())
.verifyErrorSatisfies(
ex -> assertThat(ex).isInstanceOf(RuntimeException.class).hasMessage(eurekaException.getMessage()));
}
}
@@ -21,7 +21,7 @@ import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.web.server.test.LocalServerPort;
import org.springframework.boot.test.web.server.LocalServerPort;
import org.springframework.cloud.client.discovery.event.InstancePreRegisteredEvent;
import org.springframework.cloud.client.discovery.event.InstanceRegisteredEvent;
import org.springframework.cloud.client.serviceregistry.Registration;
+8 -3
View File
@@ -5,14 +5,14 @@
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix</artifactId>
<version>5.0.0-SNAPSHOT</version>
<version>5.0.2</version>
<relativePath>..</relativePath> <!-- lookup parent from repository -->
</parent>
<artifactId>spring-cloud-netflix-eureka-server</artifactId>
<name>Spring Cloud Netflix Eureka Server</name>
<url>https://projects.spring.io/spring-cloud/</url>
<properties>
<jersey.version>3.1.11</jersey.version>
<jersey.version>4.0.2</jersey.version>
<wro4j.version>1.10.1</wro4j.version>
<wiremock.version>2.27.2</wiremock.version>
</properties>
@@ -81,6 +81,11 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-resttestclient</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-restclient</artifactId>
@@ -200,7 +205,7 @@
<dependency>
<groupId>org.webjars.npm</groupId>
<artifactId>jquery</artifactId>
<version>3.6.0</version>
<version>3.6.4</version>
</dependency>
<dependency>
<groupId>org.webjars.npm</groupId>
@@ -23,10 +23,10 @@ import org.junit.jupiter.api.Test;
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.resttestclient.TestRestTemplate;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.web.server.test.LocalServerPort;
import org.springframework.boot.web.server.test.client.TestRestTemplate;
import org.springframework.boot.test.web.server.LocalServerPort;
import org.springframework.cloud.netflix.eureka.server.ApplicationContextTests.Application;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpEntity;
@@ -21,9 +21,9 @@ import java.util.Map;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.resttestclient.TestRestTemplate;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.web.server.test.client.TestRestTemplate;
import org.springframework.cloud.netflix.eureka.server.ApplicationContextTests.Application;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
@@ -21,9 +21,9 @@ import java.util.Map;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.resttestclient.TestRestTemplate;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.web.server.test.client.TestRestTemplate;
import org.springframework.cloud.netflix.eureka.server.ApplicationContextTests.Application;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
@@ -23,9 +23,9 @@ import org.junit.jupiter.api.Test;
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.resttestclient.TestRestTemplate;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.web.server.test.LocalServerPort;
import org.springframework.boot.web.server.test.client.TestRestTemplate;
import org.springframework.boot.test.web.server.LocalServerPort;
import org.springframework.cloud.netflix.eureka.server.ApplicationServletPathTests.Application;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpEntity;
@@ -28,9 +28,9 @@ import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.autoconfigure.endpoint.web.WebEndpointProperties;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.resttestclient.TestRestTemplate;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.web.server.test.LocalServerPort;
import org.springframework.boot.web.server.test.client.TestRestTemplate;
import org.springframework.boot.test.web.server.LocalServerPort;
import org.springframework.cloud.netflix.eureka.server.ApplicationTests.Application;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpEntity;
@@ -21,9 +21,9 @@ import java.util.Map;
import org.junit.jupiter.api.Test;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.resttestclient.TestRestTemplate;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.web.server.test.LocalServerPort;
import org.springframework.boot.web.server.test.client.TestRestTemplate;
import org.springframework.boot.test.web.server.LocalServerPort;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
@@ -32,9 +32,9 @@ import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.resttestclient.TestRestTemplate;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.util.TestPropertyValues;
import org.springframework.boot.web.server.test.client.TestRestTemplate;
import org.springframework.cloud.context.environment.EnvironmentChangeEvent;
import org.springframework.cloud.netflix.eureka.EurekaClientConfigBean;
import org.springframework.cloud.netflix.eureka.server.EurekaServerAutoConfiguration.RefreshablePeerEurekaNodes;
@@ -4,7 +4,7 @@
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix</artifactId>
<version>5.0.0-SNAPSHOT</version>
<version>5.0.2</version>
</parent>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
<name>Spring Cloud Starter Netflix Eureka Client</name>
@@ -3,7 +3,7 @@
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix</artifactId>
<version>5.0.0-SNAPSHOT</version>
<version>5.0.2</version>
</parent>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
<name>Spring Cloud Starter Netflix Eureka Server</name>