Compare commits

...
1561 Commits
Author SHA1 Message Date
Ryan Baxter bbb4a0ff9b Merge branch '1.4.x' of github.com:spring-cloud/spring-cloud-netflix into 1.4.x 2019-05-29 11:05:36 -04:00
Ryan Baxter c04f0ff427 Updating readme 2019-05-29 11:05:24 -04:00
buildmaster 5f686dc4eb Bumping versions to 1.4.8.BUILD-SNAPSHOT after release 2019-05-22 19:16:37 +00:00
buildmaster d60ca72de6 Going back to snapshots 2019-05-22 19:16:36 +00:00
buildmaster 3fdbf7cac1 Update SNAPSHOT to 1.4.7.RELEASE 2019-05-22 19:02:57 +00:00
Ryan Baxter dc58633628 Bumping versions 2019-05-22 11:44:40 -04:00
Ryan Baxter e2d8b0c117 Cleanup ThreadLocal in SendResponseFilter. Fixes #2283 (#3530) 2019-05-10 13:49:04 -04:00
Ryan Baxter 58335907f2 Merge branch '1.4.x' of github.com:spring-cloud/spring-cloud-netflix into 1.4.x 2019-03-28 12:51:14 -04:00
Ryan Baxter 6ec4dda189 Merge branch 'spring-operator-polish-urls-remaining-1.4.x' into 1.4.x 2019-03-28 12:50:50 -04:00
Ryan Baxter 2568580731 Fixed tests 2019-03-28 12:50:29 -04:00
Spring Operator e49e38932f URL Cleanup (#3469)
This commit updates URLs to prefer the https protocol. Redirects are not followed to avoid accidentally expanding intentionally shortened URLs (i.e. if using a URL shortener).

# Fixed URLs

## Fixed Success
These URLs were switched to an https URL with a 2xx status. While the status was successful, your review is still recommended.

* [ ] http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd with 2 occurrences migrated to:
  https://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd ([https](https://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd) result 200).
* [ ] http://repo.spring.io/libs-milestone-local with 2 occurrences migrated to:
  https://repo.spring.io/libs-milestone-local ([https](https://repo.spring.io/libs-milestone-local) result 302).
* [ ] http://repo.spring.io/libs-snapshot-local with 2 occurrences migrated to:
  https://repo.spring.io/libs-snapshot-local ([https](https://repo.spring.io/libs-snapshot-local) result 302).
* [ ] http://repo.spring.io/release with 1 occurrences migrated to:
  https://repo.spring.io/release ([https](https://repo.spring.io/release) result 302).

# Ignored
These URLs were intentionally ignored.

* http://maven.apache.org/POM/4.0.0 with 82 occurrences
* http://www.isdc.ro/wro with 1 occurrences
* http://www.w3.org/2000/svg with 2 occurrences
* http://www.w3.org/2001/XMLSchema-instance with 41 occurrences
2019-03-26 11:53:05 -04:00
Spring Operator 71153c0c26 URL Cleanup (#3447)
This commit updates URLs to prefer the https protocol. Redirects are not followed to avoid accidentally expanding intentionally shortened URLs (i.e. if using a URL shortener).

# Fixed URLs

## Fixed Success
These URLs were switched to an https URL with a 2xx status. While the status was successful, your review is still recommended.

* [ ] http://www.apache.org/licenses/ with 1 occurrences migrated to:
  https://www.apache.org/licenses/ ([https](https://www.apache.org/licenses/) result 200).
* [ ] http://www.apache.org/licenses/LICENSE-2.0 with 488 occurrences migrated to:
  https://www.apache.org/licenses/LICENSE-2.0 ([https](https://www.apache.org/licenses/LICENSE-2.0) result 200).
2019-03-26 11:51:15 -04:00
Spring Operator aeb3af891a URL Cleanup
This commit updates URLs to prefer the https protocol. Redirects are not followed to avoid accidentally expanding intentionally shortened URLs (i.e. if using a URL shortener).

# HTTP URLs that Could Not Be Fixed
These URLs were unable to be fixed. Please review them to see if they can be manually resolved.

* [ ] http://conor.cc (200) with 4 occurrences could not be migrated:
   ([https](https://conor.cc) result SSLProtocolException).
* [ ] http://reactivex.io/ (200) with 1 occurrences could not be migrated:
   ([https](https://reactivex.io/) result SSLHandshakeException).
* [ ] http://richclarkdesign.com (200) with 1 occurrences could not be migrated:
   ([https](https://richclarkdesign.com) result SSLHandshakeException).
* [ ] http://tinysort.sjeiti.com/ (200) with 1 occurrences could not be migrated:
   ([https](https://tinysort.sjeiti.com/) result SSLException).
* [ ] http://www.sjeiti.com/ (301) with 1 occurrences could not be migrated:
   ([https](https://www.sjeiti.com/) result SSLException).
* [ ] http://foo.com (301) with 1 occurrences could not be migrated:
   ([https](https://foo.com) result SSLHandshakeException).

# Fixed URLs

## Fixed But Review Recommended
These URLs were fixed, but the https status was not OK. However, the https status was the same as the http request or http redirected to an https URL, so they were migrated. Your review is recommended.

* [ ] http://ejohn.org/ (301) with 1 occurrences migrated to:
  https://johnresig.com/ ([https](https://ejohn.org/) result ClosedChannelException).
* [ ] http://ejohn.org/blog/javascript-micro-templating/ (301) with 1 occurrences migrated to:
  https://johnresig.com/blog/javascript-micro-templating/ ([https](https://ejohn.org/blog/javascript-micro-templating/) result ClosedChannelException).
* [ ] http://192.168.13.90:9999/health (ConnectTimeoutException) with 1 occurrences migrated to:
  https://192.168.13.90:9999/health ([https](https://192.168.13.90:9999/health) result ConnectTimeoutException).
* [ ] http://192.168.13.90:9999/info (ConnectTimeoutException) with 1 occurrences migrated to:
  https://192.168.13.90:9999/info ([https](https://192.168.13.90:9999/info) result ConnectTimeoutException).
* [ ] http://foo.com:8000/ (ConnectTimeoutException) with 2 occurrences migrated to:
  https://foo.com:8000/ ([https](https://foo.com:8000/) result ConnectTimeoutException).
* [ ] http://www.w3.org/TR/html4/loose.dtd (ReadTimeoutException) with 1 occurrences migrated to:
  https://www.w3.org/TR/html4/loose.dtd ([https](https://www.w3.org/TR/html4/loose.dtd) result ReadTimeoutException).
* [ ] http://compose.docker.io/ (UnknownHostException) with 1 occurrences migrated to:
  https://compose.docker.io/ ([https](https://compose.docker.io/) result UnknownHostException).
* [ ] http://custom-example.com (UnknownHostException) with 1 occurrences migrated to:
  https://custom-example.com ([https](https://custom-example.com) result UnknownHostException).
* [ ] http://custom-example.com/ (UnknownHostException) with 1 occurrences migrated to:
  https://custom-example.com/ ([https](https://custom-example.com/) result UnknownHostException).
* [ ] http://earlymade.com (UnknownHostException) with 4 occurrences migrated to:
  https://earlymade.com ([https](https://earlymade.com) result UnknownHostException).
* [ ] http://ec2-256-156-243-129.compute-1.amazonaws.com:7001/eureka/ (UnknownHostException) with 1 occurrences migrated to:
  https://ec2-256-156-243-129.compute-1.amazonaws.com:7001/eureka/ ([https](https://ec2-256-156-243-129.compute-1.amazonaws.com:7001/eureka/) result UnknownHostException).
* [ ] http://example.com,http://example2.com (UnknownHostException) with 2 occurrences migrated to:
  https://example.com,http://example2.com ([https](https://example.com,https://example2.com) result UnknownHostException).
* [ ] http://example1.com,http://example2.com (UnknownHostException) with 1 occurrences migrated to:
  https://example1.com,http://example2.com ([https](https://example1.com,https://example2.com) result UnknownHostException).
* [ ] http://first.example.com (UnknownHostException) with 1 occurrences migrated to:
  https://first.example.com ([https](https://first.example.com) result UnknownHostException).
* [ ] http://hostname:port/turbine/turbine.stream (UnknownHostException) with 1 occurrences migrated to:
  https://hostname:port/turbine/turbine.stream ([https](https://hostname:port/turbine/turbine.stream) result UnknownHostException).
* [ ] http://hystrix-app:port/hystrix.stream (UnknownHostException) with 1 occurrences migrated to:
  https://hystrix-app:port/hystrix.stream ([https](https://hystrix-app:port/hystrix.stream) result UnknownHostException).
* [ ] http://legacy.example.com (UnknownHostException) with 1 occurrences migrated to:
  https://legacy.example.com ([https](https://legacy.example.com) result UnknownHostException).
* [ ] http://my.turbine.sever:8080/turbine.stream?cluster=CLUSTERNAME (UnknownHostException) with 1 occurrences migrated to:
  https://my.turbine.sever:8080/turbine.stream?cluster=CLUSTERNAME ([https](https://my.turbine.sever:8080/turbine.stream?cluster=CLUSTERNAME) result UnknownHostException).
* [ ] http://my.turbine.sever:8989/turbine.stream (UnknownHostException) with 1 occurrences migrated to:
  https://my.turbine.sever:8989/turbine.stream ([https](https://my.turbine.sever:8989/turbine.stream) result UnknownHostException).
* [ ] http://my.turbine.sever:8989/turbine.stream?cluster=customers (UnknownHostException) with 1 occurrences migrated to:
  https://my.turbine.sever:8989/turbine.stream?cluster=customers ([https](https://my.turbine.sever:8989/turbine.stream?cluster=customers) result UnknownHostException).
* [ ] http://my.turbine.sever:8989/turbine.stream?cluster=default (UnknownHostException) with 1 occurrences migrated to:
  https://my.turbine.sever:8989/turbine.stream?cluster=default ([https](https://my.turbine.sever:8989/turbine.stream?cluster=default) result UnknownHostException).
* [ ] http://my.turbine.sever:8989/turbine.stream?cluster=products (UnknownHostException) with 1 occurrences migrated to:
  https://my.turbine.sever:8989/turbine.stream?cluster=products ([https](https://my.turbine.sever:8989/turbine.stream?cluster=products) result UnknownHostException).
* [ ] http://sidecar.local.spring.io:5678/configserver/default-master.yml (UnknownHostException) with 1 occurrences migrated to:
  https://sidecar.local.spring.io:5678/configserver/default-master.yml ([https](https://sidecar.local.spring.io:5678/configserver/default-master.yml) result UnknownHostException).
* [ ] http://turbine-hostname:port/turbine.stream (UnknownHostException) with 1 occurrences migrated to:
  https://turbine-hostname:port/turbine.stream ([https](https://turbine-hostname:port/turbine.stream) result UnknownHostException).
* [ ] http://turbine-hostname:port/turbine.stream?cluster= (UnknownHostException) with 1 occurrences migrated to:
  https://turbine-hostname:port/turbine.stream?cluster= ([https](https://turbine-hostname:port/turbine.stream?cluster=) result UnknownHostException).
* [ ] http://user2:pwd2@test2.com (UnknownHostException) with 1 occurrences migrated to:
  https://user2:pwd2@test2.com ([https](https://user2:pwd2@test2.com) result UnknownHostException).
* [ ] http://user:foo@example.com:80/eureka (UnknownHostException) with 1 occurrences migrated to:
  https://user:foo@example.com:80/eureka ([https](https://user:foo@example.com:80/eureka) result UnknownHostException).
* [ ] http://user:pwd@test1.com (UnknownHostException) with 1 occurrences migrated to:
  https://user:pwd@test1.com ([https](https://user:pwd@test1.com) result UnknownHostException).
* [ ] http://example.com/users_service (404) with 1 occurrences migrated to:
  https://example.com/users_service ([https](https://example.com/users_service) result 404).

## Fixed Success
These URLs were switched to an https URL with a 2xx status. While the status was successful, your review is still recommended.

* [ ] http://asciidoctor.org with 1 occurrences migrated to:
  https://asciidoctor.org ([https](https://asciidoctor.org) result 200).
* [ ] http://example.com with 17 occurrences migrated to:
  https://example.com ([https](https://example.com) result 200).
* [ ] http://example.com/ with 5 occurrences migrated to:
  https://example.com/ ([https](https://example.com/) result 200).
* [ ] http://github.com/ with 1 occurrences migrated to:
  https://github.com/ ([https](https://github.com/) result 200).
* [ ] http://jquery-howto.blogspot.com/2009/09/get-url-parameters-values-with-jquery.html with 1 occurrences migrated to:
  https://jquery-howto.blogspot.com/2009/09/get-url-parameters-values-with-jquery.html ([https](https://jquery-howto.blogspot.com/2009/09/get-url-parameters-values-with-jquery.html) result 200).
* [ ] http://martinfowler.com/bliki/CircuitBreaker.html with 1 occurrences migrated to:
  https://martinfowler.com/bliki/CircuitBreaker.html ([https](https://martinfowler.com/bliki/CircuitBreaker.html) result 200).
* [ ] http://projects.spring.io/spring-cloud/ with 7 occurrences migrated to:
  https://projects.spring.io/spring-cloud/ ([https](https://projects.spring.io/spring-cloud/) result 200).
* [ ] http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html with 1 occurrences migrated to:
  https://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html ([https](https://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html) result 200).
* [ ] http://www.gnu.org/licenses/gpl.html with 1 occurrences migrated to:
  https://www.gnu.org/licenses/gpl.html ([https](https://www.gnu.org/licenses/gpl.html) result 200).
* [ ] http://www.slideshare.net/MikeyCohen1/edge-architecture-ieee-international-conference-on-cloud-engineering-32240146/27 with 1 occurrences migrated to:
  https://www.slideshare.net/MikeyCohen1/edge-architecture-ieee-international-conference-on-cloud-engineering-32240146/27 ([https](https://www.slideshare.net/MikeyCohen1/edge-architecture-ieee-international-conference-on-cloud-engineering-32240146/27) result 200).
* [ ] http://commons.apache.org/proper/commons-configuration with 1 occurrences migrated to:
  https://commons.apache.org/proper/commons-configuration ([https](https://commons.apache.org/proper/commons-configuration) result 301).
* [ ] http://creativecommons.org/licenses/MIT/ with 4 occurrences migrated to:
  https://creativecommons.org/licenses/MIT/ ([https](https://creativecommons.org/licenses/MIT/) result 301).
* [ ] http://plugins.jetbrains.com/plugin/6546 with 1 occurrences migrated to:
  https://plugins.jetbrains.com/plugin/6546 ([https](https://plugins.jetbrains.com/plugin/6546) result 301).
* [ ] http://raw.github.com/ with 1 occurrences migrated to:
  https://raw.github.com/ ([https](https://raw.github.com/) result 301).
* [ ] http://service.com with 4 occurrences migrated to:
  https://service.com ([https](https://service.com) result 301).
* [ ] http://www.opensource.org/licenses/mit-license.php with 1 occurrences migrated to:
  https://www.opensource.org/licenses/mit-license.php ([https](https://www.opensource.org/licenses/mit-license.php) result 301).
* [ ] http://eclipse.org with 1 occurrences migrated to:
  https://eclipse.org ([https](https://eclipse.org) result 302).
* [ ] http://eclipse.org/m2e/ with 2 occurrences migrated to:
  https://eclipse.org/m2e/ ([https](https://eclipse.org/m2e/) result 302).
* [ ] http://example2.com/ with 1 occurrences migrated to:
  https://example2.com/ ([https](https://example2.com/) result 302).
* [ ] http://simplegrid.info with 4 occurrences migrated to:
  https://simplegrid.info ([https](https://simplegrid.info) result 302).
* [ ] http://simplegrid.info/ with 1 occurrences migrated to:
  https://simplegrid.info/ ([https](https://simplegrid.info/) result 302).
* [ ] http://www.springsource.com/developer/sts with 1 occurrences migrated to:
  https://www.springsource.com/developer/sts ([https](https://www.springsource.com/developer/sts) result 302).

# Ignored
These URLs were intentionally ignored.

* http://%s:%s with 1 occurrences
* http://ATLAS/api/v1/graph?q=name,rest,:eq,:avg with 1 occurrences
* http://ATLAS/api/v1/tags with 1 occurrences
* http://PROD-SVC with 2 occurrences
* http://badClients/good with 1 occurrences
* http://badClients/null with 1 occurrences
* http://badClients/ping with 1 occurrences
* http://badClients/timeout with 1 occurrences
* http://bad_hostname with 1 occurrences
* http://bar with 1 occurrences
* http://bar/ with 1 occurrences
* http://foo with 22 occurrences
* http://foo/ with 7 occurrences
* http://foo/%20bar with 1 occurrences
* http://foo/%20bar?hello=1+2 with 2 occurrences
* http://foo/?name=%7bcookie with 1 occurrences
* http://foo:7001/ with 1 occurrences
* http://foo:7777/ with 2 occurrences
* http://good-name with 2 occurrences
* http://host/doStuff with 1 occurrences
* http://host:7777/Management/health with 1 occurrences
* http://host:7777/Management/info with 1 occurrences
* http://host:7777/Server/Management/health with 1 occurrences
* http://host:7777/Server/Management/info with 1 occurrences
* http://host:7777/Server/health with 1 occurrences
* http://host:7777/Server/info with 1 occurrences
* http://host:7777/health with 1 occurrences
* http://host:7777/info with 1 occurrences
* http://host:8888/Management/health with 3 occurrences
* http://host:8888/Management/info with 3 occurrences
* http://host:8888/health with 2 occurrences
* http://host:8888/info with 2 occurrences
* http://listener with 6 occurrences
* http://localhost with 143 occurrences
* http://localhost:%d%s with 3 occurrences
* http://localhost:%d/eager/sample with 1 occurrences
* http://localhost:%d/service/redirectedUri with 1 occurrences
* http://localhost:5678/configserver with 1 occurrences
* http://localhost:5678/customers with 1 occurrences
* http://localhost:5678/hosts/ with 1 occurrences
* http://localhost:7001 with 1 occurrences
* http://localhost:7001/ with 1 occurrences
* http://localhost:7001/api/v1/publish with 2 occurrences
* http://localhost:7001/api/v1/publish/ with 1 occurrences
* http://localhost:7777/local with 4 occurrences
* http://localhost:8000/health.json with 1 occurrences
* http://localhost:8000/src/test/resources/health.json with 1 occurrences
* http://localhost:8081 with 3 occurrences
* http://localhost:8761 with 2 occurrences
* http://localhost:8761/eureka/ with 5 occurrences
* http://localhost:9000 with 4 occurrences
* http://localhost:9999 with 2 occurrences
* http://mhhost2:0/foo/health with 2 occurrences
* http://mhhost2:0/foo/info with 2 occurrences
* http://myhost2:9000 with 1 occurrences
* http://myhost:8080 with 1 occurrences
* http://myhost:8989 with 1 occurrences
* http://myhost:9000 with 1 occurrences
* http://myservice with 1 occurrences
* http://peer1/eureka/ with 1 occurrences
* http://peer1/eureka/,http://peer2/eureka/,http://peer3/eureka/ with 1 occurrences
* http://peer2/eureka/ with 1 occurrences
* http://simple/ with 1 occurrences
* http://simple/emptypost with 1 occurrences
* http://simple/header with 1 occurrences
* http://simple/path/ with 2 occurrences
* http://simple/post with 1 occurrences
* http://simple/request?param= with 1 occurrences
* http://simple_bad with 1 occurrences
* http://test1.com with 1 occurrences
* http://test1.com,http://test2.com with 1 occurrences
* http://test1.com,http://user2:pwd2@test2.com with 1 occurrences
* http://test2.com with 1 occurrences
* http://test3.com,http://test4.com with 1 occurrences
* http://test3.com,http://user4:pwd4@test4.com with 1 occurrences
* http://test:test@localhost:8761 with 1 occurrences
* http://test@localhost:8761 with 1 occurrences
* http://testclient/orders/ with 1 occurrences
* http://testclient/orders/1 with 1 occurrences
* http://user:password@localhost:8761/eureka with 1 occurrences
* http://user:password@localhost:8761/eureka/ with 1 occurrences
2019-03-26 03:43:19 -05:00
Spring Operator c538e32c3e URL Cleanup (#3426)
This commit updates URLs to prefer the https protocol. Redirects are not followed to avoid accidentally expanding intentionally shortened URLs (i.e. if using a URL shortener).

# Fixed URLs

## Fixed Success 
These URLs were switched to an https URL with a 2xx status. While the status was successful, your review is still recommended.

* http://maven.apache.org/xsd/maven-4.0.0.xsd with 41 occurrences migrated to:  
  https://maven.apache.org/xsd/maven-4.0.0.xsd ([https](https://maven.apache.org/xsd/maven-4.0.0.xsd) result 200).
* http://stackoverflow.com/questions/1593051/how-to-programmatically-determine-the-current-checked-out-git-branch with 1 occurrences migrated to:  
  https://stackoverflow.com/questions/1593051/how-to-programmatically-determine-the-current-checked-out-git-branch ([https](https://stackoverflow.com/questions/1593051/how-to-programmatically-determine-the-current-checked-out-git-branch) result 200).
* http://stackoverflow.com/questions/29300806/a-bash-script-to-check-if-a-string-is-present-in-a-comma-separated-list-of-strin with 1 occurrences migrated to:  
  https://stackoverflow.com/questions/29300806/a-bash-script-to-check-if-a-string-is-present-in-a-comma-separated-list-of-strin ([https](https://stackoverflow.com/questions/29300806/a-bash-script-to-check-if-a-string-is-present-in-a-comma-separated-list-of-strin) result 200).
* http://www.apache.org/licenses/LICENSE-2.0 with 2 occurrences migrated to:  
  https://www.apache.org/licenses/LICENSE-2.0 ([https](https://www.apache.org/licenses/LICENSE-2.0) result 200).

# Ignored
These URLs were intentionally ignored.

* http://maven.apache.org/POM/4.0.0 with 82 occurrences
* http://www.w3.org/2001/XMLSchema-instance with 41 occurrences
2019-03-16 11:57:58 -04:00
Ryan Baxter 8334ff96bc Fixing key names 2018-12-17 20:10:33 -05:00
Ryan Baxter 4ab9897b3b Merge remote-tracking branch 'origin/1.3.x' into 1.4.x 2018-12-17 10:09:28 -05:00
ivansjg 2fffb2606e Inner map metrics with same name are being overwritten on actuator me… (#3317)
* Inner map metrics with same name are being overwritten on actuator metrics endpoint

* Add Hystrix Inner map metrics tests
2018-12-17 10:08:19 -05:00
Ryan Baxter 0c3fbc34f6 Do Not Use AIM Proxy In EurekaClient (#3240)
* By not using the proxy in the EurekaClient we avoid the problem of trying to fetch the bean during shutdown.  Fixes #3174
2018-10-19 10:42:25 -04:00
buildmaster 01ac98df8f Bumping versions to 1.4.7.BUILD-SNAPSHOT after release 2018-10-15 20:55:16 +00:00
buildmaster 3a62567ec8 Going back to snapshots 2018-10-15 20:55:15 +00:00
buildmaster 3f0a43f913 Update SNAPSHOT to Edgware.SR5 2018-10-15 20:44:32 +00:00
Ryan Baxter edd24bc51b Only copy the requestentity in zuul if the request is retryable. Fixes #2903 (#3221) 2018-10-09 09:38:24 -04:00
Ryan Baxter 482deb0485 Adds additional-spring-configuration-metadata. Fixes #3164 2018-10-02 09:43:06 -04:00
Dennis Effing 81579f522f Fix for #1251 (#3211)
Example uses the same value of eureka.client.serviceUrl.defaultZone for all peers. The eureka server knows who it is and doesn't attempt to replicate to itself [1], so this simplification will work.

[1]https://github.com/Netflix/eureka/blob/v1.4.10/eureka-core/src/main/java/com/netflix/eureka/registry/PeerAwareInstanceRegistryImpl.java#L616-L619

Cherry picked from commit 4b40a45
2018-09-26 16:22:40 -04:00
Ryan Baxter 46719c0c31 Fix invalid URI error when Feign request URI does not end in / (#3136)
* Fix invalid URI error when Feign request URI does not end in /
2018-08-13 14:08:55 -04:00
Ryan Baxter d98b3ce3d6 Remove commented out lines 2018-08-06 10:27:46 -04:00
Ryan Baxter f19c7fbbe2 Exclude Netty dependencies. Fixes #3119 2018-08-06 10:25:36 -04:00
Ryan Baxter fd20f81885 Make sure management path is set correctly when not using metadata provider. Fixes #3098 (#3100) 2018-07-30 13:48:46 -04:00
Ryan Baxter cf0d54450a Inject OK Http client bean instead of using variable. Fixes #43 in spring cloud openfeign. 2018-07-24 09:42:58 -04:00
Patrick Way 82fcb82d92 fixes #3053 (#3079)
* fixes 3053 Use RibbonStatsRecorder for updating ServerStats upon sucessful requests
2018-07-19 20:03:46 -04:00
Bertrand Renuart cb0a1d6d83 Invoke super.onCacheRefreshed() before custom logic (#2604) 2018-07-12 07:43:51 -04:00
Ryan Baxter 42449ee34e Check EurkaClient proxy before casting to DiscoveryClient. Fixes #3058 (#3070) 2018-07-11 16:48:00 -04:00
AddoZhang 965fbf847b Filter out service without instances from health status (#3068)
* #3063 filter out service without instances from health status

* #3063 use not empty condition
2018-07-10 14:03:17 -04:00
arkin 7630acffc6 Fixes Ribbon Apache Client Configuration Effectively Ignoring PoolKeepAliveTime (#3039)
* Fixes Ribbon Apache Client Configuration Effectively Ignoring PoolKeepAliveTime
2018-06-29 15:49:46 -04:00
buildmaster f8f5a88ec6 Bumping versions to 1.4.6.BUILD-SNAPSHOT after release 2018-06-29 15:45:55 +00:00
buildmaster d84b32fc92 Going back to snapshots 2018-06-29 15:45:54 +00:00
buildmaster 6eff7e25a3 Update SNAPSHOT to 1.4.5.RELEASE 2018-06-29 15:16:42 +00:00
Ryan Baxter a57c719649 Disable servo by default. (#3041) 2018-06-29 09:30:57 -04:00
Taras Danylchuk c181163a75 fixes https://github.com/spring-cloud/spring-cloud-netflix/issues/2972 (#3018)
root cause:
cached bean trying to re-register
resolution summary:
get re-created bean from context to re-register
2018-06-27 11:46:34 -04:00
Ryan Baxter 8af3ae8af8 Use management metadata in sidecar. Fixes 2859. (#3028) 2018-06-26 10:36:46 -04:00
Ryan Baxter ab7b0fb3a8 Clarify health and status url context path docs. Fixes #2804. 2018-06-25 09:30:48 -04:00
Ryan Baxter 7b75fe934e Return 404 upstream when using Eureka and RestTemplate. Fixes #2861 (#3023) 2018-06-25 09:05:28 -04:00
Yongsung Yoon 8c7116b2d8 Add support cluster query param in TurbineStream (#3001) 2018-06-21 12:39:41 -04:00
Spencer Gibb 2df81038f9 Adds .jdk8 file back 2018-06-15 14:32:06 -04:00
Ryan Baxter 381a097045 Does not set accept-encoding header when zuul proxies request if already present. Fixes #2998 (#3011) 2018-06-15 14:16:23 -04:00
Ryan Baxter 0970a3ef62 Adding boot autoconfigure processor 2018-06-11 05:21:27 -04:00
Ryan Baxter 84084fc36a Upgrading Zuul to 1.3.1. Closes #2974 2018-05-30 15:09:00 -04:00
Ryan Baxter d95a01b9b5 Compatibility with Java 1.7 when cherry picking 50924f296f 2018-05-30 15:08:38 -04:00
Spencer Gibb b9bfd4fbb2 Moves from archaius to boot properties.
This fixes problems in testing while maintaining backwards compatibility.

Allows upgrade of zuul to 1.3.1
2018-05-30 14:52:17 -04:00
Ryan Baxter f14d94fe3e Revert "Updating Zuul version."
This reverts commit 61a920e0a5.
2018-05-30 12:53:02 -04:00
Ryan Baxter 61a920e0a5 Updating Zuul version. 2018-05-30 10:04:34 -04:00
Jawher Moussa 0c4a46bea3 Fix Zuul's RequestContext.getOriginResponseHeaders not being populated (#2980)
Fixes #2979
2018-05-29 20:05:33 -04:00
Ryan Baxter 038106de17 Fixing typo in hystrix dashboard starter
Closes #2975
2018-05-29 13:43:17 -04:00
ScienJus 82b51b7a36 Fixed: remove misplaced StringEncoder setting when dealing with protobuf (#2453)
* Fixed: remove misplaced StringEncoder setting place when dealing with protobuf

* test SpringEncoder when protobuf is not in classpath
2018-05-18 11:46:49 -04:00
Mário Buratto d62c788cd7 Fixed content length handling issues. (#2894) (#2920)
* Fixed content length handling issues. (#2894)

* Added test setup and cleanup for RequestContext. (#2894)
2018-05-14 19:36:58 -04:00
saga 21ff95e97b Repair inconsistency (#2932)
Fix #2910
2018-05-14 19:30:24 -04:00
Ryan Baxter 4e155f4c3b Use condition on type string instead of class
Avoid problems if OKHTTP is not on the classpath.  Fixes #2797
2018-05-02 15:48:37 -04:00
Ryan Baxter 520d12631b Fix bean names. Fixes #2844 2018-04-17 13:28:18 -04:00
Ryan Baxter d8582f7814 Changing Cloudfoundry to Cloud Foundry 2018-04-17 12:32:59 -04:00
buildmaster 3ebda28fed Bumping versions to 1.4.5.BUILD-SNAPSHOT after release 2018-03-26 21:33:48 +00:00
buildmaster 3a0ff1f94d Going back to snapshots 2018-03-26 21:33:47 +00:00
buildmaster 50a02e3ba4 Update SNAPSHOT to 1.4.4.RELEASE 2018-03-26 20:57:46 +00:00
Ryan Baxter bf99c6236e Update to latest Eureka version. Fixes #2792 2018-03-22 09:25:57 -04:00
Ryan Baxter 722a626e55 Merge remote-tracking branch 'origin/1.3.x' into 1.4.x 2018-03-19 15:58:24 -04:00
Ryan Baxter 90a514d935 Remove old circle config 2018-03-19 15:56:57 -04:00
Ryan Baxter b5a2291ec6 Fixing yaml config formatting 2018-03-19 14:47:14 -04:00
Ryan Baxter d2d2dede3f Merge remote-tracking branch 'origin/1.3.x' into 1.4.x 2018-03-19 14:46:19 -04:00
Ryan Baxter 3a5e12b895 Adding circle 2.0 config 2018-03-19 14:29:39 -04:00
Ryan Baxter dadd86056e Fixes #2779 2018-03-14 09:38:03 -04:00
Ryan Baxter dd4b967fbf Fix NPE when empty body during retry (#2775) 2018-03-13 16:31:37 -04:00
darkius b99faba3cd Fix management context path in URL (#2702) (#2769) 2018-03-13 09:23:46 -04:00
Ryan Baxter 57a6693de7 Bumping ribbon version. Fixes #2752 2018-03-12 15:41:32 -04:00
Ryan Baxter a8b92a2211 Merge branch '1.4.x' of github.com:spring-cloud/spring-cloud-netflix into 1.4.x 2018-02-23 15:32:57 -05:00
Ryan Baxter 7e433bf901 Fixes #2740. 2018-02-23 15:32:33 -05:00
Patrick Way 16155ed852 Fix npe when no servers available (#2727)
* Retryable Clients should validate the service server and throw an exception if necessary

* fixing spelling error

* RetryableRibbonLoadBalancingClient should throw a ClientException which can be handled by the RibbonRoutingFilter

* moving service instance validation and service instance chooser to the AbstractLoadBalancingClient

* Updating RetryCallback within RetryableRibbonLoadBalancingHttpClient to handel Exception
2018-02-23 09:44:32 -05:00
Ryan Baxter c84d20cdbe Reenabling ignored test 2018-02-22 09:39:29 -05:00
Ryan Baxter 276b2ada0c Ignoring potential test problem 2018-02-21 20:35:50 -05:00
Ryan Baxter 2c4ae35127 Making application classes not public 2018-02-21 20:27:18 -05:00
Ryan Baxter 021dc55898 making sure ssl is disabled 2018-02-21 20:13:26 -05:00
Ryan Baxter c35796af7e Use disable ssl validation property. Fixes #2729 (#2733) 2018-02-20 15:19:57 -05:00
Ryan Baxter 6eb497770b Merge branch '1.3.x' into 1.4.x 2018-02-19 20:48:56 -05:00
Ryan Baxter ba17eb6a31 Feign compression configuration fixes (#2717)
* feign compression configuration fixes.  Fixes #2462
2018-02-19 07:39:53 -05:00
Spencer Gibb 31c974c461 remove brixton references 2018-02-12 11:42:26 -05:00
Spencer Gibb d4e7fdef7e remove brixton references 2018-02-12 11:41:06 -05:00
buildmaster 70ea5ed597 Bumping versions to 1.4.4.BUILD-SNAPSHOT after release 2018-02-08 15:59:23 +00:00
buildmaster dd9e3b60db Going back to snapshots 2018-02-08 15:59:22 +00:00
buildmaster 6b023df258 Update SNAPSHOT to 1.4.3.RELEASE 2018-02-08 15:44:15 +00:00
Ryan Baxter d70c12e2a4 Configuring firewall to allow matrix parameters 2018-02-07 19:57:36 -05:00
Ryan Baxter 8f0c15e966 using snapshot 2018-02-07 16:37:32 -05:00
Ryan Baxter fdf88bfdd7 Using snapshot 2018-02-07 16:36:49 -05:00
Ryan Baxter 24e31f997c using build snapshot 2018-02-07 16:36:00 -05:00
Ryan Baxter c53a4a0ce9 Using release 2018-02-07 16:16:35 -05:00
Ryan Baxter 33aae30c92 Using build release 2018-02-07 16:16:01 -05:00
Ryan Baxter d76e1ffc8f Using build release 2018-02-07 16:15:09 -05:00
Ryan Baxter e6943b8f78 Return content of last request when retrying failed requests (#2685) 2018-02-07 14:17:34 -05:00
Ryan Baxter ba87fef3b2 Set secure health check url. Fixes #2673 (#2710) 2018-02-05 13:23:06 -05:00
Ryan Baxter a9aca1b8ed Client is registered in the LoadBalancerContext. Fixes #2699. 2018-01-30 15:34:45 -05:00
Marcin Grzejszczak 6975781a0b Edgware branch for e2e 2018-01-25 21:28:36 +01:00
Marcin Grzejszczak 665fe67aa6 Edgware branch for e2e 2018-01-25 21:28:07 +01:00
Taylor Wicksell 5b149c7ff2 do not rely on constructor injection in EurekaClientAutoConfiguration (#2670) 2018-01-25 10:55:48 -05:00
Patrick Way 35477d9c06 Allowing RibbonLoadbalancedRetryPolicy to update ServerStats for circuit tripping exceptions (#2483)
* Allowing RibbonLoadbalancedRetryPolicy to update ServerStats for circuit tripping exceptions
2018-01-25 10:15:55 -05:00
saga 576baf6fff Improve Zuul Hystrix Timeouts (#2645) 2018-01-25 07:45:35 -05:00
Spencer Gibb ca80c57797 Adds newline to turbine stream
See gh-2637
2018-01-24 15:44:06 -05:00
Ryan Baxter 7d2a4b155d Bumping commons and config versions 2018-01-23 16:05:13 -05:00
saga ff68e0f66e Prevent RibbonRoutingFilter throws exceptions when Http status codes are non-standard(Against the 1.4.x branches) (#2671)
* This PR fixes #2639 and against the 1.4 branches
2018-01-22 11:27:15 -05:00
Ryan Baxter d51112e6af Pass the right request to getSecureRequest. Fixes #2667. (#2669) 2018-01-19 15:27:15 -05:00
Ryan Baxter 3c9792545b Merge remote-tracking branch 'origin/1.4.x' 2018-01-18 20:03:43 -05:00
Ryan Baxter 1c79bd2646 Flip disable ssl flag for SimpleHostRoutingFilter. Fixes #2503. 2018-01-18 14:01:41 -05:00
Ryan Baxter c79ac8ba19 Remove / from prefix if present.
Fixes #2625
2018-01-17 18:16:18 -05:00
Ryan Baxter a399cca7ce Use disableSslProperty when creating Feign http cients. Fixes 2652. (#2654) 2018-01-16 20:10:50 -05:00
buildmaster 3c0c054d62 Bumping versions to 1.4.3.BUILD-SNAPSHOT after release 2018-01-16 12:56:05 +00:00
buildmaster 3a07faf23a Going back to snapshots 2018-01-16 12:56:04 +00:00
buildmaster 0bfa706a39 Update SNAPSHOT to 1.4.2.RELEASE 2018-01-16 12:43:02 +00:00
Ryan Baxter 837267fb0a Bumping version to next release 2018-01-12 14:37:33 -05:00
Ryan Baxter 8d18dfbc3d Set hystrix timeout for Zuul routes based on whether the hystrix command timeout, default timeout, or ribbon timeouts are set. Fixes #2606 (#2633) 2018-01-11 10:05:02 -05:00
Ryan Baxter d2155dc561 Only strip the prefix if it actually part of the path. Fixes #2377 (#2624) 2018-01-08 14:42:33 -05:00
saga 882219f962 spring-retry listener features (#2609) 2018-01-04 09:42:26 -05:00
Ryan Baxter 8dfcdbed76 Adding repos to sc-netflix-hystrix-contract pom 2018-01-04 07:49:06 -05:00
Ryan Baxter 8017995ba3 Moving sc-build to 1.3.8.BUILD-SNAPSHOT 2018-01-03 19:42:03 -05:00
Ryan Baxter ca399ffd0b Moving dependencies to snapshots 2018-01-03 16:28:41 -05:00
Ryan Baxter a4c995a394 Disable following redirects in SimpleHostRoutingFilter. Fixes #2578. (#2608) 2018-01-03 14:19:39 -05:00
Nastya Smirnova 9deab33dc1 fixes #2524 (#2574)
set proper status and health eureka urls if prefer ip address is set
2018-01-02 15:42:59 -05:00
buildmaster 7c20c274d7 Bumping versions to 1.3.7.BUILD-SNAPSHOT after release 2017-12-21 21:34:12 +00:00
buildmaster 7339021684 Going back to snapshots 2017-12-21 21:34:11 +00:00
buildmaster 579fb1bfa7 Update SNAPSHOT to 1.3.6.RELEASE 2017-12-21 21:30:03 +00:00
周立 94358489ef Change spring-cloud-starter-hystrix-dashboard to spring-cloud-starter-netflix-hystrix-dashboard (#2561)
Change spring-cloud-starter-hystrix-dashboard to spring-cloud-starter-netflix-hystrix-dashboard
2017-12-18 09:05:30 -05:00
Craig Rueda 504720e366 InputStream should always be closed after reading contents from upstreams (#2501)
* InputStream should always be closed after reading contents from upstreams
2017-12-15 14:07:34 -05:00
Ryan Baxter 07de257371 Merge remote-tracking branch 'origin/1.3.x' into 1.4.x 2017-12-08 17:19:57 -08:00
Ryan Baxter 0401ad96e5 Fixes double encoding when creating secure URLs (#2526)
* Fixes double encoding when creating secure URLs.  Fixes #2478.
2017-12-08 10:39:21 -08:00
Ryan Baxter efb91874f8 Correcting image links. Fixes #2487 2017-12-03 15:06:48 -08:00
Daniel Lavoie ebdcca4fa8 Hystrix Dashboard Cannot display anything for Turbine Stream (#2484)
Closes #2475
2017-12-01 16:38:15 -05:00
周立 2287e0caf2 fix zuul filters package url in Edgware (#2489)
fix zuul filters package url in Edgware
2017-11-30 10:48:35 -05:00
Spencer Gibb dde7ff4c45 Update docs branches 2017-11-28 12:38:23 -05:00
saga 6c52269dc5 Associated with this PR # 2466 (#2470)
Use StringBuffer for String concatenation
2017-11-27 07:55:39 -05:00
saga 736a3e4610 Format indent adjustment (#2468)
Format indent adjustment
2017-11-26 07:32:33 -05:00
Spencer Gibb 1e87b50998 Update releaser build to build docs 2017-11-21 18:37:48 -05:00
Spencer Gibb f59a228daf Pass system properties to releaser build command 2017-11-21 17:48:01 -05:00
Ryan Baxter db3a412c8a Fixing command to run maven 2017-11-20 16:10:55 -05:00
Ryan Baxter 202f96876e Bumping versions to 1.4.1.BUILD-SNAPSHOT after release 2017-11-20 16:03:53 -05:00
Ryan Baxter 2489d5e234 Going back to snapshots 2017-11-20 16:03:52 -05:00
Ryan Baxter 64ad2ba20c Update SNAPSHOT to 1.4.0.RELEASE 2017-11-20 15:54:27 -05:00
Yongsung Yoon 60c4e1b007 Add support loadBalancerKey in RibbonRoutingFilter of Zuul for Canary test (#2439)
* Add support loadBalancerKey in RibbonRoutingFilter

* Add documentation about how to provide a loadBalancerKey to Ribbon

* Add integrationtest for RibbonRoutingFilter's loadBalancerKey support
2017-11-20 06:28:23 -05:00
Ryan Baxter 6e3b4fdd7b Adds backoff policies when retrying requests (#2436)
* Adds backoff policies when retrying requests.  Fixes #2195

* fixing final variable
2017-11-16 20:11:55 -05:00
Nastya Smirnova 62a8f72b98 Incorrect statusPageUrl and healthCheckUrl are reported to Eureka if management.context-path is not set (#2145) 2017-11-14 12:54:12 -05:00
Ryan Baxter 89441ac126 Added zuul timeout documentation. Fixes #2201 2017-11-10 15:54:05 -05:00
Ryan Baxter d9f7842aec Fix HystrixClientFallbackFactory implementation in docs. Fixes #2428 2017-11-08 11:00:51 -05:00
Ryan Baxter 65762b1dce Remove deprecated RetryableStatusCodeException. Fixes #2003 (#2427) 2017-11-07 17:26:17 -05:00
Nastya Smirnova ba24811356 Report jmx and management ports to Eureka metadata map (#1830)
Follows: https://github.com/spring-cloud/spring-cloud-netflix/pull/1317
2017-11-07 13:42:23 -05:00
agseijas 573d52119a Adds feign-* missing managed dependencies (#2417)
Probably we could import a bom from feign.
2017-11-07 10:56:10 -05:00
Ryan Baxter 3cafacc3e9 Fixes #2415 2017-11-06 15:43:20 -05:00
Spencer Gibb a805b53d86 Merge branch 'daniellavoie-no-eureka-fix' 2017-10-30 18:10:15 -04:00
Daniel Lavoie c0c59320a5 Regression fix for hystrix stream without eureka registration 2017-10-30 18:10:11 -04:00
Spencer Gibb 271bfcfb31 Fix tests 2017-10-27 18:43:31 -04:00
JagmohanSharma 798a4bb2b9 https://github.com/spring-cloud/spring-cloud-netflix/issues/2387 (#2388)
In order to fix issue with TPS in hystrix-dashboard threadpool section, removing average calculation for propertyValue_metricsRollingStatisticalWindowInMilliseconds. This was done for hystrixCommand.js previously but not for hystrixThreadpool.js.
2017-10-24 13:18:34 -04:00
Spencer Gibb df7f31098c Going back to snapshots 2017-10-23 17:44:26 -04:00
Spencer Gibb fa9524f9c9 Update SNAPSHOT to 1.4.0.RC1 2017-10-23 17:39:56 -04:00
Spencer Gibb 1368f059bb Change contract property name 2017-10-23 17:16:32 -04:00
Spencer Gibb 8701060355 Add workaround for locally failing test. 2017-10-23 17:05:30 -04:00
Spencer Gibb ee067ed3f2 Merge branch 'raiRaiyan-gh-2303' 2017-10-23 14:43:38 -04:00
Raiyan b57dedb74a - Eureka client auto configures the secure port when secure port is enabled
- The eureka instance auto registration also changes the secure port when the server port is random (0)

Fixes gh-2303
2017-10-23 14:43:20 -04:00
Spencer Gibb d7c13adac0 Merge branch 'tiny-dancer-patch-1' 2017-10-23 14:19:13 -04:00
mg bd2473a7bf Update spring-cloud-netflix.adoc
Update documentation to reflect https://github.com/spring-cloud/spring-cloud-netflix/issues/1048
2017-10-23 14:18:40 -04:00
Gregor Zurowski de16cb71f1 Add new filters actuator endpoint (#2244)
* Add new Zuul filters endpoint and refactor routes endpoint
* Refactor FiltersEndpoint
- Extend from AbstractEndpoint and simplify code
- Move tests classes into package endpoint
- Remove usage of Lombok
* Conditionally enable Zuul routes and filters endpoints
* Provide FilterRegistry to FiltersEndpoint via constructor
2017-10-23 14:08:00 -04:00
Nastya Smirnova ffc431753b Create TurbineClustersProvider
Extract separate class TurbineClustersProvider to be able to provide custom solution for retrieving configured clusters (#2219)
2017-10-20 21:46:29 -04:00
Spencer Gibb 28de82e63c Use updated Registration rather than getLocalServiceInstance()
See https://github.com/spring-cloud/spring-cloud-commons/issues/265
2017-10-18 11:34:38 -04:00
Spencer Gibb 6c65266f05 Formatting spaces->tabs 2017-10-17 13:37:28 -04:00
Spencer Gibb 6ffe2f1af2 Downgrade archaius to 0.7.4 for java 7 compatibility.
see https://github.com/Netflix/archaius/pull/522
2017-10-17 13:12:26 -04:00
Dave Syer 68ce0cf25f Merge branch 'feature/eureka-stubs' 2017-10-17 10:47:35 +01:00
Spencer Gibb 7cff8ddbd3 Add missing jackson serialization for instanceinfo.
Port information was missing from data sent to eureka.

fixes gh-2372
2017-10-16 16:23:51 -04:00
Dave Syer 9d1eed6a82 Add script to build contract utils 2017-10-16 16:54:35 +01:00
Dave Syer eeadc829b9 Parameterize contract version 2017-10-13 15:17:46 +01:00
Dave Syer efe040549c Move contract helper out of the reactor build 2017-10-13 15:17:46 +01:00
Dave Syer 5bc9e65cdd Add tests for server metadata 2017-10-13 15:17:46 +01:00
Dave Syer d6a604051f Split tests up into individual methods 2017-10-13 15:17:46 +01:00
Dave Syer 51a03b30f2 Consolidate stub tests into one place 2017-10-13 15:17:46 +01:00
Dave Syer 561f3b2fbf Add wiremock verification 2017-10-13 15:17:46 +01:00
Dave Syer 3a7af2c8fe Generate some stubs, yay! 2017-10-13 15:17:46 +01:00
Dave Syer 26c7c362d2 Add property to tests, parameterizing stubs 2017-10-13 15:17:46 +01:00
Dave Syer 0642ea52c9 Remove unused stubs file 2017-10-13 15:17:46 +01:00
Dave Syer 957e33207e Stabilise some tests 2017-10-13 15:17:46 +01:00
Dave Syer a39fe345b5 Remove deprecated annotation 2017-10-13 15:17:46 +01:00
Dave Syer 40e72ddb8c Tweak assertions a bit 2017-10-13 15:17:46 +01:00
Dave Syer 195c3fd75d Extract utility class into shared library for contract tests 2017-10-13 15:17:46 +01:00
Dave Syer c626bccad3 Add rest template to extract SSE events and assert them
The message has to be sent after the endpoint starts up, which only
happens after the first request is accepted, so we put that logic
in the response extractor.
2017-10-13 15:17:46 +01:00
Dave Syer e295188075 Add tests for body of message 2017-10-13 15:17:46 +01:00
Dave Syer 7804e1bd59 Add Spring Cloud Contract for hystrix stream 2017-10-13 15:17:46 +01:00
Spencer Gibb 6b6889b8b4 Fixes refresh scope bean type. 2017-10-04 19:32:57 -04:00
Fahim Farook f809c119bd Allow init params to be set on ProxyStreamServlet. (#2335)
* Allow init params to be set on ProxyStreamServlet.

Fixes gh-2301

* Added unit test for #gh-2301
2017-10-03 13:43:17 -04:00
Ryan Baxter a806dc920f Bumping versions to 1.3.6.BUILD-SNAPSHOT after release 2017-10-02 16:22:49 -04:00
Ryan Baxter 74fc02b2cc Going back to snapshots 2017-10-02 16:22:48 -04:00
Ryan Baxter c1fc987d96 Update SNAPSHOT to 1.3.5.RELEASE 2017-10-02 16:17:55 -04:00
Alex Sartan 7f97a61ed5 Fix minor grammar issue in Zuul doc (#2336) 2017-10-01 13:25:32 -04:00
Andre Dörnbrack 05a3db3cc0 Fix zuul post retry (#2209)
Modfied RibbonCommandContext to make request entity resettable. fixes gh-892
2017-09-25 13:59:31 -04:00
Ryan Baxter 145b7ce69a Remove @EnableDiscoveryClient and @EnableEurekaClient (#2242)
* Remove @EnableDiscoveryClient and @EnableEurekaClient as there are now optional.  Fixes #2241.
2017-09-25 13:18:04 -04:00
Ryan Baxter c6fa162728 Merge pull request #2293 from mattjbray/fix-requestmapping-headers
SpringMvcContract: Ignore RequestMapping headers with no value.
2017-09-22 21:15:53 +01:00
Matt Bray 527dc2cc48 SpringMvcContract: Ignore RequestMapping headers with no value.
According to:

https://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/web/bind/annotation/RequestMapping.html#headers--

the `headers` field can take several formats:

1. Require the header with a concrete value: `"My-Header=myValue"`
2. Require the header with any value: `"My-Header"`
3. Require the header is absent: `"!My-Header"`
4. Require the header with a negated value : `"My-Header!=myValue"`

This fixes `parseHeaders` for cases 2-4 (which previously threw a `StringIndexOutOfBoundsException`).

Fixes gh-1778.
2017-09-22 18:01:04 +01:00
Dave Syer 7672ee3666 Fix hystrix command keys in tests to be unique 2017-09-21 12:13:19 +01:00
Dave Syer 7ca4f33dcf Remove System.err from test 2017-09-21 11:30:07 +01:00
Spencer Gibb 78e4cb4410 Fix for potential NPE 2017-09-12 17:50:57 -06:00
spccold baa50c136a simplify org.springframework.cloud.netflix.zuul.filters.ProxyRequestH… (#1965)
* simplify org.springframework.cloud.netflix.zuul.filters.ProxyRequestHelper#setResponse

* Update ProxyRequestHelper.java
2017-09-11 17:32:16 -04:00
Ryan Baxter 24d0bedf7d Merge pull request #2255 from DominikMostek/fallback_cause
Fallback cause is propagated to fallback provider
2017-09-08 14:12:52 -04:00
Ryan Baxter 38b8786ede Merge pull request #2261 from ryanjbaxter/timeout-values
Adjust Ribbon connect and read timeout values
2017-09-08 14:08:46 -04:00
Ryan Baxter 146513aeb0 Set Ribbon connect and read timeout values to equal the Hystrix timeout. Fixes #1827. 2017-09-08 10:19:01 -04:00
Dominik Mostek 4dc5088fb2 Updated documentation with new FallbackProvider 2017-09-07 12:55:33 +02:00
Dominik Mostek 4c53fd2bf6 Fallback cause is propagated to fallback provider
Cause can now be propagated to fallback provider in order to respond accordingly to a exception type.
New interface is introduced in order not to break any existing falback providers.
2017-09-07 12:23:37 +02:00
Jin Zhang 885425e2a3 format 'pom.xml' code style (#2257) 2017-09-06 22:26:20 -04:00
Ryan Baxter b74c77b74f Merge pull request #2256 from ryanjbaxter/update-rxjava-version
Update rxjava version
2017-09-06 20:21:12 -04:00
Ryan Baxter 1bc8e8fd3a Update rxjava version. Fixes #2248. 2017-09-06 16:02:04 -04:00
Gregor Zurowski 6dbdb1d8ed Remove commons-lang builders (#2243)
This commit removes usages of commons-lang builders for equals,
hashCode and toString methods.

Signed-off-by: Gregor Zurowski <gregor@zurowski.org>
2017-08-31 19:26:53 -04:00
Tom Cawley ea5585e381 Dynamic filtering on Zuul SimpleRouteLocator.getRoutes()
* Introduce getRoutesMap() so subclasses can have read/write access to configured/discovered routes.
2017-08-31 19:20:33 -04:00
Ryan Baxter ace95a3355 Merge pull request #2240 from gzurowski/remove-lombok-from-docs
Remove Lombok from documentation
2017-08-31 16:47:25 -04:00
Spencer Gibb 019615f376 remove commons.lang.builder 2017-08-31 14:45:48 -06:00
Ryan Baxter a8d40afd58 Merge pull request #2239 from gzurowski/remove-lombok-from-netflix-core
Remove Lombok from spring-cloud-netflix-core module
2017-08-31 16:22:50 -04:00
Marcin Grzejszczak ebe3800c75 Merge branch '1.3.x' 2017-08-31 15:01:12 +02:00
Marcin Grzejszczak 30b98bea85 Referrencing resources from sc-build 2017-08-31 15:01:05 +02:00
Gregor Zurowski d9738a7ee5 Remove Lombok from documentation
Signed-off-by: Gregor Zurowski <gregor@zurowski.org>
2017-08-31 12:15:35 +02:00
Gregor Zurowski d778b938e7 Remove Lombok from spring-cloud-netflix-core module
Signed-off-by: Gregor Zurowski <gregor@zurowski.org>
2017-08-31 12:01:03 +02:00
Marcin Grzejszczak 5e9fa908b4 Merge branch '1.3.x' 2017-08-29 15:59:39 +02:00
Marcin Grzejszczak 91808c5fd9 Updated whitelists 2017-08-29 15:57:17 +02:00
Marcin Grzejszczak 0784b1ee19 Migrated to new docs; fixes #2237 2017-08-29 15:54:31 +02:00
Marcin Grzejszczak b3cdd72754 Bumped libs' 2017-08-29 15:54:01 +02:00
Marcin Grzejszczak 4a8913f7ea Migrated to new docs; fixes #2237 2017-08-29 15:04:32 +02:00
Ryan Baxter 8fbd73af1e Going back to snapshots 2017-08-24 17:54:53 -04:00
Ryan Baxter 1be2b2c295 Update SNAPSHOT to 1.4.0.M1 2017-08-24 17:49:28 -04:00
Ryan Baxter 02778fd670 fixing links in docs 2017-08-24 17:07:42 -04:00
Ryan Baxter 985f014f40 bumping sc-build version 2017-08-24 16:44:46 -04:00
Nastya Smirnova 2a63d07146 Extract getApplications method in CommonsInstanceDiscovery
This allows the ability to override behavior of retrieving configured applications
2017-08-21 13:49:42 -04:00
Ryan Baxter 947d30c5c4 Bumping versions to 1.3.5.BUILD-SNAPSHOT after release 2017-08-18 13:59:32 -04:00
Ryan Baxter e71ce3395d Going back to snapshots 2017-08-18 13:59:31 -04:00
Ryan Baxter f5e7be25dd Update SNAPSHOT to 1.3.4.RELEASE 2017-08-18 13:55:59 -04:00
Ryan Baxter c8d024c25f Merge pull request #2213 from ryanjbaxter/deprecation-warnings-for-starters
Adds deprecation warning to starters
2017-08-18 13:21:25 -04:00
Ryan Baxter b519ad8d18 Adds deprecation warning to starters. Fixes #2148. 2017-08-18 12:30:45 -04:00
Ryan Baxter fcb1f5dc54 Bumping versions to 1.3.4.BUILD-SNAPSHOT after release 2017-08-18 07:55:23 -04:00
Ryan Baxter 9b7a2f93ad Going back to snapshots 2017-08-18 07:55:22 -04:00
Ryan Baxter 9ce253b644 Update SNAPSHOT to 1.3.3.RELEASE 2017-08-18 07:51:04 -04:00
Ryan Baxter 24cbbb9a11 Merging 1.3.x into master 2017-08-17 14:47:45 -04:00
Ryan Baxter ed57c8f0fa Merge pull request #2208 from ryanjbaxter/document-https-hystrix-dashboard
Document untrusted certificates when connecting to hystrix.stream endpoint
2017-08-17 14:32:52 -04:00
Ryan Baxter 07b99704ee Fixes #1523. Document untrusted certificates when connecting to hystrix.stream endpoint. 2017-08-17 14:02:14 -04:00
Biju Kunjummen 9440e4d153 Fixes #2083. Porting #1916 to the 1.3.x branch. 2017-08-17 12:29:23 -04:00
Spencer Gibb 1840647458 Move EurekaClient.close() to EurekaRegistration.close().
This moves the lifecycle of the eureka client of of EurekaServiceRegistry.

fixes gh-2099
2017-08-16 00:53:40 -06:00
Spencer Gibb c3114e65bf Merge branch '1.3.x' 2017-08-10 13:59:46 -06:00
Spencer Gibb c2aa60f292 Update test of setContentLengthLong to include param.
Otherwise useServlet31 was always returning false.

fixes gh-2196
2017-08-10 13:58:45 -06:00
Spencer Gibb e4e29e1316 Move tests out of default and base package 2017-08-04 14:37:28 -06:00
Biju Kunjummen 63f975ad43 Sync up matching of ignored paths and route paths (#2163)
Signed-off-by: João Salavessa <joao.salavessa@sky.uk>
2017-08-04 15:41:58 -04:00
Olivier Bourgain a01fc5b758 Fix check then act issue (#2160) 2017-08-04 15:40:10 -04:00
Ryan Baxter 481e31220b Merge remote-tracking branch 'origin/1.3.x' 2017-08-04 10:57:41 -04:00
Ryan Baxter 040ce4db81 Merge pull request #2177 from repos-jmp/1.3.x
Fixes gh-2125
2017-08-04 10:51:08 -04:00
Ryan Baxter 8fb89b25d9 Merge pull request #2080 from ryanjbaxter/http-client-centralization
Centralizing HTTP client creation and configuration
2017-08-03 13:02:09 -04:00
Jayanth MP 099c9024bb Fixes gh-2125
(Updated okhttp3 from v3.6.0 to v3.8.1)
2017-08-02 17:24:19 +05:30
Ryan Baxter bd7e75f4b3 Merge remote-tracking branch 'Upstream/master' into http-client-centralization 2017-08-01 16:46:07 -04:00
Ryan Baxter b3d61a6de7 Removing duplicate install goal 2017-07-31 20:22:45 -04:00
Dave Syer e5b14e4177 Fix all the start poms to be jars again
They are all deprecated but that's no reason to break them.
2017-07-26 12:13:25 +01:00
Spencer Gibb 0de86d3faf fix hashCode 2017-07-25 08:58:39 -06:00
Gregor Zurowski aa2159b7e5 Remove Lombok from spring-cloud-netflix-eureka-client module (#2131) 2017-07-24 19:07:18 -04:00
Biju Kunjummen 1c30c24639 Replace o.s.b.a.PropertyPlaceholderAuto* with o.s.b.a.context.PropertyPlaceholderAuto* (#2155) 2017-07-24 18:11:20 -04:00
Spencer Gibb cd2ed8eeee Restore turbine stream dependencies. 2017-07-24 14:37:31 -06:00
Spencer Gibb 112a3e27a6 Fix versions of new starters 2017-07-21 14:21:44 -06:00
Daniel Lavoie bbac5a730f Rename starters to include -netflix- (#1886)
Fixes gh-665
2017-07-21 15:59:32 -04:00
Daniel Lavoie 348c96bf13 Optionally remove Jersey dependencies from Eureka Client (#1850)
Fixes gh-1849
2017-07-21 15:55:57 -04:00
Biju Kunjummen fd783734ac Add docs for default ribbon client configuration (#2142)
fixes #1741
2017-07-21 11:45:01 -04:00
Biju Kunjummen fc4f375a65 Restore ignored test - works cleanly for a full build (#2146) 2017-07-21 11:41:10 -04:00
Spencer Gibb 1d6b47ceef Bumping versions to 1.3.3.BUILD-SNAPSHOT after release 2017-07-20 11:39:09 -06:00
Spencer Gibb cda1c876b2 Going back to snapshots 2017-07-20 11:39:08 -06:00
Spencer Gibb 6112ea2558 Update SNAPSHOT to 1.3.2.RELEASE 2017-07-20 11:30:44 -06:00
Spencer Gibb 37129671b6 Merge branch '1.3.x' 2017-07-20 10:06:32 -06:00
Spencer Gibb 97f1655ff7 Ensure ordering of feign ribbon client configuration.
On certain platforms and compilers the generated bytecode is not what
the configuration expected. By moving inner classes to the upper level
and using @Import this will guarantee the proper order.

fixes gh-2086
2017-07-20 10:02:05 -06:00
Spencer Gibb 1cf509c365 Merge branch '1.3.x' 2017-07-19 12:12:01 -06:00
Spencer Gibb 6b530b0269 Ensure ordering of ribbon client configuration.
On certain platforms and compilers the generated bytecode is not what
the configuration expected. By moving inner classes to the upper level
and using @Import this will guarantee the proper order.

fixes gh-2086
2017-07-19 12:11:07 -06:00
Jayanth e525ab7d64 Hystrix open threshold documentation (#2136)
fixes gh-1943
2017-07-18 17:18:01 -04:00
Spencer Gibb 31d19fd51a Remove commons.lang.builder refs 2017-07-18 11:05:05 -06:00
Spencer Gibb 74540e9f4d Merge branch '1.3.x' 2017-07-18 10:57:41 -06:00
Spencer Gibb afc8a99d7e Add @NestedConfigurationProperty to transport.
Needed in `EurekaClientConfigBean` because `CloudEurekaTransportConfig` is a separate class.

Fixes gh-2138
2017-07-18 10:56:41 -06:00
Tummala Dhanvi (c0mrad3) 859a79ad35 Document prefer hostname #2084 (#2092) 2017-07-18 12:39:43 -04:00
Ryan Baxter 6ab27328cc Merge pull request #2128 from gzurowski/remove-lombok-from-eureka-server
Remove Lombok from spring-cloud-netflix-eureka-server module
2017-07-14 13:44:12 -04:00
Gregor Zurowski 72c31ca524 Polish code
- Remove formatter markers
- Use StringBuilder in toString method

Signed-off-by: Gregor Zurowski <gregor@zurowski.org>
2017-07-14 16:26:04 +02:00
Gregor Zurowski 4d69941593 Remove Lombok from spring-cloud-netflix-eureka-server module
Signed-off-by: Gregor Zurowski <gregor@zurowski.org>
2017-07-14 11:49:33 +02:00
Ryan Baxter 0d19a55ddd Merge pull request #2120 from gzurowski/remove-lombok-log-from-eureka-client
Remove Lombok logging from spring-cloud-netflix-eureka-client module
2017-07-13 09:36:02 -04:00
Ryan Baxter ceef16f0c8 Merge pull request #2121 from gzurowski/remove-lombok-log-from-eureka-server
Remove Lombok logging from spring-cloud-netflix-eureka-server module
2017-07-13 09:35:38 -04:00
Ryan Baxter 187f34dfee Merge pull request #2122 from gzurowski/remove-lombok-log-from-core
Remove Lombok logging from spring-cloud-netflix-core module
2017-07-13 09:35:09 -04:00
Ryan Baxter 96b1e40c0a Merge pull request #2123 from gzurowski/fix-maven-warnings
Fix Maven warnings about missing plugin versions
2017-07-13 09:34:09 -04:00
Gregor Zurowski 63d77a8b81 Fix Maven warnings about missing plugin versions
Signed-off-by: Gregor Zurowski <gregor@zurowski.org>
2017-07-13 09:38:53 +02:00
Gregor Zurowski 8022342e81 Remove Lombok logging from spring-cloud-netflix-eureka-server module
Signed-off-by: Gregor Zurowski <gregor@zurowski.org>
2017-07-13 09:21:32 +02:00
Gregor Zurowski 6379e15ce1 Remove Lombok logging from spring-cloud-netflix-eureka-client module
Signed-off-by: Gregor Zurowski <gregor@zurowski.org>
2017-07-13 09:20:29 +02:00
Gregor Zurowski 5b075623ff Remove Lombok logging from spring-cloud-netflix-core module
Signed-off-by: Gregor Zurowski <gregor@zurowski.org>
2017-07-13 08:48:56 +02:00
Marco Schulte 46cbaa053c Fixed NPE if origin is unset (#2100) 2017-07-12 15:41:32 -04:00
Ryan Baxter ffc33b4c69 Merge pull request #2105 from gzurowski/routes-endpoint-details
Provide more Zuul route details in the routes actuator endpoint
2017-07-12 10:47:49 -04:00
Ryan Baxter 1d3773ab5e Merge pull request #2111 from gzurowski/remove-lombok-from-turbine-stream
Remove Lombok from spring-cloud-netflix-turbine-stream module
2017-07-12 10:35:48 -04:00
Ryan Baxter a968b4bec8 Merge pull request #2112 from gzurowski/remove-lombok-from-turbine
Remove Lombok from spring-cloud-netflix-turbine module
2017-07-12 10:35:06 -04:00
Ryan Baxter 65902d11e4 Merge pull request #2113 from gzurowski/remove-lombok-from-sidecar
Remove Lombok from spring-cloud-netflix-sidecare module
2017-07-12 10:34:12 -04:00
Ryan Baxter 050dc31c97 Merge pull request #2114 from gzurowski/remove-lombok-from-hystrix-dashboard
Remove Lombok from spring-cloud-netflix-hystrix-dashboard module
2017-07-12 10:33:29 -04:00
Gregor Zurowski aae96faa76 Remove Lombok from spring-cloud-netflix-hystrix-dashboard module
Signed-off-by: Gregor Zurowski <gregor@zurowski.org>
2017-07-11 23:25:05 +02:00
Gregor Zurowski 0dea44acf4 Remove Lombok from spring-cloud-netflix-turbine module
Signed-off-by: Gregor Zurowski <gregor@zurowski.org>
2017-07-11 23:14:40 +02:00
Gregor Zurowski b158f6f2b7 Remove Lombok from spring-cloud-netflix-turbine-stream module
Signed-off-by: Gregor Zurowski <gregor@zurowski.org>
2017-07-11 23:00:18 +02:00
Ryan Baxter 11da3d4e3c Merge remote-tracking branch 'Upstream/master' into http-client-centralization 2017-07-11 16:48:19 -04:00
Gregor Zurowski 5f4fc247a4 Remove Lombok from spring-cloud-netflix-sidecare module
Signed-off-by: Gregor Zurowski <gregor@zurowski.org>
2017-07-11 22:39:15 +02:00
Ryan Baxter 78ba3c5394 Cleanup and code review fixes. 2017-07-11 14:49:44 -04:00
Gregor Zurowski 781fa3ea0c Add documentation about the detailed output of the routes endpoint
Signed-off-by: Gregor Zurowski <gregor@zurowski.org>
2017-07-11 15:56:13 +02:00
Gregor Zurowski a08b661af6 Remove usage of Lombok
Signed-off-by: Gregor Zurowski <gregor@zurowski.org>
2017-07-11 10:38:51 +02:00
Ryan Baxter d0009ba05a Merge pull request #2087 from brenuart/gh1534
React on ContextClosedEvent only if from "our" context
2017-07-10 13:33:39 -04:00
Ryan Baxter ab9b5ba3ec Merge pull request #2104 from gzurowski/use-filter-constants
Use filter constants where appropriate
2017-07-10 11:49:06 -04:00
Ryan Baxter 70d39aae7b Merge pull request #2107 from yongsungyoon/fix-compile-error-on-ejc
Fix compilation problem on eclipse java compiler
2017-07-10 11:39:04 -04:00
Ryan Baxter 56ccc46f5f Added documentation 2017-07-09 15:26:24 -04:00
Ryan Baxter ff33905704 Updating property names 2017-07-09 14:21:10 -04:00
Ryan Baxter 69739420fa Takes advantage of new builder pattern. Also reverted elimination of properties for feign and ribbon. 2017-07-09 13:39:04 -04:00
Yongsung Yoon 2b593bc742 Fix compilation problem on eclipse java compiler 2017-07-10 00:36:07 +09:00
Gregor Zurowski eb1b7baf1c Provide more Zuul route details in the routes actuator endpoint
Add a parameter to control the level of details returned with the
routes actuator endpoint. If requested, return all available Zuul route
details including ID, prefix, sensitive headers, etc.

Signed-off-by: Gregor Zurowski <gregor@zurowski.org>
2017-07-08 22:40:39 +02:00
Gregor Zurowski 05eef0e8f5 Use filter constants
Signed-off-by: Gregor Zurowski <gregor@zurowski.org>
2017-07-07 22:16:11 +02:00
Eko Kurniawan Khannedy c2c634707e FeignClient Configuration Properties (#1942)
* add feign client properties

* configure feign builder from properties if exists

* change string config to class config and add unit test for feign client using configuration properties

* refactoring and add primary flag configuration

* add decode404 in feign client configuration properties

* change unit test properties decode404 to true

* remove lombok from FeignClientProperties and change primary attribute to default-to-properties

fixes gh-1931
2017-07-07 15:31:56 -04:00
Biju Kunjummen 0579b326be Support for re-writing Location Headers (#1863)
* Support for re-writing Location Headers

* Added additional constructor for Route, removed auto-configuration of LocationRewriteFilter

* Polished docs, more tests
2017-07-07 15:21:44 -04:00
Gregor Zurowski 70a26fec26 Use static import for constants (#2103)
Signed-off-by: Gregor Zurowski <gregor@zurowski.org>
2017-07-07 14:35:49 -04:00
Ryan Baxter 02ec9bb98e Merge remote-tracking branch 'Upstream/master' into http-client-centralization 2017-07-07 10:54:08 -04:00
Ryan Baxter b2f608b884 OK HTTP Client changes 2017-07-07 10:10:53 -04:00
Gregor Zurowski a496dc8170 Use constant utility classes instead of constant interfaces (#2081)
Signed-off-by: Gregor Zurowski <gregor@zurowski.org>
2017-07-06 12:01:26 -04:00
Bertrand Renuart 8ad15399d6 React on ContextClosedEvent only if originating from "our" context (not another like a child) 2017-07-03 15:52:01 +02:00
Yongsung Yoon 8e11514e7c Add options for RibbonCommand to use separate thread pools for hystrix (#2074)
* Add options for RibbonCommand to use separate thread pools for hystrix

* Remove lombok annotation and Add getter/setter for ZuulProperties$HystrixThreadPool

* Add doc about how to configure hystrix thread pools in Zuul Developer Guide

* Add testcases for HystrixThreadPoolKey of RibbonCommand

* Tiny change about if block in AbstractRibbonCommand
2017-06-30 20:03:52 -04:00
Spencer Gibb 89cb5573d9 bump commons to 1.3.0ˆ 2017-06-30 17:33:57 -06:00
Spencer Gibb 5856d76e65 Merge branch '1.3.x' 2017-06-30 17:11:18 -06:00
Spencer Gibb 86b1f6ede3 Make aspect method public
fixes gh-2063
2017-06-30 17:10:27 -06:00
Ryan Baxter 572305d7c8 Fixing code formatting 2017-06-28 12:00:11 -04:00
Ryan Baxter 2aa93abc0f Centralizing HTTP client creation and configuration 2017-06-28 11:43:52 -04:00
Ryan Baxter e2954d0117 Merge pull request #2059 from brandon-atkinson/gh-2042
Rename *Test.java -> *Tests.java. Fixes #2042
2017-06-20 10:49:11 -04:00
Brandon Atkinson 497b95ec64 Rename *Test.java -> *Tests.java. Fixes #2042 2017-06-19 20:41:54 -04:00
Ryan Baxter 02e7594de5 Bumping s-c-stream to Ditmars 2017-06-19 14:06:44 -04:00
Ryan Baxter 7efa68e853 Merge remote-tracking branch 'origin/1.3.x' 2017-06-19 14:05:29 -04:00
Ryan Baxter 003fefa61d Bumping release version 2017-06-19 14:04:29 -04:00
Ryan Baxter 5c035768b0 Merge remote-tracking branch 'origin/1.3.x' 2017-06-16 11:51:09 -04:00
Ryan Baxter 9a878b0fbd Merge pull request #2044 from bright/override_all_hystrix_concurrency_strategy_methods
Override getThreadPool from HystrixConcurrencyStrategy and delegate to
2017-06-16 11:27:06 -04:00
Piotr Mionskowski 779b026e6b Override getThreadPool from HystrixConcurrencyStrategy and delegate to
existing strategy if present. Fixes #2035
2017-06-15 06:06:58 +02:00
Ryan Baxter ccae4e4ce2 Bumping s-c-config version to 1.4.0 2017-06-14 16:40:48 -04:00
Dave Syer d39a22945b Merge branch '1.3.x' 2017-06-13 13:58:08 +01:00
Dave Syer aac7799e3e Clean up Zuul context in all tests 2017-06-13 13:57:16 +01:00
Dave Syer 310f558e9c Merge branch '1.3.x' 2017-06-12 16:15:44 +01:00
Dave Syer 1a0428da97 Merge branch '1.3.x' 2017-06-12 15:52:24 +01:00
Dave Syer 4783b07407 Support for multi-valued (batched) events in stream aggregator
This allows clients to send batched up events in the same format as
before (or to continue to send single events). We can switch the
default format to an array in 1.4.x.
2017-06-12 15:44:35 +01:00
André Dörnbrack 0334c5a289 Cleanup. Cherry picking #2031. 2017-06-09 12:42:12 -04:00
André Dörnbrack 12a9a2e485 code cleanup 2017-06-09 12:34:04 -04:00
Ryan Baxter f9424231a9 Merge pull request #2031 from doernbrackandre/fix_whitespaces_in_retryable_status_codes_list
fixes a problem with whitespaces in list of retryable status codes
2017-06-09 12:00:38 -04:00
Dave Syer d4ba70db5c Merge branch '1.3.x' 2017-06-09 13:31:17 +01:00
Dave Syer a59f5e1c4f Clean up some resources to keep tests running 2017-06-09 13:24:57 +01:00
André Dörnbrack 02316d4ee0 Merge branch 'fix_whitespaces_in_retryable_status_codes_list' of github.com:doernbrackandre/spring-cloud-netflix into fix_whitespaces_in_retryable_status_codes_list 2017-06-09 13:39:44 +02:00
André Dörnbrack 4f148de74d code cleanup 2017-06-09 13:37:56 +02:00
André Dörnbrack 9f10d5207f fixes a problem with whitespaces in list of retryable status codes 2017-06-09 10:12:24 +02:00
Ryan Baxter 484bde10b3 Adding 404 to list of retryable status codes 2017-06-08 16:18:11 -04:00
Ryan Baxter 8281757da8 Add path to try and fix intermittent failures with RetryableZuulApplicationTests pass 2017-06-08 15:43:15 -04:00
Ryan Baxter 4e25e2eb81 Revert "Trying a plain RestTemplate in an attempt to fix intermittent test failures."
This reverts commit f552426304.
2017-06-08 15:34:57 -04:00
Ryan Baxter f552426304 Trying a plain RestTemplate in an attempt to fix intermittent test failures. 2017-06-08 15:16:03 -04:00
Spencer Gibb 15295dd294 Merge remote-tracking branch 'origin/master' 2017-06-08 12:18:45 -06:00
Ryan Baxter 1405a1894b Closing response in Feign load balancer 2017-06-08 13:48:56 -04:00
Ryan Baxter a1c8cfe967 Close response when retry on certain status codes. Fixes #1970. 2017-06-08 13:48:56 -04:00
Ryan Baxter f0b424c84f Merge pull request #2021 from ryanjbaxter/response-code-retry-close-wait
Close response when retry on certain status codes
2017-06-08 13:47:27 -04:00
Spencer Gibb 582746587b Merge branch '1.3.x' 2017-06-08 11:35:45 -06:00
Spencer Gibb a69fe71406 Make archaius highest priority auto-configuration. 2017-06-08 11:35:05 -06:00
Spencer Gibb 13155ce64c Upgrade eureka to v1.7.0
fixes gh-2028
2017-06-07 13:14:07 -06:00
Jin Zhang c5d95ca805 SendErrorFilter: put response code into RequestContext, keep consistent with normal cases (#2004) 2017-06-07 12:06:35 -04:00
Ryan Baxter 0b2fc81be4 Closing response in Feign load balancer 2017-06-06 10:44:42 -04:00
Spencer Gibb 9e180b8ba7 Merge branch '1.3.x' 2017-06-05 16:41:57 -06:00
Spencer Gibb e08a6e8a48 Move zuul host routing timeouts to boot properties.
Previously, these were managed directly via archaius, but due to
some combination of changes in boot 1.5.x (likely a tomcat change as
zuul filters were initialzed in a servlet context listener) and Dalston,
The filter was created before archaius could be initialized.

The properties are backwards compatible and are in the
`ZuulProperties.Host` object.

fixes gh-1950
2017-06-05 16:40:12 -06:00
Ryan Baxter 7d06c140fa Close response when retry on certain status codes. Fixes #1970. 2017-06-05 14:36:49 -04:00
Ryan Baxter d914406c84 Merge pull request #2000 from rpahli/master
use only default https ports for https check
2017-06-01 20:08:10 -04:00
Biju Kunjummen 31a3ff61e8 GH-1916: Spring Boot Auto-configuration based Zuul Server and Proxy (#1951) 2017-06-01 15:12:42 -04:00
Spencer Gibb 3773047a06 Bump to version 1.4.0.BUILD-SNAPSHOT 2017-06-01 12:50:57 -06:00
pahli a1d089038d make property injection optional 2017-05-31 23:55:17 +02:00
Ryan Baxter 562e604cee Merge pull request #2002 from ryanjbaxter/deprecate-RetryableStatusCodeException
Deprecates RetryableStatusCodeException
2017-05-31 16:33:58 -04:00
pahli 71c906b00b add private accessor 2017-05-31 22:33:10 +02:00
pahli 6d22a407cc use @ConfigurationProperties 2017-05-31 22:25:51 +02:00
pahli bdfbe3a87e make secure ports for DefaultServerIntrospector configurable 2017-05-31 22:09:35 +02:00
Ryan Baxter cb3613db71 Fixing typo 2017-05-31 14:35:38 -04:00
Ryan Baxter 7dbfe15d1a Deprecates RetryableStatusCodeException in favor of the same class in s-c-commons 2017-05-31 14:22:15 -04:00
Rico Pahlisch ccf8f86c8d use only default https ports for https check
spring boot uses all high ports and there are some trouble if ports end with 443 (e.g. 24443, ...)
2017-05-31 12:04:09 +02:00
Spencer Gibb 7425f974cb Adds timeout test.
see gh-1950
2017-05-25 14:51:58 -06:00
Spencer Gibb 58e62ebd06 Bumping versions to 1.3.2.BUILD-SNAPSHOT after release 2017-05-22 12:18:04 -06:00
Spencer Gibb 0de72d2dad Going back to snapshots 2017-05-22 12:18:03 -06:00
Spencer Gibb 7898ad772b Update SNAPSHOT to 1.3.1.RELEASE 2017-05-22 12:09:31 -06:00
Spencer Gibb 25a1881127 Ignore feign.hystrix.enabled.
Let SecurityContextConcurrencyStrategy be installed as the hystrix
concurrency strategy regardless of if feign's hystrix support is installed.

fixes gh-1969
2017-05-22 09:47:49 -06:00
Spencer Gibb 34350cb7ec Merge branch 'strelok1-master' 2017-05-19 19:00:24 -06:00
Roman Rodov e130ec03ad Add management.context-path to status & health url
fixes gh-1795
2017-05-19 18:59:37 -06:00
Spencer Gibb 0cd544b4ce Merge branch 'lalib-gh-1720' 2017-05-19 18:22:26 -06:00
balp 6362be8196 Adds ability to customize simple host conn pool
The timeToLive and timeUnit parameters added to configure connection pool.

Fixes gh-1720
2017-05-19 18:22:04 -06:00
Biju Kunjummen aa4d9d62bc Test for validating that local service instance resolves for hystrix metrics (#1922) 2017-05-19 18:40:49 -04:00
Spencer Gibb cd44a52084 Update feign to 9.5.0
fixes gh-1956
2017-05-16 21:07:19 -06:00
Spencer Gibb 98fd3c7379 Upgrade Hystrix to v1.5.12
fixes gh-1955
2017-05-16 19:52:41 -06:00
Luke Tornquist 73b5609e63 Allow easier subclassing of SimpleRouteLocator
Fixes gh-1598
2017-05-15 14:48:15 -04:00
Jin Zhang fe06370aa2 correct comments in FeignClient, SendResponseFilter, RibbonRoutingFilter (#1935) 2017-05-15 13:44:14 -04:00
Spencer Gibb a1b1a7d702 Moves EurekaHealthIndicator creation to auto config.
Fixes a race condition introduced in 1.3.0

fixes gh-1933
2017-05-15 10:04:31 -06:00
Ryan Baxter ccdf0d9f95 Removing duplicate and incorrect dependency. Fixes #1941. 2017-05-15 10:48:39 -04:00
Ryan Baxter 287ce9c0ff Merge pull request #1877 from yongsungyoon/master
Add @Component for Feign Hystrix Fallback example in doc
2017-05-11 11:40:39 -04:00
윤용성(Yongsung Yoon)/개발혁신팀/SKP b8ed846247 Update docs to indicate the need of declaring feign's fallback implementation as a Spring bean 2017-05-11 11:29:59 +09:00
Ryan Baxter 2a9a62d0f6 Merge pull request #1926 from TheSentinel454/issues_1676_wildcard_type_support
Add support for Wildcard Types in Feign Client.  Fixes gh-1676
2017-05-10 16:04:38 -04:00
Dave Syer 377bccf12a Update to latest cloud dependencies 2017-05-10 11:37:53 +01:00
Dave Syer 030a8e7111 Remove Lombok from hystrix stream 2017-05-10 11:09:15 +01:00
Luke Tornquist 189d926c6a Correct import order 2017-05-09 16:10:08 -04:00
Luke Tornquist d993fe217c Format using provided Eclipse formatter. 2017-05-09 13:20:01 -04:00
Luke Tornquist 8983c9bce1 Add support for Wildcard Types in Feign Client. Fixes gh-1676 2017-05-09 13:16:12 -04:00
Dave Syer ced1f36d19 bump spring cloud build version 2017-05-05 17:16:18 +01:00
Ryan Baxter e698fa664b Cherry Picking #1910 2017-05-04 11:55:26 -04:00
Ryan Baxter ab2cf59bf6 Merge pull request #1907 from spccold/zuul-filter-bugfix
change HttpServletResponse to HttpServletRequest
2017-05-03 09:53:17 -04:00
Ryan Baxter a315ac9e54 Merge pull request #1906 from lowzj/master-removeUnusedImport
polish FeignLoadBalancer, remove unused import statement
2017-05-02 10:05:06 -04:00
wuwo c6347ec9c8 change HttpServletResponse to HttpServletRequest 2017-05-02 17:26:42 +08:00
lowzj ac8379af29 polish FeignLoadBalancer, remove unused import statement 2017-05-02 17:13:41 +08:00
Dave Syer 69622e909b Fix typo in test method name 2017-04-27 10:29:59 +01:00
Biju Kunjummen 910167de09 Ribbon based on Eureka disabled, if Eureka client is not enabled (#1892)
Ribbon client configuration based on Eureka is disabled if eureka.client.enabed is set to false.

Fixes gh-335
2017-04-26 14:45:35 -04:00
Ryan Baxter 29fb58de84 Merge pull request #1884 from ryanjbaxter/pass-config-in-retryhandler
Pass config in retry handler
2017-04-24 20:05:29 -04:00
Ryan Baxter dbf17dea18 Pass config in retry handler. Fixes #1879. 2017-04-24 14:09:04 -04:00
Ryan Baxter 7fcbc0fd5a Merge pull request #1880 from daniellavoie/mvn-3.5.0
Update mvnw to 3.5.0
2017-04-24 10:56:37 -04:00
Daniel Lavoie 32c79b7a91 Update mvnw to 3.5.0
Fixes gh-1847
2017-04-23 16:27:06 +02:00
Ryan Baxter 1647fc3017 Merge pull request #1876 from ryanjbaxter/upgrade-hystrix-1.5.11
Upgrade Hystrix to 1.5.11 and apply fix to hystrixcommand.js
2017-04-20 16:30:09 -04:00
Ryan Baxter 17f43fd138 Fixes #1855 2017-04-20 15:12:57 -04:00
Ryan Baxter a708ceefe8 Merge pull request #1870 from ryanjbaxter/force-eurekaclient-creation-on-refresh
Make sure the EurekaClient bean is recreated after refresh.
2017-04-20 14:53:03 -04:00
Ryan Baxter 1f12902f78 Make sure the EurekaClient bean is recreated after refresh. Fixes #1857. 2017-04-19 11:29:33 -04:00
Spencer Gibb cebbcf592e polish 2017-04-18 12:23:56 -06:00
Ryan Baxter 0c7994c502 We no longer use travis so removing configuration
Fixes #1846.
2017-04-11 13:45:57 -04:00
Ryan Baxter d412df5883 Merge pull request #1808 from gonzalad/1807
Add X-Forwarded-Port header in Zuul
2017-04-10 20:17:02 -04:00
Ryan Baxter cca3744396 Bumping versions to 1.3.1.BUILD-SNAPSHOT after release 2017-04-07 06:12:17 -04:00
Ryan Baxter c98c50291c Going back to snapshots 2017-04-07 06:12:16 -04:00
Ryan Baxter e9035ab3e0 Update SNAPSHOT to 1.3.0.RELEASE 2017-04-07 06:10:01 -04:00
Ryan Baxter d8eb4432b9 Updating mvnw script 2017-04-07 06:04:35 -04:00
Ryan Baxter 8dcf544079 Merge pull request #1836 from ryanjbaxter/response-code-retry
Add the ability for ribbon clients to specify response status codes they would like to retry
2017-04-05 14:01:15 -04:00
Ryan Baxter 98cbf2f47f Merge pull request #1840 from ryanjbaxter/document-hystrix-timeout
Document Hystrix timeout configuration with Ribbon clients
2017-04-05 13:46:50 -04:00
Ryan Baxter e041d87b5a Document Hystrix timeout configuration with Ribbon clients. Fixes #1828 2017-04-05 13:44:42 -04:00
Spencer Gibb 5440aca212 Merge pull request #1829 from Aloren/feature/exceptions-monitoring
* feature/exceptions-monitoring:
  Implements zuul CounterFactory
2017-04-05 11:33:40 -06:00
Anastasiia Smirnova 834980eae7 Implements zuul CounterFactory
CounterFactory is used by ZuulException and was previously initialzed
with a dummy impl.

This adds a Spring Boot CounterService based implementation.

Also adds the ability to implement a zuul TracerFactory.
2017-04-05 11:33:29 -06:00
David-V2 a61822f9c9 Added Bad Request count to Hystrix dashboard (#1839)
* brainlessly apply this : https://github.com/Netflix/Hystrix/commit/892f6a781e67f153b0bf2f7387c87ca0721955c2
2017-04-05 12:00:14 -04:00
Ryan Baxter 6290859f81 Add the ability for ribbon clients to specify response status codes they would like to retry. Fixes #1540. 2017-04-04 15:34:08 -04:00
Spencer Gibb 62408af5ea Don't set chunked encoding with GET.
fixes gh-1824
2017-04-03 14:04:07 -06:00
Ryan Baxter 711a8f0aae Merge pull request #1817 from ryanjbaxter/use-valid-hostnames-in-feign-tests
Use valid hostnames in feign tests
2017-03-28 14:31:41 -04:00
Ryan Baxter 382988a06a Fixed hostname 2017-03-28 09:48:41 -04:00
Ryan Baxter 88431bdbea Use valid hostnames in Feign retry tests 2017-03-28 09:46:16 -04:00
Ryan Baxter 62cb0ae28f Change /routes endpoint to use EndpointMvcAdapter and AbstractEndpoint (#1802)
Change /routes endpoint to use EndpointMvcAdapter and AbstractEndpoint.  

Fixes #1797
2017-03-24 16:27:41 -04:00
gonzalad 31f5a2bb73 1807: Add X-Forwarded-Port header in Zuul
Added more unit tests
2017-03-24 19:20:06 +01:00
gonzalad cb90cd9929 Add X-Forwarded-Port header in Zuul
Add X-Forwarded-Port header in Zuul PreDecorationFilter
even with X-Forwarded-Host header being absent.
2017-03-24 16:28:09 +01:00
Ryan Baxter d402587ab2 Merge pull request #1805 from ryanjbaxter/url-protocal-el-syntax
Fixes the addition of http with EL syntax
2017-03-23 16:12:04 -04:00
Ryan Baxter 02226f938e Fixes the addition of http with EL syntax. Fixes #1796 2017-03-23 15:00:55 -04:00
Spencer Gibb 37309218ec Links to sample zuul filters.
For more advanced filter examples.

fixes gh-1748
2017-03-23 12:40:41 -06:00
Michael Tecourt 03740f1369 Make EurekaDiscoveryClient.EurekaServiceInstance constructor public (#1794)
Make EurekaDiscoveryClient.EurekaServiceInstance constructor public

fixes gh-1792
2017-03-23 14:23:25 -04:00
Ryan Baxter d3314447a8 Fixed logging statement. Fixes #1798 2017-03-20 10:58:50 -04:00
Spencer Gibb a8b170f51c Upgrade eureka to v1.6.2
fixes gh-1786
2017-03-16 14:47:08 -06:00
Ryan Baxter a669a309f6 Revert "Version changes for Dalston.RC1"
This reverts commit a628ba1b8f.
2017-03-16 13:31:53 -04:00
Ryan Baxter a628ba1b8f Version changes for Dalston.RC1 2017-03-16 11:59:46 -04:00
Ryan Baxter 5bf87c4da1 Merge pull request #1749 from bijukunjummen/GH-1334
GH-1334: Support for eagerly initializing zuul Ribbon contexts
2017-03-15 11:46:34 -04:00
Spencer Gibb b7c5b24d43 comment out failing test 2017-03-14 20:06:07 -06:00
Spencer Gibb 44bb4f2cc3 Move load balancer construction test 2017-03-14 19:01:43 -06:00
Spencer Gibb 55a58eaf30 jmx=false for tests 2017-03-14 18:49:12 -06:00
Spencer Gibb 5d3ca843b6 jmx=false for tests 2017-03-14 18:25:44 -06:00
Spencer Gibb ecf12aa0e7 Makes ServerListUpdater respect configuration.
By default, `LoadBalancerBuilder` built a load-balancer with a `PollingServerListUpdater`. This change introduces a `ServerListUpdater` bean which creates a `PollingServerListUpdater(IClientConfig)` so that `ribbon.ServerListRefreshInterval` is respected.

 fixes gh-1304
2017-03-14 12:24:38 -06:00
Biju Kunjummen 427770a6d0 Added documentation, changed property name from serviceIds to clienNames, clients 2017-03-14 04:48:43 -05:00
Biju Kunjummen 2d9604918a Changed property name from zuul.ribbon.eager-load to zuul.ribbon.eager-load.enabled 2017-03-14 04:36:10 -05:00
Biju Kunjummen 567a6c4a9f Support for eagerly loading Ribbon clients through configuration properties 2017-03-14 04:36:10 -05:00
Biju Kunjummen 31b617b10f Fixed formatting issues, added more tests 2017-03-14 04:36:10 -05:00
Biju Kunjummen a6fe648a41 GH-1334: Support for eagerly initializing zuul Ribbon named client contexts 2017-03-14 04:36:10 -05:00
Ryan Baxter 66163bee2b Merge pull request #1771 from jh409/patch-1
Update docs as @Autowired fails with many beans
2017-03-13 12:07:03 -04:00
Jack Harris db7d352c97 Update docs as @Autowired fails with many beans
Fix a suspected typo. @Autowired throws a `NoUniqueBeanDefinitionException` if there are multiple beans of the same type without a primary, but the documentation said multiple beans 'cause `@Autowired` to work', rather than 'not work'.
2017-03-13 00:19:57 +00:00
Spencer Gibb cda92f4ba3 Upgrade Hystrix to v1.5.10
fixes gh-1766
2017-03-08 19:57:04 -07:00
Ryan Baxter 133613aeb1 Merging #1762 into master 2017-03-08 10:51:33 -05:00
Spencer Gibb 15e01dfe5d Don't remove content-length header in feign ribbon.
Previously, when feign used the Ribbon RestClient, an exception was thrown if Content-Length was set. Over time, feign has moved away from RestClient, yet removing the header still happened.

 Fixes gh-1705
2017-03-06 20:11:03 -07:00
Spencer Gibb 6df7190472 Update docs for REQUEST_URI_KEY in zuul 2017-03-03 15:19:10 -07:00
Spencer Gibb 5212d138f8 Upgrade okhttp3 to 3.6.0
Also add com.squareup.okhttp3:logging-interceptor dependency management.

fixes gh-1752
2017-03-03 09:01:11 -07:00
Bertrand Renuart 465582d20c Make sure MetricsRestTemplateAspectConfiguration is applied in time.
`MetricsRestTemplateConfiguration` creates a BeanPostProcessor used to configure RestTemplate instances when added to the application context. It should be made @ConditionalOnClass(RestTemplate) instead of @ConditionalOnBean(RestTemplate) since it should be present *before* any RestTemplate bean instance is created. (#1747)

fixes gh-1153
2017-03-02 10:32:04 -05:00
Bertrand Renuart fae60e9fae Remove unused registry private field. (#1746)
fixes gh-1745
2017-03-02 10:14:31 -05:00
Ryan Baxter c89645e069 Merge pull request #1743 from ryanjbaxter/disable-hystrix-feign
Disable Hystrix support when using Feign by default
2017-03-01 16:33:34 -05:00
Ryan Baxter 6465cf4f3e Added warning to the docs about the change in default behavior. 2017-03-01 13:15:11 -05:00
Ryan Baxter 54c052c5eb Disable Hystrix support when using Feign by default. Fixes #1277. 2017-03-01 11:35:08 -05:00
nick-pww 465b8273eb Clarify @FeignClient alias creation
fixes gh-1073
2017-02-28 15:02:15 -05:00
windinn 129e0ce4b5 Use prefer-ip-address in statusPageUrlPath
prefer-ip-address does not work in statusPageUrlPath when management port != server port

This change gets `prefer-ip-address` via a relaxed property resolver to set the value during the creation of the `EurekaInstanceConfigBean`.

fixes gh-1724
2017-02-28 13:07:43 -05:00
Spencer Gibb 309b280d0d Log warning if local instance fails.
If DiscoveryClient.getLocalServiceInstance() throws an exception (ie consul isn't available), log a warning and continue. This is useful for dev type environments.

fixes gh-1603
2017-02-28 10:26:15 -07:00
Biju Kunjummen 99d9b17a2d Moves EurekaServerConfiguration to auto-configuration
Eureka ServerConfiguration is now auto-configuration based, instead of being explicitly specified via configuration pulled in through @EnableEurekaServer. This way specific beans can be conditionally overridden, configuration can be re-ordered.
Supports PeerEurekaNodes bean to be overridden by the user

Fixes gh-1717
2017-02-28 12:00:29 -05:00
Ryan Baxter 208a741823 Merge pull request #1732 from utsman/master
Refactor ZoneUtils class
2017-02-27 09:40:49 -05:00
utsman c953d59b5a Refactor ZoneUtils class 2017-02-26 01:45:31 +09:00
Spencer Gibb c0fefc4d1a Update feign to version 9.4.0
fixes gh-1731
2017-02-24 15:05:42 -07:00
Ryan Baxter 0fcc979fe1 Merge pull request #1730 from utsman/rm-dupl-check
Remove duplicate null check
2017-02-24 14:05:26 -05:00
utsman cb9d9bd8a1 Remove duplicate null check 2017-02-25 03:13:24 +09:00
Ryan Baxter 1d5a68c9e7 Merge pull request #1728 from utsman/fix-typo
Fixed typo
2017-02-24 10:07:23 -05:00
utsman 8e3f45b899 Fixed typo 2017-02-24 23:30:39 +09:00
Ryan Baxter ea87b9bfc2 Merge branch 'master' of https://github.com/spring-cloud/spring-cloud-netflix 2017-02-20 15:56:50 -05:00
Ryan Baxter df91ff7735 using apache commons logger 2017-02-20 15:56:37 -05:00
Spencer Gibb 652fe97a1b fix logger 2017-02-20 13:54:54 -07:00
Ryan Baxter 06565765b8 removing unused imports 2017-02-20 14:25:50 -05:00
Ryan Baxter fc9c7dcdfc clearing context during setup 2017-02-20 13:39:06 -05:00
Ryan Baxter 72f1ce9096 added logging to test 2017-02-20 11:18:31 -05:00
Ryan Baxter 0abf69dc1d Merge pull request #1709 from ryanjbaxter/make-feign-retry-optional
Make the use of Spring Retry optional when using Feign
2017-02-17 18:25:28 -05:00
Ryan Baxter a4f30ebf1d Make the use of Spring Retry optional when using Feign. Fixes #1708 2017-02-17 11:12:12 -05:00
Tomasz Juchniewicz ed137a93ce Fix encoding issue in SpringEncoder for binary data (#1699)
* Fix encoding issue in SpringEncoder for binary data

Fixes gh-1698

* Fix encoding issue in SpringEncoder for binary data

Fixes gh-1698

* Fix encoding issue in SpringEncoder for binary data

Add unit test.

Fixes gh-1698
2017-02-16 14:52:15 -05:00
Lars e73ee5f690 Refactors zuul tests for better readability. (#1686)
* Refactors tests for better readability. Polishes imports. Removes hostname and port from TestRestTemplate-calls. Introduces @LocalServerPort
2017-02-16 12:48:48 -05:00
Ryan Baxter de886d6c3d Merge branch 'master' of https://github.com/spring-cloud/spring-cloud-netflix 2017-02-15 20:09:27 -05:00
Ryan Baxter 050d5f898f Porting changes that remove RetryTemplate from FeignLoadBalancer constructor from 1.2.x branch 2017-02-15 20:09:15 -05:00
Spencer Gibb e3341a19cd Add @FeignClient(primary)
Adds the ability to turn off Spring Cloud Netflix making the feign instances as primary.

fixes gh-1016
2017-02-15 17:46:12 -07:00
Spencer Gibb 8f5e3ad7c0 polish 2017-02-15 17:30:42 -07:00
Ryan Baxter 384c9b9725 Merge branch 'master' of https://github.com/spring-cloud/spring-cloud-netflix 2017-02-15 13:43:02 -05:00
Ryan Baxter 981fa5db9a Merging PR #1689 into master 2017-02-15 13:42:46 -05:00
Ryan Baxter c417a9a55e Merge pull request #1695 from ryanjbaxter/uri-equal-to-empty-string
Adds a check for an empty URI in updateToHttpsIfNeeded
2017-02-14 15:33:12 -05:00
Ryan Baxter 52ab4d3ecd Adds a check for an empty URI in updateToHttpsIfNeeded. Fixes #1690. 2017-02-14 14:50:55 -05:00
Ryan Baxter 62bc2758eb Merge pull request #1694 from ryanjbaxter/default-zuul-fallbackprovider
Add the ability to provide a default ZuulFallbackProvider
2017-02-14 14:42:09 -05:00
Ryan Baxter 731c8bf0fd Add the ability to provide a default ZuulFallbackProvider. Fixes #1506 2017-02-14 13:59:25 -05:00
Erik Kringen d78da7b994 Add support for Feign.SetterFactory (#1673)
Fixes gh-1414
2017-02-10 13:37:17 -05:00
Roman Terentiev c795bd16a7 #1203 Improve filter performance by using only one instance of AllEncompassingFormHttpMessageConverter (#1681) 2017-02-10 12:25:27 -05:00
Spencer Gibb 7237275f5d polish 2017-02-10 10:14:12 -07:00
Johannes Edmeier 3e7b196950 Close response on errors writing to the outputStream (#1372)
Currently all errors during writing to the outputStream are ignored. So the
response is read to the end. This is a problem when the response is
infite or very long running (`hystrix.stream` for example) and results in the
socket never being closed and eating up threads (on zuul and the proxied
backend). With this commit the errors during writing are not ignored resulting
in closing the response.
2017-02-10 12:12:26 -05:00
Ryan Baxter 919c8fa72a Merge pull request #1678 from lowzj/master-RequestParam
fix gh-1672, support @RequestParam without a value
2017-02-09 19:38:00 -05:00
Ryan Baxter bcb97bce1c Merging PR #1680 into master 2017-02-09 15:12:19 -05:00
Ryan Baxter 64d8883210 Adding missing commit from #1457 2017-02-09 14:29:40 -05:00
Ryan Baxter 0af99769ad Adding missing commit from PR #1457 2017-02-09 14:29:12 -05:00
lowzj c8fded80d5 fix gh-1672, support @RequestParam without a value 2017-02-09 13:58:30 +08:00
Spencer Gibb c6a3157fd8 Adds information on RibbonRoutingFilter HTTP Clients 2017-02-08 20:55:08 -07:00
Ben Klein 8afb02cf03 Zuul Developer Guide: minor edits 2017-02-08 21:20:16 -06:00
Spencer Gibb 675e4c1031 Adds example zuul filters. 2017-02-08 19:47:57 -07:00
Spencer Gibb d21d03b738 initial zuul developer guide 2017-02-08 18:53:21 -07:00
Spencer Gibb ff70c08fb9 More zuul constant and javadoc updates 2017-02-08 18:52:41 -07:00
Spencer Gibb 506a9a44af Move many zuul strings to FilterConstants.
Also adds minimal javadoc to classes.

See gh-1435
2017-02-08 12:09:53 -07:00
Spencer Gibb 10e8634d38 add additional conditional on class in case of webflux 2017-02-08 10:29:32 -07:00
Spencer Gibb a1577127b7 hopefully fix flaky test 2017-02-06 21:11:25 -07:00
Spencer Gibb 5a1f1d2c64 Remove unused import. 2017-02-06 20:20:22 -07:00
Ryan Baxter a915651797 Merge pull request #1670 from bijukunjummen/gh-1641
gh-1641: Fixed instructions for configuring EurekaIntanceConfig in AWS
2017-02-06 11:20:11 -05:00
Biju Kunjummen 133d054fc8 Fixed instructions for configuring EurekaIntanceConfig in AWS 2017-02-03 22:50:30 -08:00
Eloi c87f6ca983 delegate to the library httpclient parse the content type (#1664)
Fixes gh-1663
2017-02-02 11:05:01 -05:00
Spencer Gibb a2e1836e24 Merge pull request #1656 from sbley/master
* pull1656:
  Separate adding X-ForwardedProto header
2017-02-01 15:33:13 -07:00
Stefan Bley 53649f6020 Separate adding X-ForwardedProto header
Add X-Forwarded-Proto header in Zuul PreDecorationFilter even with X-Forwarded-Host header being absent
2017-02-01 15:33:00 -07:00
Spencer Gibb 601e220411 implement Registration.getServiceId() 2017-02-01 13:45:05 -07:00
Ryan Baxter ed6c4b1925 Revert "Version changes for 1.3.0.M1"
This reverts commit 46ee0ce161.
2017-01-27 14:25:34 -05:00
Ryan Baxter 46ee0ce161 Version changes for 1.3.0.M1 2017-01-27 13:02:13 -05:00
Ryan Baxter 71b3110acf Updating config and stream versions for Dalston 2017-01-27 12:01:33 -05:00
Eloi e6f2db70ef Maintain content type for data parts in multipart requests (#1614)
maintain multipart content type for data parts

Fixes gh-1581
2017-01-27 10:26:11 -05:00
Matt Sicker 65829c437c Fix docs about @Configuration with @FeignClient (#1650)
As discovered in #1643, using `@Configuration` on a custom configuration with `@FeignClient` is unnecessary and creates extra work for exclusion from a `@ComponentScan`. This updates the docs to make this explicit.
2017-01-26 11:40:58 -05:00
Spencer Gibb f27defbdf4 Make sure service-registry actuator is activated. 2017-01-25 15:15:46 -07:00
Spencer Gibb 41bf8eadfd Rename RESET_OVERRIDE to CANCEL_OVERRIDE 2017-01-25 14:23:34 -07:00
Spencer Gibb d76bd84466 Handle content-type with charset.
A new version of httpclient introduced by boot changed the behaviour that previously allowed the charset. It now has to be parsed out and passed to the apache `ContentType` object explicitly.

fixes gh-1649
2017-01-25 11:47:11 -07:00
Ryan Baxter ca244c5dbb Merge pull request #1637 from tmack8001/zuul-route-constructor-custom-sensitive-headers
ZuulProperties.ZuulRoute consturctor missing explicitly setting of customSensitiveHeaders boolean
2017-01-23 09:38:44 -05:00
Trevor Mack ff0ac568f4 addressing issues/1636 ZuulProperties.ZuulRoute consturctor missing explicitly setting of customSensitiveHeaders boolean when provided with sensitiveHeaders 2017-01-21 23:12:45 -08:00
Spencer Gibb 5d0b2fae86 Ignore misbehaving test 2017-01-20 13:42:04 -07:00
Spencer Gibb f8a8b3cf31 Fix broken test logic, rather than >= should be <= 2017-01-20 13:41:49 -07:00
Jin Zhang 88396411f7 improve efficiency of SendResponseFilter#addResponseHeaders() (#1622) 2017-01-20 15:08:38 -05:00
Ryan Baxter 42931f9300 Merge pull request #1626 from ryanjbaxter/apply-formatter-to-collections-1526
Remove check that does not apply Formatters to Collections
2017-01-17 11:44:26 -05:00
Ryan Baxter a5bd17c0c0 Remove check that does not apply Formatters to Collection in Feign Client parameters. Fixes #1526 2017-01-17 11:16:25 -05:00
Spencer Gibb a5e5f81d88 Changes equals assertion to greaterThanOrEquals.
Hopefully this fixes flaky tests.
2017-01-16 11:41:45 -07:00
Spencer Gibb 66da2d8f48 Merge pull request #1586 from Infrag/master
* pull1586:
  Adds composed @RequestMapping annotations support
2017-01-13 14:03:52 -07:00
Ondřej Božek b619ee00bf Adds composed @RequestMapping annotations support
Fixed short circuit condition to correctly detect @RequestMapping shortcuts (@GetMapping, @PostMaping etc.)

Fixes gh-1201
2017-01-13 14:03:37 -07:00
Johannes Edmeier 899d8bc24d Add CompositeRouteLocator (#1448)
Configure a CompositeRouteLocator by default so it is easier to compose
multiple RouteLocators.
2017-01-12 16:38:01 -05:00
Spencer Gibb bf586ba2cb polish 2017-01-12 14:32:57 -07:00
Spencer Gibb 22248dd9e9 Merge pull request #1591 from tranhungt/gzip_decompression
* gzip_decompression:
  Disables httpclient auto decompression of encoded data
2017-01-12 14:31:32 -07:00
Hung Tran 6dfc7a815b Disables httpclient auto decompression of encoded data
Applies only to SimpleHostRoutingFilter.

fixes gh-1480
2017-01-12 14:31:22 -07:00
Arnaud Brunet b27ba0434a More robust instantiation in SpringClientFactory
SpringClientFactory returns null if the class is not aware of IClientConfig.

This change catches the exception when trying the constructor with IClientConfig so classes that aren't aware of IClientConfig can be created.

Fixes gh-1608
2017-01-12 16:15:31 -05:00
Spencer Gibb 3b41b5e15f Remove mocks for application event listeners.
fixes gh-1616
2017-01-12 13:39:46 -07:00
Ryan Baxter 8029deb1e4 Merging PR #1457 into master. 2017-01-10 12:52:36 -05:00
Ryan Baxter 5ee9990d93 Upgrade Ribbon to 2.2.2
Fixes gh-1441
2017-01-09 23:38:06 -05:00
Spencer Gibb 8a9c5fe4a1 Update fixes for hystrix stream test 2017-01-09 21:11:31 -07:00
Abhijit Sarkar 45d769b05b Support header map and query map (#1361)
Adds support for Map types in feign for `@RequestHeader` and `@RequestParam`.

Fixes gh-1360
2017-01-09 22:45:03 -05:00
Rob Worsnop af032476a8 Modified RibbonAutoConfiguration to support AsyncLoadBalancerInterceptor (#1507) 2017-01-09 22:02:10 -05:00
Spencer Gibb c52309ad59 Update to spring-cloud-build 1.3.1.BUILD-SNAPSHOT 2017-01-09 17:22:08 -07:00
Spencer Gibb 8526371d25 Merge pull request #1451 from madgnome/#1341-single-deferred-result
* #1341-single-deferred-result:
  #1341 SingleDeferredResult should uses RESULT_NONE from DeferredResult instead of having its own empty result.
2017-01-09 16:44:04 -07:00
Julien Hoarau 7f4a6fd94c #1341 SingleDeferredResult should uses RESULT_NONE from DeferredResult instead of having its own empty result. 2017-01-09 16:43:40 -07:00
Spencer Gibb 6fc5d1aea3 Merge pull request #1485 from eacdy/master
* pull1485:
  fix spell error
2017-01-09 16:11:40 -07:00
周立 1860b26491 fix spell error
fix spell error
2017-01-09 16:11:30 -07:00
Thibaud Lepretre fccbe1aff4 Create sidecar.hostname and sidecar.ipAddress (#1561)
In addition to `eureka.instance.hostname` property you can now defined `sidecar.hostname` in order to set different hostname from application and its sidecar.
However if `eureka.instance.hostname` is present it will override `sidecar.hostname`.

Fixes #981
2017-01-09 17:13:36 -05:00
Bertrand Renuart fa45a9f3a4 Use a fixed size buffer for the copy operation (#1538)
Set the default buffer size to 8192 to match Tomcat and Jetty defaults
Use a buffer per worker thread and use it for subsequent requests
2017-01-09 14:38:45 -05:00
Biju Kunjummen 98cd592f3e Fix null instanceinfo on EurekaInstanceRenewedEvent (#1574)
Fixes gh-1546
2017-01-09 12:41:23 -05:00
Spencer Gibb 64b81ff5a4 Update hystrix to 1.5.9
fixes gh-1600
2017-01-09 10:11:39 -07:00
Ryan Baxter f3deb04521 Pass along client config in RibbonCommand.run (#1573)
Pass along client config in RibbonCommand.run.  

Fixes gh-1530
2017-01-09 11:55:05 -05:00
Ryan Baxter ab454f1e1b Make FeignClientRegistrar implement EnvironmentAware (#1569)
Make FeignClientRegistrar implement EnvironmentAware to inject the environment.  

Fixes gh-1568
2017-01-09 11:06:51 -05:00
Jacques-Etienne Beaudet bd6d732fc7 Fix potential decoding and reencoding issues in query params when using SimpleHostRoutingFilter (#1464)
Some webserver are picky with the encoding (uWSGI for example) and the current code behavior of decoding and reencoding the query string can lead to valid requests
rejected by the backend after the modifications in Zuul. This commit adds an optional parameter to force the original encoding of the query string in SimpleHostRoutingFilter.

Fixes gh-971
2017-01-09 10:53:16 -05:00
Ryan Baxter 4eac8a5a47 Merge pull request #1599 from ahmednasir91/upgrade-hystrix-157
Fixes #1440
2017-01-09 07:04:21 -05:00
Ahmed Nasir 82dd2ebd05 Fixes #1440 2017-01-09 14:20:31 +05:00
Ryan Baxter 1cd194a1e1 Merge pull request #1578 from rahmanusta/patch-1
Update spring-cloud-netflix.adoc
2016-12-27 19:50:08 -05:00
Rahman Usta f26a5554d5 Update spring-cloud-netflix.adoc
- Remove unintended white-space
 - Specify imagesdir
2016-12-26 16:03:41 +02:00
Spencer Gibb c380039b3e Add test to make sure eureka.instance.*virtualHostName can be set properly. 2016-12-16 14:00:31 -07:00
Bart Blommaerts 9125f54897 Tiny grammatical fix (#1552) 2016-12-15 11:29:14 -05:00
Spencer Gibb 08fe5a89e9 Move SendErrorFilter to type error.
This will clear up empty 200 responses.

fixes gh-1123
2016-12-12 15:01:32 -07:00
Ryan Baxter 2e46bdf9d2 Porting #1450 for Dalston release 2016-12-12 15:09:16 -05:00
Spencer Gibb 18b9c46a8b update eureka config first bootstrap for service registry 2016-12-12 10:43:05 -07:00
Dave Syer a99e23f9fc Update to Boot 1.5.0 2016-12-12 12:31:32 +00:00
Spencer Gibb 8b089222bd make external configurations optional 2016-12-08 13:47:19 -07:00
Spencer Gibb 5b25c9ad1a Only auto-register if conditions are correct.
s-c-commons creates an AutoServiceRegistrationProperties bean if enabled.

This commit only auto registers with eureka if that bean is available.
2016-12-08 12:27:10 -07:00
Spencer Gibb ec80797694 avoid potential NPE 2016-12-08 12:27:10 -07:00
Bertrand Renuart 8b7d6848b3 use com.netflix.loadbalancer.DummyPing instead of NoopPing
use `com.netflix.loadbalancer.DummyPing` instead of `NoopPing`

This eliminates the startup of another theadpool.

fixes gh-1504
2016-12-05 13:26:05 -05:00
Ryan Baxter edb14e2a6b Merge pull request #1528 from ryanjbaxter/feign-url-protocol-1522
Don’t add URL protocol when url is set using EL
2016-12-05 13:14:58 -05:00
Ryan Baxter 6a82644153 Don’t add URL protocol when url is set using EL. Fixes #1522. 2016-12-05 12:48:01 -05:00
Ryan Baxter ac3401bc4f Fixed import ordering 2016-12-01 20:28:29 -05:00
Ryan Baxter 9da71b1655 Removed unnecessary null check and fixed imports 2016-12-01 20:28:28 -05:00
Ryan Baxter ed31004aa8 Uses configuration from IConfigClient reference to always use the most up to date configuration. Fixes #1481. 2016-12-01 20:28:28 -05:00
Ryan Baxter fe50674c8e Merge pull request #1520 from ryanjbaxter/eureka-client-zone-doc-1327
Document Eureka client zone config
2016-12-01 19:15:38 -05:00
Spencer Gibb 1fe1ea58f6 Don't override values with defaults.
Defaults were set too late and were overriding values set in the environment.

Specifically, spring.application.name took precedence over eureka.instance.appname.

 fixes gh-1516
2016-11-30 11:55:57 -07:00
Spencer Gibb b3f1a30027 Move initalizing appname, etc.. to afterPropertiesSet 2016-11-30 11:55:24 -07:00
Spencer Gibb 111a95d262 Fix Eureka Ribbon Auto Config conditions.
Specifically, add `@ConditionalOnBean(EurekaClient.class)`.

Fixes an issue where eureka and ribbon are on the classpath, eureka.client.enabled=false which would cause a bean not found exception.

fixes gh-1511

(cherry picked from commit d1f8c03)
2016-11-29 14:56:55 -07:00
Ryan Baxter 35528a7199 Merge pull request #1496 from ryanjbaxter/upgrade-eureka-to-1.6.1
Upgrade Eureka to 1.6.1.  Fixes #1495.
2016-11-22 20:22:49 -05:00
Ryan Baxter 927b753262 Upgrade Eureka to 1.6.1. Fixes #1495. 2016-11-22 19:59:27 -05:00
Ryan Baxter 8359016981 Updating generated README 2016-11-22 17:14:39 -05:00
Ryan Baxter 5372fe9d6e Merge pull request #1494 from ryanjbaxter/document-feign-request-headers
Document how to use thread isolation with hystrix and feign.  Fixes #1191.
2016-11-22 17:08:05 -05:00
Ryan Baxter 8814da3b78 Document how to use thread isolation with hystrix and feign. Fixes #1191. 2016-11-22 15:39:13 -05:00
Bertrand Renuart 2d748bf63c use different bean names for Hystrix and HystrixStream features (#1470)
Fixes gh-1462
2016-11-16 09:39:48 -07:00
Ryan Baxter eff1f0d77a Fixes #1459 2016-11-14 15:30:28 -05:00
Spencer Gibb aec8ec43ef Fix broken test. 2016-11-07 11:24:52 -07:00
Spencer Gibb 93cd1e7a4a Upgrade to eureka 1.6.0
fixes gh-1345
2016-11-07 10:52:47 -07:00
Spencer Gibb ea4e5d76e0 Create EurekaServiceRegistry
Use the new ServiceRegistry interface

Creates a new EurekaRegistration object that aggregates classes needed
for a single registration.
2016-11-07 10:52:47 -07:00
Robin Stocker e6298f8107 Fix NoClassDefFoundError loading RxJavaAutoConfiguration without spring-webmvc (#1442)
RxJavaReturnValueHandlerConfig can only be loaded when both spring-web
and spring-webmvc are on the classpath, because it contains a reference
to the WebMvcConfigurerAdapter class.

But the ConditionalOnClass annotation only included the class from
spring-web. In our situation, only spring-web was on the classpath,
resulting in a NoClassDefFoundError for WebMvcConfigurerAdapter. Fix it
by adding that class to the condition as well.
2016-11-03 10:27:15 -04:00
Dave Syer 704a874e84 Add example of empty sensitive headers
Emphasises that it's a black list, and clarifies that you need to
set it to empty to get authorization and cookie headers.
2016-11-03 12:06:43 +00:00
Spencer Gibb 428ed6c88c Bump to 1.3.0.BUILD-SNAPSHOT 2016-10-27 15:37:59 -06:00
Ryan Baxter dd62879b7b Merge pull request #1430 from ryanjbaxter/zuul-hystrix-fallback-doc
Document Hystrix Fallback For Zuul
2016-10-27 15:33:52 -04:00
Ryan Baxter 14a31cd5f8 Switched media type to application/json 2016-10-27 15:09:21 -04:00
Ryan Baxter 8a7df36d88 Added route config 2016-10-27 15:02:17 -04:00
Ryan Baxter fe56d96295 Fixes #1429 2016-10-27 14:25:18 -04:00
Ryan Baxter fabf90bed4 Merge pull request #1375 from ryanjbaxter/simplify-retry-logic
Provide A Retry Policy For Ribbon Clients
2016-10-26 15:42:32 -04:00
Ryan Baxter c3a84f1b73 Merge remote-tracking branch 'Upstream/master' into simplify-retry-logic 2016-10-26 15:05:12 -04:00
Ryan Baxter 5a5a1aaa7f -Made spring-retry optional
-additional refactoring from changes in s-c-commons
2016-10-26 15:04:51 -04:00
Venil Noronha aef753a3a0 Adds Feign Logger factory interface (#1411)
Fixes gh-1363
2016-10-25 17:39:22 -04:00
Ryan Baxter 08028db982 Merge pull request #1425 from ryanjbaxter/eureka-app-name-default
Resolve spring.application.name via property resolver
2016-10-25 14:31:12 -04:00
Ryan Baxter 85b2fe37e2 Added some additional tests 2016-10-25 13:54:29 -04:00
Spencer Gibb 81959b5ef3 Use new FilterRegistrationBean package.
Breaks Spring Boot 1.3 compatibility, enables 1.5
2016-10-25 11:24:42 -06:00
Ryan Baxter 657d9bb8e8 Merge remote-tracking branch 'Upstream/master' into eureka-app-name-default 2016-10-25 13:04:35 -04:00
Ryan Baxter 2dfee97563 Resolve spring.application.name value via a property resolver instead of @Value. Fixes #1398 2016-10-25 12:56:08 -04:00
Dave Syer 7f075d11ee Allow Cors requests through to backend by default
Instead of blocking them (which is the default behaviour of a
Spring MVC controller) Cors requests will flow through the Zuul
filters by default. Users can control it by grabbing the
ZuulHandlerMapping in a @PostConstruct and injecting some
CorsConfiguration via its setCorsConfigurations() method.
2016-10-25 14:33:53 +01:00
Dave Syer a38b7b71ac Append to X-Forwarded-* headers instead of replacing them
This fixes most of the issues people encounter when there are
multiple proxies in the request. The tricky thing is that there
is another header "Forwarded" that we don't recognize, but which
backends probably do, at least some of the time (since it is
from an actual RFC). The problem is that "Forwarded" does not
contain the ports, so Spring UriComponentsBuilder cannot use it
to rewrite links to a specific port. Since we do not support it
already, this change doesn't make things any worse, but the
corner case is there still.
2016-10-25 12:56:49 +01:00
Dave Syer 139ab95438 Make configuration imports deterministic 2016-10-25 12:20:31 +01:00
Dave Syer 71ac67f9f1 Suppress some warnings 2016-10-25 12:20:21 +01:00
Dave Syer 0e1b856fc5 Extract proxy header manipulation into method 2016-10-25 07:50:38 +01:00
Ryan Baxter 0235d77932 Zuul Route Hystrix Fallback
Hystrix fallback support for Zuul routes.

Fixes gh-250.
2016-10-24 15:24:31 -04:00
Ryan Baxter 6e1ca54edc increased max retried to help with failures 2016-10-24 13:42:21 -04:00
Ryan Baxter 274213bc83 Merge pull request #1412 from ryanjbaxter/creating-feign-clients-with-builder
Document Manual Feign Client Creation
2016-10-20 16:12:15 -04:00
Ryan Baxter 5a42cb1b2b Updates based on latest version from commons 2016-10-20 15:09:52 -04:00
Ryan Baxter ee99efba36 Merge remote-tracking branch 'Upstream/master' into simplify-retry-logic 2016-10-20 14:38:37 -04:00
Ryan Baxter b16a95d0f2 Fixed typo 2016-10-20 13:40:59 -04:00
Ryan Baxter 2c8bac5666 Use client interface instead of Eureka directly 2016-10-20 13:31:41 -04:00
Spencer Gibb 8e6b643829 Use new ServletRegistrationBean package.
Breaks Spring Boot 1.3 compatibility, enables 1.5
2016-10-20 11:19:54 -06:00
Ryan Baxter cc24d00fde Fixes #1211 2016-10-19 20:06:52 -04:00
Spencer Gibb ddc1069e86 Move properties to new namespace.
Moving eureka.server.{expectedNumberOfRenewsPerMin,defaultOpenForTrafficCount} to eureka.instance.registry so relaxed binding can be used. Default to old values for backwards compatibility.
2016-10-19 12:36:15 -06:00
Ryan Baxter c9704d3c97 Updating versions for next release 2016-10-18 10:16:01 -04:00
Ryan Baxter 34775eb8db Revert "Version changes for the release"
This reverts commit 90d6490fea.
2016-10-18 10:11:03 -04:00
Ryan Baxter 90d6490fea Version changes for the release 2016-10-18 09:44:57 -04:00
Gregor Zurowski acb9e5ebdf Fix formatting (#1397)
Signed-off-by: Gregor Zurowski <gregor@zurowski.org>
2016-10-13 16:08:28 -04:00
Spencer Gibb 12fff7c97f Merge pull request #1339 from alenavorozhbieva/master
* pull1339:
  Support DELETE method body for SimpleHostRoutingFilter
2016-10-13 09:34:22 -06:00
Alena acb12ea7d4 Support DELETE method body for SimpleHostRoutingFilter
fixes gh-1329
2016-10-13 09:34:08 -06:00
Dave Syer e94c35d331 Exclude aws jars from eureka client by default
Saves about 5MB in the final executable jar, and it should be
optional for Spring Cloud users.
2016-10-13 10:03:19 +01:00
Ryan Baxter a685a72660 Merge pull request #1384 from bslota/master
#1376 Register and cancel event sending fix
2016-10-11 19:34:25 -04:00
Bartłomiej Słota 4aaa7d0555 InstanceRegistry class refactor + renew method test #1376 2016-10-11 21:46:25 +02:00
Ryan Baxter 2f09aa291b Merge pull request #1390 from ryanjbaxter/upgrade-zuul-1.3.0
Upgrade zuul 1.3.0
2016-10-11 14:53:39 -04:00
Ryan Baxter bdf2f25259 Fixes #1306 2016-10-11 14:27:47 -04:00
Ryan Baxter 5a0af27115 Merge remote-tracking branch 'Upstream/master' 2016-10-11 14:20:12 -04:00
Ryan Baxter 18c4bc060b Upgrade hystrix 1.5.6 (#1388)
Fixes gh-1374
2016-10-11 13:41:31 -04:00
Spencer Gibb d23aa67f7b Merge pull request #1370 from tiny-dancer/master
* pull1370:
  Warning for GC Overhead Limit Reached with servo.
2016-10-11 10:29:19 -06:00
mg 5a127d0700 Warning for GC Overhead Limit Reached with servo.
Fixes gh-947
2016-10-11 10:29:04 -06:00
Spencer Gibb aa160940df import order 2016-10-11 10:25:02 -06:00
Max Ishchenko c8829f2aa4 Prevent double url encoding for secure ribbon urls (#1389)
Secure ribbon urls were forced to use https scheme via UriComponentsBuilder, that was created from original uri. This transformation url encoded previously encoded url parts that were used to create builder. This was introduced in c883495.

This change fixes double url encoding using RibbonUtils.updateToHttpsIfNeeded that fixes double escaping case and corner case with '+' in url as well.

Fixes gh-1382
2016-10-11 10:19:33 -04:00
Bartłomiej Słota 0985c8f092 Merge pull request #1 from spring-cloud/master
Remove @Autowired from FeignClientFactoryBean
2016-10-11 00:09:45 +02:00
Bartłomiej Słota 279edf0665 super class method wrappers removal and test update #1376 2016-10-10 22:54:39 +02:00
Ryan Baxter 50fac81a30 Revert "Fixes #1374"
This reverts commit 99b86e7a29.
2016-10-10 15:32:20 -04:00
Ryan Baxter 99b86e7a29 Fixes #1374 2016-10-10 15:31:42 -04:00
Bartłomiej Słota 151e021ef9 formatting fixed + tests, fixes #1376 2016-10-08 00:24:35 +02:00
Bartłomiej Słota dd97b6a4b7 #1376 Register and cancel event sending fix 2016-10-07 00:11:24 +02:00
Spencer Gibb f30e8b7b46 Remove @Autowired from FeignClientFactoryBean
@Autowired causes NullPointerExceptions because of some unknown lifecycle issues.

fixes gh-1366
2016-10-06 10:19:46 -06:00
Spencer Gibb ba3923d706 Fix zuul error when there are colons in request param name.
Previously, parameter names with colons (ie foo:bar), caused an IllegalArgumentException because 41c364002f introduced UriTemplate to properly encode.

fixes gh-1193
2016-10-05 12:51:28 -06:00
Spencer Gibb 622cc83204 polish 2016-10-04 18:48:28 -06:00
bpicode 8e18c3d3b6 Add support for fallback factories in feign client annotation. (#1373)
Adds `@FeignClient.fallbackFactory` to define a `feign.hystrix.FallbackFactory`.

fixes gh-1117
2016-10-04 20:46:33 -04:00
Spencer Gibb 0adbd5662f polish 2016-10-04 18:39:07 -06:00
Ryan Baxter f00d1159c8 Merge remote-tracking branch 'Upstream/master' into simplify-retry-logic 2016-10-04 10:49:02 -04:00
Ryan Baxter 4c90ce437e Implementation of factory pattern for creating retry policies 2016-10-04 10:48:40 -04:00
Mathias Düsterhöft e109093b83 add config option to not ignore security headers (#1354)
* add config option to not ignore security headers
* fix field documentation of ignoreSecurityHeaders
* add documenation for  zuul.ignoreSecurityHeaders

fixes gh-1096
2016-10-03 23:30:17 -04:00
Ryan Baxter 4ba3411292 Clarified zuul.stripPrefix usage
Helps with the confusion seen in #1365
2016-10-03 13:44:02 -07:00
Jacques-Etienne Beaudet 8e1be54759 Support '+' in encoded query string when rebuilding the URI to https
RibbonUtils now replace the encoded space character '+' in the query string in favor of the equivalent '%20' when rewriting the URI in https. This is due to UriComponentsBuilder verifying the allowed characters in the encoded URI when building to the URI java.net class. The '+' is considered illegal but is widely used in the field. (#1367)
2016-10-03 14:35:30 -04:00
Spencer Gibb be6f2634b5 Allow OkHttpClient to be customized.
Moved common functionality to AbstractLoadBalancingClient
2016-09-23 14:09:41 -06:00
Ryan Baxter 7191e820a2 Implementing retry policy 2016-09-23 15:01:09 -04:00
Spencer Gibb 9eed249028 Allow customization of HttpClient.
Uses ribbon settings to set MaxConnTotal and MaxConnPerRoute. Also allows user to create a custom HttpClient as a constructor argument.

fixes gh-1149
2016-09-22 19:42:20 -06:00
Spencer Gibb bbff2b24d0 Put Apache Http Client and OkHttpClient in ribbon context.
This eliminates them being created for every zuul request.

Also makes properties consistent accross modules: ribbon.httpclient.*, ribbon.restclient.* and ribbon.okhttp.*

fixes gh-1150
2016-09-22 15:46:53 -06:00
Ryan Baxter b91fa734d2 Bumping versions for next release 2016-09-22 14:55:08 -04:00
Ryan Baxter 302eae6aeb Revert "version changes for Camden release"
This reverts commit 088afa6d71.
2016-09-22 14:21:39 -04:00
Ryan Baxter 088afa6d71 version changes for Camden release 2016-09-22 13:15:22 -04:00
Dave Syer 5f96c415e3 Upgrade xstream to 1.4.9
Fixes XXE vulnerability in Eureka Server (external entity processing
on by default in older versions of the library).
2016-09-22 16:23:27 +01:00
Ryan Baxter 6c9fa68d5a Translate ribbon.ReadTimeout to apache http client socket timeout. Fixes #1357. (#1358) 2016-09-21 14:03:14 -04:00
Dave Syer bc4f5a3788 Ensure version is scraped from parent pom 2016-09-20 13:34:30 +01:00
Dave Syer f094ecfd88 Allow user to set system properties to control http client in zuul
The SimpleHostRoutingFilter now accepts normal -Dhttps.proxy= and
-Dhttps.port= settings (and other things that generally work with
java.net).

Fixes gh-510
2016-09-20 12:30:49 +01:00
Marcin Grzejszczak 13268f7c63 Updating mvnw for all projects 2016-09-19 19:31:33 +02:00
Marcin Grzejszczak aa820ce347 Updating mvnw for all projects 2016-09-19 14:18:37 +02:00
Dave Syer 6310059531 Move unnecessary dependencies up a level 2016-09-19 12:02:34 +01:00
Marcin Grzejszczak 6f92859608 Updating mvnw for all projects 2016-09-19 12:46:58 +02:00
Spencer Gibb 758ff920fc Merge pull request #1351 from VanRoy/improve-formbodywrapperfilter-test
* improve-formbodywrapperfilter-test:
  Add test on FormBodyWrapperFilter to avoid regressions (#1171)
2016-09-16 14:42:48 -06:00
Julien Roy 7ba8063940 Add test on FormBodyWrapperFilter to avoid regressions (#1171) 2016-09-16 14:42:31 -06:00
Niklas Herder 61de118130 Use management.port for locating hystrix.stream (#1317)
Allow override of /hystrix.stream location via management.port metadata.
2016-09-16 15:15:46 -04:00
Matthew Jenkins 4bf64f7005 Use statusPage/healthCheckUrlPath w/ custom management.port (#1349)
Use statusPage/healthCheckUrlPath w/ custom management.port

Added RelaxedPropertyResolver to handle multiple valid formats for
eureka properties.  Added tests.

Fixes gh-1348
2016-09-15 21:20:35 -04:00
Spencer Gibb 85eab87dce formatting 2016-09-15 08:34:59 -06:00
rockinrimmer 5ba0cc5860 Check if object is already a ResponseEntity, if so return instead of … (#1343)
* Check if object is already a ResponseEntity, if so return instead of wrapping in another ResponseEnitiy. Which caused headers and status code from original ResponseEnitiy to be lost and for body to be output with whole ResponseEntity instead of just the body

* added test
2016-09-15 10:15:42 -04:00
Marcin Grzejszczak 08aae5be3b Updating mvnw for all projects 2016-09-15 16:13:07 +02:00
Ryan Baxter 071bad218a Document Eureka client zone config. Fixes #31327 2016-09-14 10:41:38 -04:00
Ryan Baxter 027e7fc5c6 Merging changes from #1338 2016-09-13 08:57:01 -04:00
Spencer Gibb 498e8a1486 Use default maxSemaphore property.
Rather than hard code the default maxSemaphores for zuul use the already defined `zuul.semaphore.maxSemaphores` property.

fixes gh-1332
2016-09-12 09:36:22 -06:00
Ryan Baxter 09c6bc1d12 Merge pull request #1325 from herder/fix_registry_failures_report_time_mismatch
Fix lastFetch status calculation.
2016-09-08 09:38:09 -04:00
Niklas Herder 62521f38e8 Fix lastFetch status calculation.
Was previously milliseconds/seconds when calculating whether to display the message about reporting failures.
2016-09-08 11:24:11 +02:00
Spencer Gibb a6785afa5a Exclude commons-logging from archaius starter
fixes gh-126
2016-09-07 11:16:51 -06:00
Marcin Grzejszczak 7ebb46a092 Removed adoc footer 2016-09-07 18:02:13 +02:00
Marcin Grzejszczak a9fcc0a002 Updating mvnw for all projects 2016-09-07 17:29:18 +02:00
Ryan Baxter 08ed3c7fc4 Revert "Updated versions for Camden.RC1 release"
This reverts commit 3c1a23e7b1.
2016-09-06 14:25:21 -04:00
Ryan Baxter 3c1a23e7b1 Updated versions for Camden.RC1 release 2016-09-06 14:16:23 -04:00
Spencer Gibb c7403361fd polish 2016-09-06 08:40:49 -06:00
Sébastien Nussbaumer d9efb0a84d Allow Content-Length header with values greater than 2 GB (#1320)
fixes gh-1319
2016-09-06 10:38:16 -04:00
Ryan Baxter 4f81255970 Merge pull request #1318 from jkschneider/no-commons-lang
Remove dep on commons-lang in DimensionalServoMetricNaming (#1268)
2016-09-06 07:45:24 -04:00
Jon Schneider e556ef84a4 Eliminate dependency on commons-lang in DimensionalServoMetricNaming (#1268) 2016-09-02 22:06:18 -07:00
Jon Schneider 9587003d44 Sanitize Servo metric tag key/value pairs before publishing to Atlas (#1315) 2016-09-01 17:32:30 -04:00
Jon Schneider 8f7ea41fe8 Log partial failure reasons for metrics batches published to Atlas (#1314) 2016-09-01 14:57:52 -04:00
Jon Schneider b4284d18d5 Escape regex path variables in the uri tag for Spectator (#1311) 2016-09-01 11:27:30 -04:00
Spencer Gibb 048d401309 Merge pull request #1310 from garciafl/master
* garciafl-master:
  Removes RibbonCommand suffix.
2016-09-01 09:24:39 -06:00
Garcia Florian 85a1f3ec20 Removes RibbonCommand suffix.
This is a regression that was originally fixed in 1.1.x

Fixes gh-1308
2016-09-01 09:23:24 -06:00
Spencer Gibb 959b007269 removed duplicate feign ApacheHttpClient configuration 2016-08-31 12:02:25 -06:00
Spencer Gibb 9b550f7293 Support delete with body in zuul where possible.
The apache http client and ok http client support delete with body, ribbon rest client does not.

fixes gh-949
2016-08-31 11:43:05 -06:00
Spencer Gibb dc26b1efa8 Merge pull request #1102 from lowzj/request-param-processor
* lowzj-request-param-processor:
  update RequestParamParameterProcessor to support map param
2016-08-31 11:05:05 -06:00
lowzj d356e57134 update RequestParamParameterProcessor to support map param
fixes gh-1097
2016-08-31 11:04:20 -06:00
Spencer Gibb c5b0ffe310 Document customizing the Ribbon Client using properties
fixes gh-1188
2016-08-30 10:17:04 -06:00
Spencer Gibb 1ffa7825ed Add {spring-cloud-version} 2016-08-30 09:58:21 -06:00
Spencer Gibb d95f3cd1c5 Mention starters to include for features.
fixes gh-1134
2016-08-30 09:44:18 -06:00
Spencer Gibb 6ba64d97c8 Upgrade feign to 9.3.1
fixes gh-1303
2016-08-30 09:22:40 -06:00
Spencer Gibb fa508a2c7e Add warning for eureka healthcheck.
fixes gh-1276
2016-08-30 09:14:32 -06:00
Spencer Gibb d04df564f0 Try and fix old static wonkiness in test. 2016-08-29 12:47:35 -06:00
Spencer Gibb 5f192dd6ce Fix NPE when instance has no status page url.
fixes gh-1285
2016-08-29 12:29:57 -06:00
Spencer Gibb 6819922d26 Fix MetricsTagProvider for non web apps.
Guard creating and creation of classes that use it with @ConditionalOnClass(name = "javax.servlet.http.HttpServletRequest")

fixes gh-1302
2016-08-29 10:43:17 -06:00
Ryan Baxter ec726e863c Merge pull request #1296 from ryanjbaxter/upgrade-eureka-1.4.11-1288
Upgrade Eureka to 1.4.11
2016-08-25 14:15:11 -04:00
Ryan Baxter 610754981b Upgrade Eureka to 1.4.11. Fixes #1288 2016-08-25 13:53:24 -04:00
Ryan Baxter 485034dec0 Merge pull request #1294 from ryanjbaxter/upgrade-hystrix-1.5.5-1289
Upgrade Hystrix to 1.5.5
2016-08-24 19:29:38 -04:00
Ryan Baxter 9316124733 Upgrade Hystrix to 1.5.5. Fixes #1289 2016-08-24 16:10:50 -04:00
Ryan Baxter 1b9d91dc1e Merge pull request #1293 from ryanjbaxter/upgrade-stream
Updated SC Stream to Brooklyn SNAPSHOT
2016-08-24 09:55:07 -04:00
Ryan Baxter 15550e1855 Updated SC Stream to Brooklyn SNAPSHOT. Fixes #1292. 2016-08-24 09:32:30 -04:00
Spencer Gibb 43adc84dfd Make moving to https urls consistent.
This fixes a case where the ribbon property is set `ribbon.IsSecure=false`, but because the eureka secure port was enabled, the uri created by ribbon was prefixed with https when it shouldn't have.

All places where isSecure is need have been consolidated into RibbonUtils.

fixes gh-1270
2016-08-22 17:16:13 -06:00
Spencer Gibb 8d6aeebb61 Feign URI tests updated to be more inclusive.
Previously with a `@FeignClient(name="http://bad_hostname")` would pass the start time test and fail later in runtime. The test now fails fast.

fixes gh-1257
2016-08-22 15:05:59 -06:00
Ryan Baxter 1c8c0cfbf0 Moved parent element in pom so milestone profile activation occurs correctly 2016-08-22 15:32:31 -04:00
Ryan Baxter 047e25f7f7 Revert "Camden.M1 release"
This reverts commit 258e53a402.
2016-08-22 15:31:32 -04:00
Ryan Baxter 258e53a402 Camden.M1 release 2016-08-22 15:01:16 -04:00
Marcin Grzejszczak c8c4dfba6e Updating ghpages for all projects 2016-08-22 13:32:23 +02:00
Ryan Baxter 0bed544188 Merge pull request #1221 from stephlag/zuul_hystrix_threadpool
Make Hystrix Thread Pool available while using Zuul
2016-08-19 12:31:03 -04:00
Ryan Baxter 3cc07d36a2 Merge pull request #1282 from ryanjbaxter/upgrade-feign-to-9.3.0
Upgrade Feign to 9.3.0
2016-08-19 12:07:28 -04:00
Ryan Baxter 78b53a5215 Upgrade Feign to 9.3.0. Fixes #1281. 2016-08-19 11:14:11 -04:00
Marcin Grzejszczak 886382f568 Updating ghpages for all projects 2016-08-19 11:46:36 +02:00
Ryan Baxter a9dd1b4568 Merge pull request #1278 from ryanjbaxter/upgrade-feign-to-9.2.0
Upgrade Feign to 9.2.0
2016-08-18 14:43:29 -04:00
Ryan Baxter 323243f1ec Upgrade Feign to 9.2.0. Fixes #1273. 2016-08-18 14:24:53 -04:00
Spencer Gibb 25366c2a37 Add not about zuul route ordering.
fixes gh-1266
2016-08-18 11:33:29 -06:00
Stéphane Lagraulet b98c9ebc1d Add tests to verify old constructors 2016-08-18 14:27:11 +02:00
Dave Syer cb44cd2e33 Add additional test to look for null hosts in Zuul
Conflicts:
	spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/ribbon/RibbonClientConfigurationTests.java
2016-08-18 12:59:05 +01:00
Marcin Grzejszczak 1fefd410be Updating ghpages for all projects 2016-08-18 13:15:30 +02:00
Stéphane Lagraulet f5bb5ff9c1 Keep old constructors to maintain backwards compatibility with spring cloud sleuth 2016-08-18 11:24:15 +02:00
Ryan Baxter e2e7c490db Merge pull request #1247 from Coramo/master
fix 'RibbonRequest' cannot to encode issues
2016-08-17 13:48:36 -04:00
Dave Syer 68cf346025 Change repo URLs to https 2016-08-17 17:33:02 +01:00
Dave Syer 7927372b75 Polish 2016-08-17 17:33:02 +01:00
Stéphane Lagraulet ca2c9018c6 Merge branch 'master' of https://github.com/spring-cloud/spring-cloud-netflix into zuul_hystrix_threadpool 2016-08-17 18:11:52 +02:00
Spencer Gibb 9ed5621a78 Revert "Adds zuul property to customize Hystrix ExecutionIsolationStrategy"
This reverts commit 21df6e43a3.
2016-08-17 09:57:35 -06:00
Dave Syer 58cf528463 Remove extra (redundant) condition
A problem in Spring Boot means that the extra conditions are combined
with OR not AND, so it's a bug to have more than one until that
gets fixed (in an AnyNestedCondition).

See https://github.com/spring-projects/spring-boot/pull/6672
2016-08-17 14:04:45 +01:00
Marcin Grzejszczak 4602fc1105 Updating ghpages for all projects 2016-08-17 12:45:28 +02:00
Dave Syer b9e2a1b21e Fix test so it actually works if there is a server on localhost:80 2016-08-17 09:19:33 +01:00
Dave Syer f76f294f7f Rename test to conform to usual pattern 2016-08-17 09:04:37 +01:00
Spencer Gibb 64fff7edd2 Merge branch 'context-path-prefix-support' of https://github.com/kakawait/spring-cloud-netflix into kakawait-context-path-prefix-support 2016-08-16 12:59:10 -06:00
Spencer Gibb beb84dbe07 Merge branch 'molindo-1108-proxy-headers' 2016-08-16 12:57:10 -06:00
Stefan Fussenegger d9768b5378 Improved zuul proxy header support.
- add zuul.add-host-header property to add Host header
- add port to X-Forwarded-Host as defined in RFC 7239
- extract PreDecorationFilter.filterOrder() into a public constant

fixes gh-1108
2016-08-16 12:56:54 -06:00
Spencer Gibb 34befdf1d2 Merge branch 'stephlag-zuul_hystrix_threadpool' 2016-08-16 10:44:32 -06:00
Stéphane Lagraulet 21df6e43a3 Adds zuul property to customize Hystrix ExecutionIsolationStrategy
Add a check to current context as contentLength is already in the context
Get content length from Headers when RibbonCommandContext is built + add tests
Use request content length RibbonRoutingFilter
Add documentation for new zuul.ribbonIsolationStrategy property

fixes gh-339
2016-08-16 10:43:24 -06:00
Jin Zhang bc7b8367a9 add *.swp *.swo to .gitignore (#1181) 2016-08-16 12:01:04 -04:00
Marcin Grzejszczak c7a6720593 Updated e2e tests with new brewery parameters 2016-08-16 15:27:29 +02:00
Marcin Grzejszczak cf0c3bda92 Deploying documentation to proper folder
What we're missing ATM is different documentation versions for different application versions. What this change does is that it's:

- finding out what is the current branch (e.g. 1.0.x)
- finding out out what is the name of the main adoc file (e.g. spring-cloud-sleuth)
- pulling the changes from gh-pages after checkout
- finding out what is the list of comma separated whitelisted branches (via the `docs.whitelisted.branches` prop)
- in gh-pages creating a folder with name of the branch  (e.g. /1.0.x)
copying all the docs/target/generated-docs/ to that folder
- if the branch from which we're calling the script is NOT master then we're changing the ${main.adoc}.html to index.html so that it's easier to access the docs (e.g. http://cloud.spring.io/spring-cloud-sleuth/1.0.x/)
2016-08-16 14:57:22 +02:00
Coramo 2db2a033ab add 'RibbonRequest' test 2016-08-12 12:02:58 +08:00
Coramo cf72184883 Merge branch 'master' of https://github.com/spring-cloud/spring-cloud-netflix 2016-08-12 11:00:43 +08:00
Stéphane Lagraulet 62344dccda Merge branch 'master' into zuul_hystrix_threadpool 2016-08-11 09:42:03 +02:00
Stéphane Lagraulet 03caa1b8ce Remove deprecated and unused constructors for RibbonCommandContext and RestClientRibbonCommand 2016-08-11 09:41:15 +02:00
Coramo 97c8f4c026 fix 'RibbonRequest' cannot to encode issues 2016-08-11 11:05:14 +08:00
Spencer Gibb 674e45f473 Add Client to list of feign objects that can be customized. 2016-08-10 14:13:28 -06:00
Ryan Baxter 36fec07a17 Merge pull request #1093 from daniellavoie/hystrix-security
Expose security context to any Hystrix command.
2016-08-10 15:20:19 -04:00
Spencer Gibb 0c694a018c Merge pull request #1242 from mikexliu/master
* pull1242:
  Add @Qualifier customization for @FeignClient
2016-08-10 12:22:45 -06:00
Mike Liu f37b513f21 Add @Qualifier customization for @FeignClient
Changed test to use @Qualifier.
Add documentation to reference the new attribute.
2016-08-10 12:22:33 -06:00
Spencer Gibb 56c7466e64 Merge branch 'Egencia-master' 2016-08-10 12:01:27 -06:00
libetl 519be4db06 MetricsInterceptorConfiguration modifies potenially unmodifiable list.
fixes gh-1240
2016-08-10 12:00:49 -06:00
Spencer Gibb 4255c5578b Merge pull request #1244 from cah-oster/master
* pull1244:
  Fixed double-encoding issue in RibbonClientConfiguration
2016-08-10 11:25:10 -06:00
Scott Oster 5e698278a8 Fixed double-encoding issue in RibbonClientConfiguration
fixes gh-1241
2016-08-10 11:24:59 -06:00
Ryan Baxter b09b0bcdbd Added Codacy badge to README 2016-08-10 10:36:34 -04:00
Spencer Gibb 909a51000f Remove @Ignore
fixes gh-1157
2016-08-09 16:50:57 -06:00
Spencer Gibb 306b43624b update readme 2016-08-09 14:51:19 -06:00
Ryan Baxter ec22c23bc5 Added CircleCI and Codecov badges 2016-08-09 16:45:26 -04:00
Ryan Baxter a4ba11eabb Updated sonar profile configuration 2016-08-09 14:31:13 -04:00
Stéphane Lagraulet 58559aff16 Add documentation for new zuul.ribbonIsolationStrategy property 2016-08-09 18:32:36 +02:00
Ryan Baxter 3e3511ac44 merge 2016-08-09 11:46:03 -04:00
Ryan Baxter 36ae029c18 circleci updates 2016-08-09 11:44:01 -04:00
Stéphane Lagraulet 4dc016f3e5 Merge branch 'master' into zuul_hystrix_threadpool
Conflicts:
	spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/route/support/AbstractRibbonCommand.java
2016-08-09 17:40:30 +02:00
Ryan Baxter d90e99216b Merge pull request #1225 from coveord/fix-content-length
Content-length not properly set when using the FormBodyWrapperFilter
2016-08-09 10:30:20 -04:00
Stéphane Lagraulet 67838807e8 Add zuulProperties as a method parameter 2016-08-09 09:36:30 +02:00
Jacques-Etienne Beaudet dc2cdd55c0 Merge branch 'master' into fix-content-length 2016-08-08 22:45:20 -04:00
Daniel Lavoie 5b0f6013e8 Expose security context to any Hystrix command.
Fix issue gh-1054
2016-08-08 23:05:10 +02:00
Ryan Baxter 52c956831e circleci updates 2016-08-08 15:03:00 -04:00
Ryan Baxter 4f93897b71 more circle ci configuration 2016-08-08 13:57:23 -04:00
Ryan Baxter 5676c8f753 added artifacts directory to circle config 2016-08-08 13:20:12 -04:00
Ryan Baxter eed72600c5 initial commit for circleci build 2016-08-08 11:47:29 -04:00
Stéphane Lagraulet 35ca9691d2 Merge branch 'master' into zuul_hystrix_threadpool
Conflicts:
	spring-cloud-netflix-core/src/test/java/org/springframework/cloud/netflix/zuul/filters/route/okhttp/OkHttpRibbonCommandIntegrationTests.java
2016-08-08 17:29:10 +02:00
Stéphane Lagraulet 072f7760a4 Use request content length RibbonRoutingFilter 2016-08-08 17:07:35 +02:00
Ryan Baxter 3c1599a1f4 Merge pull request #1213 from mhartle/master
FormBodyWrapperFilter may add multiples of every multipart part to a request
2016-08-08 10:58:59 -04:00
Ryan Baxter 90808124f5 Merge pull request #1206 from daniellavoie/spring-boot-test-1.4
Migrate tests to Spring Boot Test 1.4
2016-08-08 10:53:17 -04:00
Stéphane Lagraulet 3c96fcc888 Get content length from Headers when RibbonCommandContext is built + add tests 2016-08-05 18:57:20 +02:00
Jacques-Etienne Beaudet d21a7ef8e2 Fix an issue where the FormBodyWrapperFilter would encode the form parameters differently than on the original request.
The FormBodyWrapperFilter handles the application/x-www-form-urlencoded. In the case of requests received by curl or javascript, the FormHttpMessageConverter will reencode the parameters differently (for example, '(' will be encoded while it's not with the javascript encodeURIComponent method).

While this doesn't create any problem, the content length was not properly set in AbstractRibbonCommand. This causes the form params being stripped or the backend server would wait a long time for additional bytes depending on if the content length header was bigger/smaller than the actual data.
2016-08-03 14:27:46 -04:00
Stéphane Lagraulet b1ec12af43 Add a check to current context as contentLength is already in the context 2016-08-03 15:32:08 +02:00
Stéphane Lagraulet 7929dfec0f Add a zuul property to customize Hystrix ExecutionIsolationStrategy 2016-08-02 13:39:04 +02:00
Michael Hartle 8bb223f6e3 Added a minimal test for FormBodyWrapperFilter handling multiple part names with multiple parts 2016-08-02 12:15:15 +02:00
Ryan Baxter 8b911e6074 Merge pull request #1217 from ryanjbaxter/move-to-open-feign
Changed version and group id to use latest OpenFeign release
2016-07-29 17:07:18 -04:00
Ryan Baxter 10a3d1df69 Changed version and group id to use latest OpenFeign release. Fixes #1189. 2016-07-29 14:21:21 -04:00
Dave Syer 8cf581d496 Correct description of cloud foundry instance id
Fixes gh-1214
2016-07-27 11:37:47 +01:00
Michael Hartle 0095ba8984 Fixed an issue where the pre FormBodyWrapperFilter adds multiples of every multipart part to a request 2016-07-26 13:37:46 +02:00
Daniel Lavoie 6f32aa95a7 Migrate tests to Spring Boot Test 1.4
Fixes gh-1205
2016-07-22 00:54:48 +02:00
Dave Syer afb43c5883 Actually fix the feign client validation issue
We need to still assert that the FeignClient is valid (no name and
value specified together for instance). Added missing tests.
2016-07-21 10:36:18 +01:00
Dave Syer 85ef54a9a1 Fix Feign validation for Spring 4.2 and 4.3
There is a utility method in Spring that we can use to merge all
the aliases. That way 4.2 and 4.3 behave the same way.

Fixes gh-1192
2016-07-21 08:28:33 +01:00
Dave Syer 2f581a1181 Use JUnit assertions 2016-07-21 08:28:31 +01:00
Dave Syer 110f872779 Fix generic type signature (otherwise breaks with Spring 4.3) 2016-07-21 08:28:27 +01:00
Spencer Gibb 54931afa8b Remove assertion that fails in spring 4.3.x
Need to make this class 4.2.x compatible.

see gh-1192
2016-07-16 10:36:27 -06:00
Ryan Baxter 2bdd2dab78 Merge pull request #1173 from denyska/master
Disable cookie management for RibbonLoadBalancingHttpClient Fixes gh-301
2016-07-14 12:55:32 -04:00
Spencer Gibb 2908323702 Add debug logging that code is setting spring.aop.proxyTargetClass=true
See gh-1105
2016-07-13 18:08:12 -06:00
Ryan Baxter 5d37bfe2fa Merge pull request #1183 from ryanjbaxter/master
Upgrade Eureka to 1.4.10.  Fixes #1180.
2016-07-13 10:26:41 -04:00
Ryan Baxter 0b0bdb17aa Upgrade Eureka to 1.4.10. Fixes #1180. 2016-07-13 09:19:38 -04:00
Spencer Gibb e5b2ae967b Remove phantom spring-cloud-netflix-zuul-server from dependencies pom
fixes gh-1175
2016-07-11 21:49:43 -06:00
Dave Syer c03ae0ab47 Update README with new CLA link 2016-07-11 14:35:10 +01:00
Denys Kurylenko 5d664cd00d Disable cookie management for RibbonLoadBalancingHttpClient Fixes gh-301 2016-07-08 18:48:47 -07:00
Ryan Baxter 00ed67f1b7 Upgrade Eureka to 1.4.9. Fixes #1167. 2016-07-08 10:31:34 -04:00
Spencer Gibb 277ded519d Merge pull request #1156 from brenuart/gh1155
remove Guava ImmutableMap in favour of Collections.unmodifiab…

fixes gh-1155
2016-07-01 16:41:37 -06:00
Spencer Gibb 7835c4047b temporarily comment out FormZuulProxyApplicationTests.postWithMultipartForm 2016-07-01 15:34:46 -06:00
Spencer Gibb ab0af4554c Update to s-c-build 1.2.0 2016-07-01 15:14:19 -06:00
Bertrand Renuart 926414a014 GH1155: remove Guava ImmutableMap in favour of Collections.unmodifiableMap()
Make sanitizeUrlTemplate() protected for easy sub-classing
2016-07-01 14:14:58 +02:00
Spencer Gibb 3991c8c5f7 Allow custom feign clients when not using ribbon.
fixes gh-1143
2016-06-29 12:39:58 -06:00
Spencer Gibb cb4d60ca8d fix typo 2016-06-29 11:39:04 -06:00
Thibaud Leprêtre 7ebe1977d8 Handle context-path on X-Forwarded-Prefix support
Since revision 7b270c4b46, Zuul add support of `X-Forwarded-Prefix` for route with `stripPrefix=true`.
However it supposes that Zuul context-path is equals to `/`. By using a custom context-path on Zuul we can expect that `zuul.add-proxy-headers=true` will compute a prefix regarding that context-path.

Indeed with following architecture:

- Zuul with context-path equals to `/foo`
- A random service (*bar-service*) without context-path

Zuul configurations:

```
zuul:
  add-proxy-headers: true
  routes:
    bar-service: /bar/**
```

We expect that *bar-service* when targeting `http://blabla.com/foo/bar/1`  will produce endpoint url equals to `http://blabla.com/foo/bar` and not only `http://blabla.com/bar` (that will not be resolvable).

Furthermore context-path influence not only `stripPrefix=true` routes because with following configuration

```
zuul:
  add-proxy-headers: true
  routes:
    bar-service:
      path: /bar/**
      strip-prefix: false
```

We expect that *bar-service* when targeting `http://blabla.com/foo/bar/1` will also prodcues endpoint url equals to `http://blabla.com/foo/bar`...

---

Moreover since *Spring 4.3* and new [`ForwardedHeaderFilter`](http://docs.spring.io/spring-framework/docs/4.3.0.BUILD-SNAPSHOT/javadoc-api/org/springframework/web/filter/ForwardedHeaderFilter.html) to handle `X-Forwarded-*` headers, when filter catches `X-Forwarded-Prefix` header it will override request context-path by `X-Forwarded-Prefix` header value and then **removes headers from request**. Thus the fact to support context-path will allow to use that filter with Zuul!

---

Attention there is only one edge case, when `X-Forwarded-Prefix` header is present as same as custom `context-path`! In that case context-path will be ignored in favor to `X-Forwarded-Prefix` as same does `ForwardedHeaderFilter`
2016-06-29 10:37:52 +02:00
Spencer Gibb 5e9c71e0e3 Merge pull request #1138 from orchit/master
* orchit-master:
  Adds ability to disable hostname validation.
2016-06-28 10:33:50 -06:00
Patrick Cornelißen 723287b305 Adds ability to disable hostname validation.
Adds property zuul.sslHostnameValidationEnabled to be able to disable the hostname validation in the simpleHostRoutingFilter

fixes gh-1057
2016-06-28 10:32:49 -06:00
Spencer Gibb 46b2e45fd5 Adds a RibbonRequestCustomizer.
This allows developers to customize the request builders for zuul requests to inject headers or modify the request in general.  Each zuul request type (RestClient, Apache HttpClient and OkHttp) is supported.

fixes gh-1141
2016-06-27 13:15:54 -06:00
Spencer Gibb 390999e042 Add default zuul.ribbon.httpclient.enabled=true 2016-06-24 16:17:33 -06:00
Spencer Gibb 8a7e165214 Split ProxyRequestHelper to function without Actuator.
Previously ProxyRequestHelper contained a TraceRepository field. This caused zuul apps to fail with a class not found exception if they excluded actuator. This splits TraceRepository functionality into a new TraceProxyRequestHelper that extends ProxyRequestHelper. Auto configuration creates the appropriate ProxyRequestHelper based on the existence or not of actuator classes.

fixes gh-1135
2016-06-24 16:08:23 -06:00
Spencer Gibb 5742f5e811 add .shelf to .gitignore 2016-06-24 09:58:30 -06:00
Spencer Gibb 52b6578fcf polish 2016-06-24 09:32:18 -06:00
Spencer Gibb 2f205f20c5 Skip tests that only fail in travis for now. 2016-06-24 09:20:19 -06:00
Spencer Gibb e1df7c3b4d Add back RestClientRibbonCommand api's. 2016-06-24 09:13:18 -06:00
Spencer Gibb 7c2f806745 Add hystrix.stream.queue.size to customize queue size.
Also added descriptions to properties.

fixes gh-1131
2016-06-24 08:41:45 -06:00
Spencer Gibb 6877f0898f Move RestClientRibbonCommand back to original place.
Made it public and undid other refactorings.
2016-06-24 08:15:12 -06:00
Marcin Grzejszczak 74ac6eae8f Made RestClientRibbonCommand public 2016-06-24 09:10:54 +02:00
Spencer Gibb 75610e92a7 added todo 2016-06-23 22:34:34 -06:00
Spencer Gibb 7dc8b86001 Load ribbon classes if defined via properties.
Allows ribbon class name properties to be used to define beans.

This seems like boilerplate, but works, though not easily extensible.

fixes gh-927
2016-06-23 20:20:34 -06:00
Will Tran dfbfcfecc7 Without explicit client config of IsSecure, lookup from registration
instead of defaulting to false.

Fixes gh-1126
2016-06-23 15:12:35 -06:00
Spencer Gibb 7ac81f8fd5 Adds zuul okhttp support & zuul refactor.
Adds a OkHttpRibbonCommand and accomanying classes. They should be
considered beta.

Refactors zuul ribbon command classes and tests.

fixes gh-1125
2016-06-23 12:10:59 -06:00
Spencer Gibb fd36a0cc72 Default to HttpClientRibbonCommandFactory 2016-06-22 21:08:34 -06:00
Spencer Gibb 398c5aa009 upgrade feign to v8.17.0
fixes gh-1081
2016-06-22 15:53:18 -06:00
Spencer Gibb 7a90c0cd88 Set entity contentLength to 0 for GET requests.
Zuul sets an empty entity for GET requests. The apache http client either sets transfer encoding to chunked or a content length header. This change sets the apache entity contentLength to 0 (not the header), to that in RequestContent the "content-length" header is set to 0 rathern than transfer encoding.

See gh-1042
2016-06-22 13:01:51 -06:00
Spencer Gibb cfcca5f881 Set entity contentLength for HttpClientRibbonCommand.
If the content length isn't set on the entity, when http client determines which header to set, it sets transfer-encoding to chunked rather than content-length.

This fixes a missing content-length issue when using `HttpClientRibbonCommandFactory`.

See gh-1042
2016-06-22 13:01:34 -06:00
Spencer Gibb ca67265c79 Merge pull request #1120 from jmirc/master
* pull1120:
  Fix hystrix dashboard TPS.
2016-06-21 15:23:05 -06:00
Jérôme Mirc b422fe297c Fix hystrix dashboard TPS.
fixes gh-1113

See https://github.com/Netflix/Hystrix/issues/1251
2016-06-21 15:21:10 -06:00
Spencer Gibb 856c47138a Don't use deprecated constructor.
Eliminates a legacy use of a static singleton. This will help allow multiple registrations.
2016-06-20 18:27:12 -06:00
Spencer Gibb 83cdf647c9 Angel eureka clients can use brixton eureka servers.
Updates so CloudJacksonJson extension is properly recognized by Eureka
Server as LegacyJacksonJson.

see gh-978
fixes gh-1111
2016-06-17 16:53:44 -06:00
Dave Syer ff46a7dc50 Merge branch '1.1.x'
Conflicts:
	spring-cloud-netflix-dependencies/pom.xml
2016-06-17 15:10:51 +01:00
Dave Syer 9e479481cc Exempt @RequestParams of type Collection from feign expander
It isn't very helpful to have a Collection converted to a String
anyway. We need to implement something new in Feign to apply
the converter (expander) to individual elements in the collection
but this change should get back to the old behaviour with
List<String> at least.

Fixes gh-1115
2016-06-17 14:55:35 +01:00
Spencer Gibb 532627fad2 Merge pull request #1106 from spring-cloud/zuul-122
Upgrade to zuul 1.2.2
2016-06-16 13:58:10 -06:00
Spencer Gibb aa23660d0c Upgrade to zuul 1.2.2
fixes gh-1091
closes gh-958
2016-06-16 13:50:33 -06:00
Spencer Gibb 20db868592 Don't send 4xx errors to /error
fixes gh-1110
2016-06-16 11:47:31 -06:00
Spencer Gibb 02948657a4 Don't send 4xx errors to /error
fixes gh-1110
2016-06-16 11:45:52 -06:00
Spencer Gibb 050c66250c quote var 2016-06-15 17:34:00 -06:00
Spencer Gibb 88ce4fe81b skip source generation 2016-06-15 17:33:50 -06:00
Spencer Gibb e819dd39ca Only install and skip javadoc generation 2016-06-15 17:33:38 -06:00
Spencer Gibb cfb13ac59f quote var 2016-06-15 17:17:52 -06:00
Spencer Gibb 00aee4be00 skip source generation 2016-06-15 17:16:12 -06:00
Spencer Gibb a669975fb0 Only install and skip javadoc generation 2016-06-15 17:09:14 -06:00
Spencer Gibb 161d719dba add *.log to .gitignore 2016-06-15 15:38:13 -06:00
Marcin Grzejszczak ccc75f2978 Bumped up version of cloud-stream to snapshot 2016-06-14 11:24:48 +02:00
Marcin Grzejszczak 8b0598abee Bumped up version of cloud-config to snapshot 2016-06-14 10:50:21 +02:00
Marcin Grzejszczak 31598b4329 Bumped up version of commons to snapshot 2016-06-14 10:37:04 +02:00
Spencer Gibb dd220458f8 polish 2016-06-13 09:46:32 -06:00
Spencer Gibb d4163dde8e Polish 2016-06-13 09:46:32 -06:00
Spencer Gibb 3bd563e495 remove h2 test dep 2016-06-13 09:46:32 -06:00
Dave Syer 525c5852fb Add JAVA_OPTS to travis 2016-06-13 08:40:36 +01:00
Dave Syer 69501bd110 Merge 1.1.x 2016-06-13 08:05:07 +01:00
Dave Syer 95e086a543 Revert change to sources plugin 2016-06-13 07:58:13 +01:00
Dave Syer f6cd2d279d Update README 2016-06-11 10:50:32 +01:00
Dave Syer 9cab69a968 Update readme script to handle local includes 2016-06-11 09:54:41 +01:00
Dave Syer 6906c7ba55 Update to 1.1.3 snapshots 2016-06-10 17:05:29 +01:00
Spencer Gibb 243c13b7ee Make turbine.combineHostPort=true the default.
fixes gh-1087
2016-06-09 16:28:48 -06:00
Spencer Gibb 09cc1f2db0 polish 2016-06-09 13:09:09 -06:00
Spencer Gibb 7d295bdc8b Update to SNAPSHOT 2016-06-09 11:30:39 -06:00
Spencer Gibb b6807fc264 Update SNAPSHOT to 1.1.2.RELEASE 2016-06-09 11:06:25 -06:00
Spencer Gibb b3ef770819 Merge pull request #1024 from jebeaudet/fix-query-string-in-class-requestmapping
* fix-query-string-in-class-requestmapping:
  Support path parms in Class @RequestMapping for feign
2016-06-09 10:45:05 -06:00
Jacques-Etienne Beaudet 726f355e9c Support path parms in Class @RequestMapping for feign
This commit adds the support to SpringMvcContract for path parameters
defined in the class' @RequestMapping Annotation that is applied to all
methods of a feign interface.

fixes gh-1023
2016-06-09 10:44:52 -06:00
Dave Syer ad7e341b78 Clarify turnine config some more 2016-06-09 16:48:03 +01:00
Dave Syer 53a3076e1c Add docs on turbine.combineHostPort 2016-06-09 16:22:20 +01:00
Dave Syer 02d935dbaa Add @ConditionalOnEnabledEndpoint to archaius endpoint
Fixes gh-936
2016-06-09 11:22:47 +01:00
Dave Syer 4507d1d46d Add listener for HeartbeatEvent to refresh zuul routes
Fixes gh-1084
2016-06-09 11:22:47 +01:00
Marcin Grzejszczak 2566707256 Zuul filters missing error status code (#1088)
* Added missing error code for SimpleHostRoutingFilter
* Added missing error code for RibbonRoutingFilter
2016-06-09 10:25:08 +02:00
Spencer Gibb 6b1113e355 Remove condition for eureka healthcheck.
fixes gh-1051
2016-06-08 17:50:58 -06:00
Spencer Gibb de45269ec3 update gradle tip. 2016-06-06 19:16:24 -06:00
Spencer Gibb 479a976459 remove unused property 2016-06-06 19:16:06 -06:00
Spencer Gibb 332b5605d6 Update to SNAPSHOT 2016-06-06 19:11:27 -06:00
Spencer Gibb c3d16ddb30 Update SNAPSHOT to 1.1.1.RELEASE 2016-06-06 18:54:25 -06:00
Dave Syer b6fa67c49f Use Servlet 3.0 Part instead of Spring MultipartFile
So that it can handle multi-part requests that do not have a
file name.

Fixes gh-1067
2016-06-06 14:32:43 +01:00
Dave Syer 1c7c96a245 Add local copies of hystrix images
Fixes gh-1076
2016-06-06 13:54:51 +01:00
Dave Syer 0da6f27aac Explicitly exclude form-body params that appear in query string
Fixes gh-1080
2016-06-06 13:43:18 +01:00
Dave Syer b5f8c73060 Update tp mvn 3.3.9 2016-06-04 09:14:45 +01:00
Spencer Gibb 5e2db65383 Upgrade Hystrix to v1.5.3
fixes gh-1074
2016-06-03 15:44:28 -06:00
Spencer Gibb fc08b55eac Merge pull request #1071 from jebeaudet/fix-hardcoded-path-encoding
* fix-hardcoded-path-encoding:
  Fixed the path encoding in ProxyRequestHelper when the character encoding was specifically set on HttpServletRequest.
2016-06-03 13:28:49 -06:00
Jacques-Etienne Beaudet 8229eb657e Fixed the path encoding in ProxyRequestHelper when the character encoding was specifically set on HttpServletRequest.
When the character encoding was set to UTF-8 for example, the path was correctly decoded in PreDecorationFilter but was reencoded in ProxyRequestHelper using the Servlet default ISO-8859-1. This commit uses the character encoding when set and fallback on default.
2016-06-03 13:24:29 -06:00
Spencer Gibb 1c532d9637 Merge pull request #979 from marcosbarbero/master
* pull979:
  Use request.characterEncoding prior to default encoding
2016-06-03 13:21:06 -06:00
Marcos Barbero c743ba893c Use request.characterEncoding prior to default encoding
fixes gh-647
2016-06-03 13:19:38 -06:00
Spencer Gibb a5eb3b6012 Merge pull request #1046 from venilnoronha/issue-1041-fix
* issue-1041-fix:
  Enables Hystrix metrics poll interval config.
2016-06-03 13:05:53 -06:00
Venil Noronha 2d6306644c Enables Hystrix metrics poll interval config.
Fixes gh-1041
2016-06-03 13:05:43 -06:00
Spencer Gibb 711f095ebc Merge pull request #1059 from acennan/patch-1
* patch-1:
  Support header placeholders in SpringMvcContract.
2016-06-03 12:56:29 -06:00
Damian Jackson 0705c9f540 Support header placeholders in SpringMvcContract.
When using property placeholders in the @RequestMapping annotation the ones placed in the headers attribute do not get replaced. This appears to be because the other attributes, such as the url, use the resolve() function to perform the substitution whereas the header is parsed as-is. This change adds a call to resolve for each side of the equals in the header string so that the properties are substituted correctly.
2016-06-03 12:56:21 -06:00
Spencer Gibb 1e52fe2749 Merge pull request #1061 from daniellavoie/ribbon-2.2.0
* ribbon-2.2.0:
  Upgrade ribbon to 2.2.0
2016-06-03 12:28:19 -06:00
Daniel Lavoie 65e7650b16 Upgrade ribbon to 2.2.0
fix gh-1045
2016-06-03 11:22:52 -06:00
Spencer Gibb cc16a7a741 Mark @HystrixConnectionFactory as @Deprecated. 2016-06-03 11:22:17 -06:00
Spencer Gibb 9d3f2d0cfd revert to old .travis.yml 2016-05-27 18:31:00 -06:00
Spencer Gibb 0cc3fe6ab4 reduce logging more 2016-05-27 18:15:36 -06:00
Spencer Gibb 9e03342690 travis logs filling up, switch to INFO 2016-05-27 18:13:04 -06:00
Spencer Gibb 8501969643 don't fork jar plugin so it gets Xmx setting. 2016-05-27 17:54:47 -06:00
Spencer Gibb 0f5d8ec2a6 revert 2016-05-27 17:40:38 -06:00
Spencer Gibb 7c084f855f I'm an idiot and should now stop coding. 2016-05-27 17:32:00 -06:00
Spencer Gibb af26f0f41e attempt to fix build 2016-05-27 17:28:08 -06:00
Spencer Gibb 1c0e44cc8e attempt to fix build 2016-05-27 17:26:30 -06:00
Spencer Gibb e0ae584ea7 attempt to fix build 2016-05-27 17:14:22 -06:00
Spencer Gibb ab056f3190 attempt to fix build 2016-05-27 17:06:43 -06:00
Spencer Gibb 16e827f3ba Merge branch 'daniellavoie-fix-unit-test' 2016-05-27 16:36:38 -06:00
Daniel Lavoie 4fd36592dc Fix RestTemplateRetryTest Unit test 2016-05-27 16:29:26 -06:00
Dave Syer 4a1e637b83 Fix content type when missing from incoming request
If there is no content type incoming, then it should be
absent in the outgoing request (not "null").

Fixes gh-1037
2016-05-24 09:02:48 +01:00
Spencer Gibb d19a6f2615 Use RouteLocator interface.
fixes gh-1030
2016-05-23 16:07:08 -06:00
Spencer Gibb c3f1210619 set MAVEN_OPTS = -Xms256m -Xmx1024m 2016-05-23 15:08:13 -06:00
Spencer Gibb 56fddcc5e2 remove trusty from travis 2016-05-23 14:42:15 -06:00
Spencer Gibb 2567e60834 Upgrade to eureka v1.4.8
fixes gh-1044
2016-05-23 14:15:42 -06:00
Spencer Gibb 315e3487a9 try to fix travis build 2016-05-23 12:50:43 -06:00
Spencer Gibb f040726478 try to fix travis build 2016-05-23 12:47:54 -06:00
Spencer Gibb 27bb2cf826 update to dist trusty to get new jdk version 2016-05-23 12:35:25 -06:00
Spencer Gibb 2ff2ce4de4 Only prepend hostname if it has text 2016-05-23 12:17:06 -06:00
Spencer Gibb 69fd8e7eed Merge pull request #1043 from ryanwmoore/master
Fix minor misspelling in docs
2016-05-23 11:22:31 -06:00
Ryan W. Moore 66387a15b7 Fix minor misspelling in docs 2016-05-23 09:55:58 -04:00
Dave Syer a0c1b4c05d Align instanceId calculation with the one done on the client
The Angel client has an idiosyncratic way of calculating an instance
id, and the Brixton client aligned with that already, but the
Brixton server did not. This change should make Brixton Eureka
Servers work with Angel clients.

See gh-978
2016-05-18 17:32:26 +02:00
Dave Syer d5252375e1 Add back versions for deprecated *-amqp jars 2016-05-17 17:41:13 +01:00
Dave Syer 880efd1843 Remove @AliasFor from @FeignClient.serviceId()
The way it was being used internally means that we didn't need the
annotation anyway. It would be nice to have it back if the Spring
issue gets resolved, because then we could actually use it as
intended.

Fixes gh-1025
2016-05-17 15:33:42 +01:00
Dave Syer 9823d07817 Revert "Add support in SpringMvcContract for query string in Class @RequestMapping"
This reverts commit 2c502e3997.
2016-05-17 15:26:34 +01:00
Dave Syer 2b58487ad7 Fix typo Sream->Stream 2016-05-17 12:10:18 +01:00
Jacques-Etienne Beaudet 2c502e3997 Add support in SpringMvcContract for query string in Class @RequestMapping
This commit adds the support for query string defined in the class'
@RequestMapping Annotation that is applied to all method of a
controller.

Fxies gh-1023, fixes gh-1024
2016-05-17 12:08:49 +01:00
Dave Syer 32d481df26 Be defensive about classpath in eureka auto config
Before this change we were seeing test failures in
spring-cloud-netflix-eureka-server (but only with Spring Boot 1.4)
caused by annotation processing explosion when
RefreshScopeAutoConfiguration is not on the classpath.
2016-05-16 12:46:03 +01:00
Dave Syer b084eb03ff Re-instate .settings.xml for Travis 2016-05-12 11:34:36 +01:00
Dave Syer 043a965db3 Update README and remove .settings.xml where appropriate 2016-05-12 10:47:36 +01:00
Marcin Grzejszczak 65b4b0310b Update runAcceptanceTests.sh 2016-05-11 14:30:32 +02:00
Dave Syer 5d50a773e7 Make test more robust by creating feign clients and validating them
This test should run with Spring Boot 1.4.0.M2 now.

See https://github.com/spring-projects/spring-boot/issues/5870
2016-05-11 10:22:57 +01:00
Dave Syer c399f1117b Revert to snapshots 2016-05-10 17:09:04 +01:00
Dave Syer d9327a02a2 Update for 1.1.0.RELEASE 2016-05-10 17:00:17 +01:00
Dave Syer 617ecf11ec Track customization of sensitive headers so route can be cleared
When the users explicitly sets the sensitive headers of a rroute to
empty, it means they should be empty, not the global defaults.

Fixes gh-1012
2016-05-09 11:47:41 +01:00
Spencer Gibb 83caebf384 Merge pull request #983 from venilnoronha/issue-966-fix
* issue-966-fix:
  Adds path parameter to @FeignClient.
2016-05-06 14:06:34 -06:00
Venil Noronha d3cba4d80e Adds path parameter to @FeignClient.
Fixes gh-966
2016-05-06 14:06:22 -06:00
Spencer Gibb 654ea7094c Merge pull request #1010 from shakuzen/patch-1
Typo fixes
2016-05-06 11:43:06 -06:00
Tommy Ludwig 52a3974a78 Typo fixes 2016-05-07 02:36:42 +09:00
Dave Syer cbd398d7f6 Add explicit release disabled flag for artifactory for plugins 2016-05-06 18:09:41 +01:00
Dave Syer 12f3edd4ab Add explicit release disabled flag for artifactory in dependencies 2016-05-06 17:59:37 +01:00
Spencer Gibb 76f292a6ba Merge pull request #1007 from shivangshah/master
* pull1007:
  Updating RxJava version to 1.1.5 This update on RxJava version is in regards to the PR that got merged [`here`](https://github.com/ReactiveX/RxJava/pull/3820) for making RxJavaPlugins' `reset` method to be public. We have to work this around in Spring Sleuth. Details on the implementation can be found [`here`] (https://github.com/spring-cloud/spring-cloud-sleuth/pull/243).
2016-05-06 10:58:59 -06:00
Shivang Shah 9ce9d670c9 Updating RxJava version to 1.1.5
This update on RxJava version is in regards to the PR that got merged [`here`](https://github.com/ReactiveX/RxJava/pull/3820) for making RxJavaPlugins' `reset` method to be public. We have to work this around in Spring Sleuth. Details on the implementation can be found [`here`] (https://github.com/spring-cloud/spring-cloud-sleuth/pull/243).

1.1.5
2016-05-06 10:55:03 -06:00
Spencer Gibb 4888299b28 polish 2016-05-06 10:54:29 -06:00
Dave Syer e4f3428344 Add explicit release disabled flag for artifactory 2016-05-06 17:47:14 +01:00
Dave Syer c4e879ea96 Switch parent of docs poms 2016-05-06 17:40:09 +01:00
Dave Syer 83235b13c1 Update parent to 1.1.0.RELEASE 2016-05-06 17:13:33 +01:00
Dave Syer 5de52b96f4 Some changes to help with Spring Boot 1.4 compatibility
The jackson version needs to be explicit (not in parent potentially)
and there is a weirdness with @RequestMapping in Spring 4.3
2016-05-05 16:55:09 +01:00
Spencer Gibb 2aedd9b27b Merge pull request #1004 from jebeaudet/fix-IgnoredHeadersCasingNotIgnored
* fix-IgnoredHeadersCasingNotIgnored:
  Sensitive headers set in PreDecorationFilter no longer override previously set ignored headers. Removed the case sensitiveness when the sensitive headers are set. Fixes https://github.com/spring-cloud/spring-cloud-netflix/issues/1003
  Test for default ribbon client configuration
  Tidy up more compiler warnings for generics
  Add note to clarify that zuul starter does not include discovery
2016-05-04 14:19:18 -06:00
Jacques-Etienne Beaudet ea1a4c5add Sensitive headers set in PreDecorationFilter no longer override previously set ignored headers.
Removed the case sensitiveness when the sensitive headers are set.
Fixes https://github.com/spring-cloud/spring-cloud-netflix/issues/1003
2016-05-04 13:40:21 -04:00
Dave Syer 88864153eb Test for default ribbon client configuration 2016-05-04 08:50:57 +01:00
Dave Syer 9ad3d21b75 Tidy up more compiler warnings for generics 2016-05-03 11:53:22 +01:00
Dave Syer 1c9d11de23 Add note to clarify that zuul starter does not include discovery
Fixes gh-992
2016-05-03 10:05:44 +01:00
Spencer Gibb 860d7b8446 Log warning if ServoMonitorCache size exceeds threshold.
Fixes gh-947
2016-05-02 12:27:33 -06:00
Sébastien PERALTA 5613e48141 Append to X-Forwarded-Prefix in case it already exists
Fixes gh-993
2016-04-28 13:22:38 +01:00
Dave Syer 3a251e2a38 Revert "Use the original query string when forwarding the request"
This reverts commit 8952cff24d.
2016-04-28 12:03:10 +01:00
Dave Syer c7c191c01e Ensure Servo metrics are exported the same as default metrics
Adds an `@ExportMetricReader` which was missing before and
led to people losing their metric exports when they had Servo
on the classpath.

Also allow servo metrics autoconfiguration to be disabled via
a flag netflix.metrics.servo.enabled=false (as an alternative to
excluding the class in `@EnableAutoConfiguration`).
2016-04-28 11:57:00 +01:00
Dave Syer e0bc9d11f1 Update docs for Turbine AMQP -> Stream 2016-04-27 14:21:05 +01:00
Dave Syer 6087bc755a Use eureka.instance zone data consistently determining client zone
The zone for a remote server comes from its
eureka.instance.metadataMap.zone, but we didn't (until this change)
apply the same logic to the client. If the client is registering
itslef with eureka then it will have a metadataMap itself and
we should be able to just reverse the logic.

Fixes gh-991
2016-04-27 09:10:42 +01:00
Nicolas Byl 8952cff24d Use the original query string when forwarding the request
to ensure compatibility with legacy apps

Fixes gh-989
2016-04-26 17:31:22 +01:00
Andrei Sfat 1c3de94c42 Add slash to eureka.client.service-url
Makes use of StringUtils.commaDelimitedListToStringArray

Fixes gh-980
2016-04-26 12:14:52 +01:00
Andrei Sfat 9bd3a66b16 #920 add slash when eureka.client.service-url.defaultZone does not contain one 2016-04-26 12:14:41 +01:00
Dave Syer 314d229ccf Add @ConditionalOnEnabledHealthIndicator("hystrix")
Users will have to switch from health.hystrix.enabled to
management.health.* for consistency with other health
indicators.

Fixes gh-985
2016-04-26 09:13:06 +01:00
Matt Reynolds 5c2937b05c filter basic auth credentials from Eureka replica data for display
so they don't appear on the dashboard

Fixes gh-974
2016-04-26 09:05:52 +01:00
Spencer Gibb d1a31a9a2b Upgrade feign to 8.16.2
fixes gh-987
2016-04-25 15:31:55 -06:00
Spencer Gibb 5acf4e1a2e Throw IOException in RibbonLoadBalancerClient.execute
Fixes proper RestTemplate behavior.

fixes gh-986
2016-04-25 13:48:00 -06:00
Pedro Alvarado 2b40952429 Add support for placeholders to Feign spring-mvc RequestMapping annotation.
Fixes gh-894
2016-04-25 11:01:26 +01:00
Dave Syer 8b306df132 Use @PropertySource instead of @Bean for http encoder properties
Protects us against changes in Spring Boot 1.4 where the naming
convention changes.
2016-04-20 14:34:44 +01:00
Dave Syer 8a4fb82b98 Remove reference to 'parent' poms in BOM 2016-04-20 14:20:29 +01:00
Spencer Gibb e0c67b30f8 Pass headers back to feign request.
Spring HttpMessageConverters can modify headers. This change passes the modified headersr back to the feign request, so the proper headers are sent on the request.

 fixes gh-977
2016-04-20 06:46:23 -06:00
Spencer Gibb 33efc60de7 remove spring-cloud-connectors version 2016-04-20 06:42:06 -06:00
Dave Syer 5fc76aaa72 Fix javadocs in @FeignClient
The descriptions of name/serviceId/value and url were out of date
(name is mandatory now and can be mixed with url).
2016-04-19 14:58:59 +01:00
Dave Syer 24579f67e2 Revert to snapshots 2016-04-18 14:07:42 +01:00
Dave Syer d99196aeb1 Update to RC2 2016-04-18 14:02:49 +01:00
Spencer Gibb 7c531eb411 Upgrade Hystrix to 1.5.2
fixes gh-968
2016-04-12 21:57:12 -06:00
Spencer Gibb df5303912f Add global zuul sensitiveHeaders option.
Route specific sensitiveHeaders override global.

fixes gh-944
2016-04-08 10:38:24 -06:00
Spencer Gibb 4479a2b2ee Merge pull request #945 from tkvangorder/master
* pull945:
  Ribbon retry works & fix Content-Length error.
2016-04-07 16:15:23 -06:00
Tyler Van Gorder 05351b7809 Ribbon retry works & fix Content-Length error.
This change requires setting `ribbon.http.client.enabled=true`.

This change addresses issue #648 Getting Retry Working In RestTemplate. There is also a fix in place that addresses the issue #357 RestTemplate Error.

fixes gh-648
2016-04-07 16:15:03 -06:00
Spencer Gibb a3ab3259e3 Make RibbonClientHttpRequestFactory disabled by default.
fixes gh-961
2016-04-07 15:10:39 -06:00
Spencer Gibb e87d9432c7 Merge pull request #883 from aivans/master
* pull883:
  Send 404 in zuul servlet when no route is found.
2016-04-07 13:44:40 -06:00
Adrian Ivan d0841f792e Send 404 in zuul servlet when no route is found.
Fixes false 200 in zuul when using zuul servlet rather than mvc servlet.

Fixes gh-865
2016-04-07 13:44:29 -06:00
Spencer Gibb cef3777313 Upgrade RxJava to v1.1.2
fixes gh-957
2016-04-05 17:16:44 -06:00
Spencer Gibb 0e2d8c1a11 Update feign to v8.16.0
fixes gh-956
2016-04-05 17:12:12 -06:00
Spencer Gibb c055bd5327 Update archaius to v0.7.4
fixes gh-955
2016-04-05 17:05:33 -06:00
Spencer Gibb 3f8c4834a3 Upgrade to ribbon 2.1.5
fixes gh-954
2016-04-05 17:00:42 -06:00
Tim te Beek 593549551a Set or append to X-Forwarded-For for downstream requests
Fixes gh-352
2016-04-05 15:42:56 +01:00
Spencer Gibb c0d767351a Remove need for http basic auth client filter.
https://github.com/Netflix/eureka/releases/tag/v1.4.5

restores http basic auth.
2016-04-04 12:13:24 -06:00
Spencer Gibb 0b9ea25d86 Use config client default service id constant. 2016-04-04 11:53:12 -06:00
Dave Syer fcd0feb61e Ensure whitespace is stripped from appConfig in turbine
Fixes gh-948
2016-04-04 16:59:44 +01:00
Spencer Gibb 1c4db22c28 Angel metadata.instanceId works with Brixton
Fixes gh-642
2016-04-01 13:02:43 -06:00
Spencer Gibb bdc5b915e8 Merge pull request #933 from tkvangorder/master
* pull933:
  Adding the ability to specify a custom retry handler in the ribbon client configuration.
2016-03-31 11:37:45 -06:00
Tyler Van Gorder 983221a710 Adding the ability to specify a custom retry handler in the ribbon client configuration.
fixes gh-931
2016-03-31 11:36:57 -06:00
Spencer Gibb 1cf7ac9260 Upgrade to eureka 1.4.6
fixes gh-932
2016-03-29 16:07:12 -06:00
Marcin Grzejszczak b3a8b1df38 Removed an import 2016-03-25 13:59:48 +01:00
Marcin Grzejszczak cd42566daf Added tests for HystrixStream 2016-03-25 13:57:52 +01:00
Dave Syer 5d2065b3e7 Add some javadocs to ZuulProperties 2016-03-24 12:31:51 +00:00
Dave Syer c57a758e91 Update to Eureka 1.4.5 2016-03-24 09:58:21 +00:00
Spencer Gibb 892eea752b Lazily look up MetricsClientHttpRequestInterceptor in BPP.
fixes gh-912
2016-03-23 12:00:06 -06:00
Marcin Grzejszczak 3f9e76b876 Revert to snapshots 2016-03-23 12:43:41 +01:00
Marcin Grzejszczak 29988b5f58 Bump for 1.1.0.RC1 2016-03-23 12:38:05 +01:00
Spencer Gibb 951758ef30 Update mvnw to determine profile on mac and linux 2016-03-22 12:37:15 -06:00
Spencer Gibb d8da9af29d try and fix LoadBalancerFeignClientOverrideTests 2016-03-21 18:40:39 -06:00
Spencer Gibb d774847d00 try and fix LoadBalancerFeignClientOverrideTests 2016-03-21 18:10:12 -06:00
Spencer Gibb 5e38ae1234 polish 2016-03-21 17:54:50 -06:00
Spencer Gibb 67b6eafbf0 Use ribbon configuration for ReadTimeout & ConnectTimeout.
Allows feign/ribbon users to use standard config files rather than creating a bean of Request.Options.

fixes gh-696
2016-03-21 17:23:21 -06:00
Spencer Gibb 08f7076f6e Mark @FeignClient beans as primary.
When fallback beans are created, there was no longer a unique bean of the feign interface which caused autowire problems.

fixes gh-899
2016-03-16 17:01:45 -06:00
Spencer Gibb b9a6876d00 Upgrade ribbon to 2.1.3
fixes gh-908
2016-03-16 14:36:52 -06:00
Spencer Gibb f76675a561 Upgrade ribbon to 2.1.1
fixes gh-907
2016-03-16 13:20:36 -06:00
Spencer Gibb cae1379440 Merge pull request #903 from marcpa00/patch-1
Typo in example code for `DiscoveryClient`
2016-03-14 14:54:57 -06:00
Marc Paquette a7e34d706d Typo in example code for DiscoveryClient
`DiscoveryClient` field declared with name `discoveryClient` but `serviceUrl()` method uses `client`.
2016-03-14 16:31:20 -04:00
Spencer Gibb 2bca3504cd Merge pull request #778 from jmnarloch/rxjava-stream
* rxjava-stream:
  Spring Mvc RxJava integration.
2016-03-14 14:14:53 -06:00
Jakub Narloch bca86191b3 Spring Mvc RxJava integration.
Support for Single via a ReturnValueHandler.
Support for Observable via SseEmitter.
2016-03-14 14:14:06 -06:00
Spencer Gibb 0f61521c2d Upgrade eureka to 1.4.4
fixes gh-902
2016-03-14 10:56:11 -06:00
Spencer Gibb 37357d4d80 Update jersey to 1.19.1
fixes gh-749
2016-03-14 10:48:11 -06:00
Spencer Gibb 38644689c5 Merge pull request #901 from mduesterhoeft/patch-1
typo fixed
2016-03-14 09:10:46 -06:00
Mathias Düsterhöft 615d860f82 typo fixed 2016-03-14 11:48:22 +01:00
Spencer Gibb 074b2e6ecb Merge pull request #841 from mbenson/feignExpanders
* feignExpanders:
  Where a given String conversion is supported, register Feign Param.Expanders backed by a Feign-specific FormattingConversionService.
2016-03-11 17:03:20 -07:00
Matt Benson a71e13ef07 Where a given String conversion is supported, register Feign Param.Expanders
backed by a Feign-specific FormattingConversionService.
2016-03-11 17:03:04 -07:00
Spencer Gibb b8f11e79c6 Atlas no longer requires a RestTemplate bean.
fixes gh-881
2016-03-10 18:13:20 -07:00
Spencer Gibb 4f31596e4f Fallback to server.port if management.port not set.
See gh-896
2016-03-10 17:30:46 -07:00
Spencer Gibb a1857556ed Put min/max constraints on sidecar.port 2016-03-10 12:54:33 -07:00
Spencer Gibb 802482fff3 Allow CommonsInstanceDiscovery to resolve multiple services on a single host.
fixes gh-897
2016-03-10 11:54:03 -07:00
Dave Syer 371edbf827 Prevent possible memory leak with archaius 2016-03-09 16:58:31 +00:00
Jean-Eric Cuendet f8df337893 Verify that the stream is more than ZERO bytes before un-gzipping
Fixes gh-891
2016-03-09 13:47:16 +00:00
Spencer Gibb 3c8a0d0edb Upgrade feign to 8.15.1 2016-03-08 20:39:10 -07:00
Spencer Gibb 7f9d453afe Merge pull request #884 from spring-cloud/issues_feign_broken_vnd_content_type
8.15 version of Feign breaks VND content types
2016-03-08 20:39:03 -07:00
Marcin Grzejszczak 69a705731b Added Sonar support 2016-03-08 22:10:26 +01:00
Spencer Gibb 4aa156773c Upgrade eureka to 1.4.3
fixes gh-886
2016-03-08 12:27:32 -07:00
Marcin Grzejszczak 61e9d0723c Test to prove the issue 2016-03-08 14:36:37 +01:00
Dave Syer 2670890845 Whitespace 2016-03-08 08:18:38 +00:00
Spencer Gibb 48c9d48789 Upgrade Hystrix to 1.5.1
fixes gh-882
2016-03-07 23:09:02 -07:00
Spencer Gibb a913369dd0 Upgrade feign version to 8.15.0
fixes gh-880
2016-03-07 14:31:44 -07:00
Spencer Gibb eed5a6f10b Test RestTemplate with ribbon when metrics are enabled. 2016-03-07 14:08:27 -07:00
Spencer Gibb 0634c4bc37 Disabling the metrics interceptor fixes the tests.
I'm not sure that is a good thing though.
2016-03-07 12:30:39 -07:00
Dave Syer 8375e3b444 Adapt to changes in commons that put onus on user with @LoadBalanced 2016-03-07 18:04:10 +00:00
Spencer Gibb 790ac76a48 Change type of loadBalancerClient back LoadBalancerClient. 2016-03-04 11:21:43 -07:00
Dave Syer 1d1ad75afb Allow double-encoded JSON (as sent by Angel clients) in turbine
Fixes gh-873
2016-03-04 17:42:33 +00:00
Dave Syer 5bd18e4567 Mostly whitespace 2016-03-04 14:30:11 +00:00
Dave Syer bda11adfd5 Ensure content type is application/json
For compatiblity with Angel streams we only need to set the content
type explicitly.

Fixes gh-873
2016-03-04 13:28:40 +00:00
Dave Syer 000fee96aa Use "=" as separator in @RequestMapping(headers=...)
Consistent with Spring MVC (and untested up to now apparently).

Fixes gh-874
2016-03-04 09:38:31 +00:00
Dave Syer 718cafcd04 Add X-Forwarded-Port explicitly for Tomcat (and other servers)
Fixes gh-872
2016-03-03 11:29:30 +00:00
Dave Syer 908dcc0ec8 Support for multivalued map of file uploads
i.e. user sends multiple files with the same parameter name.

Fixes gh-870
2016-03-03 09:33:07 +00:00
Spencer Gibb 4f6b2bceae Record load balancer stats in RibbonHttpRequest.
fixes gh-731
2016-03-02 21:38:51 -07:00
Spencer Gibb 472b9d1757 Don't run PreDecorationFilter if serviceId already set.
fixes gh-695
2016-03-02 18:25:52 -07:00
Spencer Gibb 8a2a608af0 Add zuul.removeSemicolonContent to enable matrix params.
fixes gh-542
2016-03-02 15:24:04 -07:00
Spencer Gibb 60f4a5bc13 Move o.s.c.util to o.s.c.commons.util 2016-03-02 11:04:21 -07:00
Dave Syer a5d839fe44 Fix mvnw script for milestones 2016-03-02 17:34:26 +00:00
Dave Syer 9ea64308cb Add Authorize to sensitive headers in zuul proxy 2016-03-02 16:17:01 +00:00
Spencer Gibb b8cbf4e637 Don't debug body if zuul servlet or if disabled.
fixes gh-857
2016-03-01 16:20:54 -07:00
Spencer Gibb 2808162037 Upgrade Hystrix to 1.4.24
Upgrade RxJava to 1.1.1

fixes gh-866
2016-03-01 15:29:01 -07:00
Spencer Gibb 9e0d8cae17 Support HttpEntity not just ResponseEntity
fixes gh-859
2016-02-29 10:55:04 -07:00
Spencer Gibb b6fef04761 Preserve upstream character encoding. Only default to UTF-8 if not set.
fixes gh-530
2016-02-26 14:43:12 -07:00
Spencer Gibb b1bcf483c9 polish 2016-02-25 17:31:35 -07:00
Dave Syer d2e004dc68 Add support for "sensitiveHeaders" in zuul.routes
By default we now discard all Set-Cookie and Cookie headers. User
can manipulate it per route via zuul.routes.*.sensitiveHeaders, or
globally via zuul.ignoredHeaders.
2016-02-25 16:51:22 +00:00
Dave Syer 40361f1b8e Add whitelist hosts and sensitive headers 2016-02-25 12:57:33 +00:00
Dave Syer 17eb2f8d91 Refer to correct config props object in docs 2016-02-25 11:53:38 +00:00
Spencer Gibb 727ea4d473 Upgrade eureka to 1.4.2
fixes gh-854
2016-02-24 17:20:17 -07:00
Spencer Gibb 46fa2110da Use default instanceid for sidecar
fixes gh-847
2016-02-24 13:48:14 -07:00
Dave Syer ca81f5671a Add HTTP basic back to Eureka client
Latest Eureka from Netflix uses a different HTTP client, and it
ignores the HTTP basic credentials in a service URL. This change
partially restores the old behaviour by providing an interceptor
(ClientFilter) that has a single, global username/password
taken from the first serviceUrl that contains credentials.

Fixes gh-849
2016-02-24 17:57:52 +00:00
Dave Syer bc0eef9ae2 Exclude jackson XML from eureka client by default
Any client that wants to can include it back again, but generally
it only causes problems (XML returned from apps instead of
JSON by Spring MVC for instance). In general it only causes problems
for services whose clients use "Accept: application/xml,*/*", for
instance (like a browser).

See gh-306
2016-02-24 09:34:12 +00:00
Dave Syer 093354e231 Check if client is in bootstrap and default to not register
Eureka now has the option (maybe always there) to not register
and that's a sensible default in the bootstrap phase (when we
might not know the port yet).
2016-02-24 09:14:29 +00:00
Dave Syer d5f6dbe118 Revert "Add Feign expanders based on Spring conversion service"
This reverts commit 3f34ccc8fb. We
need to discuss a bit more (that thread local is probably unavoidable
given the design of Feign, but I don't like it yet).

See gh-841
2016-02-23 17:21:45 +00:00
Dave Syer 41c364002f Encode query params in Zuul filter
Some slightly tricky manipulation involved here, but hopefully
UriTemplate to the rescue.

Fixes gh-682
2016-02-23 15:19:23 +00:00
Matt Benson 3f34ccc8fb Add Feign expanders based on Spring conversion service
Automatically registers Spring conversion-based Feign Expanders
when available

Fixes gh-841
2016-02-23 11:50:23 +00:00
Matt Benson 05305568ff Parameter name discovery using compiler parameters
Spring MVC Feign Contract did not support parameter name fallback
for the #value() attributes of known parameter annotations. Makes
this feature available when the interface has been compiled with
the Java 8 -parameters compiler arg

Fixes gh-835
2016-02-23 11:42:40 +00:00
Matt Benson c3766720fa Parameter name discovery for Feign clients
Supports Spring REST parameter annotations considered
only #value() members without respecting @AliasFor meta-annotations.
Address by passing a Spring-synthesized annotation to individual
AnnotatedParameterProcessors. This approach has the benefit of impacting
present as well as any future implementations alike.

Fixes gh-828
2016-02-23 11:39:49 +00:00
Dave Syer c3efcbabb8 Fix links to client code 2016-02-23 10:28:51 +00:00
Dave Syer 79b7480f4f Move servlet detection filter to ZuulConfiguration
It seems like a generic feature to me (not specific to the proxy),
so logically it should live in the base class.

Fixes gh-844
2016-02-23 10:02:54 +00:00
Dave Syer 1a96e594f0 Do not override register() method in instance registry
The super class deals with syncing to peers, so we need that
call. It still delegates to the other register method and seems
to work just fine without the override.

Fixes gh-838
2016-02-23 09:49:16 +00:00
Dave Syer 32b3ca4159 Set registration retries to non-zero by default if peered 2016-02-23 09:49:16 +00:00
Spencer Gibb aa2d0eb442 Merge pull request #797 from AndreasKl/simplefilter-connection-settings-config
* simplefilter-connection-settings-config:
  Add the ability to configure the max connections and max per route on PoolingHttpClientConnectionManager.
2016-02-22 17:41:18 -07:00
Andreas Kluth 65bf3bb6ee Add the ability to configure the max connections and max per route on PoolingHttpClientConnectionManager. 2016-02-22 17:39:31 -07:00
Spencer Gibb bfd4efcd94 Ignore EurekaHealthIndicator (boot) in EurekaHealthCheckHandler (eureka).
See corresponding change in s-c-commons https://github.com/spring-cloud/spring-cloud-commons/commit/539a537abba58ed2261c4485d7f9426d2aa57453

fixes gh-643
2016-02-22 17:01:57 -07:00
Spencer Gibb c1704235b4 polish 2016-02-22 15:23:24 -07:00
Spencer Gibb 572220ae1f Default secureVirtualHostName to spring.application.name.
See gh-826
2016-02-22 14:04:53 -07:00
Dave Syer 48913cbb64 Add zuul.ignoredHeaders configuration hook
User can exclude headers (generally in responses is most useful)
by configuring them, or calling a setter in ZuulProperties.

If Spring Security is on the classpath we add a few headers
automatically, corresponding to the ones that would be added
by Spring Security in the remote backend anyway (so they are not
added twice). Nothing is actually removed, so if the remote
service doesn't add those headers, we don't change anything.

The X-Application-Context header is also added to the hard coded
list of ignored headers, because it isn't relevant in the
gateway (and leaks information about the remote service).

Fixes gh-819
2016-02-22 13:23:24 +00:00
Spencer Gibb 86ac0127a5 Upgrade eureka to 1.4.1
Plus polish

fixes gh-836
2016-02-19 17:01:40 -07:00
Dave Syer 104361608c Whitespace tidy up 2016-02-18 10:43:28 +00:00
Dave Syer c291358858 Add additional null check for uri
Fixes gh-803 (again)
2016-02-18 10:42:45 +00:00
Dave Syer 86d515282e Import the autoconfig for server properties
Otherwise there can be duplicate beans with the same type and different
names, becasue the autoconfig does not (for some reason) use
@EnableConfigurationProperties to create the ServerProperties bean.

It isn't an issue until someone writes some autoconfig that itself
imports the ZuulConfiguration (i.e. regular concious users of
@EnableZuulServer do not see any problems and hence no tests fail
here or in integration projects).

Fixes gh-821
2016-02-15 15:58:50 +00:00
Nicolas Byl 67258446f9 Improved query string handling to present empty keys correctly
I.e. show empty "foo" as foo (not foo=)

Fixes gh-825
2016-02-15 10:35:41 +00:00
Dave Syer 5c2919074f Set -Pmilestone automatically based on pom version 2016-02-12 17:45:17 +00:00
Dave Syer 68682ce48a Make grep quiet when setting env vars 2016-02-12 15:48:42 +00:00
Dave Syer 81dd95457f Fix logic with MVN_GOAL 2016-02-12 15:06:20 +00:00
Dave Syer 90e7fd8d74 Align travis build with tools in spring-cloud/build 2016-02-12 13:23:19 +00:00
Dave Syer d66cae9c49 Fix spelling 2016-02-11 22:13:22 +00:00
Dave Syer 2323512304 Clarification regardinff shared interfaces in server and client 2016-02-11 22:09:54 +00:00
Spencer Gibb 213df388f3 Upgrade feign to 8.14.4
fixes gh-822
2016-02-11 08:53:22 -07:00
Spencer Gibb 47747f3256 Polish and extensibility 2016-02-09 16:28:57 -07:00
Spencer Gibb 834dfe22dd Handle ClientException.SERVER_THROTTLED as 503
fixes gh-406
2016-02-09 16:02:18 -07:00
Spencer Gibb 1b190a32bd refactored zuul proxy tests 2016-02-09 15:02:31 -07:00
Spencer Gibb 57ebc6344c Upgrade eureka to 1.3.8
fixes gh-813
2016-02-05 12:52:04 -07:00
Dave Syer 443406f75f Revert to snapshots 2016-02-05 07:24:05 +00:00
Dave Syer 61ef6dd511 Update to 1.1.0.M5 2016-02-05 07:23:28 +00:00
Dave Syer e660cbd6ee Put repository declarations back 2016-02-05 06:47:14 +00:00
Dave Syer 8fa249bab8 Remove duplicate distribution mgmt from pom 2016-02-05 06:41:36 +00:00
Spencer Gibb 3524f414ff Upgrade servo to 0.10.1
fixes gh-809
2016-02-04 14:21:55 -07:00
Marcin Grzejszczak ad7921e32c Merge pull request #811 from spring-cloud/feign_upgrade
Upgrading feign
2016-02-04 19:07:03 +01:00
Marcin Grzejszczak 90d0725fe0 Upgrading feign 2016-02-04 11:26:34 +01:00
Dave Syer c784ff1bc3 Add bin dir to ignores 2016-02-03 16:01:42 +00:00
Dave Syer d5277925bc More Zuul context resets 2016-02-03 10:24:12 +00:00
Dave Syer 5b86b57771 Rename a test so it gets run in CI
Also does not rename another one because it fails (see gh-804). The
bug can be fixed in feign (https://github.com/Netflix/feign/pull/324),
and if that gets merged and released we can revert some of the recent
changes to the apache load balancer here.
2016-02-03 10:23:05 +00:00
Spencer Gibb c2483cbe4e Upgrade feign to 8.14.2
fixes gh-807
2016-02-02 12:55:30 -07:00
Spencer Gibb 9c3010074d Update readme for code of conduct.
See https://github.com/spring-cloud/spring-cloud-build/issues/26
2016-02-01 19:59:30 -07:00
Spencer Gibb 199c740c17 Merge pull request #802 from herder/patch-1
Fix typo: zule-core -> zuul-core.
2016-02-01 15:22:13 -07:00
Spencer Gibb 63896485b0 Fix broken zuul tests. 2016-02-01 15:01:28 -07:00
Spencer Gibb 01fc27cb49 Temporarily ignore failing test so snapshots can build. 2016-02-01 12:51:35 -07:00
Spencer Gibb 3611edd1a0 Merge pull request #800 from brharrington/spectator-issue-264
* spectator-issue-264:
  fix registration bug in SpectatorMetricServices
2016-02-01 12:33:23 -07:00
Brian Harrington 63b0c8c67d fix registration bug in SpectatorMetricServices
The primary change is to fix a memory leak reported in
Netflix/spectator#264. Each time a gauge was updated it
was creating a new registration and because the map holds
a strong reference these would never get collected.
Further, the aggregate value created by the multiple
registrations was not correct.

In addition I added some test cases around the various
inputs and checked that the results were reflected as
expected in the registry. I noticed the timer values
had a unit of milliseconds, but it isn't immediately
clear if the reported value can ever less than 1.0. The
conversion to long is now delayed until after converting
to nanoseconds so duration values less than 1.0 will now
work instead of just recording 0.

For the histogram I changed to just using a cast to `long`
to avoid boxing to a `Double`. As an FYI for the future,
there is a DoubleDistributionSummary we have experimented
with in spectator-ext-sandbox that might be more appropriate
for this use-case.
2016-02-01 12:20:01 -07:00
Dave Syer 32c0f90999 Remove regex mapper properties from ZuulProperties
It is up to the user to configure a mapper if needed (one is no
longer provided automatically), so it doesn't need to take up
space in ZuulProperties
2016-01-31 16:19:51 +00:00
Dave Syer 82d8a11021 Defensive coding to avoid potential NPE
Fixes gh-803
2016-01-31 16:19:16 +00:00
Dave Syer 2e9ff4c7d7 Make eureka application manager @Lazy
So that it isn't instantated eagerly on startup by the RefreshScope.

Fixes gh-789
2016-01-29 13:13:30 +00:00
Niklas Herder c95e2f450d Fix typo: zule-core -> zuul-core. 2016-01-29 13:27:33 +01:00
Dave Syer cb13b9dd77 Reset Zuul state some more
Tests are very sensitive to the Zuul RequestContext which is
thread bound.
2016-01-28 17:48:42 +00:00
Marcin Grzejszczak 7747674b5c Updated e2e script 2016-01-28 13:39:02 +01:00
Dave Syer 29e691a4da Fix some zuul tests (clear request context before test) 2016-01-27 13:53:22 +00:00
Dave Syer 22b08f1a7f Fix Feign Ribbon with Apache HTTP client
The Apcahe client does not allow empty body for PATCH, nor does it
allow a request to be pre-populated with a Content-Length. Spring
Cloud tests were trying to do the former, and Feign allows the latter.
2016-01-27 13:38:48 +00:00
Dave Syer 65ec773066 Fix FeignHttpClientTests 2016-01-27 13:06:02 +00:00
Adrian Ivan 2f905b81ed Detect Zuul vs DispatcherServlet execution
Change SimpleRouteLocator to work with both Zuul and DispatcherServlet

Fixes gh-794
2016-01-27 10:51:56 +00:00
Dave Syer 1534ca41f7 Add dependency management for netty
Fixes gh-710
2016-01-26 16:02:26 +00:00
Dave Syer 7bdab0f23b Relay eureka.environment to Archaius if it is set
Apparently we already support eureka.datacenter as an alias for
archaius.deployment.datacenter and it looks like when that code
was written we intended to support eureka.environment in a similar way.
But it was never finished off, so this change adds the necessary one
line of code.

Fixes gh-791
2016-01-26 14:05:54 +00:00
Dave Syer 82991a7fc2 Make feign client bean id unique (use full classname)
Fixes gh-790
2016-01-26 10:49:21 +00:00
Dave Syer 3c5126c740 Consolidate tests and bootstrap config for config server 2016-01-25 11:43:11 +00:00
Dave Syer dbb6059558 Simplify config server discovery with DiscoverClient metadata
Since DiscoverClient now supports metadata natively, we can use that and not rely
on Eureka interafces at all.

Fixes gh-787. Also fixes https://github.com/spring-cloud/spring-cloud-config/issues/302
2016-01-25 10:17:57 +00:00
Dave Syer 92a35ba77f Add explicit docs for eureka.hostname in secure app registration
Eureka supports native placeholders, but Spring can also be used.
Added some docs to show how more explicitly.

See gh-761
2016-01-24 08:29:55 +00:00
Spencer Gibb ddd7979a25 Don't refresh the ipAddress if set by user config.
fixes gh-573
2016-01-20 13:52:58 -07:00
Spencer Gibb 3fb26f69e5 Add ability to disable hystrix metrics
fixes gh-781
2016-01-20 13:06:13 -07:00
Spencer Gibb 0b9fc290d2 Upgrade eureka to 1.3.7
fixes gh-779
2016-01-19 17:18:50 -07:00
Spencer Gibb e2f6bd0e2e Upgrade Hystrix to v1.4.23
fixes gh-777
2016-01-19 15:28:50 -07:00
Dave Syer a6e47a0b47 Ensure management.port defaults to server.port for eureka registration
Otherwise apps register the wrong health and status URLs by default. If
there is no explicit management.port we just need a default that is
the same as server.port.
2016-01-19 07:04:38 +00:00
Dave Syer be0f030ccf Move shared package under eureka 2016-01-19 07:02:37 +00:00
Dave Syer b46dab3099 Put @Bean EurekaServerConfig in nested class to avoid cycle
A new integration test ill be added in spring-cloud-samples/tests.

Fixes gh-759
2016-01-18 17:35:17 +00:00
Dave Syer c97f69517d Fix format in javadoc 2016-01-18 17:03:05 +00:00
Dave Syer 053296de93 Ensure request body is not buffered when direct to ZuulServlet
A change in Zuul in NetflixOSS means that it buffers all requests unless
you switch it off at the level of the servlet. And even when you do that
you need to ensure that Spring Cloud doesn't re-introduce a buffer through
the Servlet30RequestWrapper.

This change restores the feature in Spring Cloud Angel that multipart files
posted to /zuul/* go straight through the servlet and are not buffered in
memory.

Fixes gh-773
2016-01-18 16:51:35 +00:00
Dave Syer 249f524ad9 Fix typo in docs 2016-01-16 09:46:46 +00:00
Spencer Gibb 62d340bcfe Support @AliasFor annotation elements in Feign.
fixes gh-766
2016-01-15 17:30:08 -07:00
Dave Syer 9287e66cfc Add ServerProperties in case not a web app (for tests) 2016-01-15 15:34:42 +00:00
Dave Syer 98e1ac7375 Add fullPath as convenience property on Route
More often than not what Route.path was used it had to be concatenated
with the prefix. This change just encapsulates that concern in the
Route itself.
2016-01-15 15:34:42 +00:00
Dave Syer f9fc8ba8aa Change signature of RouteLocator.getRoutes()
If it returns Routes instead of Strings it's a lot more obvious
what it's supposed.
2016-01-15 15:34:42 +00:00
Dave Syer 2585798ab5 Consolidate RouteLocator features in base class 2016-01-15 15:34:42 +00:00
Marcin Grzejszczak 1d85260ccd Fixed wrong branch of the script for e2e 2016-01-15 12:36:54 +01:00
Marcin Grzejszczak e4f81fb62e Updated e2e scripts 2016-01-15 12:36:03 +01:00
Marcin Grzejszczak 1e582dea0a Added killing of apps after e2e tests 2016-01-15 10:40:14 +01:00
Spencer Gibb f00f761996 Support feign hystrix fallbacks.
Added @FeignClient(fallback).

Renamed FeignClientFactory to FeignContext.

fixes gh-762
2016-01-14 16:19:59 -07:00
Spencer Gibb 390f0016e6 Upgrade to Feign 8.14.1
fixes gh-727
2016-01-14 16:19:59 -07:00
Dave Syer 3ecd9cb0cf Move discovery related route locator stuff into a new package 2016-01-14 17:15:30 +00:00
Dave Syer 9161c54c43 Factor out common interface from ProxyRouteLocator
The RouteLocator interface wasn't very useful to anyone in its
1.0.x form. If ProxyRouteLocator features are consolidated into
the RouteLocator interface then users can supply their own
strategies more easily.

Also added RefreshableRouteLocator for implementations that need
to recompute routes when something changes. SimpleRouteLocator
doesn't need to do that because all the routes are in the configuration.
2016-01-14 17:15:30 +00:00
Spencer Gibb b4cf375044 ignore ipr 2016-01-12 15:53:24 -07:00
Spencer Gibb b894f8dbb3 Upgrade archaius to v 0.7.3
Added spring-cloud-starter-archaius so downstream projects
like consul and zookeeper don't need to maintain the list of
archaius depenencies.

fixes gh-765
2016-01-12 11:19:16 -07:00
Spencer Gibb af88007cc3 Merge pull request #745 from jkschneider/metrics-deconflict-services
Servo and Spectator metrics defer to other Counter/GaugeServices
2016-01-12 10:42:47 -07:00
Spencer Gibb c1e567afc7 Move eureka-client code to separate module.
This move should be transparant to users of spring-cloud-starter-eureka.

fixes gh-579
2016-01-11 16:45:30 -07:00
Marcin Grzejszczak 1ee1a924ba Reverting changes before adding acceptance tests 2016-01-08 22:16:38 +01:00
Dave Syer 704fa7a1be Ensure we are using dependencies poms from other projects 2016-01-08 16:40:06 +00:00
Dave Syer 682b71565d Add profile for repos 2016-01-08 13:24:31 +00:00
Dave Syer 3f742d9675 Add spring-cloud-netflix-dependencies module as a BOM
The new module is a BOM that doesn't have any parent or direct
dependency management in spring-boot-*. So users can include it
in their dependency management without polluting the spring boot
dependency versions.

Luckily it can also be used in the main spring-cloud-netflix pom,
which should no longer be used as a BOM.
2016-01-07 13:45:46 +00:00
Dave Syer 0e8ce13c07 Copy javadocs from interfaces to config property fields 2015-12-30 17:55:05 +00:00
Dave Syer e4a1b50edb Change name of mispelled class 2015-12-30 17:54:03 +00:00
Dave Syer 832bd41f5d Add some docs for config properties 2015-12-30 15:06:30 +00:00
Jon Schneider af5c2360ea Servo and Spectator metrics defer to other Counter/GaugeService implementations 2015-12-28 14:31:10 -06:00
Marcin Grzejszczak 86e16f58b9 Analysing the stalling test issue 2015-12-28 18:34:37 +01:00
Marcin Grzejszczak 13aa5be9b9 Changing maven logging level 2015-12-28 17:40:03 +01:00
Marcin Grzejszczak 1e13740bda Trying to fix the hanging build 2015-12-28 17:10:52 +01:00
Marcin Grzejszczak 7e738dedc5 Temporarilly adding more logging to maven 2015-12-28 16:43:50 +01:00
Spencer Gibb d809ac9999 fix eureka-first test 2015-12-23 17:34:30 -07:00
Marcin Grzejszczak 952be93124 Removed unnecessary sudo: false 2015-12-23 18:56:16 +01:00
Marcin Grzejszczak 096f452cfa Trying to make the build pass 2015-12-23 16:28:08 +01:00
Marcin Grzejszczak 7b8a02ede8 Added running of acceptance-tests 2015-12-23 10:43:45 +01:00
Spencer Gibb 94c73da943 Use new InetUtils bean to determin nic.
Allows for more fine-grained configuration of what to ignore.
2015-12-22 18:10:56 -07:00
Spencer Gibb 03f6d12e50 Implement ServiceInstance.getMetadata.
Introduce ServerIntrospector.getMetadata(Server).

fixes gh-419
2015-12-22 15:04:57 -07:00
Spencer Gibb 8938aa4621 Revert "Update SNAPSHOT to MILESTONE 1.1.0.M4"
This reverts commit 721fdc5918.
2015-12-22 11:25:47 -07:00
Spencer Gibb 721fdc5918 Update SNAPSHOT to MILESTONE 1.1.0.M4 2015-12-22 11:21:20 -07:00
Marcin Grzejszczak ad2716c361 Removed increased polling interval 2015-12-21 14:59:53 +01:00
Marcin Grzejszczak fae2c5d1b5 Increasing polling interval for e2e tests even more 2015-12-21 13:39:30 +01:00
Marcin Grzejszczak de1021e20c Increased polling interval for e2e tests 2015-12-21 13:05:27 +01:00
Marcin Grzejszczak e5a58ef7c1 Removed version param to use default BOM Brixton Snapshot version 2015-12-18 23:12:44 +01:00
Spencer Gibb d36fff1772 remove outdated RUNNING.md 2015-12-18 13:46:41 -07:00
Spencer Gibb 8d259b9d8f Merge pull request #669 from zanella/invalid_hostname
* invalid_hostname:
  Added check for invalid hostname
2015-12-18 13:11:53 -07:00
Rafael Zanella 7c7513ee25 Added check for invalid hostname
The exception class has to be "fixed"

You may register a serviceId with invalid URI characters (e.g.: '_'), but the URI::getHost() fails when such chars are found.
2015-12-18 13:11:22 -07:00
Spencer Gibb 4ffeff200e Merge pull request #734 from hscholz/master
* pull734:
  fixes gh-716 adds option to decode 404s
2015-12-18 12:47:55 -07:00
hscholz 66c047e6d5 fixes gh-716 adds option to decode 404s 2015-12-18 12:12:29 -07:00
Spencer Gibb a00fd2c348 Merge pull request #663 from jettro/master
* pull663:
  Case insensitive Content-Encoding check
2015-12-18 11:22:07 -07:00
Jettro Coenradie f707e5f053 Case insensitive Content-Encoding check
Fixes a problem with a header in the response containing
content-encoding in lowercase letters. Uses HttpHeaders for case
insensitve check.

Also fixes an issue checking if a request is made for gzip content.
If headers has more than gzip (ie gzip,deflate,sdch), checks if
contains gzip instead of equals to.

Fixes gh-662
2015-12-18 11:21:18 -07:00
Spencer Gibb a61c18c69c polish 2015-12-18 10:50:31 -07:00
Spencer Gibb 7234a99756 Merge pull request #735 from jkschneider/metrics-gauge-deconflict
* jkschneider-metrics-gauge-deconflict:
  Deconflict GaugeService provided by Servo/Spectator integration
2015-12-18 10:50:10 -07:00
Jon Schneider 33d651847d Deconflict GaugeService provided by Servo/Spectator integration 2015-12-18 09:07:41 -08:00
Dave Syer 2bb6befbca Add vanilla integration tests 2015-12-18 11:48:47 +00:00
Dave Syer 2f0d425b66 Allow URL to be host only (per javadocs) 2015-12-18 11:33:34 +00:00
Spencer Gibb bad20d3fcc Migrate SpringClientFactory and FeignClientFactory
Now uses spring-cloud-context NamedContextFactory.

see https://github.com/spring-cloud/spring-cloud-commons/issues/69
2015-12-17 14:33:11 -07:00
Dave Syer 493caec5df Fix ribbon client factory to search context hierarchy
We need to use BeanFactoryUtils to search the context hierarchy
for custom instances.

Fixes gh-733
2015-12-17 17:07:14 +00:00
Spencer Gibb 7d78a3c347 Merge pull request #724 from jkschneider/metric-poller
Add Servo metric poller and @EnableAtlas test
2015-12-16 12:21:54 -07:00
Spencer Gibb 3f45391d29 Merge pull request #723 from jkschneider/atlas-docs
Update docs to indicate the need for spring-cloud-starter-atlas
2015-12-16 12:20:29 -07:00
Spencer Gibb 502f955091 Merge pull request #722 from jkschneider/atlas-metric-observer
Minor improvements to error messages for netflix.atlas.uri problems
2015-12-16 12:19:38 -07:00
Spencer Gibb 4720b78db5 Merge pull request #699 from stephaneLeroy/master
* pull699:
  Add Zuul Proxy regex serviceId to route mapping
2015-12-16 12:10:56 -07:00
Stéphane Leroy 4a52a7f889 Add Zuul Proxy regex serviceId to route mapping
fixes gh-693
2015-12-16 12:10:22 -07:00
Marcin Grzejszczak 9f9948707a Added scripts to run e2e tests 2015-12-16 18:23:09 +01:00
Jon Schneider 1cd363f33f Add Servo metric poller and @EnableAtlas test 2015-12-15 23:20:07 -08:00
Jon Schneider 4325b7e363 Update docs to indicate the need for spring-cloud-starter-atlas for Atlas 2015-12-15 22:17:13 -08:00
Jon Schneider e994971bec Minor improvements to error messages for netflix.atlas.uri problems 2015-12-15 21:29:20 -08:00
Spencer Gibb 0ddfb42d4d Merge pull request #694 from snussbaumer/gh-691
* gh-691:
  Enable configuration of the way HttpClient handles redirects
2015-12-15 15:52:06 -07:00
Sébastien Nussbaumer 15f940054d Enable configuration of the way HttpClient handles redirects
RibbonLoadBalancingHttpClient being IClientConfigAware, it is now
initialized within initWithNiwsConfig. The values of the config keys
FollowRedirects, ConnectTimeout and ReadTimeout are now respected.

Fixes gh-691
2015-12-15 15:43:21 -07:00
Spencer Gibb b108de33ed Merge pull request #713 from kakawait/gh-583
* gh-583:
  Removing multiple successive slashes
2015-12-15 14:38:12 -07:00
kakawait 982288ec04 Removing multiple successive slashes
Eliminates zuul URISyntaxException if route has trailing slash.

fixes gh-583
2015-12-15 14:37:52 -07:00
Spencer Gibb 804abb6d6d Move test to same package as class testing 2015-12-15 14:00:21 -07:00
Spencer Gibb 8f6cd86e56 Merge pull request #704 from hscholz/master
* pull704:
  Explicitly set target to feign client name.
2015-12-14 15:15:48 -07:00
hscholz abd32fbfd0 Explicitly set target to feign client name.
fixes gh-703
2015-12-14 15:15:27 -07:00
Spencer Gibb 2acd353c7d Allow Feign Hystrix support to be disabled.
fixes gh-717
2015-12-14 14:39:35 -07:00
Spencer Gibb 456f2c0a99 Merge pull request #670 from jkschneider/metrics-docs
Servo, Spectator, and Atlas docs
2015-12-12 11:22:58 -07:00
Jon Schneider ad6e61dd47 Servo, Spectator, and Atlas docs 2015-12-11 20:17:46 -08:00
Spencer Gibb 810b17ae06 Guard for null entity.
redefine isSuccess to 2xx status code series.

fixes gh-687
2015-12-03 11:00:11 -07:00
Dave Syer a43d9d86df Add null check in annotation processing for Feign
Allows POST with a @RequestBody

Fixes gh-689
2015-12-03 17:14:54 +00:00
Spencer Gibb 57206c639d Upgrade to Hystrix 1.4.21
fixes gh-685
2015-12-02 14:07:31 -07:00
Spencer Gibb 1ede1458b9 Get RequestInterceptors from feign context.
Rather than pulling them from the generic context.

fixes gh-683
2015-12-02 11:36:48 -07:00
Spencer Gibb f38e43a4b6 polish 2015-12-02 10:35:53 -07:00
Spencer Gibb cb8b9363f6 Merge pull request #671 from alexVengrovsk/update-debug
Add isDebugEnabled() for logging operations
2015-11-30 13:22:50 -07:00
alexVengrovsk 8957a40328 Update InstanceRegistry.java 2015-11-30 16:23:24 +02:00
Dave Syer 1129872061 Default status page and health URLs if possible and where needed
If the management.port is explicitly set to something other than the
server.port, we can use it to set the status page and health URL
default values. (They can still be overridden by config properties.)

If management.port=0 there's not much we can do because we don't know
the port number yet when the instance config is created.

Fixes gh-425
2015-11-30 09:29:09 +00:00
Dave Syer f2fee74880 Excludes aspectjrt from javanica
The aspectjweaver jar includes all of aspectjrt, and the former is
used at runtime in a number of places (tests fail if you remove
it). Both are not needed so we have picked one (the other one than
recommended in gh-666).

Fixes gh-666
2015-11-26 15:33:09 +00:00
Spencer Gibb 1090f2817a Upgrade zuul to v1.1.0
fixes gh-591
2015-11-24 16:37:25 -07:00
Spencer Gibb d23a57d13b Don't extend EurekaBootStrap.
EurekaBootStrap implements ServletContextListener which causes problems because of early instantiation.

fixes gh-664
2015-11-23 16:32:31 -07:00
Spencer Gibb c93a19c0d1 Merge pull request #625 from liebowitz/master
* pull625:
  Refactor SimpleHostRoutingFilter
2015-11-23 14:34:24 -07:00
Greg Liebowitz 940921ac15 Refactor SimpleHostRoutingFilter
Removed deprecated HttpClient APIs, exposed method to override client, fixed ignoredHeaders
2015-11-23 14:33:39 -07:00
Spencer Gibb 452f494c21 Merge pull request #661 from micheal-swiggs/multiple_monitoring
* multiple_monitoring:
  Enables hystrix monitoring of multiple services on a single server.
2015-11-23 12:30:15 -07:00
Micheal Swiggs 03a005033d Enables hystrix monitoring of multiple services on a single server. 2015-11-22 08:47:43 +00:00
Spencer Gibb f46e8e8e1f Merge pull request #543 from ChristianLohmann/create-httpclient-ribbon-command
* create-httpclient-ribbon-command:
  an Apache http client zuul ribbon command
2015-11-20 16:37:42 -07:00
Christian Lohmann 18dff8527d an Apache http client zuul ribbon command
This is an implementation of a RibbonCommand and a factory which makes
use of a loadbalancing http client based on apache's http-components
http-client.
With this command/factory it is possible to route PATCH http requests
via zuul/ribbon as well.

fixes gh-412
2015-11-20 16:37:18 -07:00
Spencer Gibb 81b430dbb4 polish 2015-11-20 15:34:39 -07:00
Spencer Gibb 3994a3e439 Merge pull request #655 from Oreste-Luci/master
* pull655:
  Add support for placeholders in @FeignClient definitions
2015-11-20 15:26:47 -07:00
Oreste Luci 94d4bdfcc3 Add support for placeholders in @FeignClient definitions
Includes name and url attributes.

fixes gh-414
2015-11-20 14:25:38 -07:00
Spencer Gibb 4721bee8f2 allow EurekaServerConfig to be overridden.
fixes gh-657
2015-11-20 10:48:51 -07:00
Spencer Gibb 415cd1d83c Remove unneeded hardcoded initializers. 2015-11-19 08:33:39 -07:00
Spencer Gibb bd12fa47d7 Upgrade to rxjava 1.0.14
fixes gh-651
2015-11-18 14:19:45 -07:00
Spencer Gibb a7d425deba Upgrade to feign 8.12.1
fixes gh-623
2015-11-17 17:03:26 -07:00
Spencer Gibb 06a4e0996b added ribbon.http.client.enabled conditional 2015-11-17 09:22:01 -07:00
Dave Syer 06b50c9fe0 Revert to snapshots 2015-11-17 12:27:43 +00:00
Dave Syer 05f75e70da Update to 1.1.0.M3 2015-11-17 12:27:01 +00:00
Dave Syer db2e87f1b6 Switch log to debug from info
Logging each request in the proxy is too verbose and inconsistent
with other Spring MVC logging.
2015-11-13 11:51:32 +00:00
Dave Syer db4c82c39c Add @deprecated Javadocs 2015-11-13 11:51:32 +00:00
Spencer Gibb 713e6b8461 Merge pull request #639 from jkschneider/metrics-aop-fix
* metrics-aop-fix:
  RestTemplate metrics collection join point now returns a value
2015-11-12 10:41:23 -07:00
Jon Schneider be14074817 RestTemplate metrics collection join point now returns a value 2015-11-12 10:34:07 -07:00
Dave Syer 024d9946dc Whitespace 2015-11-12 16:23:26 +00:00
Dave Syer 36e4c7cf93 Make metrics aspect conditional on Spring AOP
Also changes pointcut to use the interface so you don't need
proxyTargetClass=true.

Fixes gh-636
2015-11-12 13:53:50 +00:00
Spencer Gibb ef5785bfb7 Upgrade to Hystrix v1.4.20
fixes gh-635
2015-11-11 15:55:03 -07:00
Spencer Gibb dc1f28a74e Merge pull request #613 from jmnarloch/feign-no-content-test
* feign-no-content-test:
  Feign handling unparameterized ResponseEntity
2015-11-11 14:00:17 -07:00
Jakub Narloch cff20c5a6d Feign handling unparameterized ResponseEntity
fixes gh-612
2015-11-11 14:00:04 -07:00
Dave Syer b001fea325 Re-order configs and add refresh scope for lazy loading
so that Eureka InstanceInfo (which is designed to be immutable)
can effectively be mutated (by using a different instance) after the
dynamic port is available.
2015-11-11 11:09:28 +00:00
Spencer Gibb 3dfb8b5dc1 fix support for registering random ports with eureka.
fixes gh-570 ... again
2015-11-11 11:09:28 +00:00
Ben Klein 31e82a7597 Update spring-cloud-netflix.adoc
Reword to avoid broken AsciiDoc formatting.
2015-11-10 17:03:41 -08:00
Spencer Gibb 38055b586d Allow flexibility with Turbine http.
Allows non-eureka based InstanceDiscovery.
Allows custom InstanceDiscovery.

fixes gh-566
2015-11-10 17:17:09 -07:00
Spencer Gibb 1e716ff2c2 Upgrade eureka to v1.3.4
fixes gh-589
2015-11-10 12:25:05 -07:00
Spencer Gibb 5566749742 Merge pull request #633 from jkschneider/metrics-test-fixes
* metrics-test-fixes:
  Fix flaky Servo tests by avoiding DefaultMonitorRegistry
2015-11-10 09:20:58 -07:00
Jon Schneider 7bf6a85bd3 Fix flaky Servo tests by avoiding DefaultMonitorRegistry 2015-11-10 09:20:37 -07:00
Spencer Gibb 679e659cbc remove findbugs 2015-11-10 09:03:41 -07:00
Spencer Gibb 4d7f40f6e8 ignore failing test for now. 2015-11-09 15:01:58 -07:00
Spencer Gibb dfec99780a fix failing test on travis. 2015-11-09 14:54:05 -07:00
Spencer Gibb b117030a47 Merge pull request #615 from jkschneider/metrics
* metrics:
  Expanded metrics support to include Servo, Spectator, and Atlas
2015-11-09 14:11:35 -07:00
Jon Schneider c61a48735d Expanded metrics support to include Servo, Spectator, and Atlas
* For Java 8 users, Spectator is the recommended metrics library as Servo is now deprecated in favor of Spectator
* Servo support now needs to be specifically enabled via @EnableServo, even if servo-core is included on the classpath
* Added starter modules for both Spectator and Atlas support
* ServoMetricReader defines a convention for mapping tag-based metrics to hiearchical names for rendering by the Actuator /metrics endpoint
2015-11-09 14:10:44 -07:00
Spencer Gibb e4a4448497 Only deploy snapshots on master not in PR
fixes gh-630
2015-11-09 12:38:25 -07:00
Dave Syer 98d76dfe8c Correct path to magnfiying glass
It still isn't actually used (and would only be used on a link to
a non-existent JSP page), but at least it can render now.

See gh-628
2015-11-09 14:56:38 +00:00
Dave Syer 88cbeb015a Use better icon image for magnifying glass
Fixes gh-628
2015-11-09 14:15:38 +00:00
Spencer Gibb 2cf4a38398 Exclude commons-logging from eureka-client
fixes gh-525
2015-11-04 16:49:49 -07:00
Spencer Gibb 7eb5855815 fix resource filtering so it works with boot 1.3.x
get's eureka branding back.

fixes gh-627
2015-11-04 16:39:04 -07:00
Spencer Gibb d954a5c525 Merge pull request #621 from ametiste-oss/health-check-without-circuit-fails-fixed
Health check fails on commands without circuit breaker.
2015-11-04 15:26:01 -07:00
Spencer Gibb 509c8e9f13 polish 2015-11-04 14:54:51 -07:00
Spencer Gibb 4fdb85e678 Merge pull request #619 from jmnarloch/feign-parameter-processors
* feign-parameter-processors:
  Feign annotated parameter processors
2015-11-04 14:25:43 -07:00
Jakub Narloch 31d2f65528 Feign annotated parameter processors 2015-11-04 14:12:12 -07:00
Spencer Gibb 50efa8536d add optional DiscoveryClientOptionalArgs
For extensibility by connectors
2015-11-04 13:49:52 -07:00
Konstantin A. Zolotukhin 5d3a0da50e null check for command bound circuit breaker 2015-10-31 13:36:17 +02:00
Jakub Narloch 966e03ba64 Feign OkHttp client configuration 2015-10-22 12:04:09 -06:00
Dave Syer 22f4b82efa Revert profile and add comment 2015-10-20 09:34:47 -04:00
Dave Syer eb475769ca Remove confusing profile from settings.xml 2015-10-20 09:27:59 -04:00
Dave Syer d3000a23e9 Fix ordering problem with Zuul tests 2015-10-20 07:18:29 -04:00
Dave Syer 1fe28af3f0 Fix issue with forward:... routes
We have to ensure that the ZuulController is not mapped on a
forward otherwise we just go back through the same code
path and render nothing.
2015-10-20 06:46:31 -04:00
Spencer Gibb 6d5591020d Upgrade feign to 8.11.0
Adds support for feign-hystrix

fixes gh-606
2015-10-19 10:17:10 -06:00
Spencer Gibb 9e4cad750a Upgrade hystrix to 1.4.18
fixes gh-600
2015-10-19 09:27:33 -06:00
Spencer Gibb 248732e6ff Force isCircuitBreakerOpen to String (if it's a Boolean for example)
see https://github.com/Netflix/Hystrix/pull/927
2015-10-19 09:27:33 -06:00
Dave Syer cd30bea0c8 Add smarts for local route handling in Zuul proxy
User can provide a url in the route that starts with "forward:"
(instead of "http:" etc.) to handle the request locally.

Also properly ignores ignored routes, so they can be handled locally
(rather than giving up and sending 404).

Fixes gh-536
2015-10-18 09:59:06 -04:00
Dave Syer 43cab5f9b5 Clarify secure application discovery a bit 2015-10-18 09:22:12 -04:00
Spencer Gibb fa75ddf452 polish 2015-10-14 11:33:57 -06:00
Spencer Gibb ce4076621a Merge pull request #588 from alexVengrovsk/master
* pull588:
  Add isDebugEnabled() check
2015-10-13 11:07:37 -06:00
alexVengrovsk 914fee9ae4 Add isDebugEnabled() check
It is good thing to make this checks because of expensive concatenation of String objects (debug messages).
2015-10-13 10:43:43 -06:00
Spencer Gibb a3a7c60925 exclude commons-logging from ribbon
fixes gh-596
2015-10-13 09:57:38 -06:00
Spencer Gibb 8103bdbff8 revert zuul 1.1.0-rc.2 as it isn't published to maven central. 2015-10-12 12:43:26 -06:00
Spencer Gibb fc20cc7135 Upgrade zuul to v1.1.0-rc.2
fixes gh-591
2015-10-12 12:32:44 -06:00
Spencer Gibb 7fcc559edb Remove blitz4j
fixes gh-527
2015-10-12 12:08:34 -06:00
Spencer Gibb f878cfcf67 Polish 2015-10-12 11:25:27 -06:00
Spencer Gibb 3e0e47612c Do not require eurekaConfig.
Helps when eureka is on the classpath, but is explicitly disabled.

fixes gh-521
2015-10-12 11:16:08 -06:00
Spencer Gibb a96666b902 Move DiscoveryClient creation so it is guarded.
Move it back to EurekaDiscoveryClientConfiguration.

fixes gh-578
2015-10-12 10:26:09 -06:00
Spencer Gibb 5b3a9f8f31 Align feign logging.
Since all feign clients now have access to the type, logging can apply a type regardless.

Fixes gh-431
2015-10-09 17:07:01 -06:00
Spencer Gibb ef67fa328c Add local service to zuul ignoredServices by default.
fixes gh-447
2015-10-09 16:14:34 -06:00
Spencer Gibb 8058ced90d Remove dependency on governator.
Eureka now only directly depends on java.inject.

Fixes gh-529
2015-10-09 14:42:17 -06:00
Spencer Gibb 5f41de87d2 Polish 2015-10-09 14:00:24 -06:00
Spencer Gibb c051cb83d2 Merge pull request #585 from mbenson/master
* pull585:
  Fix feign scanning that fails if clients attr is not use
2015-10-09 12:21:40 -06:00
Matt Benson 568bc47b3e Fix feign scanning that fails if clients attr is not use
fixes gh-584
2015-10-09 12:21:17 -06:00
Spencer Gibb fe989530e3 remove reflection to set InstanceInfo.port 2015-10-09 12:00:40 -06:00
Spencer Gibb 51ea8afb24 Set port on InstanceInfo to support random server.port.
fixes gh-570
2015-10-09 11:47:56 -06:00
Spencer Gibb 5065e47565 Upgrade Hystrix to v1.4.17
fixes gh-576
2015-10-09 10:52:21 -06:00
Spencer Gibb 0cbfc20293 updated README 2015-10-08 17:08:00 -06:00
Spencer Gibb 2d595e86f3 remove extra punctuation 2015-10-08 16:21:52 -06:00
Spencer Gibb 82b21f34f5 Merge pull request #581 from jmnarloch/feign-compression-docs
* feign-compression-docs:
  Feign compression documentation
2015-10-08 16:12:24 -06:00
Jakub Narloch 68fa6afa17 Feign compression documentation 2015-10-08 16:12:05 -06:00
Spencer Gibb c5950df6e4 polish 2015-10-08 15:41:09 -06:00
Spencer Gibb d433096779 Merge pull request #577 from alexVengrovsk/master
* pull577:
  Use instanceof for better readability
2015-10-08 14:50:50 -06:00
alexVengrovsk e4b63a5b51 Use instanceof for better readability 2015-10-08 12:01:44 +03:00
Spencer Gibb 8147b7de51 Merge pull request #575 from alexVengrovsk/master
* pull575:
  Use "<>" and use isInfoEnabled
2015-10-07 13:01:38 -06:00
alexVengrovsk 4510f657b9 Use "<>" and use isInfoEnabled 2015-10-07 12:54:23 -06:00
Spencer Gibb 810502c1f3 Allow overriding default feign beans.
Similar to @RibbonClient

fixes gh-288
2015-10-05 14:57:27 -06:00
Spencer Gibb 0df6f0c0ae fix(title-xss): escaping text acquired from parameters to avoid any xss attacks
https://github.com/Netflix/Hystrix/pull/921
2015-10-05 09:29:12 -06:00
Dave Syer a7abfd4242 Upgrade to Zuul 1.1
Still a release candidate (not yet GA), but seems to work, so we'll
try and update before Spring Cloud is released again.

Fixes gh-546, fixes gh-567, fixes gh-553 (probably)
2015-10-03 08:26:57 +01:00
Dave Syer 5f84bcddd6 Align with package changes in Spring Cloud Config 2015-10-01 11:53:35 +01:00
Spencer Gibb 0c2c564be5 Merge pull request #490 from jmnarloch/feign-content-encoding-snapshot
* feign-content-encoding-snapshot:
  Feign request/response gzip compression
2015-09-30 12:17:41 -06:00
Jakub Narloch 8bdfaf2c3d Feign request/response gzip compression 2015-09-30 12:13:41 -06:00
Dave Syer 3ef58cdc39 Change DiscoveryClient->EurekaClient in docs 2015-09-30 11:34:34 +01:00
Dave Syer 17dc4f6f55 Update some dependencies 2015-09-30 11:34:34 +01:00
Spencer Gibb 65bf36ecf9 Upgrade hystrix to 1.4.16
fixes gh-561
2015-09-29 20:09:30 -06:00
Spencer Gibb 187af71535 move refs to EurekaInstanceConfigBean to interface.
Specifically CloudEurekaInstanceConfig where needed.

see gh-302
2015-09-29 11:32:04 -06:00
Dave Syer 4877de4916 Remove unused dependencies 2015-09-29 17:49:59 +01:00
Dave Syer c6fda88fed Support for ServerIntrospector in Feign client
Other Ribbon clients in Spring Cloud use a ServerIntrospector
to check if the Server wanted to be secure. This change levels things
up (and makes the Spring Feign Client a lit easier to customize).

See gh-414
2015-09-29 15:57:11 +01:00
Dave Syer 422bc42cf6 Be less greedy with logging request bodies in Zuul traces
Most clients send "Transfer-Encoding: chunked" so this isn't often
an issue, but if they don't (e.g. if you use "-H Expect:" with
curl) then it's not a great idea to slurp it all into memory.

Fixes gh-563
2015-09-29 09:43:16 +01:00
Dave Syer f1f239d774 Change hystrix command key to be the service ID in Zuul proxy
When using Ribbon the hystrix config and metrics are namespaced
as "RibbonCommand" (via the group key). the command key can then be
serviceId, making it easier to remember how to configure
Ribbon and Hystrix.

Fixes gh-329
2015-09-29 09:14:50 +01:00
Spencer Gibb 0141a13c92 Merge pull request #557 from boostrack-cloud/boostrack-patch-1
DRY
2015-09-28 15:58:59 -06:00
Spencer Gibb aa8626739e Introduce Ribbon ServerIntrospector.
Allows ribbon load balancer implementations to answer questions like isSecure(Server).
2015-09-28 15:10:38 -06:00
Spencer Gibb 3ed982d235 Introduce Ribbon ServerIntrospector.
Allows ribbon load balancer implementations to answer questions like isSecure(Server).
2015-09-28 12:51:39 -06:00
Dave Syer a38ba34049 Try to guess whether a ribbon client is looking for HTTPS
There are usually some hints available, especially if the Server
came from Eureka. Unfortunately Server on it's own doesn't contain
enough information (why?), but as a fallback we can guess that
anyone using port 443 is secure.

Fixes gh-459
2015-09-28 17:53:37 +01:00
boostrack 9c144220b1 DRY 2015-09-28 09:19:30 +02:00
Spencer Gibb b10bf9c305 Use eureka securePort if enabled for turbine http aggregation.
fixes gh-417
2015-09-25 17:08:15 -06:00
Spencer Gibb 7cf0fa4824 add support for HasFeatures 2015-09-25 16:08:37 -06:00
Spencer Gibb 0a2d1703f7 Update to new stream ChannelBindingServiceProperties 2015-09-25 16:07:51 -06:00
Spencer Gibb befcada46d formatting 2015-09-25 14:33:50 -06:00
Spencer Gibb d29839ea3f Merge pull request #555 from sfat/patch-1
Clicking running instances in eureka admin page
2015-09-25 10:04:52 -06:00
Andrei Sfat 60b437e2c5 Update eureka admin page
When click one of the up and running instances this should open the actual instance in separate tab
2015-09-25 15:42:18 +03:00
Dave Syer d1cb42946b Explicitly snag secure URL for config server if desired
If the configserver registers with securePortEnabled=true we should
respect that in the discovery process.

Fixes gh-450
2015-09-25 13:39:45 +01:00
Dave Syer 3697ce7fd9 Fix broken test (assumptions about eureka-first) 2015-09-25 13:29:44 +01:00
Spencer Gibb 0204978b36 Upgrade eureka to 1.2.5.
Change EurekaInstanceConfig.getSID to getInstanceId

fixes gh-554
2015-09-24 22:23:17 -06:00
Spencer Gibb da04c53726 use new commons code to provide hostInfo.
Set the default sid from common properties.
2015-09-24 17:20:31 -06:00
Jon Schneider 8f9acab3bd Update Eureka to 1.2.5-rc.1
Remove Servo from EurekaHealthIndicator.
Remove custom DataCenterInfo.
EurekaInstanceConfig.SID is now used as eureka id.
EurekaInstanceConfigBean.getSID falls back to metadataMap.instanceId for
backwards compatibility.
2015-09-24 15:34:17 -06:00
Dave Syer ded968ad58 Ensure changes to eureka metadata are relected on refresh
And also when using eureka-first for discovering config server.
The EurekaClient is very rigid and initializes itself, registering
with the remote service on instantiation. Hance it needs to be
in @RefreshScope for it to be properly refreshable. Doing that
leads to a sequence of other changes (e.g. to account for the
fact that there is no @RefreshScope in bootstrap context).

Fixes gh-551
2015-09-24 13:37:17 +01:00
Spencer Gibb 581e9bbd58 Upgrade Hystrix to 1.4.15
fixes gh-534
2015-09-23 15:40:13 -06:00
Dave Syer cf3ae735b2 Fix test (exclude commons refresh processing if not available) 2015-09-23 14:43:16 +01:00
Dave Syer 797544e668 Clean up eureka lifecycle
When the parent (bootstrap) context registers the app as well as consuming
the registry it causes problems, e.g. when you refresh that context is
re-created and destroyed, which tends to unregister the app and it's hard
to get it back. It is simpler if the parent context use eureka read-only.
To ensure this we have to remove the @EnableDiscoveryClient from the
bootstrap context.

Tested with vanilla config server and eureka with the 'eureka-first'
sample and the 'zuul-proxy-eureka' sample.

Fixes gh-421
2015-09-23 14:15:07 +01:00
Dave Syer eb8a902056 Ensure eureka client re-registers after config client activity
Reverts part of a change made for gh-349 and rationalizes a bit of the
Eureka configuration. The Eureka client cannot be shutdown without
attempting to restart it (but there isn't an obvious public API for
that), so it's better not to shut it down at all.

See gh-421
2015-09-23 13:02:15 +01:00
Dave Syer 61294659bf Add back (and deprecate) old 'amqp' poms 2015-09-23 09:46:49 +01:00
Spencer Gibb 0d92cb0803 allow defaults for spring-cloud-stream bindings 2015-09-22 16:15:54 -06:00
Spencer Gibb 639a87bfa1 Port *-amqp to spring-cloud-stream.
Move turbine/hystrix amqp specific implementations to spring-cloud-stream based implementations and let the user decide which broker to use.

fixes gh-545
2015-09-22 09:42:45 -06:00
Spencer Gibb 9e817a7dce Downgrade hystrix to 1.4.14
1.4.15 isn't in maven central yet
2015-09-14 13:07:25 -06:00
Spencer Gibb 1888a4496a Upgrade hystrix to 1.4.15
fixes gh-534
2015-09-14 12:58:45 -06:00
Spencer Gibb 741908155a Upgrade feign to 8.10.0
fixes gh-540
2015-09-14 12:55:13 -06:00
Spencer Gibb c15fb33fc2 add ResponseEntity<Void> feign test
see gh-539
2015-09-14 12:48:36 -06:00
Spencer Gibb 4037f4ca80 Add initialization of JsonXStream back.
fixes gh-535
2015-09-10 12:59:24 -06:00
Spencer Gibb d72c9f0dc4 make use of 'metadataMap.instanceId' consistent 2015-09-10 12:18:31 -06:00
Spencer Gibb bea48c5150 Merge pull request #515 from CPGFinanceSystems-master
* CPGFinanceSystems-master:
  Add X-Forwarded-Proto HTTP header to zuul proxy requests
2015-09-08 12:34:08 -06:00
Forstner Michael cbc7aa37f4 Add X-Forwarded-Proto HTTP header to zuul proxy requests
If the zuul reverse proxy and the destination services are using a different scheme
(for example HTTPS on proxy side and HTTP on service side) an additional HTTP
header is required according to RFC7239 [http://tools.ietf.org/html/rfc7239]
2015-09-08 12:20:16 -06:00
Spencer Gibb 46860e5c2c Merge pull request #519 from spring-cloud/adrian.feign-bump
Bumps to Feign 8.8.1
2015-09-08 11:48:15 -06:00
Dave Syer ee5b9c6382 Revert back to snapshot 2015-09-08 16:39:58 +01:00
Dave Syer a11a7709bf Bump to M1 2015-09-08 16:39:15 +01:00
Adrian Cole c25e950914 Bumps to Feign 8.8.1 2015-09-08 17:29:33 +02:00
Adrian Cole 12b8e52f70 Merge pull request #513 from spring-cloud/feign-eager-instantiation-problem
Change from @Autowired to context.getBean
2015-09-08 14:23:47 +02:00
Spencer Gibb f60cc6fb42 Change from @Autowired to context.getBean.
Solves problems where FeignClientFactoryBean is run before auto-configuration.

fixed gh-441
2015-09-04 15:22:48 -06:00
Spencer Gibb 67f0035885 update README from sources 2015-09-04 09:40:38 -06:00
Spencer Gibb a92307b060 Merge pull request #512 from geoand/doc-fix
Replaced incorrect @PathParameter with @PathVariable
2015-09-04 09:37:44 -06:00
Spencer Gibb b55832e5ef removed unused README 2015-09-03 17:41:34 -06:00
Spencer Gibb 304e836980 Merge pull request #509 from jmnarloch/eureka-healthcheck
* eureka-healthcheck:
  Eureka health check
2015-09-03 17:40:01 -06:00
Jakub Narloch c9008ea277 Eureka health check 2015-09-03 17:39:22 -06:00
gandrianakis 654ccf2dea Replaced incorrect @PathParameter with @PathVariable 2015-09-03 12:15:56 +03:00
Dave Syer 72c89c51e6 Fix autoconfig ordering so that health indicators always work 2015-09-02 13:27:49 +01:00
Spencer Gibb e31f41c2a9 Created StaticServerList and updated tests to use it. 2015-08-31 12:45:30 -06:00
Spencer Gibb aef6d2a326 Use localhost if non-loopback lookup fails 2015-08-31 12:11:42 -06:00
Spencer Gibb 62129c72c2 fix condition for selfPreservationMode 2015-08-25 16:32:02 -06:00
Dave Syer 80f2735ea5 Merge branch '1.0.x'
Conflicts:
	.travis.yml
2015-08-25 15:13:20 +01:00
Dave Syer 7fc9811975 Use TRAVIS_BRANCH if available 2015-08-25 14:52:31 +01:00
Dave Syer b3ca7430b0 Move ghpages to script 2015-08-25 14:15:51 +01:00
Dave Syer 00cc64c6c5 Different special treatment of README 2015-08-25 14:04:43 +01:00
Dave Syer c905822005 Special treatnment of README 2015-08-25 12:56:15 +01:00
Dave Syer 56fae9330f Try to debug CI failures 2015-08-25 12:44:08 +01:00
Dave Syer c1cb0025c1 Use subdirectory for gh pages docs 2015-08-25 12:37:15 +01:00
Dave Syer 89ebf1fa3f Fix ghpages script to work on branches 2015-08-25 12:29:41 +01:00
Dave Syer ddd1b35b71 Merge branch '1.0.x' 2015-08-25 11:13:46 +01:00
Dave Syer ad86d48c6a Use HttpHeaders for headers (case insensitive)
Fixes gh-306
2015-08-25 11:13:29 +01:00
Spencer Gibb e8b0e613fc Merge pull request #501 from ghillert/master
Replace XD logo with a Eureka logo
2015-08-24 12:52:18 -06:00
Gunnar Hillert b1dffe00e7 Replace XD logo with a Eureka logo
* Fixes gh-310
2015-08-24 14:41:32 -04:00
Spencer Gibb b494e1d2cc refactor RibbonCommand to an interface and factory
lays the groundworkd to implement an httpclient ribbon command

fixes gh-412
2015-08-21 11:36:24 -06:00
Spencer Gibb ec22bf21eb Added LICENSE.txt 2015-08-20 16:11:18 -06:00
Roy Clarkson 56d0570674 Fix whitespace and formatting 2015-08-20 14:32:38 -05:00
Spencer Gibb 913091a716 added test for lists of request parameters 2015-08-19 10:52:01 -06:00
Adrian Cole b943a94b33 Merge pull request #494 from spring-cloud/adrian.5percent-more-ribbon
Updates to Ribbon 2.10
2015-08-19 08:27:45 -07:00
Adrian Cole 691771a13d Updates to Ribbon 2.10
Synchronizes on the version in use by Feign.

Closes #4920
2015-08-18 21:46:28 -07:00
Spencer Gibb a82a1734ce Merge pull request #493 from spring-cloud/adrian.may-the-poms-be-with-you
Consolidates references to parent pom
2015-08-18 19:10:14 -06:00
Adrian Cole 54607135b6 Consolidates references to parent pom
Some projects were failing on `./mvnw install` due to a non-existent
local path. This makes all poms use the same approach.
2015-08-18 17:49:07 -07:00
Dave Syer 67748d6626 Update readmes 2015-08-14 11:09:53 +01:00
Dave Syer cb5a8c107d Add Maven wrapper 2015-08-14 10:05:52 +01:00
Spencer Gibb d64cfa5cad polish 2015-08-13 16:40:50 -06:00
Spencer Gibb b7bcdddacd add DiscoveryClientOptionalArgs constructor param to CloudEurekaClient 2015-08-13 15:41:53 -06:00
Spencer Gibb d24bff02f3 Merge pull request #486 from steve-oakey/gh-337
* gh-337:
  Detect https from Ribbon Client Config
2015-08-12 15:36:04 -06:00
Stephen Oakey c883495f8a Detect https from Ribbon Client Config
RibbonLoadBalancer and RibbonLoadBalancer use IClientConfig IsSecure
property for service ID to determine if the service is secure. Replaces
scheme of URI of request with https if the request is secure.

fixes gh-337
2015-08-12 15:35:39 -06:00
Spencer Gibb ddb09c499b Merge pull request #485 from jghiloni/master
* pull485:
  Make `isSecure()` match `getPort()` in secure vs non-secure resolution
2015-08-11 18:18:53 -06:00
Josh Ghiloni 539ca47bab Make isSecure() match getPort() in secure vs non-secure resolution 2015-08-11 15:14:04 -06:00
Spencer Gibb 9e40714e3c Use the first non-loopback address for host/ip addr
fixes gh-468
2015-08-07 18:17:59 -06:00
Spencer Gibb 512d687615 Update feign to 8.7.1
fixes gh-479
2015-08-07 15:18:02 -06:00
Spencer Gibb b9d1d5e697 Merge pull request #478 from jkschneider/early-eureka-client
* early-eureka-client:
  make EurekaClient available before smart lifecycle phase 0
2015-08-07 14:15:27 -06:00
Jon Schneider 191a1ccc35 make EurekaClient available before smart lifecycle phase 0 2015-08-07 14:14:54 -06:00
Spencer Gibb c39efb96bd Merge pull request #460 from jmnarloch/eureka-docs
Corrected docs for the 'context-path' property reference.
2015-08-06 09:27:55 -06:00
Spencer Gibb 246830c9d3 Upgrade to Eureka 1.2.0
Implements forwarding of eureka CacheRefreshedEvent as HeartbeatEvent,
rather thank serialization hack.  Uses new Eureka DI functionality
(mostly there, some issues). Updates EurekaJacksonCodec to be
"DataCenterAware". Reference EurekaClient interface rather than
DiscoveryClient class.

fixes gh-349
2015-08-05 13:37:36 -06:00
Spencer Gibb e7a767e042 Make RxJavaAutoConfiguration ConditionalOnClass AsyncHandlerMethodReturnValueHandler
so non-web apps don't break

fixes gh-475
2015-08-05 10:39:08 -06:00
Spencer Gibb 5fb3040a80 Merge pull request #456 from jmnarloch/feign-inheritance
* feign-inheritance:
  Updated documentation for Feign hierarchical clients
2015-08-04 11:16:28 -06:00
Jakub Narloch 69c3723aac Updated documentation for Feign hierarchical clients 2015-08-04 11:16:04 -06:00
Spencer Gibb 5ac5f198aa Support returning Observable from Spring MVC Controllers.
Via spring 4.2 new AsyncHandlerMethodReturnValueHandler

fixes gh-231
2015-07-30 14:05:46 -06:00
Spencer Gibb a2270dc27a Upgrade to Hystrix 1.4.13
Also brings in patches to the hystrix dashboard.

fixes gh-465
2015-07-27 16:52:04 -06:00
Spencer Gibb e5e677c0ad remove https port 8443 registration.
It overwrote the port 443 registration.

fixes gh-461
2015-07-27 15:00:49 -06:00
Spencer Gibb 79f939bec5 Merge pull request #455 from jmnarloch/service-path
* service-path:
  Specifing only the serviceId causes NPE
2015-07-27 14:08:27 -06:00
Jakub Narloch 798a19e468 Specifing only the serviceId causes NPE 2015-07-27 14:08:00 -06:00
Spencer Gibb 371f8b3bf2 feign polishing 2015-07-27 12:05:11 -06:00
Dave Syer b0b4916d3c If user configures hostname for eureka client, do not refresh it
Fixes gh-463
2015-07-27 17:55:01 +01:00
Spencer Gibb cb732763b5 Merge pull request #464 from andreasevers/zuul-ignored-patterns
* zuul-ignored-patterns:
  If more fine-grained ignoring is needed, you can specify specific patterns to ignore. These patterns are being evaluated at the end of the route location process, which means prefixes should be included in the pattern to warrant a match. Ignored patterns span all services and supersede any other route specification.
2015-07-27 10:43:40 -06:00
andreasevers 42f6e4d1f0 If more fine-grained ignoring is needed, you can specify specific patterns to ignore. These patterns are being evaluated at the end of the route location process, which means prefixes should be included in the pattern to warrant a match. Ignored patterns span all services and supersede any other route specification.
zuul:
  ignoredPatterns: */admin/**
  routes:
    users: /myusers/**

This means that all calls such as "/myusers/101" will be forwarded to "/101" on the "users" service. But calls including "/admin/" will not resolve.
2015-07-27 10:27:43 -06:00
Jakub Narloch 59534a2447 Corrected docs for the 'context-path' property reference. 2015-07-26 18:53:10 +02:00
Spencer Gibb 558c78353c Merge pull request #448 from Sounie/master
Corrected typo in spelling of registration.
2015-07-24 13:14:02 -07:00
Stephen Souness 2cf2de3465 Corrected typo in spelling of registration. 2015-07-21 09:38:51 +01:00
Dave Syer 5bb778811f Merge branch '1.0.x' 2015-07-18 10:37:09 +01:00
Biju Kunjummen 2c688062e7 Clarified the way to add a custom EurekaInstanceConfigBean for AWS deployment 2015-07-18 10:36:51 +01:00
Spencer Gibb a6b94a38fe Add support for using Apache HttpClient with Feign
fixes gh-415
2015-07-15 17:23:41 -06:00
Spencer Gibb 22ed881805 Merge pull request #434 from qbast/master
* pull434:
  Build query string from context instead of original request
2015-07-14 09:44:24 -06:00
Jakub Stachowski dd1c5bb495 Build query string from context instead of original request
Recreate query string from either getCurrentContext().getRequestQueryParams()
or original request as fallback. This allows to override query string
params in pre filters.

fixes gh-426
2015-07-14 09:43:52 -06:00
Spencer Gibb 335481563f Merge pull request #437 from jmnarloch/feign-8.6.0
* feign-8.6.0:
  Updated feign version to 8.6.0
2015-07-13 13:18:08 -06:00
Jakub Narloch 0a34ad88f5 Updated feign version to 8.6.0 2015-07-13 20:49:18 +02:00
Spencer Gibb 9149319bd7 implement getHostName where refresh==true 2015-07-10 13:27:42 -06:00
Spencer Gibb aa63b072ae Merge pull request #427 from ericbottard/patch-2
Remove unfinished sentence
2015-07-10 10:18:12 -06:00
Spencer Gibb ffa2f27878 Merge pull request #428 from ericbottard/patch-3
Fix escaping
2015-07-10 10:17:43 -06:00
Spencer Gibb 69543470fa Merge pull request #429 from ericbottard/patch-4
Fix minor typo in doc
2015-07-10 09:40:52 -06:00
Ryan J Baxter 3a22a5e702 Fixes #314.
Should be approximateZoneFromHostname instead of approximateZoneFromDomain.
2015-07-10 09:33:02 -06:00
Eric Bottard 06bb00172e Fix minor typo in doc 2015-07-10 15:12:37 +02:00
Eric Bottard 8c2b186b67 Fix escaping 2015-07-10 14:29:17 +02:00
Eric Bottard e90824bfab Removed unfinished sentence 2015-07-10 14:08:13 +02:00
Dave Syer f682c42001 Merge branch '1.0.x' 2015-07-10 11:48:36 +01:00
Ryan J Baxter f4a69e43eb Sets the zone based on the hostname of the service if approximateZoneFromHostname is true.
The flag has always been there, it just isn't carried through to the ribbon client configuration
without this change if I understand this change correctly.

Fixes gh-315, fixes gh-423.
2015-07-10 11:47:35 +01:00
Spencer Gibb 206a5a029d Merge pull request #424 from ericbottard/patch-1
Fix grammar issue in doc
2015-07-09 14:03:14 -06:00
Eric Bottard 57cefb2591 Fix grammar issue in doc 2015-07-09 14:36:53 +02:00
Spencer Gibb ee97ef626f push versioning of turbine down to modules.
fixes https://github.com/spring-cloud-samples/turbine/issues/3
2015-07-08 14:17:40 -06:00
Spencer Gibb 5c18b02cb8 Merge pull request #420 from jmnarloch/docs
Fixed typo in ignoredServices
2015-07-07 17:31:33 -06:00
Jakub Narloch d0a82c1421 Fixed typo in ignoredServices 2015-07-06 21:13:27 +02:00
Dave Syer 91d288d781 Update to Spring Boot 1.3, stage I (make it compile) 2015-07-03 09:54:16 +01:00
Dave Syer d046791b3e Move starters into home projects 2015-06-26 15:09:53 +01:00
Dave Syer 9a45beec1d Update to Brixton 2015-06-26 12:57:06 +01:00
Dave Syer 3519ecf224 Prepare master for next snapshot 2015-06-26 10:57:19 +01:00
Dave Syer 72cecacea7 Fix path to docs in README raw text 2015-06-25 12:31:29 +01:00
Dave Syer e17766e916 Add dependency management for starters 2015-06-25 11:46:01 +01:00
Dave Syer 29841f9f57 Revert "add optional spring-security-rsa"
This reverts commit 06d4d1e158.
2015-06-24 20:24:50 +01:00
Spencer Gibb 06d4d1e158 add optional spring-security-rsa 2015-06-24 11:42:46 -06:00
Dave Syer a903b5d58c Fix guava imports 2015-06-24 17:31:06 +01:00
Dave Syer 25651f4835 Add sidecar to BOM 2015-06-24 17:23:39 +01:00
Spencer Gibb bab74edf89 Merge pull request #340 from kaczynskid/master
Corrected example of providing Turbine cluster name via instance metadata map
2015-06-23 15:06:45 -04:00
Dave Syer 652e4b96b3 Nail explicit dependencies for s-c-context 2015-06-23 17:58:59 +01:00
Spencer Gibb 34eb36323a Merge pull request #390 from heyjustin/master
Mark an instance as DOWN when the application context is stopped.
2015-06-23 12:00:30 -04:00
Spencer Gibb 12bee7772f Merge pull request #408 from brandon-atkinson/zuul-unescaped-paths
* zuul-unescaped-paths:
  Fix unescaped paths in SimpleHostRoutingFilter.
2015-06-23 09:57:26 -06:00
Brandon Atkinson 283c0f7600 Fix unescaped paths in SimpleHostRoutingFilter.
Move common code so RibbonRoutingFilter can use the same code.

Fixes gh-407
2015-06-23 09:56:46 -06:00
Spencer Gibb 0b925e5afa Merge pull request #409 from brandon-atkinson/issue-394-remove-deflate
* issue-394-remove-deflate:
  Removed deflate accept-encoding from outbound requests
2015-06-23 09:51:01 -06:00
Brandon Atkinson 80206e6b38 Removed deflate accept-encoding from outbound requests 2015-06-23 09:50:14 -06:00
Bertrand Renuart 58284a4508 Change Jersey init to avoid classpath scanning issues
Scan classpath for Jersey resources with Spring and initialize the
Jersey filter with a jaxrs Application instead. (Fixes gh-399,
fixes gh-400)
2015-06-23 13:00:38 +01:00
Bertrand Renuart 2ba5c4b9ec gh327: explicitly close the HttpResponse in case of timeout 2015-06-11 13:14:50 -06:00
Justin Walsh 69eaa27ccc Mark an instance as DOWN when the application context is stopped.
Fixes gh-377
2015-06-10 10:37:53 +02:00
Spencer Gibb 440779bcf0 Revert "attempt ordering of RibbonClients.defaultConfiguration's"
This reverts commit 0d468b3930.
2015-06-08 14:56:23 -06:00
Spencer Gibb 0d468b3930 attempt ordering of RibbonClients.defaultConfiguration's
ref gh-383
2015-06-08 14:55:22 -06:00
Spencer Gibb 0f2fbf8e1c fixed test broken during rebase 2015-06-08 14:02:17 -06:00
Spencer Gibb b746ad5504 Fix name of default ribbon config if config is not in an eclosing class
fixes gh-374
2015-06-08 13:44:07 -06:00
Dave Syer a63b825690 Add call to Lifecycle.stop()
See gh-377
2015-06-08 06:33:45 +01:00
Spencer Gibb ce96c83401 updated README from sources 2015-06-05 11:16:33 -06:00
Spencer Gibb aa002b56c4 fixed canceled leases template var referencec
fixes gh-375
2015-06-05 09:00:54 -06:00
Spencer Gibb fa84108ebf fix swapped default values
fixes gh-372
2015-06-02 13:21:29 -06:00
Spencer Gibb a23131f094 upgrade hystrix to 1.4.10
fixes gh-370
2015-06-02 08:33:33 -06:00
Spencer Gibb a0d72b3cbc removed test with encoded slashes 2015-06-02 08:33:32 -06:00
Dave Syer 23cde30063 Align metrics with Spring Boot 1.3
Should be no change for users of Boot 1.2 right now, but with this
patch it is possible to use 1.3 with the new conventions for metrics
(e.g. in particular exporting by declaring beans of type
MetricWriter)
2015-06-02 15:29:08 +01:00
Spencer Gibb 899a577980 add test for zuul with encoded path parameter 2015-06-01 14:44:54 -06:00
Spencer Gibb 682ceec402 Merge branch 'brenuart-gh354b' 2015-05-28 09:02:07 -06:00
Spencer Gibb 68c731d668 added test for metrics with period in name 2015-05-28 09:01:53 -06:00
Spencer Gibb 1a6602149d Merge branch 'gh354b' of https://github.com/brenuart/spring-cloud-netflix into brenuart-gh354b 2015-05-28 08:43:23 -06:00
Spencer Gibb dbef27ac6b more RibbonClient tests 2015-05-28 08:32:01 -06:00
Bertrand Renuart 28f890989d Allow for periods in metric name (see gh354) 2015-05-28 09:48:28 +02:00
Dave Syer bd808a76fa Add health.config for documentation purposes only 2015-05-27 10:27:02 +01:00
Spencer Gibb 2559b76747 fixed typo 2015-05-26 10:56:57 -06:00
Spencer Gibb 4255179354 use io.reactivex:rxjava
fixes gh-353
2015-05-20 12:35:49 -06:00
Spencer Gibb bd5d00c082 encode uri if needed
fixes gh-347
2015-05-18 21:51:58 -06:00
Spencer Gibb 8bb578ad97 update ServerMetricCollector to include instance and statistic tags if present.
fixes gh-348
2015-05-18 20:53:55 -06:00
Spencer Gibb 3bb1562b7f fix RibbonClientHttpRequestFactory to add headers and accept a body
fixes gh-350
2015-05-15 12:26:32 -06:00
Spencer Gibb 68b0c91fa7 document disabling of zuul filters
fixes gh-341
2015-05-11 10:08:06 -06:00
Darek Kaczyński 8fa9b71579 Corrected example of providing Turbine cluster name via instance metadata map. 2015-05-07 00:02:03 +02:00
Spencer Gibb 532cfd9bda Merge pull request #336 from marcingrzejszczak/patch-2
Fixed a typo in the doc
2015-05-06 15:20:16 -04:00
Marcin Grzejszczak 94081f82ce Fixed a typo 2015-05-05 23:49:49 +02:00
Spencer Gibb ed692c3836 document that build requires jdk8
fixes gh-328
2015-05-05 11:42:09 -06:00
Spencer Gibb e3b42e79b6 fix misspelling 2015-05-05 10:54:59 -06:00
Spencer Gibb 688b577d63 Merge pull request #334 from marcingrzejszczak/patch-1
Reason why Eureka instance is not found, is not visible
2015-05-05 11:43:32 -04:00
Spencer Gibb 85b7ccf618 Merge pull request #316 from brenuart/issue-312
Make creation of the RestClient LAZY as it is no always required (issue #312)
2015-05-04 16:26:17 -04:00
Marcin Grzejszczak eed9b996fb Reason why Eureka instance is not found is not visible
With the following configuration at `bootstrap.yaml`

```yaml

spring:
  application.name: spring-cloud-hystrix-dashboard
  profiles.active: prod
  cloud:
    config:
      discovery:
        enabled: true
        serviceId: spring-cloud-server-config-with-eureka
server.port: 9003

turbine:
  appConfig: some-service
  clusterNameExpression: 'default'
```

I wasn't able to see why Turbine can't find the instance. The reason was related to SPEL:

```
org.springframework.expression.spel.SpelEvaluationException: EL1008E:(pos 0): Property or field 'default' cannot be found on object of type 'com.netflix.appinfo.InstanceInfo' - maybe not public?
```

Anyways there was nothing there in the logs so maybe it should not be silenced like right now?
2015-05-04 16:55:11 +02:00
Dave Syer 3809bcbc90 More 1.0.2 snapshots 2015-05-01 16:24:20 +01:00
Dave Syer 0587df4ae2 Fix parent version 2015-05-01 16:19:51 +01:00
Dave Syer 53c0e0a246 Fix parent version 2015-05-01 16:19:21 +01:00
Dave Syer bad44ec8ab Fix parent version 2015-05-01 16:15:48 +01:00
Dave Syer fde4741333 Update to 1.0.3 snapshots 2015-05-01 11:22:13 +02:00
Dave Syer c77322348c Add example for SEMAPHORE in @HystrixCommand 2015-05-01 11:20:21 +02:00
Spencer Gibb c3f5678854 only invoke RestClient.initWithNiwsConfig once
fixes gh-324
2015-04-30 12:56:38 -06:00
Spencer Gibb 5166994f7c add documentation for ribbon.eureka.enabled
fixes gh-325
2015-04-30 09:42:28 -06:00
Spencer Gibb ce6d286d70 Don't execute load balancer twice
fixes gh-323
2015-04-29 22:20:10 -06:00
Bertrand Renuart df8c637a57 add short explanation in javadoc 2015-04-28 11:26:50 +02:00
Bertrand Renuart e2fa45f960 Make creation of the RestClient LAZY as it is no always required (see
https://github.com/spring-cloud/spring-cloud-netflix/issues/312)
2015-04-24 09:32:26 +02:00
Dave Syer b28fd07cdb Update to 1.0.2 snapshots 2015-04-23 11:11:21 +01:00
Dave Syer 22c261c8ce Update connectors version 2015-04-22 11:40:25 +02:00
Spencer Gibb 3e98c78c12 add PATCH to SimpleHostRoutingFilter
fixes gh-307
2015-04-17 11:49:51 -06:00
Spencer Gibb 6dce075e99 upgrade to feign 8.1.1 which includes a fixes bad urls
fixes 305
2015-04-17 10:08:21 -06:00
Spencer Gibb 3d9e998a01 fix missing jersey apache4client 2015-04-16 14:49:12 -06:00
Spencer Gibb 55a8195a67 throw more descriptive error if no ServiceInstance is found 2015-04-16 14:48:38 -06:00
Dave Syer 936a3b334e Set explicit cookie policy in HTTP client in RibbonClientConfiguration
When the Apache HTTP client is being set up for the Ribbon client we can jump
in and explicitly set a cookie policy. Obviously, since the client will generally
be shared across sessions, the only sensible default is IGNORE_COOKIES.

I couldn't find a way round this without using deprecated APIs (but there
are other instances of that in our code because of the way Netflix uses
it, so maybe that doesn't matter).

Fixes gh-301
2015-04-16 13:28:37 +01:00
Spencer Gibb 1799809562 Merge branch 'hystrix-144' 2015-04-14 13:28:03 -06:00
Chad Jaros 38e25f390f Support for @RequestMapping on class and ResponseEntity return types 2015-04-14 09:54:43 -06:00
Spencer Gibb a765839771 upgrade hystrix to 1.4.4 and integrate dashboard changes
fixes gh-300
2015-04-14 08:58:18 -06:00
Spencer Gibb 20da63c238 Merge pull request #299 from royclarkson/dashboard-cf-fix
Ignore 'Connection: close' header from stream response
2015-04-13 16:48:16 -04:00
Roy Clarkson 408910e893 Ignore 'Connection: close' header from stream response
This commit resolves an issue where some versions of Cloud Foundry are
setting the 'Connection: close' HTTP header in the Hystrix stream
response, which causes the dashboard to not display the stream data.

See https://github.com/cloudfoundry/gorouter/issues/71
2015-04-13 15:19:16 -05:00
Spencer Gibb 45449cfb84 polish 2015-04-13 12:50:45 -06:00
Alexandru Burghelea 611c0b5c1c Added posibility to append archaius configuration to existing installed configurations 2015-04-13 12:50:45 -06:00
Spencer Gibb 9699664e09 Merge pull request #294 from joshiste/master
Docs: Example of static, loadbalanced Zuul configuration
2015-04-13 10:40:59 -04:00
Spencer Gibb 3279ae601f Merge pull request #298 from joshiste/exlude-mockito-all
Exlude mockito all
2015-04-13 10:40:53 -04:00
Roy Clarkson e1b6ddf563 Format whitespace 2015-04-13 08:40:15 -05:00
Johannes Stelzer 242419726d Exclude mockito-all from zuul-core and turbine-core
However turbine and zuul are depending on mockito-all in compile-scope. Not only I want to get rid of these (usually) test-dependencies, but also mockito-all contains some hamcrest-classes (in older versions) getting in conflict with the classes from spring-test
2015-04-11 16:59:19 +02:00
Spencer Gibb 3794213aaf add a note about the Spring Cloud DiscoveryClient.
fixes gh-276
2015-04-06 15:12:38 -06:00
Johannes Stelzer 6a0737dacf Example of static, loadbalanced Zuul configuration
It took me quite a bit, to figure out how to configure Zuul to use a loadbalanced route without Eureka. I hope this short explicit example will clarify it for other people.
2015-04-02 20:33:05 +02:00
Dave Syer 873854810a Fix eureka instance metadata in Cloud Foundry example 2015-04-02 13:45:05 +01:00
Dave Syer 555b1f1c06 Use UrlPathHelper to determine the current url path in Zuul
If the app has a context path then the route locator does not match
the whole requestURI (as provided by the raw servlet API), but Spring
has a utility for stripping it off, so we can just use that.

Fixes gh-270
2015-04-01 12:05:05 +01:00
Dave Syer 5961931caf Make /error path a special case in ZuulHandlerMapping
If there is a default route (/**) then the ZuulHandlerMapping will
mask the /error path in a normal Spring Boot application. This change
makes it a special case so that ZuulHandlerMapping will never map
the /error route (the one specified by the ErrorController).

Fixes gh-284
2015-04-01 11:50:33 +01:00
Spencer Gibb 814f7e9283 added warn logging to hystrix dashboard proxy servlet 2015-03-27 10:57:03 -06:00
Spencer Gibb 20bb1af655 added debug logging to hystrix dashboard proxy servlet 2015-03-27 10:11:53 -06:00
Roy Clarkson 370ce804e3 Update docs to use @EnableCircuitBreaker 2015-03-27 10:44:06 -05:00
Spencer Gibb 2d18706219 updated to use RestTemplateCustomizer 2015-03-26 11:45:37 -06:00
Spencer Gibb 8bfef044d2 fixed bad class name 2015-03-26 11:45:37 -06:00
Spencer Gibb 28db47c72a move RibbonClientHttpRequestFactory to configuration conditional on netflix httpclient classes 2015-03-26 11:45:37 -06:00
Spencer Gibb 55d46eb6c7 add support for ribbon http client in RestTemplate.
fixes gh-280
2015-03-26 11:45:37 -06:00
Dave Syer 5f9c3e6073 Ensure management.port=-1 switches off actuator endpoints in turbine 2015-03-26 09:37:50 +00:00
Dave Syer 3714cee51d Clarify impact of @ComponentScan on @RibbonClient
Fixes gh-281
2015-03-26 09:36:27 +00:00
Dave Syer d0021f0415 Clarify turbine config
Also fixes gh-277 (metioning starters explicitly).
2015-03-25 09:42:00 +00:00
Spencer Gibb f5b6c58f30 upgrade hystrix to 1.4.1
fixes gh-279
2015-03-24 13:44:29 -06:00
Spencer Gibb f0d8c86b51 Only call shutdown() if DiscoveryClient is not null.
fixes spring-cloud-samples/tests/issues/2
2015-03-24 13:21:46 -06:00
unknown 76d0c018ee Ensure ZuulProperties.servletPath is applied to routes
Fixes gh-271, fixes gh-272
2015-03-24 13:17:43 +00:00
Dave Syer e60a0fc4fb Re-initialize DiscoveryClient if config client is in "eureka-first"
This was kind of ugly, and caused a static usage of the eureka
DiscoveryCLient to become necessary again, just so the @Bean that is
provided for the user stays accurate (it has to be the one in the main
application context, even if the parent boot strap has different
instance metadata).

I tested with a vanilla Eureka server and config server, and used the
client in tests/eureka-first.

Fixes gh-268
2015-03-23 16:53:50 +00:00
boostrack 9dc2821bc9 Small fixes to typos in docs
Fixes gh-274
2015-03-21 12:43:07 +00:00
Spencer Gibb 924363ca1c Sidecar reports true non-jvm app status to eureka.
Added a LocalApplicationHealthCheckHandler that checks the local app and sends the appropriate status to eureka.

fixes gh-251
2015-03-20 13:25:58 -06:00
Spencer Gibb 3515112cb2 move RestTemplate docs to s-c-commons 2015-03-20 13:00:19 -06:00
Dave Syer cdc5681694 Clarify role of filter beans in @EnableZuulProxy 2015-03-20 14:48:39 +00:00
Dave Syer 3ba7cfbff2 Add link to github in rendered docs 2015-03-20 11:47:28 +00:00
Dave Syer 1c54e6b937 Add annotation processor 2015-03-20 11:47:27 +00:00
Spencer Gibb 869e3ec92f upgrade to feign 8.1.0
removes ugly dagger dependency

fixes gh-183
2015-03-19 12:13:11 -06:00
Spencer Gibb edbb0acc7c Merge pull request #266 from warmuuh/patch-1
updated documentation of HystrixHealthIndicator
2015-03-19 11:20:47 -04:00
Peter 98ac81bda2 updated documentation of HystrixHealthIndicator
documentation was not conform to specified behavior as in #24
2015-03-19 14:43:12 +01:00
Dave Syer 444f3c8010 Feign client builder should not assume all annotations are the same
Simple solution is to check for instanceof before casting.

Fixes gh-265
2015-03-19 12:13:19 +00:00
Dave Syer b03b2f5629 Add ping stream to turbine AMQP
This change adds more data to the stream with {"type":"Ping"}
so (I believe) the existing dashboard client will discard it,
but stay alive.

Fixes gh-264
2015-03-18 17:03:25 +00:00
Dave Syer 72a182c914 Make turbine AMQP into an application (optional) 2015-03-18 15:55:08 +00:00
Dave Syer da24fa6d20 Refactor for config client stuff moving to commons 2015-03-18 15:42:41 +00:00
Dave Syer 369a00cb71 Validate hostname (serviceId) in @FeignClient
Since hostnames ahve quite strict syntax (e.g. no underscores) we should
validate the feign client name to prevent nasty surprises at runtime.

Fixes gh-263
2015-03-18 10:35:57 +00:00
Dave Syer 3445d093c7 Fix RabbitAdmin so it actually finds the Declarables 2015-03-17 16:08:57 +00:00
Spencer Gibb f3ced9e0ed allow zuul to have multiple values for each named header
fixes gh-260
2015-03-16 15:19:07 -06:00
Dave Syer cc2159f77b Use separate RabbitAdmin to declare queues and exchanges
Fixes gh-259
2015-03-16 14:57:58 +00:00
Dave Syer 9fe69cc80a Merge pull request #258 from sampengilly/master
Added additional Gradle tip to Eureka Server documentation.
2015-03-16 13:31:45 +00:00
sampengilly a2b0b70b55 Added additional Gradle tip to Eureka Server documentation. Tip covers the usage of the spring dependency management plugin in order to prevent fatal crashes during application startup. 2015-03-16 21:05:52 +10:00
Dave Syer 9357bdd9db Remove log4j notes since Eureka no longer requires it 2015-03-13 17:15:08 +00:00
Dave Syer 0391cfff65 Allow streaming of multipart requests in Zuul proxy
It turns out that the suckiness of Zuul with multipart requests
comes almost entirely from the Multipart handling in Spring's
DispatcherServlet. This change makes the proxy routes available
on an alternative path /zuul/<normal_path> (where
/zuul is the default value of zuul.servletPath). I have
tested those with 800MB file uploads using the main method in
the FormZuulServletProxyApplicationTests and the main
observation is that there is no OutOfMemory error (no-one tries
to download the complete request body). It works with Ribbon
and with the simple (HttpClient) filter. With Ribbon you
will need to set some timeouts if you want to upload files
as large as that, e.g. see application.yml in the tests:

hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 60000
ribbon:
  ConnectTimeout: 3000
  ReadTimeout: 60000

You need to set "Transfer-Encoding: chunked" in the
incoming request. Chrome does not do this by default
apparently, but I was able to test with curl, e.g.

$ curl -v -H "Transfer-Encoding: chunked" \
  -F "file=@mylarg.iso" \
  localhost:9999/zuul/direct/file

The old proxy paths through the DispatcherServlet are still
available (for backwards compatibility and for convenience of
having the paths available at the root of the context path).

Fixes gh-254
2015-03-13 16:55:30 +00:00
Dave Syer da4f5d3454 Fix issue with servlet request wrappers in Zuul
Because of the way that a FormBodyServletRequestWrapper was
implemented (extending the Zuul servlet 2.5 wrapper) it could
barf at runtime if anyone called its servlet 3.0 methods. The fix
for that was to extract our Servlet30RequestWrapper and extend that
instead.

Also tweaked the DebugFilter a bit so it doesn't try and display
the whole payload. Probably speeds up file uploads a bit but the
fact that we have to store the whole request body in memory is
going to kill us eventually.

See gh-254
2015-03-13 13:07:33 +00:00
Spencer Gibb e2583f5380 upgrade Ribbon to version 2.0.0.
From 2.0.RC13

fixes gh-216
2015-03-06 12:47:27 -07:00
Spencer Gibb df7abd1bc9 added test ReadTimeout parameter 2015-03-06 12:20:02 -07:00
Dave Syer 164c9f8755 Add bintray properties 2015-03-06 10:48:29 +00:00
Spencer Gibb 384fad6c40 wrap SpringLBClientFactory in a CachingLBClientFactory so LBClients are reused.
fixes gh-240
2015-03-05 12:39:22 -07:00
Spencer Gibb 4bd7c3bdcf upgrade feign to 7.3.0
fixes gh-243
2015-03-05 11:42:09 -07:00
Spencer Gibb 4e795ea783 upgrade hystrix to 1.4.0
fixes gh-242
2015-03-03 17:23:26 -07:00
Dave Syer e3a20d5d6b Update to next snapshot 2015-03-03 14:56:26 +00:00
728 changed files with 62355 additions and 8531 deletions
+42
View File
@@ -0,0 +1,42 @@
version: 2
jobs:
build:
docker:
- image: springcloud/pipeline-base
user: appuser
environment:
_JAVA_OPTIONS: "-Xms1024m -Xmx2048m"
TERM: dumb
branches:
ignore:
- gh-pages # list of branches to ignore
resource_class: large
steps:
- checkout
- restore_cache:
key: sc-netflix-{{ .Branch }}
- run:
name: "Download dependencies"
command: |
cd spring-cloud-netflix-hystrix-contract && ../mvnw clean install && \
./mvnw -s .settings.xml -U --fail-never dependency:go-offline || true
- save_cache:
key: sc-netflix-{{ .Branch }}
paths:
- ~/.m2
- run:
name: "Running build"
command: ./mvnw -s .settings.xml clean org.jacoco:jacoco-maven-plugin:prepare-agent install -U -P sonar -nsu --batch-mode -Dmaven.test.redirectTestOutputToFile=true -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn
- run:
name: "Aggregate test results"
when: always
command: |
mkdir -p ~/junit/
find . -type f -regex ".*/target/.*-reports/.*" -exec cp {} ~/junit/ \;
bash <(curl -s https://codecov.io/bash)
- store_artifacts:
path: ~/junit/
destination: artifacts
- store_test_results:
path: ~/junit/
destination: testartifacts
+8
View File
@@ -7,6 +7,14 @@
.settings/
.springBeans
target/
bin/
_site/
.idea
*.iml
*.ipr
*.iws
.factorypath
*.log
.shelf
*.swp
*.swo
+1
View File
@@ -0,0 +1 @@
-Xmx1024m -XX:CICompilerCount=1 -XX:TieredStopAtLevel=1 -Djava.security.egd=file:/dev/./urandom
+1
View File
@@ -0,0 +1 @@
-DaltSnapshotDeploymentRepository=repo.spring.io::default::https://repo.spring.io/libs-snapshot-local -P spring
BIN
View File
Binary file not shown.
+1
View File
@@ -0,0 +1 @@
distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.0/apache-maven-3.5.0-bin.zip
+11 -5
View File
@@ -9,13 +9,19 @@
</servers>
<profiles>
<profile>
<!--
N.B. this profile is only here to support users and IDEs that do not use Maven 3.3.
It isn't needed on the command line if you use the wrapper script (mvnw) or if you use
a native Maven with the right version. Eclipse users should points their Maven tooling to
this settings file, or copy the profile into their ~/.m2/settings.xml.
-->
<id>spring</id>
<activation><activeByDefault>true</activeByDefault></activation>
<repositories>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>http://repo.spring.io/libs-snapshot-local</url>
<url>https://repo.spring.io/libs-snapshot-local</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
@@ -23,7 +29,7 @@
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>http://repo.spring.io/libs-milestone-local</url>
<url>https://repo.spring.io/libs-milestone-local</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
@@ -31,7 +37,7 @@
<repository>
<id>spring-releases</id>
<name>Spring Releases</name>
<url>http://repo.spring.io/release</url>
<url>https://repo.spring.io/release</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
@@ -41,7 +47,7 @@
<pluginRepository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>http://repo.spring.io/libs-snapshot-local</url>
<url>https://repo.spring.io/libs-snapshot-local</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
@@ -49,7 +55,7 @@
<pluginRepository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>http://repo.spring.io/libs-milestone-local</url>
<url>https://repo.spring.io/libs-milestone-local</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
-27
View File
@@ -1,27 +0,0 @@
sudo: false
cache:
directories:
- $HOME/.m2
language: java
jdk:
- oraclejdk8
services:
- rabbitmq
before_install:
- git config user.name "$GIT_NAME"
- git config user.email "$GIT_EMAIL"
- git config credential.helper "store --file=.git/credentials"
- echo "https://$GH_TOKEN:@github.com" > .git/credentials
- gem install asciidoctor
install:
- mvn --settings .settings.xml install -P docs -q -U -DskipTests=true -Dmaven.test.redirectTestOutputToFile=true
- ./docs/src/main/asciidoc/ghpages.sh
script:
- '[ "${TRAVIS_PULL_REQUEST}" != "false" ] || mvn --settings .settings.xml deploy -P release -nsu -Dmaven.test.redirectTestOutputToFile=true'
- '[ "${TRAVIS_PULL_REQUEST}" = "false" ] || mvn --settings .settings.xml install -nsu -Dmaven.test.redirectTestOutputToFile=true'
env:
global:
- GIT_NAME="Dave Syer"
- GIT_EMAIL=dsyer@pivotal.io
- CI_DEPLOY_USERNAME=buildmaster
- secure: aeLXRC5oFSddwnZt1/7G2/OHr7jDbxz0ET7sej3I+eSbe3N5vbzQ6FC08es4l89l54ciXd90I1g2BMw7DTYKOO373FP78XPdAEbifJTU4DGd6fCELmoTtUPhjunBIk7E49hisPbv82892IYYA7qi/hzG548cPyZ1IgiJjq0NCsc=
+2 -2
View File
@@ -1,10 +1,10 @@
require 'asciidoctor'
require 'erb'
options = {:mkdirs => true, :safe => :unsafe, :attributes => 'linkcss'}
options = {:mkdirs => true, :safe => :unsafe, :attributes => ['linkcss', 'allow-uri-read']}
guard 'shell' do
watch(/^docs\/[A-Za-z].*\.adoc$/) {|m|
watch(/^docs\/[A-Z-a-z][^#]*\.adoc$/) {|m|
Asciidoctor.load_file('docs/src/main/asciidoc/README.adoc', :to_file => './README.adoc', safe: :safe, parse: false, attributes: 'allow-uri-read')
Asciidoctor.render_file('docs/src/main/asciidoc/spring-cloud-netflix.adoc', options.merge(:to_dir => 'target/generated-docs'))
}
+202
View File
@@ -0,0 +1,202 @@
Apache License
Version 2.0, January 2004
https://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
https://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
+195 -91
View File
@@ -1,6 +1,9 @@
// Do not edit this file (e.g. go instead to src/main/asciidoc)
image::https://travis-ci.org/spring-cloud/spring-cloud-netflix.svg?branch=master[Build Status, link=https://travis-ci.org/spring-cloud/spring-cloud-netflix]
image::https://circleci.com/gh/spring-cloud/spring-cloud-netflix/tree/master.svg?style=svg["CircleCI", link="https://circleci.com/gh/spring-cloud/spring-cloud-netflix/tree/master"]
image::https://codecov.io/gh/spring-cloud/spring-cloud-netflix/branch/master/graph/badge.svg["Codecov", link="https://codecov.io/gh/spring-cloud/spring-cloud-netflix/branch/master"]
image::https://api.codacy.com/project/badge/Grade/a6885a06921e4f72a0df0b7aabd6d118["Codacy code quality", link="https://www.codacy.com/app/Spring-Cloud/spring-cloud-netflix?utm_source=github.com&utm_medium=referral&utm_content=spring-cloud/spring-cloud-netflix&utm_campaign=Badge_Grade"]
This project provides Netflix OSS integrations for Spring Boot apps through autoconfiguration
and binding to the Spring Environment and other Spring programming model idioms. With a few
@@ -18,42 +21,54 @@ Intelligent Routing (Zuul) and Client Side Load Balancing (Ribbon).
* Circuit Breaker: embedded Hystrix dashboard with declarative Java configuration
* Declarative REST Client: Feign creates a dynamic implementation of an interface decorated with JAX-RS or Spring MVC annotations
* Client Side Load Balancer: Ribbon
* External Configuration: a bridge from the Sprnig Environment to Archaius (enables native configuration of Netflix components using Spring Boot conventions)
* Router and Filter: automatic regsitration of Zuul filters, and a simple convention over configuration approach to reverse proxy creation
* External Configuration: a bridge from the Spring Environment to Archaius (enables native configuration of Netflix components using Spring Boot conventions)
* Router and Filter: automatic registration of Zuul filters, and a simple convention over configuration approach to reverse proxy creation
== Building
:jdkversion: 1.8
=== Basic Compile and Test
To build the source you will need to install
http://maven.apache.org/run-maven/index.html[Apache Maven] v3.0.6 or above and JDK 1.7.
To build the source you will need to install JDK {jdkversion}.
Spring Cloud uses Maven for most build-related activities, and you
should be able to get off the ground quite quickly by cloning the
project you are interested in and typing
----
$ mvn install -s .settings.xml
$ ./mvnw install
----
NOTE: You may need to increase the amount of memory available to Maven by setting
a `MAVEN_OPTS` environment variable with the value `-Xmx512m -XX:MaxPermSize=128m`
NOTE: You can also install Maven (>=3.3.3) yourself and run the `mvn` command
in place of `./mvnw` in the examples below. If you do that you also
might need to add `-P spring` if your local Maven settings do not
contain repository declarations for spring pre-release artifacts.
The `.settings.xml` is only required the first time (or after updates
to dependencies). It is there to provide repository declarations so
that those do not need to be hard coded in the project poms.
NOTE: Be aware that you might need to increase the amount of memory
available to Maven by setting a `MAVEN_OPTS` environment variable with
a value like `-Xmx512m -XX:MaxPermSize=128m`. We try to cover this in
the `.mvn` configuration, so if you find you have to do it to make a
build succeed, please raise a ticket to get the settings added to
source control.
For hints on how to build the project look in `.travis.yml` if there
is one. There should be a "script" and maybe "install" command. Also
look at the "services" section to see if any services need to be
running locally (e.g. mongo or rabbit). Ignore the git-related bits
that you might find in "before_install" since they will be able git
that you might find in "before_install" since they're related to setting git
credentials and you already have those.
If you need mongo, rabbit or redis, see the README in the https://github.com/spring-cloud-samples/scripts[scripts
demo repository] for
instructions. For example consider using the "fig.yml" with
http://www.fig.sh/[Fig] to run them in Docker containers.
The projects that require middleware generally include a
`docker-compose.yml`, so consider using
https://docs.docker.com/compose/[Docker Compose] to run the middeware servers
in Docker containers. See the README in the
https://github.com/spring-cloud-samples/scripts[scripts demo
repository] for specific instructions about the common cases of mongo,
rabbit and redis.
NOTE: If all else fails, build with the command from `.travis.yml` (usually
`./mvnw install`).
=== Documentation
@@ -66,107 +81,64 @@ 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.
=== Pull Requests
Spring Cloud is released under the non-restrictive Apache 2.0 license,
and follows a very standard Github development process, using Github
tracker for issues and merging pull requests into master. If you want
to contribute even something trivial please do not hesitate, but
follow the guidelines below.
==== Sign the Contributor License Agreement
Before we accept a non-trivial patch or pull request we will need you
to sign the
https://support.springsource.com/spring_committer_signup[contributor's
agreement]. Signing the contributor's agreement does not grant anyone
commit rights to the main repository, but it does mean that we can
accept your contributions, and you will get an author credit if we do.
Active contributors might be asked to join the core team, and given
the ability to merge pull requests.
==== Code Conventions and Housekeeping
None of these is essential for a pull request, but they will all help. They can also be
added after the original pull request but before a merge.
* Use the Spring Framework code format conventions. If you use Eclipse and you follow
the ``Importing into eclipse'' instructions below you should get project specific
formatting automatically. You can also import formatter settings using the
`eclipse-code-formatter.xml` file from the `eclipse` folder. If using IntelliJ, you can
use the http://plugins.jetbrains.com/plugin/6546[Eclipse Code Formatter Plugin]
to import the same file.
* Make sure all new `.java` files to have a simple Javadoc class comment with at least an
`@author` tag identifying you, and preferably at least a paragraph on what the class is
for.
* Add the ASF license header comment to all new `.java` files (copy from existing files
in the project)
* Add yourself as an `@author` to the .java files that you modify substantially (more
than cosmetic changes).
* Add some Javadocs and, if you change the namespace, some XSD doc elements.
* A few unit tests would help a lot as well -- someone has to do it.
* If no-one else is using your branch, please rebase it against the current master (or
other target branch in the main project).
=== Working with the code
If you don't have an IDE preference we would recommend that you use
http://www.springsource.com/developer/sts[Spring Tools Suite] or
http://eclipse.org[Eclipse] when working with the code. We use the
http://eclipse.org/m2e/[m2eclipe] eclipse plugin for maven support. Other IDEs and tools
should also work without issue.
https://www.springsource.com/developer/sts[Spring Tools Suite] or
https://eclipse.org[Eclipse] when working with the code. We use the
https://eclipse.org/m2e/[m2eclipse] eclipse plugin for maven support. Other IDEs and tools
should also work without issue as long as they use Maven 3.3.3 or better.
==== Importing into eclipse with m2eclipse
We recommend the http://eclipse.org/m2e/[m2eclipe] eclipse plugin when working with
We recommend the https://eclipse.org/m2e/[m2eclipse] eclipse plugin when working with
eclipse. If you don't already have m2eclipse installed it is available from the "eclipse
marketplace".
NOTE: Older versions of m2e do not support Maven 3.3, so once the
projects are imported into Eclipse you will also need to tell
m2eclipse to use the right profile for the projects. If you
see many different errors related to the POMs in the projects, check
that you have an up to date installation. If you can't upgrade m2e,
add the "spring" profile to your `settings.xml`. Alternatively you can
copy the repository settings from the "spring" profile of the parent
pom into your `settings.xml`.
==== Importing into eclipse without m2eclipse
If you prefer not to use m2eclipse you can generate eclipse project metadata using the
following command:
[indent=0]
----
$ mvn eclipse:eclipse
$ ./mvnw eclipse:eclipse
----
The generated eclipse projects can be imported by selecting `import existing projects`
from the `file` menu.
==== Adding Project Lombok Agent
Spring Cloud uses [Project
Lombok](http://projectlombok.org/features/index.html) to generate
getters and setters etc. Compiling from the command line this
shouldn't cause any problems, but in an IDE you need to add an agent
to the JVM. Full instructions can be found in the Lombok website. The
sign that you need to do this is a lot of compiler errors to do with
missing methods and fields, e.g.
[indent=0]
----
The method getInitialStatus() is undefined for the type EurekaInstanceConfigBean EurekaDiscoveryClientConfiguration.java /spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka line 120 Java Problem
The method getInitialStatus() is undefined for the type EurekaInstanceConfigBean EurekaDiscoveryClientConfiguration.java /spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka line 121 Java Problem
The method setNonSecurePort(int) is undefined for the type EurekaInstanceConfigBean EurekaDiscoveryClientConfiguration.java /spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka line 112 Java Problem
The type EurekaInstanceConfigBean.IdentifyingDataCenterInfo must implement the inherited abstract method DataCenterInfo.getName() EurekaInstanceConfigBean.java /spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/eureka line 131 Java Problem
The method getId() is undefined for the type ProxyRouteLocator.ProxyRouteSpec PreDecorationFilter.java /spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre line 60 Java Problem
The method getLocation() is undefined for the type ProxyRouteLocator.ProxyRouteSpec PreDecorationFilter.java /spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/zuul/filters/pre line 55 Java Problem
----
==== Importing into other IDEs
Maven is well supported by most Java IDEs. Refer to you vendor documentation.
== Contributing
Spring Cloud is released under the non-restrictive Apache 2.0 license. If you would like
to contribute something, or simply want to hack on the code this document should help
you get started.
:spring-cloud-build-branch: master
Spring Cloud is released under the non-restrictive Apache 2.0 license,
and follows a very standard Github development process, using Github
tracker for issues and merging pull requests into master. If you want
to contribute even something trivial please do not hesitate, but
follow the guidelines below.
=== Sign the Contributor License Agreement
Before we accept a non-trivial patch or pull request we will need you to sign the
https://support.springsource.com/spring_committer_signup[contributor's agreement].
https://cla.pivotal.io/sign/spring[Contributor License Agreement].
Signing the contributor's agreement does not grant anyone commit rights to the main
repository, but it does mean that we can accept your contributions, and you will get an
author credit if we do. Active contributors might be asked to join the core team, and
given the ability to merge pull requests.
=== Code of Conduct
This project adheres to the Contributor Covenant https://github.com/spring-cloud/spring-cloud-build/blob/master/docs/src/main/asciidoc/code-of-conduct.adoc[code of
conduct]. By participating, you are expected to uphold this code. Please report
unacceptable behavior to spring-code-of-conduct@pivotal.io.
=== Code Conventions and Housekeeping
None of these is essential for a pull request, but they will all help. They can also be
added after the original pull request but before a merge.
@@ -174,9 +146,9 @@ added after the original pull request but before a merge.
* Use the Spring Framework code format conventions. If you use Eclipse
you can import formatter settings using the
`eclipse-code-formatter.xml` file from the
https://github.com/spring-cloud/build/tree/master/eclipse-coding-conventions.xml[Spring
https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/spring-cloud-dependencies-parent/eclipse-code-formatter.xml[Spring
Cloud Build] project. If using IntelliJ, you can use the
http://plugins.jetbrains.com/plugin/6546[Eclipse Code Formatter
https://plugins.jetbrains.com/plugin/6546[Eclipse Code Formatter
Plugin] to import the same file.
* Make sure all new `.java` files to have a simple Javadoc class comment with at least an
`@author` tag identifying you, and preferably at least a paragraph on what the class is
@@ -189,6 +161,138 @@ added after the original pull request but before a merge.
* A few unit tests would help a lot as well -- someone has to do it.
* If no-one else is using your branch, please rebase it against the current master (or
other target branch in the main project).
* When writing a commit message please follow http://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html[these conventions],
* When writing a commit message please follow https://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html[these conventions],
if you are fixing an existing issue please add `Fixes gh-XXXX` at the end of the commit
message (where XXXX is the issue number).
message (where XXXX is the issue number).
=== Checkstyle
Spring Cloud Build comes with a set of checkstyle rules. You can find them in the `spring-cloud-build-tools` module. The most notable files under the module are:
.spring-cloud-build-tools/
----
└── src
   ├── checkstyle
   │   └── checkstyle-suppressions.xml <3>
   └── main
   └── resources
   ├── checkstyle-header.txt <2>
   └── checkstyle.xml <1>
----
<1> Default Checkstyle rules
<2> File header setup
<3> Default suppression rules
==== Checkstyle configuration
Checkstyle rules are *disabled by default*. To add checkstyle to your project just define the following properties and plugins.
.pom.xml
----
<properties>
<maven-checkstyle-plugin.failsOnError>true</maven-checkstyle-plugin.failsOnError> <1>
<maven-checkstyle-plugin.failsOnViolation>true
</maven-checkstyle-plugin.failsOnViolation> <2>
<maven-checkstyle-plugin.includeTestSourceDirectory>true
</maven-checkstyle-plugin.includeTestSourceDirectory> <3>
</properties>
<build>
<plugins>
<plugin> <4>
<groupId>io.spring.javaformat</groupId>
<artifactId>spring-javaformat-maven-plugin</artifactId>
</plugin>
<plugin> <5>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
</plugin>
</plugins>
<reporting>
<plugins>
<plugin> <5>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
</plugin>
</plugins>
</reporting>
</build>
----
<1> Fails the build upon Checkstyle errors
<2> Fails the build upon Checkstyle violations
<3> Checkstyle analyzes also the test sources
<4> Add the Spring Java Format plugin that will reformat your code to pass most of the Checkstyle formatting rules
<5> Add checkstyle plugin to your build and reporting phases
If you need to suppress some rules (e.g. line length needs to be longer), then it's enough for you to define a file under `${project.root}/src/checkstyle/checkstyle-suppressions.xml` with your suppressions. Example:
.projectRoot/src/checkstyle/checkstyle-suppresions.xml
----
<?xml version="1.0"?>
<!DOCTYPE suppressions PUBLIC
"-//Puppy Crawl//DTD Suppressions 1.1//EN"
"https://www.puppycrawl.com/dtds/suppressions_1_1.dtd">
<suppressions>
<suppress files=".*ConfigServerApplication\.java" checks="HideUtilityClassConstructor"/>
<suppress files=".*ConfigClientWatch\.java" checks="LineLengthCheck"/>
</suppressions>
----
It's advisable to copy the `${spring-cloud-build.rootFolder}/.editorconfig` and `${spring-cloud-build.rootFolder}/.springformat` to your project. That way, some default formatting rules will be applied. You can do so by running this script:
```bash
$ curl https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/.editorconfig -o .editorconfig
$ touch .springformat
```
=== IDE setup
==== Intellij IDEA
In order to setup Intellij you should import our coding conventions, inspection profiles and set up the checkstyle plugin.
.spring-cloud-build-tools/
----
└── src
   ├── checkstyle
   │   └── checkstyle-suppressions.xml <3>
   └── main
   └── resources
   ├── checkstyle-header.txt <2>
   ├── checkstyle.xml <1>
   └── intellij
      ├── Intellij_Project_Defaults.xml <4>
      └── Intellij_Spring_Boot_Java_Conventions.xml <5>
----
<1> Default Checkstyle rules
<2> File header setup
<3> Default suppression rules
<4> Project defaults for Intellij that apply most of Checkstyle rules
<5> Project style conventions for Intellij that apply most of Checkstyle rules
.Code style
image::https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/{spring-cloud-build-branch}/docs/src/main/asciidoc/images/intellij-code-style.png[Code style]
Go to `File` -> `Settings` -> `Editor` -> `Code style`. There click on the icon next to the `Scheme` section. There, click on the `Import Scheme` value and pick the `Intellij IDEA code style XML` option. Import the `spring-cloud-build-tools/src/main/resources/intellij/Intellij_Spring_Boot_Java_Conventions.xml` file.
.Inspection profiles
image::https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/{spring-cloud-build-branch}/docs/src/main/asciidoc/images/intellij-inspections.png[Code style]
Go to `File` -> `Settings` -> `Editor` -> `Inspections`. There click on the icon next to the `Profile` section. There, click on the `Import Profile` and import the `spring-cloud-build-tools/src/main/resources/intellij/Intellij_Project_Defaults.xml` file.
.Checkstyle
To have Intellij work with Checkstyle, you have to install the `Checkstyle` plugin. It's advisable to also install the `Assertions2Assertj` to automatically convert the JUnit assertions
image::https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/{spring-cloud-build-branch}/docs/src/main/asciidoc/images/intellij-checkstyle.png[Checkstyle]
Go to `File` -> `Settings` -> `Other settings` -> `Checkstyle`. There click on the `+` icon in the `Configuration file` section. There, you'll have to define where the checkstyle rules should be picked from. In the image above, we've picked the rules from the cloned Spring Cloud Build repository. However, you can point to the Spring Cloud Build's GitHub repository (e.g. for the `checkstyle.xml` : `https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/spring-cloud-build-tools/src/main/resources/checkstyle.xml`). We need to provide the following variables:
- `checkstyle.header.file` - please point it to the Spring Cloud Build's, `spring-cloud-build-tools/src/main/resources/checkstyle/checkstyle-header.txt` file either in your cloned repo or via the `https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/spring-cloud-build-tools/src/main/resources/checkstyle-header.txt` URL.
- `checkstyle.suppressions.file` - default suppressions. Please point it to the Spring Cloud Build's, `spring-cloud-build-tools/src/checkstyle/checkstyle-suppressions.xml` file either in your cloned repo or via the `https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/spring-cloud-build-tools/src/checkstyle/checkstyle-suppressions.xml` URL.
- `checkstyle.additional.suppressions.file` - this variable corresponds to suppressions in your local project. E.g. you're working on `spring-cloud-contract`. Then point to the `project-root/src/checkstyle/checkstyle-suppressions.xml` folder. Example for `spring-cloud-contract` would be: `/home/username/spring-cloud-contract/src/checkstyle/checkstyle-suppressions.xml`.
IMPORTANT: Remember to set the `Scan Scope` to `All sources` since we apply checkstyle rules for production and test sources.
-74
View File
@@ -1,74 +0,0 @@
# Running Spring Platform components
## Config Server
`spring-platform-config$ java -Dspring.platform.config.server.uri=https://github.com/spencergibb/config-repo -jar spring-platform-config-server/target/spring-platform-config-server-1.0.0.BUILD-SNAPSHOT-exec.jar`
## Netflix Eureka
`spring-boot-eureka$ mvn spring-boot:run`
http://localhost:8080/eureka/jsp/status.jsp
Error running executable war:
2014-07-14 18:14:25,713 ERROR org.apache.juli.logging.DirectJDKLog:185 [localhost-startStop-1] [log] Exception starting filter servletContainer
com.sun.jersey.core.spi.scanning.ScannerException: IO error when scanning jar jar:file:/Users/sgibb/workspace/spring/spring-boot-eureka/target/eureka-server-1.0.0.BUILD-SNAPSHOT.war!/WEB-INF/lib/jersey-apache-client4-1.11.jar!/com/sun/jersey
at com.sun.jersey.core.spi.scanning.uri.JarZipSchemeScanner.scan(JarZipSchemeScanner.java:82)
at com.sun.jersey.core.spi.scanning.PackageNamesScanner.scan(PackageNamesScanner.java:223)
at com.sun.jersey.core.spi.scanning.PackageNamesScanner.scan(PackageNamesScanner.java:139)
at com.sun.jersey.api.core.ScanningResourceConfig.init(ScanningResourceConfig.java:80)
at com.sun.jersey.api.core.PackagesResourceConfig.init(PackagesResourceConfig.java:104)
at com.sun.jersey.api.core.PackagesResourceConfig.<init>(PackagesResourceConfig.java:78)
at com.sun.jersey.api.core.PackagesResourceConfig.<init>(PackagesResourceConfig.java:89)
at com.sun.jersey.spi.container.servlet.WebComponent.createResourceConfig(WebComponent.java:700)
at com.sun.jersey.spi.container.servlet.WebComponent.createResourceConfig(WebComponent.java:678)
at com.sun.jersey.spi.container.servlet.WebComponent.init(WebComponent.java:203)
at com.sun.jersey.spi.container.servlet.ServletContainer.init(ServletContainer.java:374)
at com.sun.jersey.spi.container.servlet.ServletContainer.init(ServletContainer.java:727)
at org.apache.catalina.core.ApplicationFilterConfig.initFilter(ApplicationFilterConfig.java:279)
at org.apache.catalina.core.ApplicationFilterConfig.<init>(ApplicationFilterConfig.java:109)
at org.apache.catalina.core.StandardContext.filterStart(StandardContext.java:4809)
at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5485)
at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:150)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1559)
at org.apache.catalina.core.ContainerBase$StartChild.call(ContainerBase.java:1549)
at java.util.concurrent.FutureTask.run(FutureTask.java:262)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:744)
Caused by: java.io.FileNotFoundException: /Users/sgibb/workspace/spring/spring-boot-eureka/target/eureka-server-1.0.0.BUILD-SNAPSHOT.war!/WEB-INF/lib/jersey-apache-client4-1.11.jar (No such file or directory)
at java.io.FileInputStream.open(Native Method)
at java.io.FileInputStream.<init>(FileInputStream.java:146)
at java.io.FileInputStream.<init>(FileInputStream.java:101)
at sun.net.www.protocol.file.FileURLConnection.connect(FileURLConnection.java:90)
at sun.net.www.protocol.file.FileURLConnection.getInputStream(FileURLConnection.java:188)
at java.net.URL.openStream(URL.java:1037)
at com.sun.jersey.core.spi.scanning.uri.JarZipSchemeScanner.closing(JarZipSchemeScanner.java:123)
at com.sun.jersey.core.spi.scanning.uri.JarZipSchemeScanner.scan(JarZipSchemeScanner.java:75)
... 22 more
## Netflix Zuul
`spring-platform-netflix-zuul$ java -Dzuul.filterRoot=src/main/resources/filters -jar target/spring-platform-netflix-zuul-1.0.0.BUILD-SNAPSHOT.jar`
http://localhost:6080/ (routes to Sample Frontend)
## Netflix Hystrix Dashboard
`spring-platform-netflix-hystrix$ java -jar target/spring-platform-netflix-hystrix-1.0.0.BUILD-SNAPSHOT.war`
## Netflix Turbine
`spring-platform-netflix-turbine$ java -jar target/spring-platform-netflix-turbine-1.0.0.BUILD-SNAPSHOT.war --InstanceDiscovery.impl=io.spring.platform.netflix.turbine.EurekaInstanceDiscovery --turbine.appConfig=samplefrontendservice --turbine.aggregator.clusterConfig=SAMPLEAPPS --turbine.instanceUrlSuffix=/hystrix.stream --turbine.instanceInsertPort=true`
## Sandbox Sample Backend
`spring-platform-sandbox-sample-backend$ java -jar target/spring-platform-sandbox-sample-backend-1.0.0.BUILD-SNAPSHOT.jar`
## Sandbox Sample Frontend
`spring-platform-sandbox-sample-frontend$ java -jar target/spring-platform-sandbox-sample-frontend-1.0.0.BUILD-SNAPSHOT.jar`
http://localhost:9080/
+1 -1
View File
@@ -1,4 +1,4 @@
/* Asciidoctor default stylesheet | MIT License | http://asciidoctor.org */
/* Asciidoctor default stylesheet | MIT License | https://asciidoctor.org */
/* Remove the comments around the @import statement below when using this as a custom stylesheet */
/*@import "https://fonts.googleapis.com/css?family=Open+Sans:300,300italic,400,400italic,600,600italic|Noto+Serif:400,400italic,700,700italic|Droid+Sans+Mono:400";*/
article,aside,details,figcaption,figure,footer,header,hgroup,main,nav,section,summary{display:block}
+3
View File
@@ -0,0 +1,3 @@
releaser:
maven:
buildCommand: ./scripts/build.sh {{systemProps}}
-22
View File
@@ -1,22 +0,0 @@
// Do not edit this file (e.g. go instead to src/main/asciidoc)
This project provides Netflix OSS integrations for Spring Boot apps through autoconfiguration
and binding to the Spring Environment and other Spring programming model idioms. With a few
simple annotations you can quickly enable and configure the common patterns inside your
application and build large distributed systems with battle-tested Netflix components. The
patterns provided include Service Discovery (Eureka), Circuit Breaker (Hystrix),
Intelligent Routing (Zuul) and Client Side Load Balancing (Ribbon).
== Features
* Service Discovery: Eureka instances can be registered and clients can discover the instances using Spring-managed beans
* Service Discovery: an embedded Eureka server can be created with declarative Java configuration
* Circuit Breaker: Hystrix clients can be built with a simple annotation-driven method decorator
* Circuit Breaker: embedded Hystrix dashboard with declarative Java configuration
* Declarative REST Client: Feign creates a dynamic implementation of an interface decorated with JAX-RS or Spring MVC annotations
* Client Side Load Balancer: Ribbon
* External Configuration: a bridge from the Sprnig Environment to Archaius (enabls native configuration of Netflix components using Spring Boot conventions)
* Router and Filter: automatic regsitration of Zuul filters,a nd a simple convention over configuration approach to reverse proxy creation
+22 -4
View File
@@ -1,12 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-build</artifactId>
<version>1.0.0.BUILD-SNAPSHOT</version>
<relativePath />
<artifactId>spring-cloud-netflix</artifactId>
<version>1.4.8.BUILD-SNAPSHOT</version>
</parent>
<artifactId>spring-cloud-netflix-docs</artifactId>
<packaging>pom</packaging>
@@ -15,17 +14,36 @@
<properties>
<docs.main>spring-cloud-netflix</docs.main>
<main.basedir>${basedir}/..</main.basedir>
<docs.whitelisted.branches>1.2.x,1.3.x,1.4.x</docs.whitelisted.branches>
</properties>
<build>
<plugins>
<plugin>
<artifactId>maven-deploy-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
</plugins>
</build>
<profiles>
<profile>
<id>docs</id>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.asciidoctor</groupId>
<artifactId>asciidoctor-maven-plugin</artifactId>
<inherited>false</inherited>
</plugin>
<plugin>
<groupId>com.agilejava.docbkx</groupId>
<artifactId>docbkx-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-antrun-plugin</artifactId>
+7 -4
View File
@@ -1,4 +1,7 @@
image::https://travis-ci.org/spring-cloud/spring-cloud-netflix.svg?branch=master[Build Status, link=https://travis-ci.org/spring-cloud/spring-cloud-netflix]
image::https://circleci.com/gh/spring-cloud/spring-cloud-netflix/tree/master.svg?style=svg["CircleCI", link="https://circleci.com/gh/spring-cloud/spring-cloud-netflix/tree/master"]
image::https://codecov.io/gh/spring-cloud/spring-cloud-netflix/branch/master/graph/badge.svg["Codecov", link="https://codecov.io/gh/spring-cloud/spring-cloud-netflix/branch/master"]
image::https://api.codacy.com/project/badge/Grade/a6885a06921e4f72a0df0b7aabd6d118["Codacy code quality", link="https://www.codacy.com/app/Spring-Cloud/spring-cloud-netflix?utm_source=github.com&utm_medium=referral&utm_content=spring-cloud/spring-cloud-netflix&utm_campaign=Badge_Grade"]
include::intro.adoc[]
@@ -10,12 +13,12 @@ include::intro.adoc[]
* Circuit Breaker: embedded Hystrix dashboard with declarative Java configuration
* Declarative REST Client: Feign creates a dynamic implementation of an interface decorated with JAX-RS or Spring MVC annotations
* Client Side Load Balancer: Ribbon
* External Configuration: a bridge from the Sprnig Environment to Archaius (enables native configuration of Netflix components using Spring Boot conventions)
* Router and Filter: automatic regsitration of Zuul filters, and a simple convention over configuration approach to reverse proxy creation
* External Configuration: a bridge from the Spring Environment to Archaius (enables native configuration of Netflix components using Spring Boot conventions)
* Router and Filter: automatic registration of Zuul filters, and a simple convention over configuration approach to reverse proxy creation
== Building
include::https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/docs/src/main/asciidoc/building.adoc[]
include::https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/docs/src/main/asciidoc/building-jdk8.adoc[]
== Contributing
+320 -36
View File
@@ -1,46 +1,330 @@
#!/bin/bash -x
git remote set-url --push origin `git config remote.origin.url | sed -e 's/^git:/https:/'`
set -e
if ! (git remote set-branches --add origin gh-pages && git fetch -q); then
echo "No gh-pages, so not syncing"
exit 0
fi
# Set default props like MAVEN_PATH, ROOT_FOLDER etc.
function set_default_props() {
# The script should be executed from the root folder
ROOT_FOLDER=`pwd`
echo "Current folder is ${ROOT_FOLDER}"
if ! [ -d docs/target/generated-docs ]; then
echo "No gh-pages sources in docs/target/generated-docs, so not syncing"
exit 0
fi
if [[ ! -e "${ROOT_FOLDER}/.git" ]]; then
echo "You're not in the root folder of the project!"
exit 1
fi
# Prop that will let commit the changes
COMMIT_CHANGES="no"
MAVEN_PATH=${MAVEN_PATH:-}
echo "Path to Maven is [${MAVEN_PATH}]"
REPO_NAME=${PWD##*/}
echo "Repo name is [${REPO_NAME}]"
SPRING_CLOUD_STATIC_REPO=${SPRING_CLOUD_STATIC_REPO:-git@github.com:spring-cloud/spring-cloud-static.git}
echo "Spring Cloud Static repo is [${SPRING_CLOUD_STATIC_REPO}"
}
# Check if gh-pages exists and docs have been built
function check_if_anything_to_sync() {
git remote set-url --push origin `git config remote.origin.url | sed -e 's/^git:/https:/'`
if ! (git remote set-branches --add origin gh-pages && git fetch -q); then
echo "No gh-pages, so not syncing"
exit 0
fi
if ! [ -d docs/target/generated-docs ] && ! [ "${BUILD}" == "yes" ]; then
echo "No gh-pages sources in docs/target/generated-docs, so not syncing"
exit 0
fi
}
function retrieve_current_branch() {
# Code getting the name of the current branch. For master we want to publish as we did until now
# https://stackoverflow.com/questions/1593051/how-to-programmatically-determine-the-current-checked-out-git-branch
# If there is a branch already passed will reuse it - otherwise will try to find it
CURRENT_BRANCH=${BRANCH}
if [[ -z "${CURRENT_BRANCH}" ]] ; then
CURRENT_BRANCH=$(git symbolic-ref -q HEAD)
CURRENT_BRANCH=${CURRENT_BRANCH##refs/heads/}
CURRENT_BRANCH=${CURRENT_BRANCH:-HEAD}
fi
echo "Current branch is [${CURRENT_BRANCH}]"
git checkout ${CURRENT_BRANCH} || echo "Failed to check the branch... continuing with the script"
}
# Switches to the provided value of the release version. We always prefix it with `v`
function switch_to_tag() {
git checkout v${VERSION}
}
# Build the docs if switch is on
function build_docs_if_applicable() {
if [[ "${BUILD}" == "yes" ]] ; then
./mvnw clean install -P docs -pl docs -DskipTests
fi
}
# Get the name of the `docs.main` property
# Get whitelisted branches - assumes that a `docs` module is available under `docs` profile
function retrieve_doc_properties() {
MAIN_ADOC_VALUE=$("${MAVEN_PATH}"mvn -q \
-Dexec.executable="echo" \
-Dexec.args='${docs.main}' \
--non-recursive \
org.codehaus.mojo:exec-maven-plugin:1.3.1:exec)
echo "Extracted 'main.adoc' from Maven build [${MAIN_ADOC_VALUE}]"
WHITELIST_PROPERTY=${WHITELIST_PROPERTY:-"docs.whitelisted.branches"}
WHITELISTED_BRANCHES_VALUE=$("${MAVEN_PATH}"mvn -q \
-Dexec.executable="echo" \
-Dexec.args="\${${WHITELIST_PROPERTY}}" \
org.codehaus.mojo:exec-maven-plugin:1.3.1:exec \
-P docs \
-pl docs)
echo "Extracted '${WHITELIST_PROPERTY}' from Maven build [${WHITELISTED_BRANCHES_VALUE}]"
}
# Stash any outstanding changes
###################################################################
git diff-index --quiet HEAD
dirty=$?
if [ "$dirty" != "0" ]; then git stash; fi
function stash_changes() {
git diff-index --quiet HEAD && dirty=$? || (echo "Failed to check if the current repo is dirty. Assuming that it is." && dirty="1")
if [ "$dirty" != "0" ]; then git stash; fi
}
# Switch to gh-pages branch to sync it with master
###################################################################
git checkout gh-pages
for f in docs/target/generated-docs/*; do
file=${f#docs/target/generated-docs/*}
if ! git ls-files -i -o --exclude-standard --directory | grep -q ^$file$; then
# Not ignored...
cp -rf $f .
git add -A $file
# Switch to gh-pages branch to sync it with current branch
function add_docs_from_target() {
local DESTINATION_REPO_FOLDER
if [[ -z "${DESTINATION}" && -z "${CLONE}" ]] ; then
DESTINATION_REPO_FOLDER=${ROOT_FOLDER}
elif [[ "${CLONE}" == "yes" ]]; then
mkdir -p ${ROOT_FOLDER}/target
local clonedStatic=${ROOT_FOLDER}/target/spring-cloud-static
if [[ ! -e "${clonedStatic}/.git" ]]; then
echo "Cloning Spring Cloud Static to target"
git clone ${SPRING_CLOUD_STATIC_REPO} ${clonedStatic} && git checkout gh-pages
else
echo "Spring Cloud Static already cloned - will pull changes"
cd ${clonedStatic} && git checkout gh-pages && git pull origin gh-pages
fi
DESTINATION_REPO_FOLDER=${clonedStatic}/${REPO_NAME}
mkdir -p ${DESTINATION_REPO_FOLDER}
else
if [[ ! -e "${DESTINATION}/.git" ]]; then
echo "[${DESTINATION}] is not a git repository"
exit 1
fi
DESTINATION_REPO_FOLDER=${DESTINATION}/${REPO_NAME}
mkdir -p ${DESTINATION_REPO_FOLDER}
echo "Destination was provided [${DESTINATION}]"
fi
cd ${DESTINATION_REPO_FOLDER}
git checkout gh-pages
git pull origin gh-pages
# Add git branches
###################################################################
if [[ -z "${VERSION}" ]] ; then
copy_docs_for_current_version
else
copy_docs_for_provided_version
fi
commit_changes_if_applicable
}
# Copies the docs by using the retrieved properties from Maven build
function copy_docs_for_current_version() {
if [[ "${CURRENT_BRANCH}" == "master" ]] ; then
echo -e "Current branch is master - will copy the current docs only to the root folder"
for f in docs/target/generated-docs/*; do
file=${f#docs/target/generated-docs/*}
if ! git ls-files -i -o --exclude-standard --directory | grep -q ^$file$; then
# Not ignored...
cp -rf $f ${ROOT_FOLDER}/
git add -A ${ROOT_FOLDER}/$file
fi
done
COMMIT_CHANGES="yes"
else
echo -e "Current branch is [${CURRENT_BRANCH}]"
# https://stackoverflow.com/questions/29300806/a-bash-script-to-check-if-a-string-is-present-in-a-comma-separated-list-of-strin
if [[ ",${WHITELISTED_BRANCHES_VALUE}," = *",${CURRENT_BRANCH},"* ]] ; then
mkdir -p ${ROOT_FOLDER}/${CURRENT_BRANCH}
echo -e "Branch [${CURRENT_BRANCH}] is whitelisted! Will copy the current docs to the [${CURRENT_BRANCH}] folder"
for f in docs/target/generated-docs/*; do
file=${f#docs/target/generated-docs/*}
if ! git ls-files -i -o --exclude-standard --directory | grep -q ^$file$; then
# Not ignored...
# We want users to access 1.0.0.RELEASE/ instead of 1.0.0.RELEASE/spring-cloud.sleuth.html
if [[ "${file}" == "${MAIN_ADOC_VALUE}.html" ]] ; then
# We don't want to copy the spring-cloud-sleuth.html
# we want it to be converted to index.html
cp -rf $f ${ROOT_FOLDER}/${CURRENT_BRANCH}/index.html
git add -A ${ROOT_FOLDER}/${CURRENT_BRANCH}/index.html
else
cp -rf $f ${ROOT_FOLDER}/${CURRENT_BRANCH}
git add -A ${ROOT_FOLDER}/${CURRENT_BRANCH}/$file
fi
fi
done
COMMIT_CHANGES="yes"
else
echo -e "Branch [${CURRENT_BRANCH}] is not on the white list! Check out the Maven [${WHITELIST_PROPERTY}] property in
[docs] module available under [docs] profile. Won't commit any changes to gh-pages for this branch."
fi
fi
}
# Copies the docs by using the explicitly provided version
function copy_docs_for_provided_version() {
local FOLDER=${DESTINATION_REPO_FOLDER}/${VERSION}
mkdir -p ${FOLDER}
echo -e "Current tag is [v${VERSION}] Will copy the current docs to the [${FOLDER}] folder"
for f in ${ROOT_FOLDER}/docs/target/generated-docs/*; do
file=${f#${ROOT_FOLDER}/docs/target/generated-docs/*}
copy_docs_for_branch ${file} ${FOLDER}
done
COMMIT_CHANGES="yes"
CURRENT_BRANCH="v${VERSION}"
}
# Copies the docs from target to the provided destination
# Params:
# $1 - file from target
# $2 - destination to which copy the files
function copy_docs_for_branch() {
local file=$1
local destination=$2
if ! git ls-files -i -o --exclude-standard --directory | grep -q ^${file}$; then
# Not ignored...
# We want users to access 1.0.0.RELEASE/ instead of 1.0.0.RELEASE/spring-cloud.sleuth.html
if [[ ("${file}" == "${MAIN_ADOC_VALUE}.html") || ("${file}" == "${REPO_NAME}.html") ]] ; then
# We don't want to copy the spring-cloud-sleuth.html
# we want it to be converted to index.html
cp -rf $f ${destination}/index.html
git add -A ${destination}/index.html
else
cp -rf $f ${destination}
git add -A ${destination}/$file
fi
fi
}
function commit_changes_if_applicable() {
if [[ "${COMMIT_CHANGES}" == "yes" ]] ; then
COMMIT_SUCCESSFUL="no"
git commit -a -m "Sync docs from ${CURRENT_BRANCH} to gh-pages" && COMMIT_SUCCESSFUL="yes" || echo "Failed to commit changes"
# Uncomment the following push if you want to auto push to
# the gh-pages branch whenever you commit to master locally.
# This is a little extreme. Use with care!
###################################################################
if [[ "${COMMIT_SUCCESSFUL}" == "yes" ]] ; then
git push origin gh-pages
fi
fi
}
# Switch back to the previous branch and exit block
function checkout_previous_branch() {
# If -version was provided we need to come back to root project
cd ${ROOT_FOLDER}
git checkout ${CURRENT_BRANCH} || echo "Failed to check the branch... continuing with the script"
if [ "$dirty" != "0" ]; then git stash pop; fi
exit 0
}
# Assert if properties have been properly passed
function assert_properties() {
echo "VERSION [${VERSION}], DESTINATION [${DESTINATION}], CLONE [${CLONE}]"
if [[ "${VERSION}" != "" && (-z "${DESTINATION}" && -z "${CLONE}") ]] ; then echo "Version was set but destination / clone was not!"; exit 1;fi
if [[ ("${DESTINATION}" != "" && "${CLONE}" != "") && -z "${VERSION}" ]] ; then echo "Destination / clone was set but version was not!"; exit 1;fi
if [[ "${DESTINATION}" != "" && "${CLONE}" == "yes" ]] ; then echo "Destination and clone was set. Pick one!"; exit 1;fi
}
# Prints the usage
function print_usage() {
cat <<EOF
The idea of this script is to update gh-pages branch with the generated docs. Without any options
the script will work in the following manner:
- if there's no gh-pages / target for docs module then the script ends
- for master branch the generated docs are copied to the root of gh-pages branch
- for any other branch (if that branch is whitelisted) a subfolder with branch name is created
and docs are copied there
- if the version switch is passed (-v) then a tag with (v) prefix will be retrieved and a folder
with that version number will be created in the gh-pages branch. WARNING! No whitelist verification will take place
- if the destination switch is passed (-d) then the script will check if the provided dir is a git repo and then will
switch to gh-pages of that repo and copy the generated docs to `docs/<project-name>/<version>`
- if the destination switch is passed (-d) then the script will check if the provided dir is a git repo and then will
switch to gh-pages of that repo and copy the generated docs to `docs/<project-name>/<version>`
USAGE:
You can use the following options:
-v|--version - the script will apply the whole procedure for a particular library version
-d|--destination - the root of destination folder where the docs should be copied. You have to use the full path.
E.g. point to spring-cloud-static folder. Can't be used with (-c)
-b|--build - will run the standard build process after checking out the branch
-c|--clone - will automatically clone the spring-cloud-static repo instead of providing the destination.
Obviously can't be used with (-d)
EOF
}
# ==========================================
# ____ ____ _____ _____ _____ _______
# / ____|/ ____| __ \|_ _| __ \__ __|
# | (___ | | | |__) | | | | |__) | | |
# \___ \| | | _ / | | | ___/ | |
# ____) | |____| | \ \ _| |_| | | |
# |_____/ \_____|_| \_\_____|_| |_|
#
# ==========================================
while [[ $# > 0 ]]
do
key="$1"
case ${key} in
-v|--version)
VERSION="$2"
shift # past argument
;;
-d|--destination)
DESTINATION="$2"
shift # past argument
;;
-b|--build)
BUILD="yes"
;;
-c|--clone)
CLONE="yes"
;;
-h|--help)
print_usage
exit 0
;;
*)
echo "Invalid option: [$1]"
print_usage
exit 1
;;
esac
shift # past argument or value
done
git commit -a -m "Sync docs from master to gh-pages"
# Uncomment the following push if you want to auto push to
# the gh-pages branch whenever you commit to master locally.
# This is a little extreme. Use with care!
###################################################################
git push origin gh-pages
# Finally, switch back to the master branch and exit block
git checkout master
if [ "$dirty" != "0" ]; then git stash pop; fi
exit 0
assert_properties
set_default_props
check_if_anything_to_sync
if [[ -z "${VERSION}" ]] ; then
retrieve_current_branch
else
switch_to_tag
fi
build_docs_if_applicable
retrieve_doc_properties
stash_changes
add_docs_from_target
checkout_previous_branch
Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

File diff suppressed because it is too large Load Diff
-30
View File
@@ -1,30 +0,0 @@
#!/usr/bin/env ruby
base_dir = File.join(File.dirname(__FILE__),'../../..')
src_dir = File.join(base_dir, "/src/main/asciidoc")
require 'asciidoctor'
require 'optparse'
options = {}
file = "#{src_dir}/README.adoc"
OptionParser.new do |o|
o.on('-o OUTPUT_FILE', 'Output file (default is stdout)') { |file| options[:to_file] = file unless file=='-' }
o.on('-h', '--help') { puts o; exit }
o.parse!
end
file = ARGV[0] if ARGV.length>0
srcDir = File.dirname(file)
out = "// Do not edit this file (e.g. go instead to src/main/asciidoc)\n\n"
doc = Asciidoctor.load_file file, safe: :safe, parse: false, attributes: 'allow-uri-read'
out << doc.reader.read
unless options[:to_file]
puts out
else
File.open(options[:to_file],'w+') do |file|
file.write(out)
end
end
Vendored Executable
+253
View File
@@ -0,0 +1,253 @@
#!/bin/sh
# ----------------------------------------------------------------------------
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
# ----------------------------------------------------------------------------
# ----------------------------------------------------------------------------
# Maven2 Start Up Batch script
#
# Required ENV vars:
# ------------------
# JAVA_HOME - location of a JDK home dir
#
# Optional ENV vars
# -----------------
# M2_HOME - location of maven2's installed home dir
# MAVEN_OPTS - parameters passed to the Java VM when running Maven
# e.g. to debug Maven itself, use
# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
# ----------------------------------------------------------------------------
if [ -z "$MAVEN_SKIP_RC" ] ; then
if [ -f /etc/mavenrc ] ; then
. /etc/mavenrc
fi
if [ -f "$HOME/.mavenrc" ] ; then
. "$HOME/.mavenrc"
fi
fi
# OS specific support. $var _must_ be set to either true or false.
cygwin=false;
darwin=false;
mingw=false
case "`uname`" in
CYGWIN*) cygwin=true ;;
MINGW*) mingw=true;;
Darwin*) darwin=true
#
# Look for the Apple JDKs first to preserve the existing behaviour, and then look
# for the new JDKs provided by Oracle.
#
if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK ] ; then
#
# Apple JDKs
#
export JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home
fi
if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Java/JavaVirtualMachines/CurrentJDK ] ; then
#
# Apple JDKs
#
export JAVA_HOME=/System/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home
fi
if [ -z "$JAVA_HOME" ] && [ -L "/Library/Java/JavaVirtualMachines/CurrentJDK" ] ; then
#
# Oracle JDKs
#
export JAVA_HOME=/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home
fi
if [ -z "$JAVA_HOME" ] && [ -x "/usr/libexec/java_home" ]; then
#
# Apple JDKs
#
export JAVA_HOME=`/usr/libexec/java_home`
fi
;;
esac
if [ -z "$JAVA_HOME" ] ; then
if [ -r /etc/gentoo-release ] ; then
JAVA_HOME=`java-config --jre-home`
fi
fi
if [ -z "$M2_HOME" ] ; then
## resolve links - $0 may be a link to maven's home
PRG="$0"
# need this for relative symlinks
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG="`dirname "$PRG"`/$link"
fi
done
saveddir=`pwd`
M2_HOME=`dirname "$PRG"`/..
# make it fully qualified
M2_HOME=`cd "$M2_HOME" && pwd`
cd "$saveddir"
# echo Using m2 at $M2_HOME
fi
# For Cygwin, ensure paths are in UNIX format before anything is touched
if $cygwin ; then
[ -n "$M2_HOME" ] &&
M2_HOME=`cygpath --unix "$M2_HOME"`
[ -n "$JAVA_HOME" ] &&
JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
[ -n "$CLASSPATH" ] &&
CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
fi
# For Migwn, ensure paths are in UNIX format before anything is touched
if $mingw ; then
[ -n "$M2_HOME" ] &&
M2_HOME="`(cd "$M2_HOME"; pwd)`"
[ -n "$JAVA_HOME" ] &&
JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
# TODO classpath?
fi
if [ -z "$JAVA_HOME" ]; then
javaExecutable="`which javac`"
if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
# readlink(1) is not available as standard on Solaris 10.
readLink=`which readlink`
if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
if $darwin ; then
javaHome="`dirname \"$javaExecutable\"`"
javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
else
javaExecutable="`readlink -f \"$javaExecutable\"`"
fi
javaHome="`dirname \"$javaExecutable\"`"
javaHome=`expr "$javaHome" : '\(.*\)/bin'`
JAVA_HOME="$javaHome"
export JAVA_HOME
fi
fi
fi
if [ -z "$JAVACMD" ] ; then
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
else
JAVACMD="`which java`"
fi
fi
if [ ! -x "$JAVACMD" ] ; then
echo "Error: JAVA_HOME is not defined correctly." >&2
echo " We cannot execute $JAVACMD" >&2
exit 1
fi
if [ -z "$JAVA_HOME" ] ; then
echo "Warning: JAVA_HOME environment variable is not set."
fi
CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
# For Cygwin, switch paths to Windows format before running java
if $cygwin; then
[ -n "$M2_HOME" ] &&
M2_HOME=`cygpath --path --windows "$M2_HOME"`
[ -n "$JAVA_HOME" ] &&
JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
[ -n "$CLASSPATH" ] &&
CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
fi
# traverses directory structure from process work directory to filesystem root
# first directory with .mvn subdirectory is considered project base directory
find_maven_basedir() {
local basedir=$(pwd)
local wdir=$(pwd)
while [ "$wdir" != '/' ] ; do
if [ -d "$wdir"/.mvn ] ; then
basedir=$wdir
break
fi
wdir=$(cd "$wdir/.."; pwd)
done
echo "${basedir}"
}
# concatenates all lines of a file
concat_lines() {
if [ -f "$1" ]; then
echo "$(tr -s '\n' ' ' < "$1")"
fi
}
export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-$(find_maven_basedir)}
MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
# Provide a "standardized" way to retrieve the CLI args that will
# work with both Windows and non-Windows executions.
MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@"
export MAVEN_CMD_LINE_ARGS
WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
echo "Running version check"
VERSION=$( sed '\!<parent!,\!</parent!d' `dirname $0`/pom.xml | grep '<version' | head -1 | sed -e 's/.*<version>//' -e 's!</version>.*$!!' )
echo "The found version is [${VERSION}]"
if echo $VERSION | egrep -q 'M|RC'; then
echo Activating \"milestone\" profile for version=\"$VERSION\"
echo $MAVEN_ARGS | grep -q milestone || MAVEN_ARGS="$MAVEN_ARGS -Pmilestone"
else
echo Deactivating \"milestone\" profile for version=\"$VERSION\"
echo $MAVEN_ARGS | grep -q milestone && MAVEN_ARGS=$(echo $MAVEN_ARGS | sed -e 's/-Pmilestone//')
fi
if echo $VERSION | egrep -q 'RELEASE'; then
echo Activating \"central\" profile for version=\"$VERSION\"
echo $MAVEN_ARGS | grep -q milestone || MAVEN_ARGS="$MAVEN_ARGS -Pcentral"
else
echo Deactivating \"central\" profile for version=\"$VERSION\"
echo $MAVEN_ARGS | grep -q central && MAVEN_ARGS=$(echo $MAVEN_ARGS | sed -e 's/-Pcentral//')
fi
exec "$JAVACMD" \
$MAVEN_OPTS \
-classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
"-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
${WRAPPER_LAUNCHER} ${MAVEN_ARGS} "$@"
Vendored
+145
View File
@@ -0,0 +1,145 @@
@REM ----------------------------------------------------------------------------
@REM Licensed to the Apache Software Foundation (ASF) under one
@REM or more contributor license agreements. See the NOTICE file
@REM distributed with this work for additional information
@REM regarding copyright ownership. The ASF licenses this file
@REM to you under the Apache License, Version 2.0 (the
@REM "License"); you may not use this file except in compliance
@REM with the License. You may obtain a copy of the License at
@REM
@REM https://www.apache.org/licenses/LICENSE-2.0
@REM
@REM Unless required by applicable law or agreed to in writing,
@REM software distributed under the License is distributed on an
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
@REM KIND, either express or implied. See the License for the
@REM specific language governing permissions and limitations
@REM under the License.
@REM ----------------------------------------------------------------------------
@REM ----------------------------------------------------------------------------
@REM Maven2 Start Up Batch script
@REM
@REM Required ENV vars:
@REM JAVA_HOME - location of a JDK home dir
@REM
@REM Optional ENV vars
@REM M2_HOME - location of maven2's installed home dir
@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
@REM e.g. to debug Maven itself, use
@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
@REM ----------------------------------------------------------------------------
@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
@echo off
@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on'
@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
@REM set %HOME% to equivalent of $HOME
if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
@REM Execute a user defined script before this one
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
@REM check for pre script, once with legacy .bat ending and once with .cmd ending
if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
:skipRcPre
@setlocal
set ERROR_CODE=0
@REM To isolate internal variables from possible post scripts, we use another setlocal
@setlocal
@REM ==== START VALIDATION ====
if not "%JAVA_HOME%" == "" goto OkJHome
echo.
echo Error: JAVA_HOME not found in your environment. >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
echo.
goto error
:OkJHome
if exist "%JAVA_HOME%\bin\java.exe" goto init
echo.
echo Error: JAVA_HOME is set to an invalid directory. >&2
echo JAVA_HOME = "%JAVA_HOME%" >&2
echo Please set the JAVA_HOME variable in your environment to match the >&2
echo location of your Java installation. >&2
echo.
goto error
@REM ==== END VALIDATION ====
:init
set MAVEN_CMD_LINE_ARGS=%*
@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
@REM Fallback to current working directory if not found.
set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
set EXEC_DIR=%CD%
set WDIR=%EXEC_DIR%
:findBaseDir
IF EXIST "%WDIR%"\.mvn goto baseDirFound
cd ..
IF "%WDIR%"=="%CD%" goto baseDirNotFound
set WDIR=%CD%
goto findBaseDir
:baseDirFound
set MAVEN_PROJECTBASEDIR=%WDIR%
cd "%EXEC_DIR%"
goto endDetectBaseDir
:baseDirNotFound
set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
cd "%EXEC_DIR%"
:endDetectBaseDir
IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
@setlocal EnableExtensions EnableDelayedExpansion
for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
:endReadAdditionalConfig
SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
set WRAPPER_JAR="".\.mvn\wrapper\maven-wrapper.jar""
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CMD_LINE_ARGS%
if ERRORLEVEL 1 goto error
goto end
:error
set ERROR_CODE=1
:end
@endlocal & set ERROR_CODE=%ERROR_CODE%
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
@REM check for post script, once with legacy .bat ending and once with .cmd ending
if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
:skipRcPost
@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
if "%MAVEN_BATCH_PAUSE%" == "on" pause
if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
exit /B %ERROR_CODE%
+192 -249
View File
@@ -1,18 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-build</artifactId>
<version>1.0.0.BUILD-SNAPSHOT</version>
<relativePath />
</parent>
<artifactId>spring-cloud-netflix</artifactId>
<version>1.0.0.BUILD-SNAPSHOT</version>
<version>1.4.8.BUILD-SNAPSHOT</version>
<packaging>pom</packaging>
<name>Spring Cloud Netflix</name>
<description>Spring Cloud Netflix</description>
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-build</artifactId>
<version>1.3.13.BUILD-SNAPSHOT</version>
<relativePath />
</parent>
<scm>
<url>https://github.com/spring-cloud/spring-cloud-netflix</url>
<connection>scm:git:git://github.com/spring-cloud/spring-cloud-netflix.git</connection>
@@ -20,23 +20,32 @@
<tag>HEAD</tag>
</scm>
<properties>
<bintray.package>netflix</bintray.package>
<main.basedir>${basedir}</main.basedir>
<archaius.version>0.6.5</archaius.version>
<eureka.version>1.1.147</eureka.version>
<feign.version>7.1.0</feign.version>
<hystrix.version>1.4.0-RC6</hystrix.version>
<ribbon.version>2.0-RC13</ribbon.version>
<zuul.version>1.0.28</zuul.version>
<netflix.rxjava.version>0.20.7</netflix.rxjava.version>
<java.version>1.7</java.version>
<spring-integration-dsl.version>1.0.0.RELEASE</spring-integration-dsl.version>
<cloud-connectors.version>1.1.1.BUILD-SNAPSHOT</cloud-connectors.version>
<netty.version>4.0.27.Final</netty.version>
<jackson.version>2.7.3</jackson.version>
<spring-cloud-commons.version>1.3.6.BUILD-SNAPSHOT</spring-cloud-commons.version>
<spring-cloud-config.version>1.4.7.BUILD-SNAPSHOT</spring-cloud-config.version>
<spring-cloud-stream.version>Ditmars.BUILD-SNAPSHOT</spring-cloud-stream.version>
<!-- Has to be a stable version (not one that depends on this version of netflix): -->
<donotreplacespring-cloud-contract.version>1.1.2.RELEASE</donotreplacespring-cloud-contract.version>
<!-- Plugin versions -->
<maven-compiler-plugin.version>3.6.1</maven-compiler-plugin.version>
<maven-eclipse-plugin.version>2.10</maven-eclipse-plugin.version>
<!-- Sonar -->
<surefire.plugin.version>2.19.1</surefire.plugin.version>
<sonar.java.coveragePlugin>jacoco</sonar.java.coveragePlugin>
<sonar.dynamicAnalysis>reuseReports</sonar.dynamicAnalysis>
<sonar.jacoco.reportPath>${project.basedir}/../target/jacoco.exec</sonar.jacoco.reportPath>
<sonar.language>java</sonar.language>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-eclipse-plugin</artifactId>
<version>${maven-eclipse-plugin.version}</version>
<configuration>
<useProjectReferences>false</useProjectReferences>
<additionalConfig>
@@ -53,6 +62,7 @@
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>${maven-compiler-plugin.version}</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
@@ -62,261 +72,194 @@
</build>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix-hystrix-contract</artifactId>
<version>${project.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix-dependencies</artifactId>
<version>${project.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-commons-dependencies</artifactId>
<version>${spring-cloud-commons.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-commons</artifactId>
<version>1.0.0.BUILD-SNAPSHOT</version>
<type>test-jar</type>
<scope>test</scope>
<version>${spring-cloud-commons.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-client</artifactId>
<version>1.0.0.BUILD-SNAPSHOT</version>
<artifactId>spring-cloud-config-dependencies</artifactId>
<version>${spring-cloud-config.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
<version>1.0.0.BUILD-SNAPSHOT</version>
<artifactId>spring-cloud-stream-dependencies</artifactId>
<version>${spring-cloud-stream.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix-core</artifactId>
<version>1.0.0.BUILD-SNAPSHOT</version>
<artifactId>spring-cloud-contract-dependencies</artifactId>
<version>${donotreplacespring-cloud-contract.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix-eureka-server</artifactId>
<version>1.0.0.BUILD-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix-hystrix-dashboard</artifactId>
<version>1.0.0.BUILD-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix-hystrix-amqp</artifactId>
<version>1.0.0.BUILD-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix-turbine</artifactId>
<version>1.0.0.BUILD-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix-turbine-amqp</artifactId>
<version>1.0.0.BUILD-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix-zuul-server</artifactId>
<version>1.0.0.BUILD-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.netflix.archaius</groupId>
<artifactId>archaius-core</artifactId>
<version>${archaius.version}</version>
<exclusions>
<exclusion>
<artifactId>commons-logging</artifactId>
<groupId>commons-logging</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.netflix.eureka</groupId>
<artifactId>eureka-client</artifactId>
<version>${eureka.version}</version>
<exclusions>
<exclusion>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.netflix.eureka</groupId>
<artifactId>eureka-core</artifactId>
<version>${eureka.version}</version>
<exclusions>
<exclusion>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
</exclusion>
<exclusion>
<artifactId>commons-logging</artifactId>
<groupId>commons-logging</groupId>
</exclusion>
<exclusion>
<artifactId>log4j</artifactId>
<groupId>log4j</groupId>
</exclusion>
<exclusion>
<artifactId>com.netflix.blitz4j</artifactId>
<groupId>blitz4j</groupId>
</exclusion>
</exclusions>
</dependency>
<!-- Eureka core dep that is now optional -->
<dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
<version>1.4.2</version>
</dependency>
<!-- Eureka server dep that is now optional -->
<dependency>
<groupId>com.netflix.blitz4j</groupId>
<artifactId>blitz4j</artifactId>
<version>1.36.0</version>
</dependency>
<dependency>
<groupId>com.netflix.feign</groupId>
<artifactId>feign-core</artifactId>
<version>${feign.version}</version>
</dependency>
<dependency>
<groupId>com.netflix.feign</groupId>
<artifactId>feign-ribbon</artifactId>
<version>${feign.version}</version>
<exclusions>
<exclusion>
<groupId>com.netflix.ribbon</groupId>
<artifactId>ribbon-loadbalancer</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- TODO: remove with feign 8.0.0 -->
<dependency>
<groupId>com.squareup.dagger</groupId>
<artifactId>dagger</artifactId>
<version>1.2.2</version>
</dependency>
<dependency>
<groupId>com.netflix.feign</groupId>
<artifactId>feign-slf4j</artifactId>
<version>${feign.version}</version>
</dependency>
<dependency>
<groupId>com.netflix.hystrix</groupId>
<artifactId>hystrix-core</artifactId>
<version>${hystrix.version}</version>
</dependency>
<dependency>
<groupId>com.netflix.hystrix</groupId>
<artifactId>hystrix-metrics-event-stream</artifactId>
<version>${hystrix.version}</version>
</dependency>
<dependency>
<groupId>com.netflix.hystrix</groupId>
<artifactId>hystrix-javanica</artifactId>
<version>${hystrix.version}</version>
</dependency>
<dependency>
<groupId>com.netflix.ribbon</groupId>
<artifactId>ribbon</artifactId>
<version>${ribbon.version}</version>
</dependency>
<dependency>
<groupId>com.netflix.ribbon</groupId>
<artifactId>ribbon-core</artifactId>
<version>${ribbon.version}</version>
</dependency>
<dependency>
<groupId>com.netflix.ribbon</groupId>
<artifactId>ribbon-httpclient</artifactId>
<version>${ribbon.version}</version>
</dependency>
<dependency>
<groupId>com.netflix.ribbon</groupId>
<artifactId>ribbon-eureka</artifactId>
<version>${ribbon.version}</version>
<exclusions>
<exclusion>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.netflix.rxjava</groupId>
<artifactId>rxjava-core</artifactId>
<version>${netflix.rxjava.version}</version>
</dependency>
<dependency>
<groupId>com.netflix.zuul</groupId>
<artifactId>zuul-core</artifactId>
<version>${zuul.version}</version>
<exclusions>
<exclusion>
<artifactId>groovy-all</artifactId>
<groupId>org.codehaus.groovy</groupId>
</exclusion>
<exclusion>
<artifactId>mockito-all</artifactId>
<groupId>org.mockito</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-java-dsl</artifactId>
<version>${spring-integration-dsl.version}</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>18.0</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-servlet</artifactId>
<version>1.13</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-core</artifactId>
<version>1.13</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-client</artifactId>
<version>1.13</version>
</dependency>
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-server</artifactId>
<version>1.13</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>d3js</artifactId>
<version>3.4.11</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>2.1.1</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>3.2.0</version>
</dependency>
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-smile</artifactId>
<version>${jackson.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<modules>
<module>spring-cloud-netflix-dependencies</module>
<!-- Not part of the reactor build: build and deploy separately -->
<!--module>spring-cloud-netflix-hystrix-contract</module-->
<module>spring-cloud-netflix-core</module>
<module>spring-cloud-netflix-hystrix-dashboard</module>
<module>spring-cloud-netflix-hystrix-amqp</module>
<module>spring-cloud-netflix-hystrix-stream</module>
<module>spring-cloud-netflix-eureka-client</module>
<module>spring-cloud-netflix-eureka-server</module>
<module>spring-cloud-netflix-spectator</module>
<module>spring-cloud-netflix-turbine</module>
<module>spring-cloud-netflix-turbine-amqp</module>
<module>spring-cloud-netflix-turbine-stream</module>
<module>spring-cloud-netflix-sidecar</module>
<module>spring-cloud-starter-netflix</module>
<module>spring-cloud-starter-archaius</module>
<module>spring-cloud-starter-atlas</module>
<module>spring-cloud-starter-eureka</module>
<module>spring-cloud-starter-eureka-server</module>
<module>spring-cloud-starter-feign</module>
<module>spring-cloud-starter-hystrix</module>
<module>spring-cloud-starter-hystrix-dashboard</module>
<module>spring-cloud-starter-ribbon</module>
<module>spring-cloud-starter-spectator</module>
<module>spring-cloud-starter-turbine</module>
<module>spring-cloud-starter-turbine-amqp</module>
<module>spring-cloud-starter-turbine-stream</module>
<module>spring-cloud-starter-zuul</module>
<module>docs</module>
</modules>
<profiles>
<profile>
<id>spring</id>
<repositories>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/libs-snapshot-local</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
<releases>
<enabled>false</enabled>
</releases>
</repository>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/libs-milestone-local</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>spring-releases</id>
<name>Spring Releases</name>
<url>https://repo.spring.io/release</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/libs-snapshot-local</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
<releases>
<enabled>false</enabled>
</releases>
</pluginRepository>
<pluginRepository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/libs-milestone-local</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
<pluginRepository>
<id>spring-releases</id>
<name>Spring Releases</name>
<url>https://repo.spring.io/libs-release-local</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
</profile>
<profile>
<id>sonar</id>
<build>
<plugins>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<executions>
<execution>
<id>pre-unit-test</id>
<goals>
<goal>prepare-agent</goal>
</goals>
<configuration>
<propertyName>surefireArgLine</propertyName>
<destFile>${project.build.directory}/jacoco.exec</destFile>
</configuration>
</execution>
<execution>
<id>post-unit-test</id>
<phase>test</phase>
<goals>
<goal>report</goal>
</goals>
<configuration>
<!-- Sets the path to the file which contains the execution data. -->
<dataFile>${project.build.directory}/jacoco.exec</dataFile>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<!-- Sets the VM argument line used when unit tests are run. -->
<argLine>${surefireArgLine}</argLine>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
+4
View File
@@ -0,0 +1,4 @@
#!/bin/bash
(cd spring-cloud-netflix-hystrix-contract && ../mvnw clean install -B -Pdocs ${@})
./mvnw clean install -B -Pdocs ${@}
+27
View File
@@ -0,0 +1,27 @@
#!/bin/bash
set -o errexit
mkdir -p target
SCRIPT_URL="https://raw.githubusercontent.com/spring-cloud-samples/brewery/master/runAcceptanceTests.sh"
AT_WHAT_TO_TEST="EUREKA"
cd target
curl "${SCRIPT_URL}" --output runAcceptanceTests.sh
chmod +x runAcceptanceTests.sh
echo "Killing all running apps"
./runAcceptanceTests.sh -t "${AT_WHAT_TO_TEST}" --killnow --branch edgware
./runAcceptanceTests.sh -t "${AT_WHAT_TO_TEST}" --killattheend --branch edgware
SCRIPT_URL="https://raw.githubusercontent.com/spring-cloud-samples/tests/master/scripts/runTests.sh"
curl "${SCRIPT_URL}" --output runIntegrationTests.sh
chmod +x runIntegrationTests.sh
./runIntegrationTests.sh
+130 -40
View File
@@ -1,12 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix</artifactId>
<version>1.0.0.BUILD-SNAPSHOT</version>
<relativePath>..</relativePath>
<version>1.4.8.BUILD-SNAPSHOT</version>
<relativePath>..</relativePath> <!-- lookup parent from repository -->
</parent>
<artifactId>spring-cloud-netflix-core</artifactId>
<packaging>jar</packaging>
@@ -16,6 +16,11 @@
<main.basedir>${basedir}/..</main.basedir>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
@@ -24,19 +29,38 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-commons</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-client</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-server</artifactId>
<artifactId>spring-cloud-context</artifactId>
<optional>true</optional>
</dependency>
<dependency>
@@ -44,46 +68,56 @@
<artifactId>archaius-core</artifactId>
<optional>true</optional>
</dependency>
<!-- archaius dependencies that are now runtime -->
<dependency>
<groupId>com.netflix.eureka</groupId>
<artifactId>eureka-client</artifactId>
<groupId>commons-configuration</groupId>
<artifactId>commons-configuration</artifactId>
<optional>true</optional>
</dependency>
<!-- end archaius deps -->
<dependency>
<groupId>com.netflix.servo</groupId>
<artifactId>servo-core</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.netflix.eureka</groupId>
<artifactId>eureka-core</artifactId>
<optional>true</optional>
</dependency>
<!-- Eureka core deps that are now optional -->
<dependency>
<groupId>com.thoughtworks.xstream</groupId>
<artifactId>xstream</artifactId>
<groupId>com.netflix.netflix-commons</groupId>
<artifactId>netflix-commons-util</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>net.java.dev.rome</groupId>
<artifactId>rome</artifactId>
<version>1.0.0</version>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.netflix.feign</groupId>
<groupId>com.netflix.ribbon</groupId>
<artifactId>ribbon-loadbalancer</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-core</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.netflix.feign</groupId>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-slf4j</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.netflix.feign</groupId>
<artifactId>feign-ribbon</artifactId>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-httpclient</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.squareup.dagger</groupId>
<artifactId>dagger</artifactId>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-hystrix</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-okhttp</artifactId>
<optional>true</optional>
</dependency>
<dependency>
@@ -111,11 +145,6 @@
<artifactId>ribbon-core</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.netflix.ribbon</groupId>
<artifactId>ribbon-eureka</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.netflix.ribbon</groupId>
<artifactId>ribbon-httpclient</artifactId>
@@ -130,18 +159,25 @@
<artifactId>groovy-all</artifactId>
<groupId>org.codehaus.groovy</groupId>
</exclusion>
<exclusion>
<artifactId>mockito-all</artifactId>
<groupId>org.mockito</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.netflix.rxjava</groupId>
<artifactId>rxjava-core</artifactId>
<groupId>io.reactivex</groupId>
<artifactId>rxjava</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<!-- Only needed at compile time -->
<scope>compile</scope>
<groupId>com.sun.jersey.contribs</groupId>
<artifactId>jersey-apache-client4</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<optional>true</optional>
</dependency>
<dependency>
@@ -149,5 +185,59 @@
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-commons</artifactId>
<type>test-jar</type>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-smile</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>com.googlecode.protobuf-java-format</groupId>
<artifactId>protobuf-java-format</artifactId>
<version>1.4</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>3.4.0</version>
<scope>test</scope>
</dependency>
</dependencies>
<profiles>
<profile>
<id>java8plus</id>
<activation>
<jdk>[1.8,2.0)</jdk>
</activation>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<compilerArgs>
<arg>-parameters</arg>
</compilerArgs>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* 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,
@@ -17,35 +17,44 @@
package org.springframework.cloud.netflix.archaius;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.annotation.PreDestroy;
import lombok.extern.apachecommons.CommonsLog;
import com.netflix.config.AggregatedConfiguration;
import com.netflix.config.ConcurrentCompositeConfiguration;
import com.netflix.config.ConfigurationManager;
import com.netflix.config.DeploymentContext;
import com.netflix.config.DynamicProperty;
import com.netflix.config.DynamicPropertyFactory;
import com.netflix.config.DynamicURLConfiguration;
import org.apache.commons.configuration.AbstractConfiguration;
import org.apache.commons.configuration.ConfigurationBuilder;
import org.apache.commons.configuration.EnvironmentConfiguration;
import org.apache.commons.configuration.SystemConfiguration;
import org.apache.commons.configuration.event.ConfigurationEvent;
import org.apache.commons.configuration.event.ConfigurationListener;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.condition.ConditionalOnEnabledEndpoint;
import org.springframework.boot.actuate.endpoint.Endpoint;
import org.springframework.boot.autoconfigure.AutoConfigureOrder;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cloud.context.environment.EnvironmentChangeEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.Environment;
import org.springframework.util.ReflectionUtils;
import com.netflix.config.ConcurrentCompositeConfiguration;
import com.netflix.config.ConfigurationManager;
import com.netflix.config.DynamicPropertyFactory;
import com.netflix.config.DynamicURLConfiguration;
import static com.netflix.config.ConfigurationBasedDeploymentContext.DEPLOYMENT_APPLICATION_ID_PROPERTY;
import static com.netflix.config.ConfigurationManager.APPLICATION_PROPERTIES;
import static com.netflix.config.ConfigurationManager.DISABLE_DEFAULT_ENV_CONFIG;
import static com.netflix.config.ConfigurationManager.DISABLE_DEFAULT_SYS_CONFIG;
@@ -57,21 +66,33 @@ import static com.netflix.config.ConfigurationManager.URL_CONFIG_NAME;
* @author Spencer Gibb
*/
@Configuration
@ConditionalOnClass({ ConcurrentCompositeConfiguration.class, ConfigurationBuilder.class })
@CommonsLog
@ConditionalOnClass({ ConcurrentCompositeConfiguration.class,
ConfigurationBuilder.class })
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
public class ArchaiusAutoConfiguration {
private static final Log log = LogFactory.getLog(ArchaiusAutoConfiguration.class);
private static final AtomicBoolean initialized = new AtomicBoolean(false);
@Autowired
private ConfigurableEnvironment env;
@Autowired(required = false)
private List<AbstractConfiguration> externalConfigurations = new ArrayList<>();
private DynamicURLConfiguration defaultURLConfig;
@PreDestroy
public void close() {
if (defaultURLConfig != null) {
defaultURLConfig.stopLoading();
}
setStatic(ConfigurationManager.class, "instance", null);
setStatic(ConfigurationManager.class, "customConfigurationInstalled", false);
setStatic(DynamicPropertyFactory.class, "config", null);
setStatic(DynamicPropertyFactory.class, "initializedWithDefaultConfig", false);
setStatic(DynamicProperty.class, "dynamicPropertySupportImpl", null);
initialized.compareAndSet(true, false);
}
@@ -85,7 +106,8 @@ public class ArchaiusAutoConfiguration {
@Configuration
@ConditionalOnClass(Endpoint.class)
protected static class ArchaiusEndpointConfuguration {
@ConditionalOnEnabledEndpoint("archaius")
protected static class ArchaiusEndpointConfiguration {
@Bean
protected ArchaiusEndpoint archaiusEndpoint() {
return new ArchaiusEndpoint();
@@ -95,7 +117,8 @@ public class ArchaiusAutoConfiguration {
@Configuration
@ConditionalOnProperty(value = "archaius.propagate.environmentChangedEvent", matchIfMissing = true)
@ConditionalOnClass(EnvironmentChangeEvent.class)
protected static class PropagateEventsConfiguration implements ApplicationListener<EnvironmentChangeEvent> {
protected static class PropagateEventsConfiguration
implements ApplicationListener<EnvironmentChangeEvent> {
@Autowired
private Environment env;
@@ -103,20 +126,20 @@ public class ArchaiusAutoConfiguration {
public void onApplicationEvent(EnvironmentChangeEvent event) {
AbstractConfiguration manager = ConfigurationManager.getConfigInstance();
for (String key : event.getKeys()) {
for (ConfigurationListener listener : manager.getConfigurationListeners()) {
for (ConfigurationListener listener : manager
.getConfigurationListeners()) {
Object source = event.getSource();
// TODO: Handle add vs set vs delete?
int type = AbstractConfiguration.EVENT_SET_PROPERTY;
String value = env.getProperty(key);
String value = this.env.getProperty(key);
boolean beforeUpdate = false;
listener.configurationChanged(new ConfigurationEvent(source,
type, key, value, beforeUpdate));
listener.configurationChanged(new ConfigurationEvent(source, type,
key, value, beforeUpdate));
}
}
}
}
@SuppressWarnings("deprecation")
protected void configureArchaius(ConfigurableEnvironmentConfiguration envConfig) {
if (initialized.compareAndSet(false, true)) {
String appName = this.env.getProperty("spring.application.name");
@@ -124,25 +147,21 @@ public class ArchaiusAutoConfiguration {
appName = "application";
log.warn("No spring.application.name found, defaulting to 'application'");
}
// this is deprecated, but currently it seams the only way to set it initially
System.setProperty(DEPLOYMENT_APPLICATION_ID_PROPERTY, appName);
// TODO: support for other DeploymentContexts
System.setProperty(DeploymentContext.ContextKey.appId.getKey(), appName);
ConcurrentCompositeConfiguration config = new ConcurrentCompositeConfiguration();
// support to add other Configurations (Jdbc, DynamoDb, Zookeeper, jclouds,
// etc...)
/*
* if (factories != null && !factories.isEmpty()) { for
* (PropertiesSourceFactory factory: factories) {
* config.addConfiguration(factory.getConfiguration(), factory.getName()); } }
*/
if (this.externalConfigurations != null) {
for (AbstractConfiguration externalConfig : this.externalConfigurations) {
config.addConfiguration(externalConfig);
}
}
config.addConfiguration(envConfig,
ConfigurableEnvironmentConfiguration.class.getSimpleName());
// below come from ConfigurationManager.createDefaultConfigInstance()
DynamicURLConfiguration defaultURLConfig = new DynamicURLConfiguration();
defaultURLConfig = new DynamicURLConfiguration();
try {
config.addConfiguration(defaultURLConfig, URL_CONFIG_NAME);
}
@@ -162,14 +181,36 @@ public class ArchaiusAutoConfiguration {
ConcurrentCompositeConfiguration appOverrideConfig = new ConcurrentCompositeConfiguration();
config.addConfiguration(appOverrideConfig, APPLICATION_PROPERTIES);
config.setContainerConfigurationIndex(config
.getIndexOfConfiguration(appOverrideConfig));
config.setContainerConfigurationIndex(
config.getIndexOfConfiguration(appOverrideConfig));
ConfigurationManager.install(config);
addArchaiusConfiguration(config);
}
else {
// TODO: reinstall ConfigurationManager
log.warn("Netflix ConfigurationManager has already been installed, unable to re-install");
log.warn(
"Netflix ConfigurationManager has already been installed, unable to re-install");
}
}
private void addArchaiusConfiguration(ConcurrentCompositeConfiguration config) {
if (ConfigurationManager.isConfigurationInstalled()) {
AbstractConfiguration installedConfiguration = ConfigurationManager
.getConfigInstance();
if (installedConfiguration instanceof ConcurrentCompositeConfiguration) {
ConcurrentCompositeConfiguration configInstance = (ConcurrentCompositeConfiguration) installedConfiguration;
configInstance.addConfiguration(config);
}
else {
installedConfiguration.append(config);
if (!(installedConfiguration instanceof AggregatedConfiguration)) {
log.warn(
"Appending a configuration to an existing non-aggregated installed configuration will have no effect");
}
}
}
else {
ConfigurationManager.install(config);
}
}
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* 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,
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* 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,
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* 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,
@@ -1,117 +0,0 @@
/*
* Copyright 2013-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.netflix.config;
import lombok.extern.apachecommons.CommonsLog;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.discovery.event.HeartbeatEvent;
import org.springframework.cloud.client.discovery.event.HeartbeatMonitor;
import org.springframework.cloud.config.client.ConfigClientProperties;
import org.springframework.cloud.config.client.ConfigServicePropertySourceLocator;
import org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.context.event.SmartApplicationListener;
import com.netflix.appinfo.InstanceInfo;
import com.netflix.discovery.DiscoveryClient;
/**
* Bootstrap configuration for a config client that wants to lookup the config server via
* discovery.
*
* @author Dave Syer
*/
@ConditionalOnClass({ DiscoveryClient.class, ConfigServicePropertySourceLocator.class })
@ConditionalOnExpression("${spring.cloud.config.discovery.enabled:false}")
@Configuration
@EnableDiscoveryClient
@Import(EurekaClientAutoConfiguration.class)
@CommonsLog
public class DiscoveryClientConfigServiceBootstrapConfiguration implements
SmartApplicationListener {
private HeartbeatMonitor monitor = new HeartbeatMonitor();
@Autowired
private DiscoveryClient client;
@Autowired
private ConfigClientProperties config;
@Override
public void onApplicationEvent(ApplicationEvent event) {
if (event instanceof ContextRefreshedEvent) {
refresh();
}
else if (event instanceof HeartbeatEvent) {
if (this.monitor.update(((HeartbeatEvent) event).getValue())) {
refresh();
}
}
}
@Override
public int getOrder() {
return 0;
}
@Override
public boolean supportsEventType(Class<? extends ApplicationEvent> eventType) {
return ContextRefreshedEvent.class.isAssignableFrom(eventType)
|| HeartbeatEvent.class.isAssignableFrom(eventType);
}
@Override
public boolean supportsSourceType(Class<?> sourceType) {
return true;
}
private void refresh() {
try {
log.info("Locating configserver via discovery");
InstanceInfo server = this.client.getNextServerFromEureka(this.config
.getDiscovery().getServiceId(), false);
String url = server.getHomePageUrl();
if (server.getMetadata().containsKey("password")) {
String user = server.getMetadata().get("user");
user = user == null ? "user" : user;
this.config.setUsername(user);
String password = server.getMetadata().get("password");
this.config.setPassword(password);
}
if (server.getMetadata().containsKey("configPath")) {
String path = server.getMetadata().get("configPath");
if (url.endsWith("/") && path.startsWith("/")) {
url = url.substring(0, url.length() - 1);
}
url = url + path;
}
this.config.setUri(url);
}
catch (Exception ex) {
log.warn("Could not locate configserver via discovery", ex);
}
}
}
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* 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,
@@ -16,6 +16,7 @@
package org.springframework.cloud.netflix.endpoint;
import javax.servlet.Servlet;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -60,8 +61,8 @@ public abstract class ServletWrappingEndpoint implements InitializingBean,
this.controller.setApplicationContext(applicationContext);
}
protected ServletWrappingEndpoint(Class<?> servletClass, String servletName,
String path, boolean sensitive, boolean enabled) {
protected ServletWrappingEndpoint(Class<? extends Servlet> servletClass,
String servletName, String path, boolean sensitive, boolean enabled) {
this.controller.setServletClass(servletClass);
this.controller.setServletName(servletName);
this.path = path;
@@ -76,12 +77,13 @@ public abstract class ServletWrappingEndpoint implements InitializingBean,
}
public boolean isEnabled() {
return enabled;
return this.enabled;
}
public ServletWrappingController getController() {
return controller;
return this.controller;
}
@Override
public String getPath() {
return this.path;
@@ -1,208 +0,0 @@
/*
* Copyright 2013-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.netflix.eureka;
import lombok.extern.apachecommons.CommonsLog;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.aop.framework.ProxyFactory;
import org.springframework.cloud.client.discovery.event.HeartbeatEvent;
import org.springframework.context.ApplicationContext;
import com.netflix.appinfo.DataCenterInfo;
import com.netflix.appinfo.DataCenterInfo.Name;
import com.netflix.appinfo.InstanceInfo;
import com.netflix.appinfo.UniqueIdentifier;
import com.netflix.discovery.converters.Converters.ApplicationsConverter;
import com.netflix.discovery.converters.Converters.InstanceInfoConverter;
import com.netflix.discovery.shared.Applications;
import com.thoughtworks.xstream.MarshallingStrategy;
import com.thoughtworks.xstream.converters.Converter;
import com.thoughtworks.xstream.converters.ConverterLookup;
import com.thoughtworks.xstream.converters.DataHolder;
import com.thoughtworks.xstream.converters.MarshallingContext;
import com.thoughtworks.xstream.converters.UnmarshallingContext;
import com.thoughtworks.xstream.core.TreeMarshallingStrategy;
import com.thoughtworks.xstream.io.HierarchicalStreamReader;
import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
import com.thoughtworks.xstream.mapper.Mapper;
/**
* A special purpose wrapper for an XStream TreeMarshallingStrategy that is aware of the
* {@link InstanceInfo} type and can create a more useful {@link DataCenterInfo} for it
* after unmarshalling. If the InstanceInfo has a metadataMap containing an
* <code>instanceId</code>, and the DataCenterInfo is not already an AmazonInfo, then the
* instanceId is used to create an identifier, but appending it to the existing one. This
* is useful when not running Eureka in bare EC2 VMs, so the EC2 metadata is not available
* for uniquely identifying the InstanceInfo (the default is to just use the hostname, but
* that isn't very useful when sitting behind a proxy).
*
* @author Dave Syer
*/
public class DataCenterAwareMarshallingStrategy implements MarshallingStrategy {
private TreeMarshallingStrategy delegate = new TreeMarshallingStrategy();
private ApplicationContext context;
public DataCenterAwareMarshallingStrategy(ApplicationContext context) {
this.context = context;
}
@Override
public Object unmarshal(Object root, HierarchicalStreamReader reader,
DataHolder dataHolder, ConverterLookup converterLookup, Mapper mapper) {
ConverterLookup wrapped = new DataCenterAwareConverterLookup(converterLookup,
this.context);
return this.delegate.unmarshal(root, reader, dataHolder, wrapped, mapper);
}
@Override
public void marshal(HierarchicalStreamWriter writer, Object obj,
ConverterLookup converterLookup, Mapper mapper, DataHolder dataHolder) {
ConverterLookup wrapped = new DataCenterAwareConverterLookup(converterLookup,
this.context);
this.delegate.marshal(writer, obj, wrapped, mapper, dataHolder);
}
public static class InstanceIdDataCenterInfo implements DataCenterInfo,
UniqueIdentifier {
private String instanceId;
public InstanceIdDataCenterInfo(String instanceId) {
this.instanceId = instanceId;
}
@Override
public Name getName() {
return Name.MyOwn;
}
@Override
public String getId() {
return this.instanceId;
}
}
private static class DataCenterAwareConverterLookup implements ConverterLookup {
private ConverterLookup delegate;
private ApplicationContext context;
public DataCenterAwareConverterLookup(ConverterLookup delegate,
ApplicationContext context) {
this.delegate = delegate;
this.context = context;
}
@Override
public Converter lookupConverterForType(@SuppressWarnings("rawtypes") Class type) {
Converter converter = this.delegate.lookupConverterForType(type);
if (InstanceInfo.class == type) {
return new DataCenterAwareConverter();
}
else if (Applications.class == type) {
return new PublishingApplicationsConverter(this.context);
}
return converter;
}
}
private static class PublishingApplicationsConverter extends ApplicationsConverter {
private ApplicationContext context;
public PublishingApplicationsConverter(ApplicationContext context) {
this.context = context;
}
@Override
public Object unmarshal(HierarchicalStreamReader reader,
UnmarshallingContext unmarshallingContext) {
Object obj = super.unmarshal(reader, unmarshallingContext);
ProxyFactory factory = new ProxyFactory(obj);
factory.addAdvice(new SetVersionInterceptor(this.context));
return factory.getProxy();
}
}
@CommonsLog
private static class SetVersionInterceptor implements MethodInterceptor {
private ApplicationContext context;
public SetVersionInterceptor(ApplicationContext context) {
this.context = context;
}
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
Object ret = invocation.proceed();
if ("setVersion".equals(invocation.getMethod().getName())) {
Long version = Long.class.cast(invocation.getArguments()[0]);
log.debug("Applications.setVersion() called with version: " + version);
this.context.publishEvent(new HeartbeatEvent(invocation
.getThis(), version));
}
return ret;
}
}
private static class DataCenterAwareConverter extends InstanceInfoConverter {
@Override
public void marshal(Object source, HierarchicalStreamWriter writer,
MarshallingContext context) {
InstanceInfo info = (InstanceInfo) source;
String instanceId = info.getMetadata().get("instanceId");
DataCenterInfo dataCenter = info.getDataCenterInfo();
if (instanceId != null && Name.Amazon != dataCenter.getName()) {
String old = info.getId();
String id = old.endsWith(instanceId) ? old : old + ":" + instanceId;
info = new InstanceInfo.Builder(info).setDataCenterInfo(
new InstanceIdDataCenterInfo(id)).build();
source = info;
}
super.marshal(source, writer, context);
}
@Override
public Object unmarshal(HierarchicalStreamReader reader,
UnmarshallingContext context) {
Object obj = super.unmarshal(reader, context);
InstanceInfo info = (InstanceInfo) obj;
String instanceId = info.getMetadata().get("instanceId");
DataCenterInfo dataCenter = info.getDataCenterInfo();
if (instanceId != null && Name.Amazon != dataCenter.getName()) {
String old = info.getId();
String id = old.endsWith(instanceId) ? old : old + ":" + instanceId;
info = new InstanceInfo.Builder(info).setDataCenterInfo(
new InstanceIdDataCenterInfo(id)).build();
obj = info;
}
return obj;
}
}
}
@@ -1,43 +0,0 @@
/*
* Copyright 2013-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.netflix.eureka;
import org.springframework.beans.factory.annotation.Autowired;
import com.netflix.appinfo.EurekaInstanceConfig;
import com.netflix.discovery.DiscoveryManager;
import com.netflix.discovery.EurekaClientConfig;
/**
* @author Spencer Gibb
*/
public class DiscoveryManagerInitializer {
@Autowired
private EurekaClientConfig clientConfig;
@Autowired
private EurekaInstanceConfig instanceConfig;
public synchronized void init() {
if (DiscoveryManager.getInstance().getDiscoveryClient() == null) {
DiscoveryManager.getInstance().initComponent(this.instanceConfig,
this.clientConfig);
}
}
}
@@ -1,113 +0,0 @@
/*
* Copyright 2013-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.netflix.eureka;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import javax.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
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.builder.ParentContextApplicationContextInitializer;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.client.discovery.event.HeartbeatEvent;
import org.springframework.cloud.client.discovery.event.ParentHeartbeatEvent;
import org.springframework.cloud.client.discovery.noop.NoopDiscoveryClientAutoConfiguration;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationListener;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.netflix.appinfo.EurekaInstanceConfig;
import com.netflix.discovery.EurekaClientConfig;
import com.netflix.discovery.converters.JsonXStream;
import com.netflix.discovery.converters.XmlXStream;
/**
* @author Dave Syer
*/
@Configuration
@EnableConfigurationProperties
@ConditionalOnClass(EurekaClientConfig.class)
@ConditionalOnProperty(value = "eureka.client.enabled", matchIfMissing = true)
@AutoConfigureBefore(NoopDiscoveryClientAutoConfiguration.class)
public class EurekaClientAutoConfiguration implements ApplicationListener<ParentContextApplicationContextInitializer.ParentContextAvailableEvent> {
@Autowired
private ApplicationContext applicationContext;
private static final ConcurrentMap<String, String> listenerAdded = new ConcurrentHashMap<>();
@Value("${server.port:${SERVER_PORT:${PORT:8080}}}")
int nonSecurePort;
@PostConstruct
public void init() {
XmlXStream.getInstance().setMarshallingStrategy(
new DataCenterAwareMarshallingStrategy(this.applicationContext));
JsonXStream.getInstance().setMarshallingStrategy(
new DataCenterAwareMarshallingStrategy(this.applicationContext));
}
@Bean
@ConditionalOnMissingBean(EurekaClientConfig.class)
public EurekaClientConfigBean eurekaClientConfigBean() {
return new EurekaClientConfigBean();
}
@Bean
@ConditionalOnMissingBean(EurekaInstanceConfig.class)
public EurekaInstanceConfigBean eurekaInstanceConfigBean() {
EurekaInstanceConfigBean instance = new EurekaInstanceConfigBean();
instance.setNonSecurePort(this.nonSecurePort);
return instance;
}
/**
* propagate HeartbeatEvent from parent to child. Do it via a
* ParentHeartbeatEvent since events get published to the parent context,
* otherwise results in a stack overflow
* @param event
*/
@Override
public void onApplicationEvent(final ParentContextApplicationContextInitializer.ParentContextAvailableEvent event) {
final ConfigurableApplicationContext context = event.getApplicationContext();
String childId = context.getId();
ApplicationContext parent = context.getParent();
if (parent != null && "bootstrap".equals(parent.getId())
&& parent instanceof ConfigurableApplicationContext) {
if (listenerAdded.putIfAbsent(childId, childId) == null) {
@SuppressWarnings("resource")
ConfigurableApplicationContext ctx = (ConfigurableApplicationContext) parent;
ctx.addApplicationListener(new ApplicationListener<HeartbeatEvent>() {
@Override
public void onApplicationEvent(HeartbeatEvent dhe) {
context.publishEvent(new ParentHeartbeatEvent(dhe
.getSource(), dhe.getValue()));
}
});
}
}
}
}
@@ -1,189 +0,0 @@
/*
* Copyright 2013-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.netflix.eureka;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import com.netflix.discovery.EurekaClientConfig;
/**
* @author Dave Syer
*/
@Data
@ConfigurationProperties("eureka.client")
public class EurekaClientConfigBean implements EurekaClientConfig {
public static final String DEFAULT_URL = "http://localhost:8761"
+ EurekaServerConfigBean.DEFAULT_PREFIX + "/";
public static final String DEFAULT_ZONE = "defaultZone";
private static final int MINUTES = 60;
private boolean enabled = true;
private int registryFetchIntervalSeconds = 30;
private int instanceInfoReplicationIntervalSeconds = 30;
private int initialInstanceInfoReplicationIntervalSeconds = 40;
private int eurekaServiceUrlPollIntervalSeconds = 5 * MINUTES;
private String proxyPort;
private String proxyHost;
private String proxyUserName;
private String proxyPassword;
private int eurekaServerReadTimeoutSeconds = 8;
private int eurekaServerConnectTimeoutSeconds = 5;
private String backupRegistryImpl;
private int eurekaServerTotalConnections = 200;
private int eurekaServerTotalConnectionsPerHost = 50;
private String eurekaServerURLContext;
private String eurekaServerPort;
private String eurekaServerDNSName;
private String region = "us-east-1";
private int eurekaConnectionIdleTimeoutSeconds = 30;
private String registryRefreshSingleVipAddress;
private int heartbeatExecutorThreadPoolSize = 2;
private int heartbeatExecutorExponentialBackOffBound = 10;
private int cacheRefreshExecutorThreadPoolSize = 2;
private int cacheRefreshExecutorExponentialBackOffBound = 10;
private Map<String, String> serviceUrl = new HashMap<String, String>();
{
this.serviceUrl.put(DEFAULT_ZONE, DEFAULT_URL);
}
private boolean gZipContent = true;
private boolean useDnsForFetchingServiceUrls = false;
private boolean registerWithEureka = true;
private boolean preferSameZoneEureka = true;
private boolean logDeltaDiff;
private boolean disableDelta;
private String fetchRemoteRegionsRegistry;
private Map<String, String> availabilityZones = new HashMap<String, String>();
private boolean filterOnlyUpInstances = true;
private boolean fetchRegistry = true;
private String dollarReplacement = "_-";
private String escapeCharReplacement = "__";
@Override
public boolean shouldGZipContent() {
return this.gZipContent;
}
@Override
public boolean shouldUseDnsForFetchingServiceUrls() {
return this.useDnsForFetchingServiceUrls;
}
@Override
public boolean shouldRegisterWithEureka() {
return this.registerWithEureka;
}
@Override
public boolean shouldPreferSameZoneEureka() {
return this.preferSameZoneEureka;
}
@Override
public boolean shouldLogDeltaDiff() {
return this.logDeltaDiff;
}
@Override
public boolean shouldDisableDelta() {
return this.disableDelta;
}
@Override
public String fetchRegistryForRemoteRegions() {
return this.fetchRemoteRegionsRegistry;
}
@Override
public String[] getAvailabilityZones(String region) {
String value = this.availabilityZones.get(region);
if (value == null) {
value = DEFAULT_ZONE;
}
return value.split(",");
}
@Override
public List<String> getEurekaServerServiceUrls(String myZone) {
String serviceUrls = this.serviceUrl.get(myZone);
if (serviceUrls == null || serviceUrls.isEmpty()) {
serviceUrls = this.serviceUrl.get(DEFAULT_ZONE);
}
if (serviceUrls != null) {
return Arrays.asList(serviceUrls.split(","));
}
return new ArrayList<>();
}
@Override
public boolean shouldFilterOnlyUpInstances() {
return this.filterOnlyUpInstances;
}
@Override
public boolean shouldFetchRegistry() {
return this.fetchRegistry;
}
}
@@ -1,221 +0,0 @@
/*
* Copyright 2013-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.netflix.eureka;
import java.lang.reflect.Field;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import javax.annotation.PreDestroy;
import lombok.extern.apachecommons.CommonsLog;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.endpoint.Endpoint;
import org.springframework.boot.actuate.metrics.reader.MetricReader;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
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.embedded.EmbeddedServletContainerInitializedEvent;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.discovery.event.InstanceRegisteredEvent;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationListener;
import org.springframework.context.SmartLifecycle;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Lazy;
import org.springframework.context.annotation.Scope;
import org.springframework.context.annotation.ScopedProxyMode;
import org.springframework.core.Ordered;
import org.springframework.util.ReflectionUtils;
import com.netflix.appinfo.ApplicationInfoManager;
import com.netflix.appinfo.EurekaInstanceConfig;
import com.netflix.appinfo.HealthCheckHandler;
import com.netflix.appinfo.InstanceInfo.InstanceStatus;
import com.netflix.discovery.DiscoveryManager;
import com.netflix.discovery.EurekaClientConfig;
import com.netflix.discovery.shared.EurekaJerseyClient;
/**
* @author Dave Syer
*/
@Configuration
@EnableConfigurationProperties
@ConditionalOnClass(EurekaClientConfig.class)
@ConditionalOnProperty(value = "eureka.client.enabled", matchIfMissing = true)
@CommonsLog
public class EurekaDiscoveryClientConfiguration implements SmartLifecycle, Ordered {
private AtomicBoolean running = new AtomicBoolean(false);
private int order = 0;
private AtomicInteger port = new AtomicInteger(0);
@Autowired
private EurekaInstanceConfigBean instanceConfig;
@Autowired(required = false)
private HealthCheckHandler healthCheckHandler;
@Autowired
private ApplicationContext context;
@PreDestroy
public void close() {
closeDiscoveryClientJersey();
log.info("Removing application " + this.instanceConfig.getAppname()
+ " from eureka");
DiscoveryManager.getInstance().shutdownComponent();
}
private void closeDiscoveryClientJersey() {
log.info("Closing DiscoveryClient.jerseyClient");
Field jerseyClientField = ReflectionUtils.findField(
com.netflix.discovery.DiscoveryClient.class, "discoveryJerseyClient",
EurekaJerseyClient.JerseyClient.class);
if (jerseyClientField != null) {
try {
jerseyClientField.setAccessible(true);
if (DiscoveryManager.getInstance() != null &&
DiscoveryManager.getInstance().getDiscoveryClient() != null) {
Object obj = jerseyClientField.get(DiscoveryManager.getInstance()
.getDiscoveryClient());
if (obj != null) {
EurekaJerseyClient.JerseyClient jerseyClient = (EurekaJerseyClient.JerseyClient) obj;
jerseyClient.destroyResources();
}
}
}
catch (Exception ex) {
log.error("Error closing DiscoveryClient.jerseyClient", ex);
}
}
}
@Override
public void start() {
// only set the port if the nonSecurePort is 0 and this.port != 0
if (this.port.get() != 0 && this.instanceConfig.getNonSecurePort() == 0) {
this.instanceConfig.setNonSecurePort(this.port.get());
}
// only initialize if nonSecurePort is greater than 0 and it isn't already running
// because of containerPortInitializer below
if (!this.running.get() && this.instanceConfig.getNonSecurePort() > 0) {
discoveryManagerIntitializer().init();
log.info("Registering application " + this.instanceConfig.getAppname()
+ " with eureka with status "
+ this.instanceConfig.getInitialStatus());
ApplicationInfoManager.getInstance().setInstanceStatus(
this.instanceConfig.getInitialStatus());
if (this.healthCheckHandler != null) {
DiscoveryManager.getInstance().getDiscoveryClient()
.registerHealthCheck(this.healthCheckHandler);
}
this.context.publishEvent(new InstanceRegisteredEvent<>(this,
this.instanceConfig));
this.running.set(true);
}
}
@Override
public void stop() {
log.info("Unregistering application " + this.instanceConfig.getAppname()
+ " with eureka with status OUT_OF_SERVICE");
ApplicationInfoManager.getInstance().setInstanceStatus(
InstanceStatus.OUT_OF_SERVICE);
this.running.set(false);
}
@Override
public boolean isRunning() {
return this.running.get();
}
@Override
public int getPhase() {
return 0;
}
@Override
public boolean isAutoStartup() {
return true;
}
@Override
public void stop(Runnable callback) {
callback.run();
}
@Override
public int getOrder() {
return this.order;
}
@Bean
@ConditionalOnMissingBean(DiscoveryManagerInitializer.class)
public DiscoveryManagerInitializer discoveryManagerIntitializer() {
return new DiscoveryManagerInitializer();
}
@Bean
@Lazy
@Scope(proxyMode = ScopedProxyMode.TARGET_CLASS)
@ConditionalOnMissingBean(com.netflix.discovery.DiscoveryClient.class)
public com.netflix.discovery.DiscoveryClient eurekaDiscoveryClient() {
return DiscoveryManager.getInstance().getDiscoveryClient();
}
@Bean
public DiscoveryClient discoveryClient() {
return new EurekaDiscoveryClient();
}
@Bean
protected ApplicationListener<EmbeddedServletContainerInitializedEvent> containerPortInitializer() {
return new ApplicationListener<EmbeddedServletContainerInitializedEvent>() {
@Override
public void onApplicationEvent(EmbeddedServletContainerInitializedEvent event) {
// TODO: take SSL into account when Spring Boot 1.2 is available
EurekaDiscoveryClientConfiguration.this.port.compareAndSet(0, event
.getEmbeddedServletContainer().getPort());
EurekaDiscoveryClientConfiguration.this.start();
}
};
}
@Configuration
@ConditionalOnClass(Endpoint.class)
@ConditionalOnBean(MetricReader.class)
protected static class EurekaHealthIndicatorConfiguration {
@Bean
@ConditionalOnMissingBean
public EurekaHealthIndicator eurekaHealthIndicator(
com.netflix.discovery.DiscoveryClient eurekaDiscoveryClient,
MetricReader metrics, EurekaInstanceConfig config) {
return new EurekaHealthIndicator(eurekaDiscoveryClient, metrics, config);
}
}
}
@@ -1,153 +0,0 @@
/*
* Copyright 2013-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.netflix.eureka;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.HashMap;
import java.util.Map;
import lombok.AccessLevel;
import lombok.Data;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import com.netflix.appinfo.DataCenterInfo;
import com.netflix.appinfo.EurekaInstanceConfig;
import com.netflix.appinfo.InstanceInfo.InstanceStatus;
import com.netflix.appinfo.UniqueIdentifier;
/**
* @author Dave Syer
*/
@Data
@ConfigurationProperties("eureka.instance")
public class EurekaInstanceConfigBean implements EurekaInstanceConfig {
private static final Log logger = LogFactory.getLog(EurekaInstanceConfigBean.class);
@Getter(AccessLevel.PRIVATE)
@Setter(AccessLevel.PRIVATE)
private String[] hostInfo = initHostInfo();
@Value("${spring.application.name:unknown}")
private String appname = "unknown";
private String appGroupName;
private boolean instanceEnabledOnit;
private int nonSecurePort = 80;
private int securePort = 443;
private boolean nonSecurePortEnabled = true;
private boolean securePortEnabled;
private int leaseRenewalIntervalInSeconds = 30;
private int leaseExpirationDurationInSeconds = 90;
@Value("${spring.application.name:unknown}")
private String virtualHostName;
private String secureVirtualHostName;
private String aSGName;
private Map<String, String> metadataMap = new HashMap<>();
private DataCenterInfo dataCenterInfo = new IdentifyingDataCenterInfo();
private String ipAddress = this.hostInfo[0];
private String statusPageUrlPath = "/info";
private String statusPageUrl;
private String homePageUrlPath = "/";
private String homePageUrl;
private String healthCheckUrlPath = "/health";
private String healthCheckUrl;
private String secureHealthCheckUrl;
private String namespace = "eureka";
private String hostname = this.hostInfo[1];
private boolean preferIpAddress = false;
private InstanceStatus initialStatus = InstanceStatus.UP;
public String getHostname() {
return this.preferIpAddress ? this.ipAddress : this.hostname;
}
@Override
public boolean getSecurePortEnabled() {
return this.securePortEnabled;
}
private String[] initHostInfo() {
String[] info = new String[2];
try {
info[0] = InetAddress.getLocalHost().getHostAddress();
info[1] = InetAddress.getLocalHost().getHostName();
}
catch (UnknownHostException ex) {
logger.error("Cannot get host info", ex);
}
return info;
}
@Override
public String getHostName(boolean refresh) {
return this.preferIpAddress ? this.ipAddress : this.hostname;
}
private final class IdentifyingDataCenterInfo implements DataCenterInfo,
UniqueIdentifier {
@Getter
@Setter
private Name name = Name.MyOwn;
@Override
public String getId() {
String instanceId = EurekaInstanceConfigBean.this.metadataMap
.get("instanceId");
if (instanceId != null) {
String old = getHostname();
String id = old.endsWith(instanceId) ? old : old + ":" + instanceId;
return id;
}
return getHostname();
}
}
}
@@ -1,208 +0,0 @@
/*
* Copyright 2013-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.netflix.eureka;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import com.netflix.eureka.EurekaServerConfig;
/**
* @author Dave Syer
*/
@Data
@ConfigurationProperties("eureka.server")
public class EurekaServerConfigBean implements EurekaServerConfig {
public static final String DEFAULT_PREFIX = "/eureka";
private static final int MINUTES = 60 * 1000;
private String aWSAccessId;
private String aWSSecretKey;
private int eIPBindRebindRetries = 3;
private int eIPBindingRetryIntervalMs = 5 * MINUTES;
private boolean enableSelfPreservation = true;
private double renewalPercentThreshold = 0.85;
private int renewalThresholdUpdateIntervalMs = 10 * MINUTES;
private int peerEurekaNodesUpdateIntervalMs = 15 * MINUTES;
private int numberOfReplicationRetries = 5;
private int peerEurekaStatusRefreshTimeIntervalMs = 30 * 1000;
private int waitTimeInMsWhenSyncEmpty = 5 * MINUTES;
private int peerNodeConnectTimeoutMs = 200;
private int peerNodeReadTimeoutMs = 200;
private int peerNodeTotalConnections = 1000;
private int peerNodeTotalConnectionsPerHost = 500;
private int peerNodeConnectionIdleTimeoutSeconds = 30;
private long retentionTimeInMSInDeltaQueue = 3 * MINUTES;
private long deltaRetentionTimerIntervalInMs = 30 * 1000;
private long evictionIntervalTimerInMs = 60 * 1000;
private int aSGQueryTimeoutMs = 300;
private long aSGUpdateIntervalMs = 5 * MINUTES;
private long responseCacheAutoExpirationInSeconds = 180;
private long responseCacheUpdateIntervalMs = 30 * 1000;
private boolean disableDelta;
private long maxIdleThreadInMinutesAgeForStatusReplication = 10;
private int minThreadsForStatusReplication = 1;
private int maxThreadsForStatusReplication = 1;
private int maxElementsInStatusReplicationPool = 10000;
private boolean syncWhenTimestampDiffers = true;
private int registrySyncRetries = 5;
private int maxElementsInPeerReplicationPool = 10000;
private long maxIdleThreadAgeInMinutesForPeerReplication = 15;
private int minThreadsForPeerReplication = 5;
private int maxThreadsForPeerReplication = 20;
private int maxTimeForReplication = 30000;
private boolean primeAwsReplicaConnections = true;
private boolean disableDeltaForRemoteRegions;
private int remoteRegionConnectTimeoutMs = 1000;
private int remoteRegionReadTimeoutMs = 1000;
private int remoteRegionTotalConnections = 1000;
private int remoteRegionTotalConnectionsPerHost = 500;
private int remoteRegionConnectionIdleTimeoutSeconds = 30;
private boolean gZipContentFromRemoteRegion = true;
private Map<String, String> remoteRegionUrlsWithName = new HashMap<String, String>();
private String[] remoteRegionUrls;
private Map<String, Set<String>> remoteRegionAppWhitelist;
private int remoteRegionRegistryFetchInterval = 30;
private String remoteRegionTrustStore = "";
private String remoteRegionTrustStorePassword = "changeit";
private boolean disableTransparentFallbackToOtherRegion;
private boolean batchReplication;
private boolean rateLimiterEnabled = false;
private boolean rateLimiterThrottleStandardClients = false;
private Set<String> rateLimiterPrivilegedClients = Collections.emptySet();
private int rateLimiterBurstSize = 10;
private int rateLimiterRegistryFetchAverageRate = 500;
private int rateLimiterFullFetchAverageRate = 100;
private boolean logIdentityHeaders = true;
@Override
public boolean shouldEnableSelfPreservation() {
return this.enableSelfPreservation;
}
@Override
public boolean shouldDisableDelta() {
return this.disableDelta;
}
@Override
public boolean shouldSyncWhenTimestampDiffers() {
return this.syncWhenTimestampDiffers;
}
@Override
public boolean shouldPrimeAwsReplicaConnections() {
return this.primeAwsReplicaConnections;
}
@Override
public boolean shouldDisableDeltaForRemoteRegions() {
return this.disableDeltaForRemoteRegions;
}
@Override
public boolean shouldGZipContentFromRemoteRegion() {
return this.gZipContentFromRemoteRegion;
}
@Override
public Set<String> getRemoteRegionAppWhitelist(String regionName) {
return this.remoteRegionAppWhitelist.get(regionName == null ? "global"
: regionName.trim().toLowerCase());
}
@Override
public boolean disableTransparentFallbackToOtherRegion() {
return this.disableTransparentFallbackToOtherRegion;
}
@Override
public boolean shouldBatchReplication() {
return this.batchReplication;
}
@Override
public boolean shouldLogIdentityHeaders() {
return this.logIdentityHeaders;
}
}
@@ -0,0 +1,87 @@
/*
* Copyright 2013-2017 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.feign;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Collection;
import feign.MethodMetadata;
/**
* Feign contract method parameter processor.
*
* @author Jakub Narloch
* @author Abhijit Sarkar
*/
public interface AnnotatedParameterProcessor {
/**
* Retrieves the processor supported annotation type.
*
* @return the annotation type
*/
Class<? extends Annotation> getAnnotationType();
/**
* Process the annotated parameter.
*
* @param context the parameter context
* @param annotation the annotation instance
* @param method the method that contains the annotation
* @return whether the parameter is http
*/
boolean processArgument(AnnotatedParameterContext context, Annotation annotation, Method method);
/**
* Specifies the parameter context.
*
* @author Jakub Narloch
*/
interface AnnotatedParameterContext {
/**
* Retrieves the method metadata.
*
* @return the method metadata
*/
MethodMetadata getMethodMetadata();
/**
* Retrieves the index of the parameter.
*
* @return the parameter index
*/
int getParameterIndex();
/**
* Sets the parameter name.
*
* @param name the name of the parameter
*/
void setParameterName(String name);
/**
* Sets the template parameter.
*
* @param name the template parameter
* @param rest the existing parameter values
* @return parameters
*/
Collection<String> setTemplateParameter(String name, Collection<String> rest);
}
}
@@ -0,0 +1,38 @@
/*
* Copyright 2016 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.feign;
import feign.Logger;
import feign.slf4j.Slf4jLogger;
/**
* @author Venil Noronha
*/
public class DefaultFeignLoggerFactory implements FeignLoggerFactory {
private Logger logger;
public DefaultFeignLoggerFactory(Logger logger) {
this.logger = logger;
}
@Override
public Logger create(Class<?> type) {
return this.logger != null ? this.logger : new Slf4jLogger(type);
}
}
@@ -0,0 +1,33 @@
/*
* Copyright 2013-2016 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.feign;
import feign.Feign;
import feign.Target;
/**
* @author Spencer Gibb
*/
class DefaultTargeter implements Targeter {
@Override
public <T> T target(FeignClientFactoryBean factory, Feign.Builder feign, FeignContext context,
Target.HardCodedTarget<T> target) {
return feign.target(target);
}
}
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* 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,
@@ -37,7 +37,7 @@ import org.springframework.context.annotation.Import;
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import({ FeignClientsConfiguration.class, FeignClientsRegistrar.class })
@Import(FeignClientsRegistrar.class)
public @interface EnableFeignClients {
/**
@@ -71,4 +71,18 @@ public @interface EnableFeignClients {
*/
Class<?>[] basePackageClasses() default {};
/**
* A custom <code>@Configuration</code> for all feign clients. Can contain override
* <code>@Bean</code> definition for the pieces that make up the client, for instance
* {@link feign.codec.Decoder}, {@link feign.codec.Encoder}, {@link feign.Contract}.
*
* @see FeignClientsConfiguration for the defaults
*/
Class<?>[] defaultConfiguration() default {};
/**
* List of classes annotated with @FeignClient. If not empty, disables classpath scanning.
* @return
*/
Class<?>[] clients() default {};
}
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* 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,
@@ -16,13 +16,39 @@
package org.springframework.cloud.netflix.feign;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.TimeUnit;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.HttpClientConnectionManager;
import org.apache.http.impl.client.CloseableHttpClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.client.actuator.HasFeatures;
import org.springframework.cloud.commons.httpclient.ApacheHttpClientConnectionManagerFactory;
import org.springframework.cloud.commons.httpclient.ApacheHttpClientFactory;
import org.springframework.cloud.commons.httpclient.OkHttpClientConnectionPoolFactory;
import org.springframework.cloud.commons.httpclient.OkHttpClientFactory;
import org.springframework.cloud.netflix.feign.support.FeignHttpClientProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import feign.Client;
import feign.Feign;
import feign.httpclient.ApacheHttpClient;
import feign.okhttp.OkHttpClient;
import okhttp3.ConnectionPool;
import javax.annotation.PreDestroy;
/**
* @author Spencer Gibb
@@ -30,8 +56,156 @@ import feign.Feign;
*/
@Configuration
@ConditionalOnClass(Feign.class)
@AutoConfigureAfter(ArchaiusAutoConfiguration.class)
@Import(FeignClientsConfiguration.class)
@EnableConfigurationProperties({FeignClientProperties.class, FeignHttpClientProperties.class})
public class FeignAutoConfiguration {
@Autowired(required = false)
private List<FeignClientSpecification> configurations = new ArrayList<>();
@Bean
public HasFeatures feignFeature() {
return HasFeatures.namedFeature("Feign", Feign.class);
}
@Bean
public FeignContext feignContext() {
FeignContext context = new FeignContext();
context.setConfigurations(this.configurations);
return context;
}
@Configuration
@ConditionalOnClass(name = "feign.hystrix.HystrixFeign")
protected static class HystrixFeignTargeterConfiguration {
@Bean
@ConditionalOnMissingBean
public Targeter feignTargeter() {
return new HystrixTargeter();
}
}
@Configuration
@ConditionalOnMissingClass("feign.hystrix.HystrixFeign")
protected static class DefaultFeignTargeterConfiguration {
@Bean
@ConditionalOnMissingBean
public Targeter feignTargeter() {
return new DefaultTargeter();
}
}
// the following configuration is for alternate feign clients if
// ribbon is not on the class path.
// see corresponding configurations in FeignRibbonClientAutoConfiguration
// for load balanced ribbon clients.
@Configuration
@ConditionalOnClass(ApacheHttpClient.class)
@ConditionalOnMissingClass("com.netflix.loadbalancer.ILoadBalancer")
@ConditionalOnMissingBean(CloseableHttpClient.class)
@ConditionalOnProperty(value = "feign.httpclient.enabled", matchIfMissing = true)
protected static class HttpClientFeignConfiguration {
private final Timer connectionManagerTimer = new Timer(
"FeignApacheHttpClientConfiguration.connectionManagerTimer", true);
@Autowired(required = false)
private RegistryBuilder registryBuilder;
private CloseableHttpClient httpClient;
@Bean
@ConditionalOnMissingBean(HttpClientConnectionManager.class)
public HttpClientConnectionManager connectionManager(
ApacheHttpClientConnectionManagerFactory connectionManagerFactory,
FeignHttpClientProperties httpClientProperties) {
final HttpClientConnectionManager connectionManager = connectionManagerFactory
.newConnectionManager(httpClientProperties.isDisableSslValidation(), httpClientProperties.getMaxConnections(),
httpClientProperties.getMaxConnectionsPerRoute(),
httpClientProperties.getTimeToLive(),
httpClientProperties.getTimeToLiveUnit(), registryBuilder);
this.connectionManagerTimer.schedule(new TimerTask() {
@Override
public void run() {
connectionManager.closeExpiredConnections();
}
}, 30000, httpClientProperties.getConnectionTimerRepeat());
return connectionManager;
}
@Bean
public CloseableHttpClient httpClient(ApacheHttpClientFactory httpClientFactory,
HttpClientConnectionManager httpClientConnectionManager,
FeignHttpClientProperties httpClientProperties) {
RequestConfig defaultRequestConfig = RequestConfig.custom()
.setConnectTimeout(httpClientProperties.getConnectionTimeout())
.setRedirectsEnabled(httpClientProperties.isFollowRedirects())
.build();
this.httpClient = httpClientFactory.createBuilder().
setConnectionManager(httpClientConnectionManager).
setDefaultRequestConfig(defaultRequestConfig).build();
return this.httpClient;
}
@Bean
@ConditionalOnMissingBean(Client.class)
public Client feignClient(HttpClient httpClient) {
return new ApacheHttpClient(httpClient);
}
@PreDestroy
public void destroy() throws Exception {
connectionManagerTimer.cancel();
if(httpClient != null) {
httpClient.close();
}
}
}
@Configuration
@ConditionalOnClass(OkHttpClient.class)
@ConditionalOnMissingClass("com.netflix.loadbalancer.ILoadBalancer")
@ConditionalOnMissingBean(okhttp3.OkHttpClient.class)
@ConditionalOnProperty(value = "feign.okhttp.enabled")
protected static class OkHttpFeignConfiguration {
private okhttp3.OkHttpClient okHttpClient;
@Bean
@ConditionalOnMissingBean(ConnectionPool.class)
public ConnectionPool httpClientConnectionPool(FeignHttpClientProperties httpClientProperties,
OkHttpClientConnectionPoolFactory connectionPoolFactory) {
Integer maxTotalConnections = httpClientProperties.getMaxConnections();
Long timeToLive = httpClientProperties.getTimeToLive();
TimeUnit ttlUnit = httpClientProperties.getTimeToLiveUnit();
return connectionPoolFactory.create(maxTotalConnections, timeToLive, ttlUnit);
}
@Bean
public okhttp3.OkHttpClient client(OkHttpClientFactory httpClientFactory,
ConnectionPool connectionPool, FeignHttpClientProperties httpClientProperties) {
Boolean followRedirects = httpClientProperties.isFollowRedirects();
Integer connectTimeout = httpClientProperties.getConnectionTimeout();
Boolean disableSslValidation = httpClientProperties.isDisableSslValidation();
this.okHttpClient = httpClientFactory.createBuilder(disableSslValidation).
connectTimeout(connectTimeout, TimeUnit.MILLISECONDS).
followRedirects(followRedirects).
connectionPool(connectionPool).build();
return this.okHttpClient;
}
@PreDestroy
public void destroy() {
if(okHttpClient != null) {
okHttpClient.dispatcher().executorService().shutdown();
okHttpClient.connectionPool().evictAll();
}
}
@Bean
@ConditionalOnMissingBean(Client.class)
public Client feignClient(okhttp3.OkHttpClient client) {
return new OkHttpClient(client);
}
}
}
@@ -1,11 +1,11 @@
/*
* Copyright 2013-2015 the original author or authors.
* Copyright 2013-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* 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,
@@ -22,6 +22,8 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import org.springframework.core.annotation.AliasFor;
/**
* Annotation for interfaces declaring that a REST client with that interface should be
* created (e.g. for autowiring into another component). If ribbon is available it will be
@@ -29,6 +31,7 @@ import java.lang.annotation.Target;
* using a <code>@RibbonClient</code> with the same name (i.e. value) as the feign client.
*
* @author Spencer Gibb
* @author Venil Noronha
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@@ -36,20 +39,76 @@ import java.lang.annotation.Target;
public @interface FeignClient {
/**
* The serviceId with optional protocol prefix. Synonym for {@link #serviceId()
* serviceId}. Either serviceId or url must be specified but not both.
* The name of the service with optional protocol prefix. Synonym for {@link #name()
* name}. A name must be specified for all clients, whether or not a url is provided.
* Can be specified as property key, eg: ${propertyKey}.
*/
@AliasFor("name")
String value() default "";
/**
* The serviceId with optional protocol prefix. Synonym for {@link #value() value}.
* Either serviceId or url must be specified but not both.
* The service id with optional protocol prefix. Synonym for {@link #value() value}.
*
* @deprecated use {@link #name() name} instead
*/
@Deprecated
String serviceId() default "";
/**
* The service id with optional protocol prefix. Synonym for {@link #value() value}.
*/
@AliasFor("value")
String name() default "";
/**
* Sets the <code>@Qualifier</code> value for the feign client.
*/
String qualifier() default "";
/**
* An absolute URL or resolvable hostname (the protocol is optional).
*/
String url() default "";
/**
* Whether 404s should be decoded instead of throwing FeignExceptions
*/
boolean decode404() default false;
/**
* A custom <code>@Configuration</code> for the feign client. Can contain override
* <code>@Bean</code> definition for the pieces that make up the client, for instance
* {@link feign.codec.Decoder}, {@link feign.codec.Encoder}, {@link feign.Contract}.
*
* @see FeignClientsConfiguration for the defaults
*/
Class<?>[] configuration() default {};
/**
* Fallback class for the specified Feign client interface. The fallback class must
* implement the interface annotated by this annotation and be a valid spring bean.
*/
Class<?> fallback() default void.class;
/**
* Define a fallback factory for the specified Feign client interface. The fallback
* factory must produce instances of fallback classes that implement the interface
* annotated by {@link FeignClient}. The fallback factory must be a valid spring
* bean.
*
* @see feign.hystrix.FallbackFactory for details.
*/
Class<?> fallbackFactory() default void.class;
/**
* Path prefix to be used by all method-level mappings. Can be used with or without
* <code>@RibbonClient</code>.
*/
String path() default "";
/**
* Whether to mark the feign proxy as a primary bean. Defaults to true.
*/
boolean primary() default true;
}
@@ -1,11 +1,11 @@
/*
* Copyright 2013-2015 the original author or authors.
* Copyright 2013-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* 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,
@@ -16,14 +16,17 @@
package org.springframework.cloud.netflix.feign;
import java.util.List;
import lombok.Data;
import lombok.EqualsAndHashCode;
import java.util.Map;
import java.util.Objects;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.cloud.netflix.feign.ribbon.LoadBalancerFeignClient;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
@@ -34,18 +37,22 @@ import feign.Logger;
import feign.Request;
import feign.RequestInterceptor;
import feign.Retryer;
import feign.Target.HardCodedTarget;
import feign.codec.Decoder;
import feign.codec.Encoder;
import feign.codec.ErrorDecoder;
import feign.ribbon.LoadBalancingTarget;
import feign.slf4j.Slf4jLogger;
/**
* @author Spencer Gibb
* @author Venil Noronha
* @author Eko Kurniawan Khannedy
* @author Gregor Zurowski
*/
@Data
@EqualsAndHashCode(callSuper = false)
class FeignClientFactoryBean implements FactoryBean<Object>, InitializingBean {
class FeignClientFactoryBean implements FactoryBean<Object>, InitializingBean,
ApplicationContextAware {
/***********************************
* WARNING! Nothing in this class should be @Autowired. It causes NPEs because of some lifecycle race condition.
***********************************/
private Class<?> type;
@@ -53,92 +60,207 @@ class FeignClientFactoryBean implements FactoryBean<Object>, InitializingBean {
private String url;
@Autowired
private Decoder decoder;
private String path;
@Autowired
private Encoder encoder;
private boolean decode404;
@Autowired
private Logger logger;
private ApplicationContext applicationContext;
@Autowired
private Contract contract;
private Class<?> fallback = void.class;
@Autowired(required = false)
private Logger.Level logLevel;
@Autowired(required = false)
private Retryer retryer;
@Autowired(required = false)
private ErrorDecoder errorDecoder;
@Autowired(required = false)
private Request.Options options;
@Autowired(required = false)
private Client ribbonClient;
@Autowired(required = false)
private List<RequestInterceptor> requestInterceptors;
private Class<?> fallbackFactory = void.class;
@Override
public void afterPropertiesSet() throws Exception {
if (StringUtils.hasText(this.name)) {
Assert.state(!StringUtils.hasText(this.url),
"Either value or url can be specified, but not both");
}
Assert.hasText(this.name, "Name must be set");
}
protected Feign.Builder feign() {
Feign.Builder builder = Feign.builder()
// required values
.logger(this.logger).encoder(this.encoder).decoder(this.decoder)
.contract(this.contract);
@Override
public void setApplicationContext(ApplicationContext context) throws BeansException {
this.applicationContext = context;
}
// optional values
if (this.logLevel != null) {
builder.logLevel(this.logLevel);
}
if (this.retryer != null) {
builder.retryer(this.retryer);
}
if (this.errorDecoder != null) {
builder.errorDecoder(this.errorDecoder);
}
if (this.options != null) {
builder.options(this.options);
}
if (this.requestInterceptors != null) {
builder.requestInterceptors(this.requestInterceptors);
}
protected Feign.Builder feign(FeignContext context) {
FeignLoggerFactory loggerFactory = get(context, FeignLoggerFactory.class);
Logger logger = loggerFactory.create(this.type);
// @formatter:off
Feign.Builder builder = get(context, Feign.Builder.class)
// required values
.logger(logger)
.encoder(get(context, Encoder.class))
.decoder(get(context, Decoder.class))
.contract(get(context, Contract.class));
// @formatter:on
configureFeign(context, builder);
return builder;
}
protected <T> T loadBalance(Feign.Builder builder, Class<T> type, String schemeName) {
builder.logger(new Slf4jLogger(type)); // TODO: how to have choice here?
if (this.ribbonClient != null) {
return builder.client(this.ribbonClient).target(type, schemeName);
protected void configureFeign(FeignContext context, Feign.Builder builder) {
FeignClientProperties properties = applicationContext.getBean(FeignClientProperties.class);
if (properties != null) {
if (properties.isDefaultToProperties()) {
configureUsingConfiguration(context, builder);
configureUsingProperties(properties.getConfig().get(properties.getDefaultConfig()), builder);
configureUsingProperties(properties.getConfig().get(this.name), builder);
} else {
configureUsingProperties(properties.getConfig().get(properties.getDefaultConfig()), builder);
configureUsingProperties(properties.getConfig().get(this.name), builder);
configureUsingConfiguration(context, builder);
}
} else {
configureUsingConfiguration(context, builder);
}
else {
return builder.target(LoadBalancingTarget.create(type, schemeName));
}
protected void configureUsingConfiguration(FeignContext context, Feign.Builder builder) {
Logger.Level level = getOptional(context, Logger.Level.class);
if (level != null) {
builder.logLevel(level);
}
Retryer retryer = getOptional(context, Retryer.class);
if (retryer != null) {
builder.retryer(retryer);
}
ErrorDecoder errorDecoder = getOptional(context, ErrorDecoder.class);
if (errorDecoder != null) {
builder.errorDecoder(errorDecoder);
}
Request.Options options = getOptional(context, Request.Options.class);
if (options != null) {
builder.options(options);
}
Map<String, RequestInterceptor> requestInterceptors = context.getInstances(
this.name, RequestInterceptor.class);
if (requestInterceptors != null) {
builder.requestInterceptors(requestInterceptors.values());
}
if (decode404) {
builder.decode404();
}
}
protected void configureUsingProperties(FeignClientProperties.FeignClientConfiguration config, Feign.Builder builder) {
if (config == null) {
return;
}
if (config.getLoggerLevel() != null) {
builder.logLevel(config.getLoggerLevel());
}
if (config.getConnectTimeout() != null && config.getReadTimeout() != null) {
builder.options(new Request.Options(config.getConnectTimeout(), config.getReadTimeout()));
}
if (config.getRetryer() != null) {
Retryer retryer = getOrInstantiate(config.getRetryer());
builder.retryer(retryer);
}
if (config.getErrorDecoder() != null) {
ErrorDecoder errorDecoder = getOrInstantiate(config.getErrorDecoder());
builder.errorDecoder(errorDecoder);
}
if (config.getRequestInterceptors() != null && !config.getRequestInterceptors().isEmpty()) {
// this will add request interceptor to builder, not replace existing
for (Class<RequestInterceptor> bean : config.getRequestInterceptors()) {
RequestInterceptor interceptor = getOrInstantiate(bean);
builder.requestInterceptor(interceptor);
}
}
if (config.getDecode404() != null) {
if (config.getDecode404()) {
builder.decode404();
}
}
}
private <T> T getOrInstantiate(Class<T> tClass) {
try {
return applicationContext.getBean(tClass);
} catch (NoSuchBeanDefinitionException e) {
return BeanUtils.instantiateClass(tClass);
}
}
protected <T> T get(FeignContext context, Class<T> type) {
T instance = context.getInstance(this.name, type);
if (instance == null) {
throw new IllegalStateException("No bean found of type " + type + " for "
+ this.name);
}
return instance;
}
protected <T> T getOptional(FeignContext context, Class<T> type) {
return context.getInstance(this.name, type);
}
protected <T> T loadBalance(Feign.Builder builder, FeignContext context,
HardCodedTarget<T> target) {
Client client = getOptional(context, Client.class);
if (client != null) {
builder.client(client);
Targeter targeter = get(context, Targeter.class);
return targeter.target(this, builder, context, target);
}
throw new IllegalStateException(
"No Feign Client for loadBalancing defined. Did you forget to include spring-cloud-starter-netflix-ribbon?");
}
@Override
public Object getObject() throws Exception {
if (StringUtils.hasText(this.name) && !this.name.startsWith("http")) {
this.name = "http://" + this.name;
}
if (StringUtils.hasText(this.name)) {
return loadBalance(feign(), this.type, this.name);
FeignContext context = applicationContext.getBean(FeignContext.class);
Feign.Builder builder = feign(context);
if (!StringUtils.hasText(this.url)) {
String url;
if (!this.name.startsWith("http")) {
url = "http://" + this.name;
}
else {
url = this.name;
}
url += cleanPath();
return loadBalance(builder, context, new HardCodedTarget<>(this.type,
this.name, url));
}
if (StringUtils.hasText(this.url) && !this.url.startsWith("http")) {
this.url = "http://" + this.url;
}
return feign().target(this.type, this.url);
String url = this.url + cleanPath();
Client client = getOptional(context, Client.class);
if (client != null) {
if (client instanceof LoadBalancerFeignClient) {
// not lod balancing because we have a url,
// but ribbon is on the classpath, so unwrap
client = ((LoadBalancerFeignClient)client).getDelegate();
}
builder.client(client);
}
Targeter targeter = get(context, Targeter.class);
return targeter.target(this, builder, context, new HardCodedTarget<>(
this.type, this.name, url));
}
private String cleanPath() {
String path = this.path.trim();
if (StringUtils.hasLength(path)) {
if (!path.startsWith("/")) {
path = "/" + path;
}
if (path.endsWith("/")) {
path = path.substring(0, path.length() - 1);
}
}
return path;
}
@Override
@@ -151,4 +273,99 @@ class FeignClientFactoryBean implements FactoryBean<Object>, InitializingBean {
return true;
}
public Class<?> getType() {
return type;
}
public void setType(Class<?> type) {
this.type = type;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public boolean isDecode404() {
return decode404;
}
public void setDecode404(boolean decode404) {
this.decode404 = decode404;
}
public ApplicationContext getApplicationContext() {
return applicationContext;
}
public Class<?> getFallback() {
return fallback;
}
public void setFallback(Class<?> fallback) {
this.fallback = fallback;
}
public Class<?> getFallbackFactory() {
return fallbackFactory;
}
public void setFallbackFactory(Class<?> fallbackFactory) {
this.fallbackFactory = fallbackFactory;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
FeignClientFactoryBean that = (FeignClientFactoryBean) o;
return Objects.equals(applicationContext, that.applicationContext) &&
decode404 == that.decode404 &&
Objects.equals(fallback, that.fallback) &&
Objects.equals(fallbackFactory, that.fallbackFactory) &&
Objects.equals(name, that.name) &&
Objects.equals(path, that.path) &&
Objects.equals(type, that.type) &&
Objects.equals(url, that.url);
}
@Override
public int hashCode() {
return Objects.hash(applicationContext, decode404, fallback, fallbackFactory,
name, path, type, url);
}
@Override
public String toString() {
return new StringBuilder("FeignClientFactoryBean{")
.append("type=").append(type).append(", ")
.append("name='").append(name).append("', ")
.append("url='").append(url).append("', ")
.append("path='").append(path).append("', ")
.append("decode404=").append(decode404).append(", ")
.append("applicationContext=").append(applicationContext).append(", ")
.append("fallback=").append(fallback).append(", ")
.append("fallbackFactory=").append(fallbackFactory)
.append("}").toString();
}
}
@@ -0,0 +1,173 @@
/*
* Copyright 2013-2017 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.feign;
import feign.Logger;
import feign.RequestInterceptor;
import feign.Retryer;
import feign.codec.ErrorDecoder;
import org.springframework.boot.context.properties.ConfigurationProperties;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
/**
* @author Eko Kurniawan Khannedy
*/
@ConfigurationProperties("feign.client")
public class FeignClientProperties {
private boolean defaultToProperties = true;
private String defaultConfig = "default";
private Map<String, FeignClientConfiguration> config = new HashMap<>();
public boolean isDefaultToProperties() {
return defaultToProperties;
}
public void setDefaultToProperties(boolean defaultToProperties) {
this.defaultToProperties = defaultToProperties;
}
public String getDefaultConfig() {
return defaultConfig;
}
public void setDefaultConfig(String defaultConfig) {
this.defaultConfig = defaultConfig;
}
public Map<String, FeignClientConfiguration> getConfig() {
return config;
}
public void setConfig(Map<String, FeignClientConfiguration> config) {
this.config = config;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
FeignClientProperties that = (FeignClientProperties) o;
return defaultToProperties == that.defaultToProperties &&
Objects.equals(defaultConfig, that.defaultConfig) &&
Objects.equals(config, that.config);
}
@Override
public int hashCode() {
return Objects.hash(defaultToProperties, defaultConfig, config);
}
public static class FeignClientConfiguration {
private Logger.Level loggerLevel;
private Integer connectTimeout;
private Integer readTimeout;
private Class<Retryer> retryer;
private Class<ErrorDecoder> errorDecoder;
private List<Class<RequestInterceptor>> requestInterceptors;
private Boolean decode404;
public Logger.Level getLoggerLevel() {
return loggerLevel;
}
public void setLoggerLevel(Logger.Level loggerLevel) {
this.loggerLevel = loggerLevel;
}
public Integer getConnectTimeout() {
return connectTimeout;
}
public void setConnectTimeout(Integer connectTimeout) {
this.connectTimeout = connectTimeout;
}
public Integer getReadTimeout() {
return readTimeout;
}
public void setReadTimeout(Integer readTimeout) {
this.readTimeout = readTimeout;
}
public Class<Retryer> getRetryer() {
return retryer;
}
public void setRetryer(Class<Retryer> retryer) {
this.retryer = retryer;
}
public Class<ErrorDecoder> getErrorDecoder() {
return errorDecoder;
}
public void setErrorDecoder(Class<ErrorDecoder> errorDecoder) {
this.errorDecoder = errorDecoder;
}
public List<Class<RequestInterceptor>> getRequestInterceptors() {
return requestInterceptors;
}
public void setRequestInterceptors(List<Class<RequestInterceptor>> requestInterceptors) {
this.requestInterceptors = requestInterceptors;
}
public Boolean getDecode404() {
return decode404;
}
public void setDecode404(Boolean decode404) {
this.decode404 = decode404;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
FeignClientConfiguration that = (FeignClientConfiguration) o;
return loggerLevel == that.loggerLevel &&
Objects.equals(connectTimeout, that.connectTimeout) &&
Objects.equals(readTimeout, that.readTimeout) &&
Objects.equals(retryer, that.retryer) &&
Objects.equals(errorDecoder, that.errorDecoder) &&
Objects.equals(requestInterceptors, that.requestInterceptors) &&
Objects.equals(decode404, that.decode404);
}
@Override
public int hashCode() {
return Objects.hash(loggerLevel, connectTimeout, readTimeout, retryer,
errorDecoder, requestInterceptors, decode404);
}
}
}
@@ -0,0 +1,79 @@
/*
* Copyright 2013-2015 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.feign;
import org.springframework.cloud.context.named.NamedContextFactory;
import java.util.Arrays;
import java.util.Objects;
/**
* @author Dave Syer
* @author Gregor Zurowski
*/
class FeignClientSpecification implements NamedContextFactory.Specification {
private String name;
private Class<?>[] configuration;
public FeignClientSpecification() {}
public FeignClientSpecification(String name, Class<?>[] configuration) {
this.name = name;
this.configuration = configuration;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Class<?>[] getConfiguration() {
return configuration;
}
public void setConfiguration(Class<?>[] configuration) {
this.configuration = configuration;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
FeignClientSpecification that = (FeignClientSpecification) o;
return Objects.equals(name, that.name) &&
Arrays.equals(configuration, that.configuration);
}
@Override
public int hashCode() {
return Objects.hash(name, configuration);
}
@Override
public String toString() {
return new StringBuilder("FeignClientSpecification{")
.append("name='").append(name).append("', ")
.append("configuration=").append(Arrays.toString(configuration))
.append("}").toString();
}
}
@@ -1,11 +1,11 @@
/*
* Copyright 2013-2015 the original author or authors.
* Copyright 2013-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* 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,
@@ -16,40 +16,111 @@
package org.springframework.cloud.netflix.feign;
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.annotation.Autowired;
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.autoconfigure.web.HttpMessageConverters;
import org.springframework.cloud.netflix.feign.support.ResponseEntityDecoder;
import org.springframework.cloud.netflix.feign.support.SpringDecoder;
import org.springframework.cloud.netflix.feign.support.SpringEncoder;
import org.springframework.cloud.netflix.feign.support.SpringMvcContract;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
import org.springframework.core.convert.ConversionService;
import org.springframework.format.support.DefaultFormattingConversionService;
import org.springframework.format.support.FormattingConversionService;
import com.netflix.hystrix.HystrixCommand;
import feign.Contract;
import feign.Feign;
import feign.Logger;
import feign.slf4j.Slf4jLogger;
import feign.Retryer;
import feign.codec.Decoder;
import feign.codec.Encoder;
import feign.hystrix.HystrixFeign;
/**
* @author Dave Syer
* @author Venil Noronha
*/
@Configuration
public class FeignClientsConfiguration {
@Autowired
private ObjectFactory<HttpMessageConverters> messageConverters;
@Autowired(required = false)
private List<AnnotatedParameterProcessor> parameterProcessors = new ArrayList<>();
@Autowired(required = false)
private List<FeignFormatterRegistrar> feignFormatterRegistrars = new ArrayList<>();
@Autowired(required = false)
private Logger logger;
@Bean
public SpringDecoder feignDecoder() {
return new SpringDecoder();
@ConditionalOnMissingBean
public Decoder feignDecoder() {
return new ResponseEntityDecoder(new SpringDecoder(this.messageConverters));
}
@Bean
public SpringEncoder feignEncoder() {
return new SpringEncoder();
@ConditionalOnMissingBean
public Encoder feignEncoder() {
return new SpringEncoder(this.messageConverters);
}
@Bean
public Logger feignLogger() {
return new Slf4jLogger();
@ConditionalOnMissingBean
public Contract feignContract(ConversionService feignConversionService) {
return new SpringMvcContract(this.parameterProcessors, feignConversionService);
}
@Bean
public Contract feignContract() {
return new SpringMvcContract();
public FormattingConversionService feignConversionService() {
FormattingConversionService conversionService = new DefaultFormattingConversionService();
for (FeignFormatterRegistrar feignFormatterRegistrar : feignFormatterRegistrars) {
feignFormatterRegistrar.registerFormatters(conversionService);
}
return conversionService;
}
@Configuration
@ConditionalOnClass({ HystrixCommand.class, HystrixFeign.class })
protected static class HystrixFeignConfiguration {
@Bean
@Scope("prototype")
@ConditionalOnMissingBean
@ConditionalOnProperty(name = "feign.hystrix.enabled", matchIfMissing = false)
public Feign.Builder feignHystrixBuilder() {
return HystrixFeign.builder();
}
}
@Bean
@ConditionalOnMissingBean
public Retryer feignRetryer() {
return Retryer.NEVER_RETRY;
}
@Bean
@Scope("prototype")
@ConditionalOnMissingBean
public Feign.Builder feignBuilder(Retryer retryer) {
return Feign.builder().retryer(retryer);
}
@Bean
@ConditionalOnMissingBean(FeignLoggerFactory.class)
public FeignLoggerFactory feignLoggerFactory() {
return new DefaultFeignLoggerFactory(logger);
}
}
@@ -1,11 +1,11 @@
/*
* Copyright 2013-2015 the original author or authors.
* Copyright 2013-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* 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,
@@ -16,8 +16,15 @@
package org.springframework.cloud.netflix.feign;
import java.io.IOException;
import java.lang.annotation.Annotation;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -25,31 +32,46 @@ import org.springframework.beans.factory.BeanClassLoaderAware;
import org.springframework.beans.factory.annotation.AnnotatedBeanDefinition;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.annotation.AnnotationAttributes;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.core.type.ClassMetadata;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.core.type.filter.AbstractClassTestingTypeFilter;
import org.springframework.core.type.filter.AnnotationTypeFilter;
import org.springframework.core.type.filter.TypeFilter;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;
/**
* @author Spencer Gibb
* @author Jakub Narloch
* @author Venil Noronha
*/
public class FeignClientsRegistrar implements ImportBeanDefinitionRegistrar,
ResourceLoaderAware, BeanClassLoaderAware {
class FeignClientsRegistrar implements ImportBeanDefinitionRegistrar,
ResourceLoaderAware, BeanClassLoaderAware, EnvironmentAware {
// patterned after Spring Integration IntegrationComponentScanRegistrar
// and RibbonClientsConfigurationRegistgrar
private ResourceLoader resourceLoader;
private ClassLoader classLoader;
private Environment environment;
public FeignClientsRegistrar() {
}
@@ -64,15 +86,65 @@ public class FeignClientsRegistrar implements ImportBeanDefinitionRegistrar,
}
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata,
public void registerBeanDefinitions(AnnotationMetadata metadata,
BeanDefinitionRegistry registry) {
registerDefaultConfiguration(metadata, registry);
registerFeignClients(metadata, registry);
}
Set<String> basePackages = getBasePackages(importingClassMetadata);
private void registerDefaultConfiguration(AnnotationMetadata metadata,
BeanDefinitionRegistry registry) {
Map<String, Object> defaultAttrs = metadata
.getAnnotationAttributes(EnableFeignClients.class.getName(), true);
if (defaultAttrs != null && defaultAttrs.containsKey("defaultConfiguration")) {
String name;
if (metadata.hasEnclosingClass()) {
name = "default." + metadata.getEnclosingClassName();
}
else {
name = "default." + metadata.getClassName();
}
registerClientConfiguration(registry, name,
defaultAttrs.get("defaultConfiguration"));
}
}
public void registerFeignClients(AnnotationMetadata metadata,
BeanDefinitionRegistry registry) {
ClassPathScanningCandidateComponentProvider scanner = getScanner();
scanner.addIncludeFilter(new AnnotationTypeFilter(FeignClient.class));
scanner.setResourceLoader(this.resourceLoader);
Set<String> basePackages;
Map<String, Object> attrs = metadata
.getAnnotationAttributes(EnableFeignClients.class.getName());
AnnotationTypeFilter annotationTypeFilter = new AnnotationTypeFilter(
FeignClient.class);
final Class<?>[] clients = attrs == null ? null
: (Class<?>[]) attrs.get("clients");
if (clients == null || clients.length == 0) {
scanner.addIncludeFilter(annotationTypeFilter);
basePackages = getBasePackages(metadata);
}
else {
final Set<String> clientClasses = new HashSet<>();
basePackages = new HashSet<>();
for (Class<?> clazz : clients) {
basePackages.add(ClassUtils.getPackageName(clazz));
clientClasses.add(clazz.getCanonicalName());
}
AbstractClassTestingTypeFilter filter = new AbstractClassTestingTypeFilter() {
@Override
protected boolean match(ClassMetadata metadata) {
String cleaned = metadata.getClassName().replaceAll("\\$", ".");
return clientClasses.contains(cleaned);
}
};
scanner.addIncludeFilter(
new AllTypeFilter(Arrays.asList(filter, annotationTypeFilter)));
}
for (String basePackage : basePackages) {
Set<BeanDefinition> candidateComponents = scanner
.findCandidateComponents(basePackage);
@@ -84,69 +156,150 @@ public class FeignClientsRegistrar implements ImportBeanDefinitionRegistrar,
Assert.isTrue(annotationMetadata.isInterface(),
"@FeignClient can only be specified on an interface");
BeanDefinitionHolder holder = createBeanDefinition(annotationMetadata);
BeanDefinitionReaderUtils.registerBeanDefinition(holder, registry);
Map<String, Object> attributes = annotationMetadata
.getAnnotationAttributes(
FeignClient.class.getCanonicalName());
String name = getClientName(attributes);
registerClientConfiguration(registry, name,
attributes.get("configuration"));
registerFeignClient(registry, annotationMetadata, attributes);
}
}
}
}
private BeanDefinitionHolder createBeanDefinition(
AnnotationMetadata annotationMetadata) {
Map<String, Object> attributes = annotationMetadata
.getAnnotationAttributes(FeignClient.class.getCanonicalName());
private void registerFeignClient(BeanDefinitionRegistry registry,
AnnotationMetadata annotationMetadata, Map<String, Object> attributes) {
String className = annotationMetadata.getClassName();
BeanDefinitionBuilder definition = BeanDefinitionBuilder
.genericBeanDefinition(FeignClientFactoryBean.class);
validate(attributes);
definition.addPropertyValue("url", getUrl(attributes));
definition.addPropertyValue("name", getServiceId(attributes));
definition.addPropertyValue("path", getPath(attributes));
String name = getName(attributes);
definition.addPropertyValue("name", name);
definition.addPropertyValue("type", className);
definition.addPropertyValue("decode404", attributes.get("decode404"));
definition.addPropertyValue("fallback", attributes.get("fallback"));
definition.addPropertyValue("fallbackFactory", attributes.get("fallbackFactory"));
definition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE);
String beanName = StringUtils.uncapitalize(className.substring(className
.lastIndexOf(".") + 1));
return new BeanDefinitionHolder(definition.getBeanDefinition(), beanName);
String alias = name + "FeignClient";
AbstractBeanDefinition beanDefinition = definition.getBeanDefinition();
boolean primary = (Boolean)attributes.get("primary"); // has a default, won't be null
beanDefinition.setPrimary(primary);
String qualifier = getQualifier(attributes);
if (StringUtils.hasText(qualifier)) {
alias = qualifier;
}
BeanDefinitionHolder holder = new BeanDefinitionHolder(beanDefinition, className,
new String[] { alias });
BeanDefinitionReaderUtils.registerBeanDefinition(holder, registry);
}
private void validate(Map<String, Object> attributes) {
if (StringUtils.hasText((String) attributes.get("value"))) {
Assert.isTrue(!StringUtils.hasText((String) attributes.get("name")),
"Either name or value can be specified, but not both");
}
AnnotationAttributes annotation = AnnotationAttributes.fromMap(attributes);
// This blows up if an aliased property is overspecified
annotation.getAliasedString("name", FeignClient.class, null);
}
private String getServiceId(Map<String, Object> attributes) {
if (StringUtils.hasText((String) attributes.get("name"))) {
return (String) attributes.get("name");
/* for testing */ String getName(Map<String, Object> attributes) {
String name = (String) attributes.get("serviceId");
if (!StringUtils.hasText(name)) {
name = (String) attributes.get("name");
}
return (String) attributes.get("value");
if (!StringUtils.hasText(name)) {
name = (String) attributes.get("value");
}
name = resolve(name);
if (!StringUtils.hasText(name)) {
return "";
}
String host = null;
try {
String url;
if (!name.startsWith("http://") && !name.startsWith("https://")) {
url = "http://" + name;
} else {
url = name;
}
host = new URI(url).getHost();
}
catch (URISyntaxException e) {
}
Assert.state(host != null, "Service id not legal hostname (" + name + ")");
return name;
}
private String resolve(String value) {
if (StringUtils.hasText(value)) {
return this.environment.resolvePlaceholders(value);
}
return value;
}
private String getUrl(Map<String, Object> attributes) {
return (String) attributes.get("url");
String url = resolve((String) attributes.get("url"));
if (StringUtils.hasText(url) && !(url.startsWith("#{") && url.contains("}"))) {
if (!url.contains("://")) {
url = "http://" + url;
}
try {
new URL(url);
}
catch (MalformedURLException e) {
throw new IllegalArgumentException(url + " is malformed", e);
}
}
return url;
}
private String getPath(Map<String, Object> attributes) {
String path = resolve((String) attributes.get("path"));
if (StringUtils.hasText(path)) {
path = path.trim();
if (!path.startsWith("/")) {
path = "/" + path;
}
if (path.endsWith("/")) {
path = path.substring(0, path.length() - 1);
}
}
return path;
}
protected ClassPathScanningCandidateComponentProvider getScanner() {
return new ClassPathScanningCandidateComponentProvider(false) {
return new ClassPathScanningCandidateComponentProvider(false, this.environment) {
@Override
protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
protected boolean isCandidateComponent(
AnnotatedBeanDefinition beanDefinition) {
if (beanDefinition.getMetadata().isIndependent()) {
// TODO until SPR-11711 will be resolved
if (beanDefinition.getMetadata().isInterface()
&& beanDefinition.getMetadata().getInterfaceNames().length == 1
&& Annotation.class.getName().equals(
beanDefinition.getMetadata().getInterfaceNames()[0])) {
&& beanDefinition.getMetadata()
.getInterfaceNames().length == 1
&& Annotation.class.getName().equals(beanDefinition
.getMetadata().getInterfaceNames()[0])) {
try {
Class<?> target = ClassUtils.forName(beanDefinition
.getMetadata().getClassName(),
Class<?> target = ClassUtils.forName(
beanDefinition.getMetadata().getClassName(),
FeignClientsRegistrar.this.classLoader);
return !target.isAnnotation();
}
catch (Exception ex) {
this.logger.error("Could not load target class: "
+ beanDefinition.getMetadata().getClassName(), ex);
this.logger.error(
"Could not load target class: "
+ beanDefinition.getMetadata().getClassName(),
ex);
}
}
@@ -178,10 +331,90 @@ public class FeignClientsRegistrar implements ImportBeanDefinitionRegistrar,
}
if (basePackages.isEmpty()) {
basePackages.add(ClassUtils.getPackageName(importingClassMetadata
.getClassName()));
basePackages.add(
ClassUtils.getPackageName(importingClassMetadata.getClassName()));
}
return basePackages;
}
private String getQualifier(Map<String, Object> client) {
if (client == null) {
return null;
}
String qualifier = (String) client.get("qualifier");
if (StringUtils.hasText(qualifier)) {
return qualifier;
}
return null;
}
private String getClientName(Map<String, Object> client) {
if (client == null) {
return null;
}
String value = (String) client.get("value");
if (!StringUtils.hasText(value)) {
value = (String) client.get("name");
}
if (!StringUtils.hasText(value)) {
value = (String) client.get("serviceId");
}
if (StringUtils.hasText(value)) {
return value;
}
throw new IllegalStateException("Either 'name' or 'value' must be provided in @"
+ FeignClient.class.getSimpleName());
}
private void registerClientConfiguration(BeanDefinitionRegistry registry, Object name,
Object configuration) {
BeanDefinitionBuilder builder = BeanDefinitionBuilder
.genericBeanDefinition(FeignClientSpecification.class);
builder.addConstructorArgValue(name);
builder.addConstructorArgValue(configuration);
registry.registerBeanDefinition(
name + "." + FeignClientSpecification.class.getSimpleName(),
builder.getBeanDefinition());
}
@Override
public void setEnvironment(Environment environment) {
this.environment = environment;
}
/**
* Helper class to create a {@link TypeFilter} that matches if all the delegates
* match.
*
* @author Oliver Gierke
*/
private static class AllTypeFilter implements TypeFilter {
private final List<TypeFilter> delegates;
/**
* Creates a new {@link AllTypeFilter} to match if all the given delegates match.
*
* @param delegates must not be {@literal null}.
*/
public AllTypeFilter(List<TypeFilter> delegates) {
Assert.notNull(delegates);
this.delegates = delegates;
}
@Override
public boolean match(MetadataReader metadataReader,
MetadataReaderFactory metadataReaderFactory) throws IOException {
for (TypeFilter filter : this.delegates) {
if (!filter.match(metadataReader, metadataReaderFactory)) {
return false;
}
}
return true;
}
}
}
@@ -0,0 +1,34 @@
/*
* Copyright 2013-2015 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.feign;
import org.springframework.cloud.context.named.NamedContextFactory;
/**
* A factory that creates instances of feign classes. It creates a Spring
* ApplicationContext per client name, and extracts the beans that it needs from there.
*
* @author Spencer Gibb
* @author Dave Syer
*/
public class FeignContext extends NamedContextFactory<FeignClientSpecification> {
public FeignContext() {
super(FeignClientsConfiguration.class, "feign", "feign.client.name");
}
}
@@ -0,0 +1,29 @@
/*
* Copyright 2013-2016 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.feign;
import org.springframework.format.FormatterRegistrar;
import org.springframework.format.support.FormattingConversionService;
/**
* Allows an application to customize the Feign {@link FormattingConversionService}.
*
* @author Matt Benson
*/
public interface FeignFormatterRegistrar extends FormatterRegistrar {
}
@@ -0,0 +1,36 @@
/*
* Copyright 2016 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.feign;
import feign.Logger;
/**
* Allows an application to use a custom Feign {@link Logger}.
*
* @author Venil Noronha
*/
public interface FeignLoggerFactory {
/**
* Factory method to provide a {@link Logger} for a given {@link Class}.
*
* @param type the {@link Class} for which a {@link Logger} instance is to be created
* @return a {@link Logger} instance
*/
public Logger create(Class<?> type);
}
@@ -0,0 +1,111 @@
/*
* Copyright 2013-2016 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.feign;
import org.springframework.util.Assert;
import feign.Feign;
import feign.Target;
import feign.hystrix.FallbackFactory;
import feign.hystrix.HystrixFeign;
import feign.hystrix.SetterFactory;
/**
* @author Spencer Gibb
* @author Erik Kringen
*/
@SuppressWarnings("unchecked")
class HystrixTargeter implements Targeter {
@Override
public <T> T target(FeignClientFactoryBean factory, Feign.Builder feign, FeignContext context,
Target.HardCodedTarget<T> target) {
if (!(feign instanceof feign.hystrix.HystrixFeign.Builder)) {
return feign.target(target);
}
feign.hystrix.HystrixFeign.Builder builder = (feign.hystrix.HystrixFeign.Builder) feign;
SetterFactory setterFactory = getOptional(factory.getName(), context,
SetterFactory.class);
if (setterFactory != null) {
builder.setterFactory(setterFactory);
}
Class<?> fallback = factory.getFallback();
if (fallback != void.class) {
return targetWithFallback(factory.getName(), context, target, builder, fallback);
}
Class<?> fallbackFactory = factory.getFallbackFactory();
if (fallbackFactory != void.class) {
return targetWithFallbackFactory(factory.getName(), context, target, builder, fallbackFactory);
}
return feign.target(target);
}
private <T> T targetWithFallbackFactory(String feignClientName, FeignContext context,
Target.HardCodedTarget<T> target,
HystrixFeign.Builder builder,
Class<?> fallbackFactoryClass) {
FallbackFactory<? extends T> fallbackFactory = (FallbackFactory<? extends T>)
getFromContext("fallbackFactory", feignClientName, context, fallbackFactoryClass, FallbackFactory.class);
/* We take a sample fallback from the fallback factory to check if it returns a fallback
that is compatible with the annotated feign interface. */
Object exampleFallback = fallbackFactory.create(new RuntimeException());
Assert.notNull(exampleFallback,
String.format(
"Incompatible fallbackFactory instance for feign client %s. Factory may not produce null!",
feignClientName));
if (!target.type().isAssignableFrom(exampleFallback.getClass())) {
throw new IllegalStateException(
String.format(
"Incompatible fallbackFactory instance for feign client %s. Factory produces instances of '%s', but should produce instances of '%s'",
feignClientName, exampleFallback.getClass(), target.type()));
}
return builder.target(target, fallbackFactory);
}
private <T> T targetWithFallback(String feignClientName, FeignContext context,
Target.HardCodedTarget<T> target,
HystrixFeign.Builder builder, Class<?> fallback) {
T fallbackInstance = getFromContext("fallback", feignClientName, context, fallback, target.type());
return builder.target(target, fallbackInstance);
}
private <T> T getFromContext(String fallbackMechanism, String feignClientName, FeignContext context,
Class<?> beanType, Class<T> targetType) {
Object fallbackInstance = context.getInstance(feignClientName, beanType);
if (fallbackInstance == null) {
throw new IllegalStateException(String.format(
"No " + fallbackMechanism + " instance of type %s found for feign client %s",
beanType, feignClientName));
}
if (!targetType.isAssignableFrom(beanType)) {
throw new IllegalStateException(
String.format(
"Incompatible " + fallbackMechanism + " instance. Fallback/fallbackFactory of type %s is not assignable to %s for feign client %s",
beanType, targetType, feignClientName));
}
return (T) fallbackInstance;
}
private <T> T getOptional(String feignClientName, FeignContext context,
Class<T> beanType) {
return context.getInstance(feignClientName, beanType);
}
}
@@ -0,0 +1,29 @@
/*
* Copyright 2013-2016 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.feign;
import feign.Feign;
import feign.Target;
/**
* @author Spencer Gibb
*/
interface Targeter {
<T> T target(FeignClientFactoryBean factory, Feign.Builder feign, FeignContext context,
Target.HardCodedTarget<T> target);
}
@@ -0,0 +1,77 @@
/*
* Copyright 2013-2015 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.feign.annotation;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Map;
import org.springframework.cloud.netflix.feign.AnnotatedParameterProcessor;
import org.springframework.web.bind.annotation.PathVariable;
import feign.MethodMetadata;
import static feign.Util.checkState;
import static feign.Util.emptyToNull;
/**
* {@link PathVariable} parameter processor.
*
* @author Jakub Narloch
* @author Abhijit Sarkar
* @see AnnotatedParameterProcessor
*/
public class PathVariableParameterProcessor implements AnnotatedParameterProcessor {
private static final Class<PathVariable> ANNOTATION = PathVariable.class;
@Override
public Class<? extends Annotation> getAnnotationType() {
return ANNOTATION;
}
@Override
public boolean processArgument(AnnotatedParameterContext context, Annotation annotation, Method method) {
String name = ANNOTATION.cast(annotation).value();
checkState(emptyToNull(name) != null,
"PathVariable annotation was empty on param %s.", context.getParameterIndex());
context.setParameterName(name);
MethodMetadata data = context.getMethodMetadata();
String varName = '{' + name + '}';
if (!data.template().url().contains(varName)
&& !searchMapValues(data.template().queries(), varName)
&& !searchMapValues(data.template().headers(), varName)) {
data.formParams().add(name);
}
return true;
}
private <K, V> boolean searchMapValues(Map<K, Collection<V>> map, V search) {
Collection<Collection<V>> values = map.values();
if (values == null) {
return false;
}
for (Collection<V> entry : values) {
if (entry.contains(search)) {
return true;
}
}
return false;
}
}
@@ -0,0 +1,70 @@
/*
* Copyright 2013-2015 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.feign.annotation;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Map;
import org.springframework.cloud.netflix.feign.AnnotatedParameterProcessor;
import org.springframework.web.bind.annotation.RequestHeader;
import feign.MethodMetadata;
import static feign.Util.checkState;
import static feign.Util.emptyToNull;
/**
* {@link RequestHeader} parameter processor.
*
* @author Jakub Narloch
* @author Abhijit Sarkar
* @see AnnotatedParameterProcessor
*/
public class RequestHeaderParameterProcessor implements AnnotatedParameterProcessor {
private static final Class<RequestHeader> ANNOTATION = RequestHeader.class;
@Override
public Class<? extends Annotation> getAnnotationType() {
return ANNOTATION;
}
@Override
public boolean processArgument(AnnotatedParameterContext context, Annotation annotation, Method method) {
int parameterIndex = context.getParameterIndex();
Class<?> parameterType = method.getParameterTypes()[parameterIndex];
MethodMetadata data = context.getMethodMetadata();
if (Map.class.isAssignableFrom(parameterType)) {
checkState(data.headerMapIndex() == null, "Header map can only be present once.");
data.headerMapIndex(parameterIndex);
return true;
}
String name = ANNOTATION.cast(annotation).value();
checkState(emptyToNull(name) != null,
"RequestHeader.value() was empty on parameter %s", parameterIndex);
context.setParameterName(name);
Collection<String> header = context.setTemplateParameter(name, data.template().headers().get(name));
data.template().header(name, header);
return true;
}
}
@@ -0,0 +1,73 @@
/*
* Copyright 2013-2015 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.feign.annotation;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Map;
import org.springframework.cloud.netflix.feign.AnnotatedParameterProcessor;
import org.springframework.web.bind.annotation.RequestParam;
import static feign.Util.checkState;
import static feign.Util.emptyToNull;
import feign.MethodMetadata;
/**
* {@link RequestParam} parameter processor.
*
* @author Jakub Narloch
* @author Abhijit Sarkar
* @see AnnotatedParameterProcessor
*/
public class RequestParamParameterProcessor implements AnnotatedParameterProcessor {
private static final Class<RequestParam> ANNOTATION = RequestParam.class;
@Override
public Class<? extends Annotation> getAnnotationType() {
return ANNOTATION;
}
@Override
public boolean processArgument(AnnotatedParameterContext context, Annotation annotation, Method method) {
int parameterIndex = context.getParameterIndex();
Class<?> parameterType = method.getParameterTypes()[parameterIndex];
MethodMetadata data = context.getMethodMetadata();
if (Map.class.isAssignableFrom(parameterType)) {
checkState(data.queryMapIndex() == null, "Query map can only be present once.");
data.queryMapIndex(parameterIndex);
return true;
}
RequestParam requestParam = ANNOTATION.cast(annotation);
String name = requestParam.value();
checkState(emptyToNull(name) != null,
"RequestParam.value() was empty on parameter %s",
parameterIndex);
context.setParameterName(name);
Collection<String> query = context.setTemplateParameter(name,
data.template().queries().get(name));
data.template().query(name, query);
return true;
}
}
@@ -0,0 +1,63 @@
/*
* Copyright 2013-2017 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.feign.encoding;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import org.springframework.util.Assert;
/**
* The base request interceptor.
*
* @author Jakub Narloch
*/
public abstract class BaseRequestInterceptor implements RequestInterceptor {
/**
* The encoding properties.
*/
private final FeignClientEncodingProperties properties;
/**
* Creates new instance of {@link BaseRequestInterceptor}.
*
* @param properties the encoding properties
*/
protected BaseRequestInterceptor(FeignClientEncodingProperties properties) {
Assert.notNull(properties, "Properties can not be null");
this.properties = properties;
}
/**
* Adds the header if it wasn't yet specified.
*
* @param requestTemplate the request
* @param name the header name
* @param values the header values
*/
protected void addHeader(RequestTemplate requestTemplate, String name, String... values) {
if (!requestTemplate.headers().containsKey(name)) {
requestTemplate.header(name, values);
}
}
protected FeignClientEncodingProperties getProperties() {
return properties;
}
}
@@ -0,0 +1,53 @@
/*
* Copyright 2013-2017 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.feign.encoding;
import feign.Client;
import feign.Feign;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
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.cloud.netflix.feign.FeignAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* Configures the Feign response compression.
*
* @author Jakub Narloch
* @see FeignAcceptGzipEncodingInterceptor
*/
@Configuration
@EnableConfigurationProperties(FeignClientEncodingProperties.class)
@ConditionalOnClass(Feign.class)
@ConditionalOnBean(Client.class)
@ConditionalOnProperty(value = "feign.compression.response.enabled", matchIfMissing = false)
//The OK HTTP client uses "transparent" compression.
//If the accept-encoding header is present it disable transparent compression
@ConditionalOnMissingBean(type = "okhttp3.OkHttpClient")
@AutoConfigureAfter(FeignAutoConfiguration.class)
public class FeignAcceptGzipEncodingAutoConfiguration {
@Bean
public FeignAcceptGzipEncodingInterceptor feignAcceptGzipEncodingInterceptor(FeignClientEncodingProperties properties) {
return new FeignAcceptGzipEncodingInterceptor(properties);
}
}
@@ -0,0 +1,49 @@
/*
* Copyright 2013-2017 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.feign.encoding;
import feign.RequestTemplate;
/**
* Enables the HTTP response payload compression by specifying the {@code Accept-Encoding} headers.
* Although this does not yet mean that the requests will be compressed, it requires the remote server
* to understand the header and be configured to compress responses. Still no all responses might be compressed
* based on the media type matching and other factors like the response content length.
*
* @author Jakub Narloch
*/
public class FeignAcceptGzipEncodingInterceptor extends BaseRequestInterceptor {
/**
* Creates new instance of {@link FeignAcceptGzipEncodingInterceptor}.
*
* @param properties the encoding properties
*/
protected FeignAcceptGzipEncodingInterceptor(FeignClientEncodingProperties properties) {
super(properties);
}
/**
* {@inheritDoc}
*/
@Override
public void apply(RequestTemplate template) {
addHeader(template, HttpEncoding.ACCEPT_ENCODING_HEADER, HttpEncoding.GZIP_ENCODING,
HttpEncoding.DEFLATE_ENCODING);
}
}
@@ -0,0 +1,80 @@
/*
* Copyright 2013-2017 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.feign.encoding;
import org.springframework.boot.context.properties.ConfigurationProperties;
import java.util.Arrays;
import java.util.Objects;
/**
* The Feign encoding properties.
*
* @author Jakub Narloch
*/
@ConfigurationProperties("feign.compression.request")
public class FeignClientEncodingProperties {
/**
* The list of supported mime types.
*/
private String[] mimeTypes = new String[]{"text/xml", "application/xml", "application/json"};
/**
* The minimum threshold content size.
*/
private int minRequestSize = 2048;
public String[] getMimeTypes() {
return mimeTypes;
}
public void setMimeTypes(String[] mimeTypes) {
this.mimeTypes = mimeTypes;
}
public int getMinRequestSize() {
return minRequestSize;
}
public void setMinRequestSize(int minRequestSize) {
this.minRequestSize = minRequestSize;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
FeignClientEncodingProperties that = (FeignClientEncodingProperties) o;
return Arrays.equals(mimeTypes, that.mimeTypes) &&
Objects.equals(minRequestSize, that.minRequestSize);
}
@Override
public int hashCode() {
return Objects.hash(mimeTypes, minRequestSize);
}
@Override
public String toString() {
return new StringBuilder("FeignClientEncodingProperties{")
.append("mimeTypes=").append(Arrays.toString(mimeTypes)).append(", ")
.append("minRequestSize=").append(minRequestSize)
.append("}").toString();
}
}
@@ -0,0 +1,53 @@
/*
* Copyright 2013-2017 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.feign.encoding;
import feign.Client;
import feign.Feign;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
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.cloud.netflix.feign.FeignAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* Configures the Feign request compression.
*
* @author Jakub Narloch
* @see FeignContentGzipEncodingInterceptor
*/
@Configuration
@EnableConfigurationProperties(FeignClientEncodingProperties.class)
@ConditionalOnClass(Feign.class)
@ConditionalOnBean(Client.class)
//The OK HTTP client uses "transparent" compression.
//If the content-encoding header is present it disable transparent compression
@ConditionalOnMissingBean(type = "okhttp3.OkHttpClient")
@ConditionalOnProperty(value = "feign.compression.request.enabled", matchIfMissing = false)
@AutoConfigureAfter(FeignAutoConfiguration.class)
public class FeignContentGzipEncodingAutoConfiguration {
@Bean
public FeignContentGzipEncodingInterceptor feignContentGzipEncodingInterceptor(FeignClientEncodingProperties properties) {
return new FeignContentGzipEncodingInterceptor(properties);
}
}
@@ -0,0 +1,111 @@
/*
* Copyright 2013-2017 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.feign.encoding;
import feign.RequestTemplate;
import java.util.Collection;
import java.util.Map;
/**
* Enables the HTTP request payload compression by specifying the {@code Content-Encoding} headers.
*
* @author Jakub Narloch
*/
public class FeignContentGzipEncodingInterceptor extends BaseRequestInterceptor {
/**
* Creates new instance of {@link FeignContentGzipEncodingInterceptor}.
*
* @param properties the encoding properties
*/
protected FeignContentGzipEncodingInterceptor(FeignClientEncodingProperties properties) {
super(properties);
}
/**
* {@inheritDoc}
*/
@Override
public void apply(RequestTemplate template) {
if (requiresCompression(template)) {
addHeader(template, HttpEncoding.CONTENT_ENCODING_HEADER, HttpEncoding.GZIP_ENCODING,
HttpEncoding.DEFLATE_ENCODING);
}
}
/**
* Returns whether the request requires GZIP compression.
*
* @param template the request template
* @return true if request requires compression, false otherwise
*/
private boolean requiresCompression(RequestTemplate template) {
final Map<String, Collection<String>> headers = template.headers();
return matchesMimeType(headers.get(HttpEncoding.CONTENT_TYPE))
&& contentLengthExceedThreshold(headers.get(HttpEncoding.CONTENT_LENGTH));
}
/**
* Returns whether the request content length exceed configured minimum size.
*
* @param contentLength the content length header value
* @return true if length is grater than minimum size, false otherwise
*/
private boolean contentLengthExceedThreshold(Collection<String> contentLength) {
try {
if (contentLength == null || contentLength.size() != 1) {
return false;
}
final String strLen = contentLength.iterator().next();
final long length = Long.parseLong(strLen);
return length > getProperties().getMinRequestSize();
} catch (NumberFormatException ex) {
// ignores the exception
}
return false;
}
/**
* Returns whether the content mime types matches the configures mime types.
*
* @param contentTypes the content types
* @return true if any specified content type matches the request content types
*/
private boolean matchesMimeType(Collection<String> contentTypes) {
if (contentTypes == null || contentTypes.size() == 0) {
return false;
}
if (getProperties().getMimeTypes() == null || getProperties().getMimeTypes().length == 0) {
// no specific mime types has been set - matching everything
return true;
}
for (String mimeType : getProperties().getMimeTypes()) {
if (contentTypes.contains(mimeType)) {
return true;
}
}
return false;
}
}
@@ -0,0 +1,55 @@
/*
* Copyright 2013-2017 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.feign.encoding;
/**
* Lists all constants used by Feign encoders.
*
* @author Jakub Narloch
*/
public interface HttpEncoding {
/**
* The HTTP Content-Length header.
*/
String CONTENT_LENGTH = "Content-Length";
/**
* The HTTP Content-Type header.
*/
String CONTENT_TYPE = "Content-Type";
/**
* The HTTP Accept-Encoding header.
*/
String ACCEPT_ENCODING_HEADER = "Accept-Encoding";
/**
* The HTTP Content-Encoding header.
*/
String CONTENT_ENCODING_HEADER = "Content-Encoding";
/**
* The GZIP encoding.
*/
String GZIP_ENCODING = "gzip";
/**
* The Deflate encoding.
*/
String DEFLATE_ENCODING = "deflate";
}
@@ -0,0 +1,113 @@
/*
* Copyright 2013-2015 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.feign.ribbon;
import java.util.Map;
import org.springframework.cloud.client.loadbalancer.LoadBalancedBackOffPolicyFactory;
import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryListenerFactory;
import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryPolicyFactory;
import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancedRetryPolicyFactory;
import org.springframework.cloud.netflix.ribbon.ServerIntrospector;
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
import org.springframework.util.ConcurrentReferenceHashMap;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.ILoadBalancer;
/**
* Factory for SpringLoadBalancer instances that caches the entries created.
*
* @author Spencer Gibb
* @author Dave Syer
* @author Ryan Baxter
* @author Gang Li
*/
public class CachingSpringLoadBalancerFactory {
private final SpringClientFactory factory;
private final LoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory;
private final LoadBalancedBackOffPolicyFactory loadBalancedBackOffPolicyFactory;
private final LoadBalancedRetryListenerFactory loadBalancedRetryListenerFactory;
private boolean enableRetry = false;
private volatile Map<String, FeignLoadBalancer> cache = new ConcurrentReferenceHashMap<>();
public CachingSpringLoadBalancerFactory(SpringClientFactory factory) {
this.factory = factory;
this.loadBalancedRetryPolicyFactory = new RibbonLoadBalancedRetryPolicyFactory(factory);
this.loadBalancedBackOffPolicyFactory = null;
this.loadBalancedRetryListenerFactory = null;
}
@Deprecated
//TODO remove in 2.0.x
public CachingSpringLoadBalancerFactory(SpringClientFactory factory,
LoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory) {
this.factory = factory;
this.loadBalancedRetryPolicyFactory = loadBalancedRetryPolicyFactory;
this.loadBalancedBackOffPolicyFactory = null;
this.loadBalancedRetryListenerFactory = null;
}
@Deprecated
//TODO remove in 2.0.0x
public CachingSpringLoadBalancerFactory(SpringClientFactory factory,
LoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory, boolean enableRetry) {
this.factory = factory;
this.loadBalancedRetryPolicyFactory = loadBalancedRetryPolicyFactory;
this.enableRetry = enableRetry;
this.loadBalancedBackOffPolicyFactory = null;
this.loadBalancedRetryListenerFactory = null;
}
@Deprecated
//TODO remove in 2.0.0x
public CachingSpringLoadBalancerFactory(SpringClientFactory factory,
LoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory,
LoadBalancedBackOffPolicyFactory loadBalancedBackOffPolicyFactory) {
this.factory = factory;
this.loadBalancedRetryPolicyFactory = loadBalancedRetryPolicyFactory;
this.loadBalancedBackOffPolicyFactory = loadBalancedBackOffPolicyFactory;
this.loadBalancedRetryListenerFactory = null;
this.enableRetry = true;
}
public CachingSpringLoadBalancerFactory(SpringClientFactory factory, LoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory,
LoadBalancedBackOffPolicyFactory loadBalancedBackOffPolicyFactory,
LoadBalancedRetryListenerFactory loadBalancedRetryListenerFactory) {
this.factory = factory;
this.loadBalancedRetryPolicyFactory = loadBalancedRetryPolicyFactory;
this.loadBalancedBackOffPolicyFactory = loadBalancedBackOffPolicyFactory;
this.loadBalancedRetryListenerFactory = loadBalancedRetryListenerFactory;
this.enableRetry = true;
}
public FeignLoadBalancer create(String clientName) {
if (this.cache.containsKey(clientName)) {
return this.cache.get(clientName);
}
IClientConfig config = this.factory.getClientConfig(clientName);
ILoadBalancer lb = this.factory.getLoadBalancer(clientName);
ServerIntrospector serverIntrospector = this.factory.getInstance(clientName, ServerIntrospector.class);
FeignLoadBalancer client = enableRetry ? new RetryableFeignLoadBalancer(lb, config, serverIntrospector,
loadBalancedRetryPolicyFactory, loadBalancedBackOffPolicyFactory, loadBalancedRetryListenerFactory) : new FeignLoadBalancer(lb, config, serverIntrospector);
this.cache.put(clientName, client);
return client;
}
}
@@ -0,0 +1,38 @@
/*
* Copyright 2013-2017 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.feign.ribbon;
import feign.Client;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author Spencer Gibb
*/
@Configuration
class DefaultFeignLoadBalancedConfiguration {
@Bean
@ConditionalOnMissingBean
public Client feignClient(CachingSpringLoadBalancerFactory cachingFactory,
SpringClientFactory clientFactory) {
return new LoadBalancerFeignClient(new Client.Default(null, null),
cachingFactory, clientFactory);
}
}
@@ -1,11 +1,11 @@
/*
* Copyright 2013-2015 the original author or authors.
* Copyright 2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* 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,
@@ -16,11 +16,22 @@
package org.springframework.cloud.netflix.feign.ribbon;
import feign.Client;
import feign.Request;
import feign.Response;
import java.io.IOException;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.springframework.cloud.netflix.ribbon.ServerIntrospector;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpRequest;
import com.netflix.client.AbstractLoadBalancerAwareClient;
import com.netflix.client.ClientException;
import com.netflix.client.ClientRequest;
@@ -30,32 +41,26 @@ import com.netflix.client.RetryHandler;
import com.netflix.client.config.CommonClientConfigKey;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.Server;
import feign.Client;
import feign.Request;
import feign.RequestTemplate;
import feign.Response;
import static org.springframework.cloud.netflix.ribbon.RibbonUtils.updateToHttpsIfNeeded;
public class RibbonLoadBalancer
extends
AbstractLoadBalancerAwareClient<RibbonLoadBalancer.RibbonRequest, RibbonLoadBalancer.RibbonResponse> {
public class FeignLoadBalancer extends
AbstractLoadBalancerAwareClient<FeignLoadBalancer.RibbonRequest, FeignLoadBalancer.RibbonResponse> {
private final Client delegate;
protected int connectTimeout;
protected int readTimeout;
protected IClientConfig clientConfig;
protected ServerIntrospector serverIntrospector;
private final int connectTimeout;
private final int readTimeout;
private final IClientConfig clientConfig;
public RibbonLoadBalancer(Client delegate, ILoadBalancer lb,
IClientConfig clientConfig) {
public FeignLoadBalancer(ILoadBalancer lb, IClientConfig clientConfig,
ServerIntrospector serverIntrospector) {
super(lb, clientConfig);
this.setRetryHandler(RetryHandler.DEFAULT);
this.clientConfig = clientConfig;
this.delegate = delegate;
this.connectTimeout = clientConfig.get(CommonClientConfigKey.ConnectTimeout);
this.readTimeout = clientConfig.get(CommonClientConfigKey.ReadTimeout);
this.serverIntrospector = serverIntrospector;
}
@Override
@@ -63,22 +68,24 @@ public class RibbonLoadBalancer
throws IOException {
Request.Options options;
if (configOverride != null) {
options = new Request.Options(configOverride.get(
CommonClientConfigKey.ConnectTimeout, this.connectTimeout),
options = new Request.Options(
configOverride.get(CommonClientConfigKey.ConnectTimeout,
this.connectTimeout),
(configOverride.get(CommonClientConfigKey.ReadTimeout,
this.readTimeout)));
}
else {
options = new Request.Options(this.connectTimeout, this.readTimeout);
}
Response response = this.delegate.execute(request.toRequest(), options);
Response response = request.client().execute(request.toRequest(), options);
return new RibbonResponse(request.getUri(), response);
}
@Override
public RequestSpecificRetryHandler getRequestSpecificRetryHandler(
RibbonRequest request, IClientConfig requestConfig) {
if (this.clientConfig.get(CommonClientConfigKey.OkToRetryOnAllOperations, false)) {
if (this.clientConfig.get(CommonClientConfigKey.OkToRetryOnAllOperations,
false)) {
return new RequestSpecificRetryHandler(true, true, this.getRetryHandler(),
requestConfig);
}
@@ -92,24 +99,68 @@ public class RibbonLoadBalancer
}
}
@Override
public URI reconstructURIWithServer(Server server, URI original) {
URI uri = updateToHttpsIfNeeded(original, this.clientConfig, this.serverIntrospector, server);
return super.reconstructURIWithServer(server, uri);
}
static class RibbonRequest extends ClientRequest implements Cloneable {
private final Request request;
private final Client client;
RibbonRequest(Request request, URI uri) {
this.request = request;
RibbonRequest(Client client, Request request, URI uri) {
this.client = client;
setUri(uri);
this.request = toRequest(request);
}
private Request toRequest(Request request) {
Map<String, Collection<String>> headers = new LinkedHashMap<>(
request.headers());
return Request.create(request.method(),getUri().toASCIIString(),headers,request.body(),request.charset());
}
Request toRequest() {
return new RequestTemplate().method(this.request.method())
.append(getUri().toASCIIString()).headers(this.request.headers())
.body(this.request.body(), this.request.charset()).request();
return toRequest(this.request);
}
Client client() {
return this.client;
}
HttpRequest toHttpRequest() {
return new HttpRequest() {
@Override
public HttpMethod getMethod() {
return HttpMethod.resolve(RibbonRequest.this.toRequest().method());
}
@Override
public URI getURI() {
return RibbonRequest.this.getUri();
}
@Override
public HttpHeaders getHeaders() {
Map<String, List<String>> headers = new HashMap<String, List<String>>();
Map<String, Collection<String>> feignHeaders = RibbonRequest.this.toRequest().headers();
for(String key : feignHeaders.keySet()) {
headers.put(key, new ArrayList<String>(feignHeaders.get(key)));
}
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.putAll(headers);
return httpHeaders;
}
};
}
@Override
public Object clone() {
return new RibbonRequest(this.request, getUri());
return new RibbonRequest(this.client, this.request, getUri());
}
}
@@ -161,4 +212,4 @@ public class RibbonLoadBalancer
}
}
}
@@ -0,0 +1,119 @@
/*
*
* * Copyright 2013-2016 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.feign.ribbon;
import java.net.URI;
import java.util.HashMap;
import java.util.Map;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.InterceptorRetryPolicy;
import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryContext;
import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryPolicy;
import org.springframework.cloud.client.loadbalancer.ServiceInstanceChooser;
import org.springframework.http.HttpRequest;
import org.springframework.retry.RetryContext;
/**
* @author Ryan Baxter
*/
public class FeignRetryPolicy extends InterceptorRetryPolicy {
private HttpRequest request;
private String serviceId;
public FeignRetryPolicy(HttpRequest request, LoadBalancedRetryPolicy policy, ServiceInstanceChooser serviceInstanceChooser, String serviceName) {
super(request, policy, serviceInstanceChooser, serviceName);
this.request = request;
this.serviceId = serviceName;
}
@Override
public boolean canRetry(RetryContext context) {
/*
* In InterceptorRetryPolicy.canRetry we ask the LoadBalancer to choose a server if one is not
* set in the retry context and then return true. RetryTemplat calls the canRetry method of
* the policy even on its first execution. So the fact that we didnt have a service instance set
* in the RetryContext signaled that it was the first execution and we should return true.
*
* In the Feign scenario, Feign as actually already queried the load balancer for a service instance
* and we set that service instance in the context when we call the open method of the policy. So in
* the Feign case we just return true if the retry count is 0 indicating we haven't yet made a failed
* request.
*/
if(context.getRetryCount() == 0) {
return true;
}
return super.canRetry(context);
}
@Override
public RetryContext open(RetryContext parent) {
/*
* With Feign (unlike Ribbon) the request already has the URI for the service instance
* we are going to make the request to, so extract that information and set the service
* instance in the context. In the Ribbon scenario the URI in the request object still has
* the service id so we choose and set the service instance later on.
*/
LoadBalancedRetryContext context = new LoadBalancedRetryContext(parent, this.request);
context.setServiceInstance(new FeignRetryPolicyServiceInstance(serviceId, request));
return context;
}
class FeignRetryPolicyServiceInstance implements ServiceInstance {
private String serviceId;
private HttpRequest request;
private Map<String, String> metadata;
FeignRetryPolicyServiceInstance(String serviceId, HttpRequest request) {
this.serviceId = serviceId;
this.request = request;
this.metadata = new HashMap<String, String>();
}
@Override
public String getServiceId() {
return serviceId;
}
@Override
public String getHost() {
return request.getURI().getHost();
}
@Override
public int getPort() {
return request.getURI().getPort();
}
@Override
public boolean isSecure() {
return "https".equals(request.getURI().getScheme());
}
@Override
public URI getUri() {
return request.getURI();
}
@Override
public Map<String, String> getMetadata() {
return metadata;
}
}
}
@@ -1,115 +0,0 @@
/*
* Copyright 2013-2015 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.cloud.netflix.feign.ribbon;
import java.io.IOException;
import java.net.URI;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLSocketFactory;
import lombok.Data;
import org.springframework.cloud.netflix.feign.ribbon.RibbonLoadBalancer.RibbonRequest;
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
import org.springframework.util.ReflectionUtils;
import com.netflix.client.ClientException;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.ILoadBalancer;
import dagger.Lazy;
import feign.Client;
import feign.Request;
import feign.Response;
/**
* @author Julien Roy
* @author Spencer Gibb
*/
public class FeignRibbonClient implements Client {
private Client defaultClient = new Default(new LazySSLSocketFactory(),
new LazyHostnameVerifier());
private SpringClientFactory factory;
public FeignRibbonClient(SpringClientFactory factory) {
this.factory = factory;
}
@Override
public Response execute(Request request, Request.Options options) throws IOException {
try {
URI asUri = URI.create(request.url());
String clientName = asUri.getHost();
URI uriWithoutSchemeAndPort = URI.create(request.url().replace(
asUri.getScheme() + "://" + asUri.getHost(),
asUri.getScheme() + "://"));
RibbonLoadBalancer.RibbonRequest ribbonRequest = new RibbonRequest(request,
uriWithoutSchemeAndPort);
LBClient client = getClient(clientName);
return client.getLoadBalancer()
.executeWithLoadBalancer(ribbonRequest, client.config).toResponse();
}
catch (ClientException ex) {
if (ex.getCause() instanceof IOException) {
throw IOException.class.cast(ex.getCause());
}
ReflectionUtils.rethrowRuntimeException(ex);
return null;
}
}
@Data
private class LBClient {
private final IClientConfig config;
private final RibbonLoadBalancer loadBalancer;
}
private LBClient getClient(String clientName) {
IClientConfig config = this.factory.getClientConfig(clientName);
ILoadBalancer lb = this.factory.getLoadBalancer(clientName);
RibbonLoadBalancer loadBalancer = new RibbonLoadBalancer(this.defaultClient, lb,
config);
return new LBClient(config, loadBalancer);
}
public void setDefaultClient(Client defaultClient) {
this.defaultClient = defaultClient;
}
private static class LazySSLSocketFactory implements Lazy<SSLSocketFactory> {
@Override
public SSLSocketFactory get() {
return (SSLSocketFactory) SSLSocketFactory.getDefault();
}
}
private static class LazyHostnameVerifier implements Lazy<HostnameVerifier> {
@Override
public HostnameVerifier get() {
return HttpsURLConnection.getDefaultHostnameVerifier();
}
}
}
@@ -1,11 +1,11 @@
/*
* Copyright 2013-2015 the original author or authors.
* Copyright 2013-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* 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,
@@ -18,15 +18,24 @@ package org.springframework.cloud.netflix.feign.ribbon;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingClass;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.client.loadbalancer.LoadBalancedBackOffPolicyFactory;
import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryListenerFactory;
import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryPolicyFactory;
import org.springframework.cloud.netflix.feign.FeignAutoConfiguration;
import org.springframework.cloud.netflix.feign.support.FeignHttpClientProperties;
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Primary;
import com.netflix.loadbalancer.ILoadBalancer;
import feign.Client;
import feign.Feign;
import feign.Request;
/**
* Autoconfiguration to be activated if Feign is in use and needs to be use Ribbon as a
@@ -37,9 +46,36 @@ import feign.Feign;
@ConditionalOnClass({ ILoadBalancer.class, Feign.class })
@Configuration
@AutoConfigureBefore(FeignAutoConfiguration.class)
@EnableConfigurationProperties({ FeignHttpClientProperties.class })
//Order is important here, last should be the default, first should be optional
// see https://github.com/spring-cloud/spring-cloud-netflix/issues/2086#issuecomment-316281653
@Import({ HttpClientFeignLoadBalancedConfiguration.class,
OkHttpFeignLoadBalancedConfiguration.class,
DefaultFeignLoadBalancedConfiguration.class })
public class FeignRibbonClientAutoConfiguration {
@Bean
public Client feignRibbonClient(SpringClientFactory factory) {
return new FeignRibbonClient(factory);
@Primary
@ConditionalOnMissingClass("org.springframework.retry.support.RetryTemplate")
public CachingSpringLoadBalancerFactory cachingLBClientFactory(
SpringClientFactory factory) {
return new CachingSpringLoadBalancerFactory(factory);
}
}
@Bean
@Primary
@ConditionalOnClass(name = "org.springframework.retry.support.RetryTemplate")
public CachingSpringLoadBalancerFactory retryabeCachingLBClientFactory(
SpringClientFactory factory,
LoadBalancedRetryPolicyFactory retryPolicyFactory,
LoadBalancedBackOffPolicyFactory loadBalancedBackOffPolicyFactory,
LoadBalancedRetryListenerFactory loadBalancedRetryListenerFactory) {
return new CachingSpringLoadBalancerFactory(factory, retryPolicyFactory, loadBalancedBackOffPolicyFactory, loadBalancedRetryListenerFactory);
}
@Bean
@ConditionalOnMissingBean
public Request.Options feignRequestOptions() {
return LoadBalancerFeignClient.DEFAULT_OPTIONS;
}
}
@@ -0,0 +1,128 @@
/*
* Copyright 2013-2017 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.feign.ribbon;
import feign.Client;
import feign.httpclient.ApacheHttpClient;
import java.util.Timer;
import java.util.TimerTask;
import javax.annotation.PreDestroy;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.HttpClientConnectionManager;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cloud.commons.httpclient.ApacheHttpClientConnectionManagerFactory;
import org.springframework.cloud.commons.httpclient.ApacheHttpClientFactory;
import org.springframework.cloud.netflix.feign.support.FeignHttpClientProperties;
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author Spencer Gibb
*/
@Configuration
@ConditionalOnClass(ApacheHttpClient.class)
@ConditionalOnProperty(value = "feign.httpclient.enabled", matchIfMissing = true)
class HttpClientFeignLoadBalancedConfiguration {
@Configuration
@ConditionalOnMissingBean(CloseableHttpClient.class)
protected static class HttpClientFeignConfiguration {
private final Timer connectionManagerTimer = new Timer(
"FeignApacheHttpClientConfiguration.connectionManagerTimer", true);
private CloseableHttpClient httpClient;
@Autowired(required = false)
private RegistryBuilder registryBuilder;
@Bean
@ConditionalOnMissingBean(HttpClientConnectionManager.class)
public HttpClientConnectionManager connectionManager(
ApacheHttpClientConnectionManagerFactory connectionManagerFactory,
FeignHttpClientProperties httpClientProperties) {
final HttpClientConnectionManager connectionManager = connectionManagerFactory
.newConnectionManager(httpClientProperties.isDisableSslValidation(), httpClientProperties.getMaxConnections(),
httpClientProperties.getMaxConnectionsPerRoute(),
httpClientProperties.getTimeToLive(),
httpClientProperties.getTimeToLiveUnit(), registryBuilder);
this.connectionManagerTimer.schedule(new TimerTask() {
@Override
public void run() {
connectionManager.closeExpiredConnections();
}
}, 30000, httpClientProperties.getConnectionTimerRepeat());
return connectionManager;
}
@Bean
@ConditionalOnProperty(value = "feign.compression.response.enabled", havingValue = "true")
public CloseableHttpClient customHttpClient(HttpClientConnectionManager httpClientConnectionManager,
FeignHttpClientProperties httpClientProperties) {
HttpClientBuilder builder = HttpClientBuilder.create().disableCookieManagement().useSystemProperties();
this.httpClient = createClient(builder, httpClientConnectionManager, httpClientProperties);
return this.httpClient;
}
@Bean
@ConditionalOnProperty(value = "feign.compression.response.enabled", havingValue = "false", matchIfMissing = true)
public CloseableHttpClient httpClient(ApacheHttpClientFactory httpClientFactory, HttpClientConnectionManager httpClientConnectionManager,
FeignHttpClientProperties httpClientProperties) {
this.httpClient = createClient(httpClientFactory.createBuilder(), httpClientConnectionManager, httpClientProperties);
return this.httpClient;
}
private CloseableHttpClient createClient(HttpClientBuilder builder, HttpClientConnectionManager httpClientConnectionManager,
FeignHttpClientProperties httpClientProperties) {
RequestConfig defaultRequestConfig = RequestConfig.custom()
.setConnectTimeout(httpClientProperties.getConnectionTimeout())
.setRedirectsEnabled(httpClientProperties.isFollowRedirects())
.build();
CloseableHttpClient httpClient = builder.setDefaultRequestConfig(defaultRequestConfig).
setConnectionManager(httpClientConnectionManager).build();
return httpClient;
}
@PreDestroy
public void destroy() throws Exception {
connectionManagerTimer.cancel();
if(httpClient != null) {
httpClient.close();
}
}
}
@Bean
@ConditionalOnMissingBean(Client.class)
public Client feignClient(CachingSpringLoadBalancerFactory cachingFactory,
SpringClientFactory clientFactory, HttpClient httpClient) {
ApacheHttpClient delegate = new ApacheHttpClient(httpClient);
return new LoadBalancerFeignClient(delegate, cachingFactory, clientFactory);
}
}
@@ -0,0 +1,132 @@
/*
* Copyright 2015 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.feign.ribbon;
import java.io.IOException;
import java.net.URI;
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
import com.netflix.client.ClientException;
import com.netflix.client.config.CommonClientConfigKey;
import com.netflix.client.config.DefaultClientConfigImpl;
import com.netflix.client.config.IClientConfig;
import feign.Client;
import feign.Request;
import feign.Response;
/**
* @author Dave Syer
*
*/
public class LoadBalancerFeignClient implements Client {
static final Request.Options DEFAULT_OPTIONS = new Request.Options();
private final Client delegate;
private CachingSpringLoadBalancerFactory lbClientFactory;
private SpringClientFactory clientFactory;
public LoadBalancerFeignClient(Client delegate,
CachingSpringLoadBalancerFactory lbClientFactory,
SpringClientFactory clientFactory) {
this.delegate = delegate;
this.lbClientFactory = lbClientFactory;
this.clientFactory = clientFactory;
}
@Override
public Response execute(Request request, Request.Options options) throws IOException {
try {
URI asUri = URI.create(request.url());
String clientName = asUri.getHost();
URI uriWithoutHost = cleanUrl(request.url(), clientName);
FeignLoadBalancer.RibbonRequest ribbonRequest = new FeignLoadBalancer.RibbonRequest(
this.delegate, request, uriWithoutHost);
IClientConfig requestConfig = getClientConfig(options, clientName);
return lbClient(clientName).executeWithLoadBalancer(ribbonRequest,
requestConfig).toResponse();
}
catch (ClientException e) {
IOException io = findIOException(e);
if (io != null) {
throw io;
}
throw new RuntimeException(e);
}
}
IClientConfig getClientConfig(Request.Options options, String clientName) {
IClientConfig requestConfig;
if (options == DEFAULT_OPTIONS) {
requestConfig = this.clientFactory.getClientConfig(clientName);
} else {
requestConfig = new FeignOptionsClientConfig(options);
}
return requestConfig;
}
protected IOException findIOException(Throwable t) {
if (t == null) {
return null;
}
if (t instanceof IOException) {
return (IOException) t;
}
return findIOException(t.getCause());
}
public Client getDelegate() {
return this.delegate;
}
static URI cleanUrl(String originalUrl, String host) {
String newUrl = originalUrl.replaceFirst(host, "");
StringBuffer buffer = new StringBuffer(newUrl);
if((newUrl.startsWith("https://") && newUrl.length() == 8) ||
(newUrl.startsWith("http://") && newUrl.length() == 7)) {
buffer.append("/");
}
return URI.create(buffer.toString());
}
private FeignLoadBalancer lbClient(String clientName) {
return this.lbClientFactory.create(clientName);
}
static class FeignOptionsClientConfig extends DefaultClientConfigImpl {
public FeignOptionsClientConfig(Request.Options options) {
setProperty(CommonClientConfigKey.ConnectTimeout,
options.connectTimeoutMillis());
setProperty(CommonClientConfigKey.ReadTimeout, options.readTimeoutMillis());
}
@Override
public void loadProperties(String clientName) {
}
@Override
public void loadDefaultValues() {
}
}
}
@@ -0,0 +1,88 @@
/*
* Copyright 2013-2017 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.feign.ribbon;
import feign.Client;
import feign.okhttp.OkHttpClient;
import okhttp3.ConnectionPool;
import java.util.concurrent.TimeUnit;
import javax.annotation.PreDestroy;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cloud.commons.httpclient.OkHttpClientConnectionPoolFactory;
import org.springframework.cloud.commons.httpclient.OkHttpClientFactory;
import org.springframework.cloud.netflix.feign.support.FeignHttpClientProperties;
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author Spencer Gibb
*/
@Configuration
@ConditionalOnClass(OkHttpClient.class)
@ConditionalOnProperty(value = "feign.okhttp.enabled")
class OkHttpFeignLoadBalancedConfiguration {
@Configuration
@ConditionalOnMissingBean(okhttp3.OkHttpClient.class)
protected static class OkHttpFeignConfiguration {
private okhttp3.OkHttpClient okHttpClient;
@Bean
@ConditionalOnMissingBean(ConnectionPool.class)
public ConnectionPool httpClientConnectionPool(FeignHttpClientProperties httpClientProperties,
OkHttpClientConnectionPoolFactory connectionPoolFactory) {
Integer maxTotalConnections = httpClientProperties.getMaxConnections();
Long timeToLive = httpClientProperties.getTimeToLive();
TimeUnit ttlUnit = httpClientProperties.getTimeToLiveUnit();
return connectionPoolFactory.create(maxTotalConnections, timeToLive, ttlUnit);
}
@Bean
public okhttp3.OkHttpClient client(OkHttpClientFactory httpClientFactory,
ConnectionPool connectionPool, FeignHttpClientProperties httpClientProperties) {
Boolean followRedirects = httpClientProperties.isFollowRedirects();
Integer connectTimeout = httpClientProperties.getConnectionTimeout();
this.okHttpClient = httpClientFactory.createBuilder(httpClientProperties.isDisableSslValidation()).
connectTimeout(connectTimeout, TimeUnit.MILLISECONDS).
followRedirects(followRedirects).
connectionPool(connectionPool).build();
return this.okHttpClient;
}
@PreDestroy
public void destroy() {
if(okHttpClient != null) {
okHttpClient.dispatcher().executorService().shutdown();
okHttpClient.connectionPool().evictAll();
}
}
}
@Bean
@ConditionalOnMissingBean(Client.class)
public Client feignClient(CachingSpringLoadBalancerFactory cachingFactory,
SpringClientFactory clientFactory, okhttp3.OkHttpClient okHttpClient) {
OkHttpClient delegate = new OkHttpClient(okHttpClient);
return new LoadBalancerFeignClient(delegate, cachingFactory, clientFactory);
}
}
@@ -0,0 +1,166 @@
/*
*
* * Copyright 2013-2016 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.feign.ribbon;
import feign.Request;
import feign.Response;
import java.io.IOException;
import java.net.URI;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancedBackOffPolicyFactory;
import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryContext;
import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryListenerFactory;
import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryPolicy;
import org.springframework.cloud.client.loadbalancer.LoadBalancedRetryPolicyFactory;
import org.springframework.cloud.client.loadbalancer.RibbonRecoveryCallback;
import org.springframework.cloud.client.loadbalancer.ServiceInstanceChooser;
import org.springframework.cloud.netflix.ribbon.RibbonLoadBalancerClient;
import org.springframework.cloud.netflix.ribbon.ServerIntrospector;
import org.springframework.retry.RetryCallback;
import org.springframework.retry.RetryContext;
import org.springframework.retry.RetryListener;
import org.springframework.retry.backoff.BackOffPolicy;
import org.springframework.retry.backoff.NoBackOffPolicy;
import org.springframework.retry.policy.NeverRetryPolicy;
import org.springframework.retry.support.RetryTemplate;
import org.springframework.util.StreamUtils;
import com.netflix.client.DefaultLoadBalancerRetryHandler;
import com.netflix.client.RequestSpecificRetryHandler;
import com.netflix.client.config.CommonClientConfigKey;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.Server;
/**
* A {@link FeignLoadBalancer} that leverages Spring Retry to retry failed requests.
* @author Ryan Baxter
* @author Gang Li
*/
public class RetryableFeignLoadBalancer extends FeignLoadBalancer implements ServiceInstanceChooser {
private final LoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory;
private final LoadBalancedBackOffPolicyFactory loadBalancedBackOffPolicyFactory;
private final LoadBalancedRetryListenerFactory loadBalancedRetryListenerFactory;
@Deprecated
//TODO remove in 2.0.x
public RetryableFeignLoadBalancer(ILoadBalancer lb, IClientConfig clientConfig,
ServerIntrospector serverIntrospector, LoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory) {
super(lb, clientConfig, serverIntrospector);
this.loadBalancedRetryPolicyFactory = loadBalancedRetryPolicyFactory;
this.setRetryHandler(new DefaultLoadBalancerRetryHandler(clientConfig));
this.loadBalancedBackOffPolicyFactory = new LoadBalancedBackOffPolicyFactory.NoBackOffPolicyFactory();
this.loadBalancedRetryListenerFactory = new LoadBalancedRetryListenerFactory.DefaultRetryListenerFactory();
}
@Deprecated
//TODO remove in 2.0.x
public RetryableFeignLoadBalancer(ILoadBalancer lb, IClientConfig clientConfig,
ServerIntrospector serverIntrospector, LoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory,
LoadBalancedBackOffPolicyFactory loadBalancedBackOffPolicyFactory) {
super(lb, clientConfig, serverIntrospector);
this.loadBalancedRetryPolicyFactory = loadBalancedRetryPolicyFactory;
this.setRetryHandler(new DefaultLoadBalancerRetryHandler(clientConfig));
this.loadBalancedBackOffPolicyFactory = loadBalancedBackOffPolicyFactory == null ?
new LoadBalancedBackOffPolicyFactory.NoBackOffPolicyFactory() : loadBalancedBackOffPolicyFactory;
this.loadBalancedRetryListenerFactory = new LoadBalancedRetryListenerFactory.DefaultRetryListenerFactory();
}
public RetryableFeignLoadBalancer(ILoadBalancer lb, IClientConfig clientConfig, ServerIntrospector serverIntrospector,
LoadBalancedRetryPolicyFactory loadBalancedRetryPolicyFactory,
LoadBalancedBackOffPolicyFactory loadBalancedBackOffPolicyFactory,
LoadBalancedRetryListenerFactory loadBalancedRetryListenerFactory) {
super(lb, clientConfig, serverIntrospector);
this.loadBalancedRetryPolicyFactory = loadBalancedRetryPolicyFactory;
this.setRetryHandler(new DefaultLoadBalancerRetryHandler(clientConfig));
this.loadBalancedBackOffPolicyFactory = loadBalancedBackOffPolicyFactory == null ?
new LoadBalancedBackOffPolicyFactory.NoBackOffPolicyFactory() : loadBalancedBackOffPolicyFactory;
this.loadBalancedRetryListenerFactory = loadBalancedRetryListenerFactory == null ?
new LoadBalancedRetryListenerFactory.DefaultRetryListenerFactory() : loadBalancedRetryListenerFactory;
}
@Override
public RibbonResponse execute(final RibbonRequest request, IClientConfig configOverride)
throws IOException {
final Request.Options options;
if (configOverride != null) {
options = new Request.Options(
configOverride.get(CommonClientConfigKey.ConnectTimeout,
this.connectTimeout),
(configOverride.get(CommonClientConfigKey.ReadTimeout,
this.readTimeout)));
}
else {
options = new Request.Options(this.connectTimeout, this.readTimeout);
}
final LoadBalancedRetryPolicy retryPolicy = loadBalancedRetryPolicyFactory.create(this.getClientName(), this);
RetryTemplate retryTemplate = new RetryTemplate();
BackOffPolicy backOffPolicy = loadBalancedBackOffPolicyFactory.createBackOffPolicy(this.getClientName());
retryTemplate.setBackOffPolicy(backOffPolicy == null ? new NoBackOffPolicy() : backOffPolicy);
RetryListener[] retryListeners = this.loadBalancedRetryListenerFactory.createRetryListeners(this.getClientName());
if (retryListeners != null && retryListeners.length != 0) {
retryTemplate.setListeners(retryListeners);
}
retryTemplate.setRetryPolicy(retryPolicy == null ? new NeverRetryPolicy()
: new FeignRetryPolicy(request.toHttpRequest(), retryPolicy, this, this.getClientName()));
return retryTemplate.execute(new RetryCallback<RibbonResponse, IOException>() {
@Override
public RibbonResponse doWithRetry(RetryContext retryContext) throws IOException {
Request feignRequest = null;
//on retries the policy will choose the server and set it in the context
//extract the server and update the request being made
if (retryContext instanceof LoadBalancedRetryContext) {
ServiceInstance service = ((LoadBalancedRetryContext) retryContext).getServiceInstance();
if (service != null) {
feignRequest = ((RibbonRequest) request.replaceUri(reconstructURIWithServer(new Server(service.getHost(), service.getPort()), request.getUri()))).toRequest();
}
}
if (feignRequest == null) {
feignRequest = request.toRequest();
}
Response response = request.client().execute(feignRequest, options);
if (retryPolicy.retryableStatusCode(response.status())) {
byte[] byteArray = response.body() == null ? new byte[]{} : StreamUtils.copyToByteArray(response.body().asInputStream());
response.close();
throw new RibbonResponseStatusCodeException(RetryableFeignLoadBalancer.this.clientName, response,
byteArray, request.getUri());
}
return new RibbonResponse(request.getUri(), response);
}
}, new RibbonRecoveryCallback<RibbonResponse, Response>() {
@Override
protected RibbonResponse createResponse(Response response, URI uri) {
return new RibbonResponse(uri, response);
}
});
}
@Override
public RequestSpecificRetryHandler getRequestSpecificRetryHandler(
FeignLoadBalancer.RibbonRequest request, IClientConfig requestConfig) {
return new RequestSpecificRetryHandler(false, false, this.getRetryHandler(), requestConfig);
}
@Override
public ServiceInstance choose(String serviceId) {
return new RibbonLoadBalancerClient.RibbonServer(serviceId,
this.getLoadBalancer().chooseServer(serviceId));
}
}
@@ -0,0 +1,45 @@
/*
* Copyright 2013-2018 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.feign.ribbon;
import feign.Response;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.net.URI;
import org.springframework.cloud.client.loadbalancer.RetryableStatusCodeException;
import org.springframework.util.StreamUtils;
/**
* A {@link RetryableStatusCodeException} for {@link Response}s
* @author Ryan Baxter
*/
public class RibbonResponseStatusCodeException extends RetryableStatusCodeException {
private Response response;
public RibbonResponseStatusCodeException(String serviceId, Response response, byte[] body, URI uri) {
super(serviceId, response.status(), response, uri);
this.response = Response.builder().body(new ByteArrayInputStream(body), body.length)
.headers(response.headers()).reason(response.reason())
.status(response.status()).request(response.request()).build();
}
@Override
public Response getResponse() {
return response;
}
}
@@ -0,0 +1,55 @@
package org.springframework.cloud.netflix.feign.support;
import com.netflix.hystrix.HystrixCommand;
import com.netflix.hystrix.HystrixCommandGroupKey;
import com.netflix.hystrix.HystrixThreadPoolKey;
/**
* Convenience class for implementing feign fallbacks that return {@link HystrixCommand}.
* Also useful for return types of {@link rx.Observable} and {@link java.util.concurrent.Future}.
* For those return types, just call {@link FallbackCommand#observe()} or {@link FallbackCommand#queue()} respectively.
* @author Spencer Gibb
*/
public class FallbackCommand<T> extends HystrixCommand<T> {
private T result;
public FallbackCommand(T result) {
this(result, "fallback");
}
protected FallbackCommand(T result, String groupname) {
super(HystrixCommandGroupKey.Factory.asKey(groupname));
this.result = result;
}
public FallbackCommand(T result, HystrixCommandGroupKey group) {
super(group);
this.result = result;
}
public FallbackCommand(T result, HystrixCommandGroupKey group, int executionIsolationThreadTimeoutInMilliseconds) {
super(group, executionIsolationThreadTimeoutInMilliseconds);
this.result = result;
}
public FallbackCommand(T result, HystrixCommandGroupKey group, HystrixThreadPoolKey threadPool) {
super(group, threadPool);
this.result = result;
}
public FallbackCommand(T result, HystrixCommandGroupKey group, HystrixThreadPoolKey threadPool, int executionIsolationThreadTimeoutInMilliseconds) {
super(group, threadPool, executionIsolationThreadTimeoutInMilliseconds);
this.result = result;
}
public FallbackCommand(T result, Setter setter) {
super(setter);
this.result = result;
}
@Override
protected T run() throws Exception {
return this.result;
}
}
@@ -0,0 +1,110 @@
/*
*
* * Copyright 2013-2016 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.feign.support;
import java.util.concurrent.TimeUnit;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
* @author Ryan Baxter
*/
@ConfigurationProperties(prefix = "feign.httpclient")
public class FeignHttpClientProperties {
public static final boolean DEFAULT_DISABLE_SSL_VALIDATION = false;
public static final int DEFAULT_MAX_CONNECTIONS = 200;
public static final int DEFAULT_MAX_CONNECTIONS_PER_ROUTE = 50;
public static final long DEFAULT_TIME_TO_LIVE = 900L;
public static final TimeUnit DEFAULT_TIME_TO_LIVE_UNIT = TimeUnit.SECONDS;
public static final boolean DEFAULT_FOLLOW_REDIRECTS = true;
public static final int DEFAULT_CONNECTION_TIMEOUT = 2000;
public static final int DEFAULT_CONNECTION_TIMER_REPEAT = 3000;
private boolean disableSslValidation = DEFAULT_DISABLE_SSL_VALIDATION;
private int maxConnections = DEFAULT_MAX_CONNECTIONS;
private int maxConnectionsPerRoute = DEFAULT_MAX_CONNECTIONS_PER_ROUTE;
private long timeToLive = DEFAULT_TIME_TO_LIVE;
private TimeUnit timeToLiveUnit = DEFAULT_TIME_TO_LIVE_UNIT;
private boolean followRedirects = DEFAULT_FOLLOW_REDIRECTS;
private int connectionTimeout = DEFAULT_CONNECTION_TIMEOUT;
private int connectionTimerRepeat = DEFAULT_CONNECTION_TIMER_REPEAT;
public int getConnectionTimerRepeat() {
return connectionTimerRepeat;
}
public void setConnectionTimerRepeat(int connectionTimerRepeat) {
this.connectionTimerRepeat = connectionTimerRepeat;
}
public boolean isDisableSslValidation() {
return disableSslValidation;
}
public void setDisableSslValidation(boolean disableSslValidation) {
this.disableSslValidation = disableSslValidation;
}
public int getMaxConnections() {
return maxConnections;
}
public void setMaxConnections(int maxConnections) {
this.maxConnections = maxConnections;
}
public int getMaxConnectionsPerRoute() {
return maxConnectionsPerRoute;
}
public void setMaxConnectionsPerRoute(int maxConnectionsPerRoute) {
this.maxConnectionsPerRoute = maxConnectionsPerRoute;
}
public long getTimeToLive() {
return timeToLive;
}
public void setTimeToLive(long timeToLive) {
this.timeToLive = timeToLive;
}
public TimeUnit getTimeToLiveUnit() {
return timeToLiveUnit;
}
public void setTimeToLiveUnit(TimeUnit timeToLiveUnit) {
this.timeToLiveUnit = timeToLiveUnit;
}
public boolean isFollowRedirects() {
return followRedirects;
}
public void setFollowRedirects(boolean followRedirects) {
this.followRedirects = followRedirects;
}
public int getConnectionTimeout() {
return connectionTimeout;
}
public void setConnectionTimeout(int connectionTimeout) {
this.connectionTimeout = connectionTimeout;
}
}
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* 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,
@@ -18,6 +18,8 @@ package org.springframework.cloud.netflix.feign.support;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.springframework.http.HttpHeaders;
@@ -35,4 +37,14 @@ public class FeignUtils {
return httpHeaders;
}
static Map<String, Collection<String>> getHeaders(HttpHeaders httpHeaders) {
LinkedHashMap<String, Collection<String>> headers = new LinkedHashMap<>();
for (Map.Entry<String, List<String>> entry : httpHeaders.entrySet()) {
headers.put(entry.getKey(), entry.getValue());
}
return headers;
}
}
@@ -0,0 +1,75 @@
package org.springframework.cloud.netflix.feign.support;
import java.io.IOException;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.LinkedList;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import feign.FeignException;
import feign.Response;
import feign.codec.Decoder;
/**
* Decoder adds compatibility for Spring MVC's ResponseEntity to any other decoder via
* composition.
* @author chadjaros
*/
public class ResponseEntityDecoder implements Decoder {
private Decoder decoder;
public ResponseEntityDecoder(Decoder decoder) {
this.decoder = decoder;
}
@Override
public Object decode(final Response response, Type type) throws IOException,
FeignException {
if (isParameterizeHttpEntity(type)) {
type = ((ParameterizedType) type).getActualTypeArguments()[0];
Object decodedObject = decoder.decode(response, type);
return createResponse(decodedObject, response);
}
else if (isHttpEntity(type)) {
return createResponse(null, response);
}
else {
return decoder.decode(response, type);
}
}
private boolean isParameterizeHttpEntity(Type type) {
if (type instanceof ParameterizedType) {
return isHttpEntity(((ParameterizedType) type).getRawType());
}
return false;
}
private boolean isHttpEntity(Type type) {
if (type instanceof Class) {
Class c = (Class) type;
return HttpEntity.class.isAssignableFrom(c);
}
return false;
}
@SuppressWarnings("unchecked")
private <T> ResponseEntity<T> createResponse(Object instance, Response response) {
MultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
for (String key : response.headers().keySet()) {
headers.put(key, new LinkedList<>(response.headers().get(key)));
}
return new ResponseEntity<>((T) instance, headers, HttpStatus.valueOf(response
.status()));
}
}
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* 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,
@@ -16,22 +16,21 @@
package org.springframework.cloud.netflix.feign.support;
import static org.springframework.cloud.netflix.feign.support.FeignUtils.getHttpHeaders;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.lang.reflect.WildcardType;
import javax.inject.Provider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.boot.autoconfigure.web.HttpMessageConverters;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.web.client.HttpMessageConverterExtractor;
import static org.springframework.cloud.netflix.feign.support.FeignUtils.getHttpHeaders;
import feign.FeignException;
import feign.Response;
import feign.codec.DecodeException;
@@ -42,19 +41,20 @@ import feign.codec.Decoder;
*/
public class SpringDecoder implements Decoder {
@Autowired
private Provider<HttpMessageConverters> messageConverters;
private ObjectFactory<HttpMessageConverters> messageConverters;
public SpringDecoder() {
public SpringDecoder(ObjectFactory<HttpMessageConverters> messageConverters) {
this.messageConverters = messageConverters;
}
@Override
public Object decode(final Response response, Type type) throws IOException,
FeignException {
if (type instanceof Class || type instanceof ParameterizedType) {
public Object decode(final Response response, Type type)
throws IOException, FeignException {
if (type instanceof Class || type instanceof ParameterizedType
|| type instanceof WildcardType) {
@SuppressWarnings({ "unchecked", "rawtypes" })
HttpMessageConverterExtractor<?> extractor = new HttpMessageConverterExtractor(
type, this.messageConverters.get().getConverters());
type, this.messageConverters.getObject().getConverters());
return extractor.extractData(new FeignResponseAdapter(response));
}
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* 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,
@@ -19,37 +19,45 @@ package org.springframework.cloud.netflix.feign.support;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Type;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Collection;
import javax.inject.Provider;
import lombok.extern.apachecommons.CommonsLog;
import org.springframework.beans.factory.annotation.Autowired;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.boot.autoconfigure.web.HttpMessageConverters;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.MediaType;
import org.springframework.http.converter.ByteArrayHttpMessageConverter;
import org.springframework.http.converter.HttpMessageConverter;
import feign.RequestTemplate;
import feign.codec.EncodeException;
import feign.codec.Encoder;
import org.springframework.http.converter.protobuf.ProtobufHttpMessageConverter;
import static org.springframework.cloud.netflix.feign.support.FeignUtils.getHeaders;
import static org.springframework.cloud.netflix.feign.support.FeignUtils.getHttpHeaders;
/**
* @author Spencer Gibb
* @author ScienJus
*/
@CommonsLog
public class SpringEncoder implements Encoder {
@Autowired
private Provider<HttpMessageConverters> messageConverters;
private static final Log log = LogFactory.getLog(SpringEncoder.class);
private ObjectFactory<HttpMessageConverters> messageConverters;
public SpringEncoder(ObjectFactory<HttpMessageConverters> messageConverters) {
this.messageConverters = messageConverters;
}
@Override
public void encode(Object requestBody, RequestTemplate request)
public void encode(Object requestBody, Type bodyType, RequestTemplate request)
throws EncodeException {
// template.body(conversionService.convert(object, String.class));
if (requestBody != null) {
@@ -62,8 +70,8 @@ public class SpringEncoder implements Encoder {
requestContentType = MediaType.valueOf(type);
}
for (HttpMessageConverter<?> messageConverter : this.messageConverters.get()
.getConverters()) {
for (HttpMessageConverter<?> messageConverter : this.messageConverters
.getObject().getConverters()) {
if (messageConverter.canWrite(requestType, requestContentType)) {
if (log.isDebugEnabled()) {
if (requestContentType != null) {
@@ -87,8 +95,23 @@ public class SpringEncoder implements Encoder {
catch (IOException ex) {
throw new EncodeException("Error converting request body", ex);
}
request.body(outputMessage.getOutputStream().toByteArray(),
Charset.forName("UTF-8")); // TODO: set charset
// clear headers
request.headers(null);
// converters can modify headers, so update the request
// with the modified headers
request.headers(getHeaders(outputMessage.getHeaders()));
// do not use charset for binary data and protobuf
Charset charset;
if (messageConverter instanceof ByteArrayHttpMessageConverter) {
charset = null;
} else if (messageConverter instanceof ProtobufHttpMessageConverter &&
ProtobufHttpMessageConverter.PROTOBUF.isCompatibleWith(outputMessage.getHeaders().getContentType())) {
charset = null;
} else {
charset = StandardCharsets.UTF_8;
}
request.body(outputMessage.getOutputStream().toByteArray(), charset);
return;
}
}
@@ -105,10 +128,10 @@ public class SpringEncoder implements Encoder {
private final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
private final RequestTemplate request;
private final HttpHeaders httpHeaders;
private FeignOutputMessage(RequestTemplate request) {
this.request = request;
httpHeaders = getHttpHeaders(request.headers());
}
@Override
@@ -118,7 +141,7 @@ public class SpringEncoder implements Encoder {
@Override
public HttpHeaders getHeaders() {
return getHttpHeaders(this.request.headers());
return this.httpHeaders;
}
public ByteArrayOutputStream getOutputStream() {
@@ -1,11 +1,11 @@
/*
* Copyright 2013-2015 the original author or authors.
* Copyright 2013-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* 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,
@@ -18,82 +18,193 @@ package org.springframework.cloud.netflix.feign.support;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.cloud.netflix.feign.AnnotatedParameterProcessor;
import org.springframework.cloud.netflix.feign.annotation.PathVariableParameterProcessor;
import org.springframework.cloud.netflix.feign.annotation.RequestHeaderParameterProcessor;
import org.springframework.cloud.netflix.feign.annotation.RequestParamParameterProcessor;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.core.DefaultParameterNameDiscoverer;
import org.springframework.core.ParameterNameDiscoverer;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.support.DefaultConversionService;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.ResourceLoader;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import feign.Contract;
import feign.MethodMetadata;
import org.springframework.web.bind.annotation.RequestMethod;
import static feign.Util.checkState;
import static feign.Util.emptyToNull;
import static org.springframework.core.annotation.AnnotatedElementUtils.findMergedAnnotation;
import feign.Contract;
import feign.Feign;
import feign.MethodMetadata;
import feign.Param;
/**
* @author Spencer Gibb
* @author Abhijit Sarkar
*/
public class SpringMvcContract extends Contract.BaseContract {
public class SpringMvcContract extends Contract.BaseContract
implements ResourceLoaderAware {
private static final String ACCEPT = "Accept";
private static final String CONTENT_TYPE = "Content-Type";
private static final ParameterNameDiscoverer PARAMETER_NAME_DISCOVERER = new DefaultParameterNameDiscoverer();
private final Map<Class<? extends Annotation>, AnnotatedParameterProcessor> annotatedArgumentProcessors;
private final Map<String, Method> processedMethods = new HashMap<>();
private final ConversionService conversionService;
private final Param.Expander expander;
private ResourceLoader resourceLoader = new DefaultResourceLoader();
public SpringMvcContract() {
this(Collections.<AnnotatedParameterProcessor> emptyList());
}
public SpringMvcContract(
List<AnnotatedParameterProcessor> annotatedParameterProcessors) {
this(annotatedParameterProcessors, new DefaultConversionService());
}
public SpringMvcContract(
List<AnnotatedParameterProcessor> annotatedParameterProcessors,
ConversionService conversionService) {
Assert.notNull(annotatedParameterProcessors,
"Parameter processors can not be null.");
Assert.notNull(conversionService, "ConversionService can not be null.");
List<AnnotatedParameterProcessor> processors;
if (!annotatedParameterProcessors.isEmpty()) {
processors = new ArrayList<>(annotatedParameterProcessors);
}
else {
processors = getDefaultAnnotatedArgumentsProcessors();
}
this.annotatedArgumentProcessors = toAnnotatedArgumentProcessorMap(processors);
this.conversionService = conversionService;
this.expander = new ConvertingExpander(conversionService);
}
@Override
protected void processAnnotationOnMethod(MethodMetadata data,
Annotation methodAnnotation, Method method) {
RequestMapping mapping = RequestMapping.class.cast(methodAnnotation);
if (mapping != null) {
// HTTP Method
checkOne(method, mapping.method(), "method");
data.template().method(mapping.method()[0].name());
public void setResourceLoader(ResourceLoader resourceLoader) {
this.resourceLoader = resourceLoader;
}
// path
checkOne(method, mapping.value(), "value");
String methodAnnotationValue = mapping.value()[0];
String pathValue = emptyToNull(methodAnnotationValue);
checkState(pathValue != null, "value was empty on method %s",
method.getName());
if (!methodAnnotationValue.startsWith("/")
&& !data.template().toString().endsWith("/")) {
methodAnnotationValue = "/" + methodAnnotationValue;
}
data.template().append(methodAnnotationValue);
// produces
checkAtMostOne(method, mapping.produces(), "produces");
String[] serverProduces = mapping.produces();
String clientAccepts = serverProduces.length == 0 ? null
: emptyToNull(serverProduces[0]);
if (clientAccepts != null) {
data.template().header(ACCEPT, clientAccepts);
}
// consumes
checkAtMostOne(method, mapping.consumes(), "consumes");
String[] serverConsumes = mapping.consumes();
String clientProduces = serverConsumes.length == 0 ? null
: emptyToNull(serverConsumes[0]);
if (clientProduces != null) {
data.template().header(CONTENT_TYPE, clientProduces);
}
// headers
// TODO: only supports one header value per key
if (mapping.headers() != null && mapping.headers().length > 0) {
for (String header : mapping.headers()) {
int colon = header.indexOf(':');
data.template().header(header.substring(0, colon),
header.substring(colon + 2));
@Override
protected void processAnnotationOnClass(MethodMetadata data, Class<?> clz) {
if (clz.getInterfaces().length == 0) {
RequestMapping classAnnotation = findMergedAnnotation(clz,
RequestMapping.class);
if (classAnnotation != null) {
// Prepend path from class annotation if specified
if (classAnnotation.value().length > 0) {
String pathValue = emptyToNull(classAnnotation.value()[0]);
pathValue = resolve(pathValue);
if (!pathValue.startsWith("/")) {
pathValue = "/" + pathValue;
}
data.template().insert(0, pathValue);
}
}
}
}
@Override
public MethodMetadata parseAndValidateMetadata(Class<?> targetType, Method method) {
this.processedMethods.put(Feign.configKey(targetType, method), method);
MethodMetadata md = super.parseAndValidateMetadata(targetType, method);
RequestMapping classAnnotation = findMergedAnnotation(targetType,
RequestMapping.class);
if (classAnnotation != null) {
// produces - use from class annotation only if method has not specified this
if (!md.template().headers().containsKey(ACCEPT)) {
parseProduces(md, method, classAnnotation);
}
// consumes -- use from class annotation only if method has not specified this
if (!md.template().headers().containsKey(CONTENT_TYPE)) {
parseConsumes(md, method, classAnnotation);
}
// headers -- class annotation is inherited to methods, always write these if
// present
parseHeaders(md, method, classAnnotation);
}
return md;
}
@Override
protected void processAnnotationOnMethod(MethodMetadata data,
Annotation methodAnnotation, Method method) {
if (!RequestMapping.class.isInstance(methodAnnotation) && !methodAnnotation
.annotationType().isAnnotationPresent(RequestMapping.class)) {
return;
}
RequestMapping methodMapping = findMergedAnnotation(method, RequestMapping.class);
// HTTP Method
RequestMethod[] methods = methodMapping.method();
if (methods.length == 0) {
methods = new RequestMethod[] { RequestMethod.GET };
}
checkOne(method, methods, "method");
data.template().method(methods[0].name());
// path
checkAtMostOne(method, methodMapping.value(), "value");
if (methodMapping.value().length > 0) {
String pathValue = emptyToNull(methodMapping.value()[0]);
if (pathValue != null) {
pathValue = resolve(pathValue);
// Append path from @RequestMapping if value is present on method
if (!pathValue.startsWith("/")
&& !data.template().toString().endsWith("/")) {
pathValue = "/" + pathValue;
}
data.template().append(pathValue);
}
}
// produces
parseProduces(data, method, methodMapping);
// consumes
parseConsumes(data, method, methodMapping);
// headers
parseHeaders(data, method, methodMapping);
data.indexToExpander(new LinkedHashMap<Integer, Param.Expander>());
}
private String resolve(String value) {
if (StringUtils.hasText(value)
&& this.resourceLoader instanceof ConfigurableApplicationContext) {
return ((ConfigurableApplicationContext) this.resourceLoader).getEnvironment()
.resolvePlaceholders(value);
}
return value;
}
private void checkAtMostOne(Method method, Object[] values, String fieldName) {
checkState(values != null && (values.length == 0 || values.length == 1),
"Method %s can only contain at most 1 %s field. Found: %s",
@@ -111,69 +222,159 @@ public class SpringMvcContract extends Contract.BaseContract {
protected boolean processAnnotationsOnParameter(MethodMetadata data,
Annotation[] annotations, int paramIndex) {
boolean isHttpAnnotation = false;
// TODO: support spring parameter annotations?
AnnotatedParameterProcessor.AnnotatedParameterContext context = new SimpleAnnotatedParameterContext(
data, paramIndex);
Method method = this.processedMethods.get(data.configKey());
for (Annotation parameterAnnotation : annotations) {
Class<? extends Annotation> annotationType = parameterAnnotation
.annotationType();
if (annotationType == PathVariable.class) {
String name = PathVariable.class.cast(parameterAnnotation).value();
checkState(emptyToNull(name) != null,
"PathVariable annotation was empty on param %s.", paramIndex);
nameParam(data, name, paramIndex);
isHttpAnnotation = true;
String varName = '{' + name + '}';
if (data.template().url().indexOf(varName) == -1
&& !searchMapValues(data.template().queries(), varName)
&& !searchMapValues(data.template().headers(), varName)) {
data.formParams().add(name);
}
AnnotatedParameterProcessor processor = this.annotatedArgumentProcessors
.get(parameterAnnotation.annotationType());
if (processor != null) {
Annotation processParameterAnnotation;
// synthesize, handling @AliasFor, while falling back to parameter name on
// missing String #value():
processParameterAnnotation = synthesizeWithMethodParameterNameAsFallbackValue(
parameterAnnotation, method, paramIndex);
isHttpAnnotation |= processor.processArgument(context,
processParameterAnnotation, method);
}
else if (annotationType == RequestParam.class) {
String name = RequestParam.class.cast(parameterAnnotation).value();
checkState(emptyToNull(name) != null,
"QueryParam.value() was empty on parameter %s", paramIndex);
Collection<String> query = addTemplatedParam(data.template().queries()
.get(name), name);
data.template().query(name, query);
nameParam(data, name, paramIndex);
isHttpAnnotation = true;
}
else if (annotationType == RequestHeader.class) {
String name = RequestHeader.class.cast(parameterAnnotation).value();
checkState(emptyToNull(name) != null,
"HeaderParam.value() was empty on parameter %s", paramIndex);
Collection<String> header = addTemplatedParam(data.template().headers()
.get(name), name);
data.template().header(name, header);
nameParam(data, name, paramIndex);
isHttpAnnotation = true;
}
// TODO
/*
* else if (annotationType == FormParam.class) { String name =
* FormParam.class.cast(parameterAnnotation).value();
* checkState(emptyToNull(name) != null,
* "FormParam.value() was empty on parameter %s", paramIndex);
* data.formParams().add(name); nameParam(data, name, paramIndex);
* isHttpAnnotation = true; }
*/
}
if (isHttpAnnotation && data.indexToExpander().get(paramIndex) == null
&& this.conversionService.canConvert(
method.getParameterTypes()[paramIndex], String.class)) {
data.indexToExpander().put(paramIndex, this.expander);
}
return isHttpAnnotation;
}
private <K, V> boolean searchMapValues(Map<K, Collection<V>> map, V search) {
Collection<Collection<V>> values = map.values();
if (values == null) {
return false;
private void parseProduces(MethodMetadata md, Method method,
RequestMapping annotation) {
checkAtMostOne(method, annotation.produces(), "produces");
String[] serverProduces = annotation.produces();
String clientAccepts = serverProduces.length == 0 ? null
: emptyToNull(serverProduces[0]);
if (clientAccepts != null) {
md.template().header(ACCEPT, clientAccepts);
}
for (Collection<V> entry : values) {
if (entry.contains(search)) {
return true;
}
}
return false;
}
private void parseConsumes(MethodMetadata md, Method method,
RequestMapping annotation) {
checkAtMostOne(method, annotation.consumes(), "consumes");
String[] serverConsumes = annotation.consumes();
String clientProduces = serverConsumes.length == 0 ? null
: emptyToNull(serverConsumes[0]);
if (clientProduces != null) {
md.template().header(CONTENT_TYPE, clientProduces);
}
}
private void parseHeaders(MethodMetadata md, Method method,
RequestMapping annotation) {
// TODO: only supports one header value per key
if (annotation.headers() != null && annotation.headers().length > 0) {
for (String header : annotation.headers()) {
int index = header.indexOf('=');
if (!header.contains("!=") && index >= 0) {
md.template().header(resolve(header.substring(0, index)),
resolve(header.substring(index + 1).trim()));
}
}
}
}
private Map<Class<? extends Annotation>, AnnotatedParameterProcessor> toAnnotatedArgumentProcessorMap(
List<AnnotatedParameterProcessor> processors) {
Map<Class<? extends Annotation>, AnnotatedParameterProcessor> result = new HashMap<>();
for (AnnotatedParameterProcessor processor : processors) {
result.put(processor.getAnnotationType(), processor);
}
return result;
}
private List<AnnotatedParameterProcessor> getDefaultAnnotatedArgumentsProcessors() {
List<AnnotatedParameterProcessor> annotatedArgumentResolvers = new ArrayList<>();
annotatedArgumentResolvers.add(new PathVariableParameterProcessor());
annotatedArgumentResolvers.add(new RequestParamParameterProcessor());
annotatedArgumentResolvers.add(new RequestHeaderParameterProcessor());
return annotatedArgumentResolvers;
}
private Annotation synthesizeWithMethodParameterNameAsFallbackValue(
Annotation parameterAnnotation, Method method, int parameterIndex) {
Map<String, Object> annotationAttributes = AnnotationUtils
.getAnnotationAttributes(parameterAnnotation);
Object defaultValue = AnnotationUtils.getDefaultValue(parameterAnnotation);
if (defaultValue instanceof String
&& defaultValue.equals(annotationAttributes.get(AnnotationUtils.VALUE))) {
Type[] parameterTypes = method.getGenericParameterTypes();
String[] parameterNames = PARAMETER_NAME_DISCOVERER.getParameterNames(method);
if (shouldAddParameterName(parameterIndex, parameterTypes, parameterNames)) {
annotationAttributes.put(AnnotationUtils.VALUE,
parameterNames[parameterIndex]);
}
}
return AnnotationUtils.synthesizeAnnotation(annotationAttributes,
parameterAnnotation.annotationType(), null);
}
private boolean shouldAddParameterName(int parameterIndex, Type[] parameterTypes, String[] parameterNames) {
// has a parameter name
return parameterNames != null && parameterNames.length > parameterIndex
// has a type
&& parameterTypes != null && parameterTypes.length > parameterIndex;
}
private class SimpleAnnotatedParameterContext
implements AnnotatedParameterProcessor.AnnotatedParameterContext {
private final MethodMetadata methodMetadata;
private final int parameterIndex;
public SimpleAnnotatedParameterContext(MethodMetadata methodMetadata,
int parameterIndex) {
this.methodMetadata = methodMetadata;
this.parameterIndex = parameterIndex;
}
@Override
public MethodMetadata getMethodMetadata() {
return this.methodMetadata;
}
@Override
public int getParameterIndex() {
return this.parameterIndex;
}
@Override
public void setParameterName(String name) {
nameParam(this.methodMetadata, name, this.parameterIndex);
}
@Override
public Collection<String> setTemplateParameter(String name,
Collection<String> rest) {
return addTemplatedParam(rest, name);
}
}
public static class ConvertingExpander implements Param.Expander {
private final ConversionService conversionService;
public ConvertingExpander(ConversionService conversionService) {
this.conversionService = conversionService;
}
@Override
public String expand(Object value) {
return this.conversionService.convert(value, String.class);
}
}
}
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* 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,
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* 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,
@@ -16,11 +16,11 @@
package org.springframework.cloud.netflix.hystrix;
import org.springframework.boot.actuate.autoconfigure.ConditionalOnEnabledHealthIndicator;
import org.springframework.boot.actuate.autoconfigure.HealthIndicatorAutoConfiguration;
import org.springframework.boot.actuate.health.HealthIndicator;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -30,14 +30,15 @@ import com.netflix.hystrix.Hystrix;
* Auto configuration for Hystrix.
*
* @author Christian Dupuis
* @author Dave Syer
*/
@Configuration
@ConditionalOnClass({ Hystrix.class, HealthIndicator.class })
@ConditionalOnProperty(value = "health.hystrix.enabled", matchIfMissing = true)
@AutoConfigureAfter({ HealthIndicatorAutoConfiguration.class })
public class HystrixAutoConfiguration {
@Bean
@ConditionalOnEnabledHealthIndicator("hystrix")
public HystrixHealthIndicator hystrixHealthIndicator() {
return new HystrixHealthIndicator();
}
@@ -1,11 +1,11 @@
/*
* Copyright 2013-2014 the original author or authors.
* Copyright 2013-2016 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* 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,
@@ -32,6 +32,9 @@ import org.springframework.boot.actuate.metrics.GaugeService;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cloud.client.actuator.HasFeatures;
import org.springframework.cloud.client.actuator.NamedFeature;
import org.springframework.context.SmartLifecycle;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@@ -47,6 +50,7 @@ import com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsStreamServl
/**
* @author Spencer Gibb
* @author Christian Dupuis
* @author Venil Noronha
*/
@Configuration
public class HystrixCircuitBreakerConfiguration {
@@ -61,6 +65,11 @@ public class HystrixCircuitBreakerConfiguration {
return new HystrixShutdownHook();
}
@Bean
public HasFeatures hystrixFeature() {
return HasFeatures.namedFeatures(new NamedFeature("Hystrix", HystrixCommandAspect.class));
}
@Configuration
@ConditionalOnProperty(value = "hystrix.stream.endpoint.enabled", matchIfMissing = true)
@ConditionalOnWebApplication
@@ -72,10 +81,16 @@ public class HystrixCircuitBreakerConfiguration {
return new HystrixStreamEndpoint();
}
@Bean
public HasFeatures hystrixStreamFeature() {
return HasFeatures.namedFeature("Hystrix Stream Servlet", HystrixStreamEndpoint.class);
}
}
@Configuration
@ConditionalOnProperty(value = "hystrix.metrics.enabled", matchIfMissing = true)
@ConditionalOnClass({ HystrixMetricsPoller.class, GaugeService.class })
@EnableConfigurationProperties(HystrixMetricsProperties.class)
protected static class HystrixMetricsPollerConfiguration implements SmartLifecycle {
private static Log logger = LogFactory
@@ -84,6 +99,9 @@ public class HystrixCircuitBreakerConfiguration {
@Autowired(required = false)
private GaugeService gauges;
@Autowired
private HystrixMetricsProperties metricsProperties;
private ObjectMapper mapper = new ObjectMapper();
private HystrixMetricsPoller poller;
@@ -113,7 +131,8 @@ public class HystrixCircuitBreakerConfiguration {
}
};
this.poller = new HystrixMetricsPoller(listener, 2000);
this.poller = new HystrixMetricsPoller(listener,
metricsProperties.getPollingIntervalMs());
// start polling and it will write directly to the listener
this.poller.start();
logger.info("Starting poller");
@@ -139,7 +158,7 @@ public class HystrixCircuitBreakerConfiguration {
else if (value instanceof Map) {
@SuppressWarnings("unchecked")
Map<String, Object> sub = (Map<String, Object>) value;
addMetrics(sub, prefix);
addMetrics(sub, prefix + "." + key);
}
}
}
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* 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,
@@ -19,8 +19,12 @@ package org.springframework.cloud.netflix.hystrix;
/**
* @author Spencer Gibb
*/
public interface HystrixConstants {
public class HystrixConstants {
String HYSTRIX_STREAM_NAME = "spring.cloud.hystrix.stream";
public static final String HYSTRIX_STREAM_DESTINATION = "springCloudHystrixStream";
private HystrixConstants() {
throw new AssertionError("Must not instantiate constant utility class");
}
}
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* 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,
@@ -30,8 +30,8 @@ import com.netflix.hystrix.HystrixCommandMetrics;
/**
* A {@link HealthIndicator} implementation for Hystrix circuit breakers.
* <p>
* This default implementation will set the system to <code>OUT_OF_SERVICE</code> and
* include all open circuits by name.
* This default implementation will not change the system state (e.g. <code>OK</code>) but
* includes all open circuits by name.
*
* @author Christian Dupuis
*/
@@ -47,7 +47,7 @@ public class HystrixHealthIndicator extends AbstractHealthIndicator {
for (HystrixCommandMetrics metrics : HystrixCommandMetrics.getInstances()) {
HystrixCircuitBreaker circuitBreaker = HystrixCircuitBreaker.Factory
.getInstance(metrics.getCommandKey());
if (circuitBreaker.isOpen()) {
if (circuitBreaker != null && circuitBreaker.isOpen()) {
openCircuitBreakers.add(metrics.getCommandGroup().name() + "::"
+ metrics.getCommandKey().name());
}
@@ -0,0 +1,73 @@
/*
* Copyright 2013-2016 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.hystrix;
import org.springframework.boot.context.properties.ConfigurationProperties;
import java.util.Objects;
/**
* @author Venil Noronha
* @author Gregor Zurowski
*/
@ConfigurationProperties("hystrix.metrics")
public class HystrixMetricsProperties {
/** Enable Hystrix metrics polling. Defaults to true. */
private boolean enabled = true;
/** Interval between subsequent polling of metrics. Defaults to 2000 ms. */
private Integer pollingIntervalMs = 2000;
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public Integer getPollingIntervalMs() {
return pollingIntervalMs;
}
public void setPollingIntervalMs(Integer pollingIntervalMs) {
this.pollingIntervalMs = pollingIntervalMs;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
HystrixMetricsProperties that = (HystrixMetricsProperties) o;
return enabled == that.enabled &&
Objects.equals(pollingIntervalMs, that.pollingIntervalMs);
}
@Override
public int hashCode() {
return Objects.hash(enabled, pollingIntervalMs);
}
@Override
public String toString() {
return new StringBuilder("HystrixMetricsProperties{")
.append("enabled=").append(enabled).append(", ")
.append("pollingIntervalMs=").append(pollingIntervalMs)
.append("}").toString();
}
}
@@ -5,7 +5,7 @@
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
* 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,
@@ -0,0 +1,82 @@
/*
* Copyright 2013-2016 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.hystrix.security;
import javax.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.AllNestedConditions;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cloud.netflix.hystrix.security.HystrixSecurityAutoConfiguration.HystrixSecurityCondition;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.core.context.SecurityContext;
import com.netflix.hystrix.Hystrix;
import com.netflix.hystrix.strategy.HystrixPlugins;
import com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategy;
import com.netflix.hystrix.strategy.eventnotifier.HystrixEventNotifier;
import com.netflix.hystrix.strategy.executionhook.HystrixCommandExecutionHook;
import com.netflix.hystrix.strategy.metrics.HystrixMetricsPublisher;
import com.netflix.hystrix.strategy.properties.HystrixPropertiesStrategy;
/**
* @author Daniel Lavoie
*/
@Configuration
@Conditional(HystrixSecurityCondition.class)
@ConditionalOnClass({ Hystrix.class, SecurityContext.class })
public class HystrixSecurityAutoConfiguration {
@Autowired(required = false)
private HystrixConcurrencyStrategy existingConcurrencyStrategy;
@PostConstruct
public void init() {
// Keeps references of existing Hystrix plugins.
HystrixEventNotifier eventNotifier = HystrixPlugins.getInstance()
.getEventNotifier();
HystrixMetricsPublisher metricsPublisher = HystrixPlugins.getInstance()
.getMetricsPublisher();
HystrixPropertiesStrategy propertiesStrategy = HystrixPlugins.getInstance()
.getPropertiesStrategy();
HystrixCommandExecutionHook commandExecutionHook = HystrixPlugins.getInstance()
.getCommandExecutionHook();
HystrixPlugins.reset();
// Registers existing plugins excepts the Concurrent Strategy plugin.
HystrixPlugins.getInstance().registerConcurrencyStrategy(
new SecurityContextConcurrencyStrategy(existingConcurrencyStrategy));
HystrixPlugins.getInstance().registerEventNotifier(eventNotifier);
HystrixPlugins.getInstance().registerMetricsPublisher(metricsPublisher);
HystrixPlugins.getInstance().registerPropertiesStrategy(propertiesStrategy);
HystrixPlugins.getInstance().registerCommandExecutionHook(commandExecutionHook);
}
static class HystrixSecurityCondition extends AllNestedConditions {
public HystrixSecurityCondition() {
super(ConfigurationPhase.REGISTER_BEAN);
}
@ConditionalOnProperty(name = "hystrix.shareSecurityContext")
static class ShareSecurityContext {
}
}
}
@@ -0,0 +1,86 @@
/*
* Copyright 2013-2016 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.hystrix.security;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import com.netflix.hystrix.HystrixThreadPoolProperties;
import org.springframework.security.concurrent.DelegatingSecurityContextCallable;
import com.netflix.hystrix.HystrixThreadPoolKey;
import com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategy;
import com.netflix.hystrix.strategy.concurrency.HystrixRequestVariable;
import com.netflix.hystrix.strategy.concurrency.HystrixRequestVariableLifecycle;
import com.netflix.hystrix.strategy.properties.HystrixProperty;
/**
* @author daniellavoie
*/
public class SecurityContextConcurrencyStrategy extends HystrixConcurrencyStrategy {
private HystrixConcurrencyStrategy existingConcurrencyStrategy;
public SecurityContextConcurrencyStrategy(
HystrixConcurrencyStrategy existingConcurrencyStrategy) {
this.existingConcurrencyStrategy = existingConcurrencyStrategy;
}
@Override
public BlockingQueue<Runnable> getBlockingQueue(int maxQueueSize) {
return existingConcurrencyStrategy != null
? existingConcurrencyStrategy.getBlockingQueue(maxQueueSize)
: super.getBlockingQueue(maxQueueSize);
}
@Override
public <T> HystrixRequestVariable<T> getRequestVariable(
HystrixRequestVariableLifecycle<T> rv) {
return existingConcurrencyStrategy != null
? existingConcurrencyStrategy.getRequestVariable(rv)
: super.getRequestVariable(rv);
}
@Override
public ThreadPoolExecutor getThreadPool(HystrixThreadPoolKey threadPoolKey,
HystrixProperty<Integer> corePoolSize,
HystrixProperty<Integer> maximumPoolSize,
HystrixProperty<Integer> keepAliveTime, TimeUnit unit,
BlockingQueue<Runnable> workQueue) {
return existingConcurrencyStrategy != null
? existingConcurrencyStrategy.getThreadPool(threadPoolKey, corePoolSize,
maximumPoolSize, keepAliveTime, unit, workQueue)
: super.getThreadPool(threadPoolKey, corePoolSize, maximumPoolSize,
keepAliveTime, unit, workQueue);
}
@Override
public ThreadPoolExecutor getThreadPool(HystrixThreadPoolKey threadPoolKey, HystrixThreadPoolProperties threadPoolProperties) {
return existingConcurrencyStrategy != null
? existingConcurrencyStrategy.getThreadPool(threadPoolKey, threadPoolProperties)
: super.getThreadPool(threadPoolKey, threadPoolProperties);
}
@Override
public <T> Callable<T> wrapCallable(Callable<T> callable) {
return existingConcurrencyStrategy != null
? existingConcurrencyStrategy
.wrapCallable(new DelegatingSecurityContextCallable<T>(callable))
: super.wrapCallable(new DelegatingSecurityContextCallable<T>(callable));
}
}
@@ -0,0 +1,114 @@
/*
* Copyright 2013-2017 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.metrics;
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.HandlerMapping;
/**
* @author Jon Schneider
*/
public class DefaultMetricsTagProvider implements MetricsTagProvider {
@Override
public Map<String, String> clientHttpRequestTags(HttpRequest request,
ClientHttpResponse response) {
String urlTemplate = RestTemplateUrlTemplateHolder.getRestTemplateUrlTemplate();
if (urlTemplate == null) {
urlTemplate = "none";
}
String status;
try {
status = (response == null) ? "CLIENT_ERROR" : ((Integer) response
.getRawStatusCode()).toString();
}
catch (IOException e) {
status = "IO_ERROR";
}
String host = request.getURI().getHost();
if( host == null ) {
host = "none";
}
String strippedUrlTemplate = urlTemplate.replaceAll("^https?://[^/]+/", "");
Map<String, String> tags = new HashMap<>();
tags.put("method", request.getMethod().name());
tags.put("uri", sanitizeUrlTemplate(strippedUrlTemplate));
tags.put("status", status);
tags.put("clientName", host);
return Collections.unmodifiableMap(tags);
}
@Override
public Map<String, String> httpRequestTags(HttpServletRequest request,
HttpServletResponse response, Object handler, String caller) {
Map<String, String> tags = new HashMap<>();
tags.put("method", request.getMethod());
tags.put("status", ((Integer) response.getStatus()).toString());
String uri = (String) request
.getAttribute(HandlerMapping.BEST_MATCHING_PATTERN_ATTRIBUTE);
if (uri == null) {
uri = request.getPathInfo();
}
if (!StringUtils.hasText(uri)) {
uri = "/";
}
uri = sanitizeUrlTemplate(uri.substring(1));
tags.put("uri", uri.isEmpty() ? "root" : uri);
Object exception = request.getAttribute("exception");
if (exception != null) {
tags.put("exception", exception.getClass().getSimpleName());
}
if (caller != null) {
tags.put("caller", caller);
}
return tags;
}
/**
* As is, the urlTemplate is not suitable for use with Atlas, as all interactions with
* Atlas take place via query parameters
*/
protected String sanitizeUrlTemplate(String urlTemplate) {
String sanitized = urlTemplate
.replaceAll("\\{(\\w+):.+}(?=/|$)", "-$1-") // extract path variable names from regex expressions
.replaceAll("/", "_")
.replaceAll("[{}]", "-");
if (!StringUtils.hasText(sanitized)) {
sanitized = "none";
}
return sanitized;
}
}
@@ -0,0 +1,84 @@
/*
* Copyright 2013-2015 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.metrics;
import java.io.IOException;
import java.util.Collection;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import org.springframework.cloud.netflix.metrics.servo.ServoMonitorCache;
import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;
import com.netflix.servo.monitor.MonitorConfig;
import com.netflix.servo.tag.SmallTagMap;
import com.netflix.servo.tag.Tags;
/**
* Intercepts RestTemplate requests and records metrics about execution time and results.
*
* @author Jon Schneider
*/
public class MetricsClientHttpRequestInterceptor implements ClientHttpRequestInterceptor {
/**
* The interceptor writes to a Servo MonitorRegistry, which we get away with for now
* because our Spectator implementation is underpinned by a ServoRegistry. When Spring
* Boot (Actuator) provides a more general purpose abstraction for dimensional metrics
* systems, this can be moved there and rewritten against that abstraction.
*/
private final ServoMonitorCache servoMonitorCache;
private final Collection<MetricsTagProvider> tagProviders;
private final String metricName;
public MetricsClientHttpRequestInterceptor(
Collection<MetricsTagProvider> tagProviders,
ServoMonitorCache servoMonitorCache, String metricName) {
this.tagProviders = tagProviders;
this.servoMonitorCache = servoMonitorCache;
this.metricName = metricName;
}
@Override
public ClientHttpResponse intercept(HttpRequest request, byte[] body,
ClientHttpRequestExecution execution) throws IOException {
long startTime = System.nanoTime();
ClientHttpResponse response = null;
try {
response = execution.execute(request, body);
return response;
}
finally {
SmallTagMap.Builder builder = SmallTagMap.builder();
for (MetricsTagProvider tagProvider : tagProviders) {
for (Map.Entry<String, String> tag : tagProvider
.clientHttpRequestTags(request, response).entrySet()) {
builder.add(Tags.newTag(tag.getKey(), tag.getValue()));
}
}
MonitorConfig.Builder monitorConfigBuilder = MonitorConfig
.builder(metricName);
monitorConfigBuilder.withTags(builder);
servoMonitorCache.getTimer(monitorConfigBuilder.build())
.record(System.nanoTime() - startTime, TimeUnit.NANOSECONDS);
}
}
}
@@ -0,0 +1,98 @@
/*
* Copyright 2013-2015 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.metrics;
import java.util.Collection;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.netflix.metrics.servo.ServoMonitorCache;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import com.netflix.servo.MonitorRegistry;
import com.netflix.servo.monitor.MonitorConfig;
import com.netflix.servo.tag.SmallTagMap;
import com.netflix.servo.tag.Tags;
import static org.springframework.web.context.request.RequestAttributes.SCOPE_REQUEST;
/**
* Intercepts incoming HTTP requests and records metrics about execution time and results.
*
* @author Jon Schneider
*/
public class MetricsHandlerInterceptor extends HandlerInterceptorAdapter {
@Value("${netflix.metrics.rest.metricName:rest}")
String metricName;
@Value("${netflix.metrics.rest.callerHeader:#{null}}")
String callerHeader;
@Autowired
MonitorRegistry registry;
@Autowired
ServoMonitorCache servoMonitorCache;
@Autowired
Collection<MetricsTagProvider> tagProviders;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
Object handler) throws Exception {
RequestContextHolder.getRequestAttributes().setAttribute("requestStartTime",
System.nanoTime(), SCOPE_REQUEST);
return super.preHandle(request, response, handler);
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response,
Object handler, Exception ex) throws Exception {
RequestContextHolder.getRequestAttributes().setAttribute("exception", ex,
SCOPE_REQUEST);
Long startTime = (Long) RequestContextHolder.getRequestAttributes().getAttribute(
"requestStartTime", SCOPE_REQUEST);
if (startTime != null)
recordMetric(request, response, handler, startTime);
super.afterCompletion(request, response, handler, ex);
}
protected void recordMetric(HttpServletRequest request, HttpServletResponse response,
Object handler, Long startTime) {
String caller = null;
if (callerHeader != null) {
caller = request.getHeader(callerHeader);
}
SmallTagMap.Builder builder = SmallTagMap.builder();
for (MetricsTagProvider tagProvider : tagProviders) {
Map<String, String> tags = tagProvider.httpRequestTags(request, response,
handler, caller);
for (Map.Entry<String, String> tag : tags.entrySet()) {
builder.add(Tags.newTag(tag.getKey(), tag.getValue()));
}
}
MonitorConfig.Builder monitorConfigBuilder = MonitorConfig.builder(metricName);
monitorConfigBuilder.withTags(builder);
servoMonitorCache.getTimer(monitorConfigBuilder.build()).record(
System.nanoTime() - startTime, TimeUnit.NANOSECONDS);
}
}
@@ -0,0 +1,131 @@
/*
* Copyright 2013-2015 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.metrics;
import java.util.ArrayList;
import java.util.Collection;
import javax.servlet.http.HttpServletRequest;
import org.aspectj.lang.JoinPoint;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.boot.actuate.metrics.reader.MetricReader;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.cloud.netflix.metrics.servo.ServoMonitorCache;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import com.netflix.servo.MonitorRegistry;
import com.netflix.servo.monitor.Monitors;
/**
* @author Jon Schneider
*/
@Configuration
@ConditionalOnProperty(value = "spring.cloud.netflix.metrics.enabled", havingValue = "true", matchIfMissing = true)
@ConditionalOnClass({ Monitors.class, MetricReader.class })
public class MetricsInterceptorConfiguration {
@Configuration
@ConditionalOnWebApplication
@ConditionalOnClass(WebMvcConfigurerAdapter.class)
static class MetricsWebResourceConfiguration extends WebMvcConfigurerAdapter {
@Bean
MetricsHandlerInterceptor servoMonitoringWebResourceInterceptor() {
return new MetricsHandlerInterceptor();
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(servoMonitoringWebResourceInterceptor());
}
}
@Configuration
@ConditionalOnClass({ RestTemplate.class, JoinPoint.class })
@ConditionalOnProperty(value = "spring.aop.enabled", havingValue = "true", matchIfMissing = true)
static class MetricsRestTemplateAspectConfiguration {
@Bean
RestTemplateUrlTemplateCapturingAspect restTemplateUrlTemplateCapturingAspect() {
return new RestTemplateUrlTemplateCapturingAspect();
}
}
@Configuration
@ConditionalOnClass({ RestTemplate.class, HttpServletRequest.class }) // HttpServletRequest implicitly required by MetricsTagProvider
static class MetricsRestTemplateConfiguration {
@Value("${netflix.metrics.restClient.metricName:restclient}")
String metricName;
@Bean
MetricsClientHttpRequestInterceptor spectatorLoggingClientHttpRequestInterceptor(
Collection<MetricsTagProvider> tagProviders,
ServoMonitorCache servoMonitorCache) {
return new MetricsClientHttpRequestInterceptor(tagProviders,
servoMonitorCache, this.metricName);
}
@Bean
BeanPostProcessor spectatorRestTemplateInterceptorPostProcessor() {
return new MetricsInterceptorPostProcessor();
}
private static class MetricsInterceptorPostProcessor
implements BeanPostProcessor, ApplicationContextAware {
private ApplicationContext context;
private MetricsClientHttpRequestInterceptor interceptor;
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) {
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
if (bean instanceof RestTemplate) {
if (this.interceptor == null) {
this.interceptor = this.context
.getBean(MetricsClientHttpRequestInterceptor.class);
}
RestTemplate restTemplate = (RestTemplate) bean;
// create a new list as the old one may be unmodifiable (ie Arrays.asList())
ArrayList<ClientHttpRequestInterceptor> interceptors = new ArrayList<>();
interceptors.add(interceptor);
interceptors.addAll(restTemplate.getInterceptors());
restTemplate.setInterceptors(interceptors);
}
return bean;
}
@Override
public void setApplicationContext(ApplicationContext context)
throws BeansException {
this.context = context;
}
}
}
}
@@ -0,0 +1,43 @@
/*
* Copyright 2013-2015 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.metrics;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpResponse;
/**
* @author Jon Schneider
*/
public interface MetricsTagProvider {
/**
* @param request RestTemplate client HTTP request
* @param response may be null in the event of a client error
* @return a map of tags added to every client HTTP request metric
*/
Map<String, String> clientHttpRequestTags(HttpRequest request,
ClientHttpResponse response);
/**
* @param request HTTP request
* @param response HTTP response
* @param handler the request method that is responsible for handling the request
* @return a map of tags added to every Spring MVC HTTP request metric
*/
Map<String, String> httpRequestTags(HttpServletRequest request,
HttpServletResponse response, Object handler, String caller);
}
@@ -0,0 +1,39 @@
/*
* Copyright 2013-2015 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.metrics;
import java.util.Collections;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpResponse;
/**
* @author Jon Schneider
*/
public class MetricsTagProviderAdapter implements MetricsTagProvider {
@Override
public Map<String, String> clientHttpRequestTags(HttpRequest request,
ClientHttpResponse response) {
return Collections.emptyMap();
}
@Override
public Map<String, String> httpRequestTags(HttpServletRequest request,
HttpServletResponse response, Object handler, String caller) {
return Collections.emptyMap();
}
}
@@ -0,0 +1,39 @@
/*
* Copyright 2013-2015 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.metrics;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
/**
* Captures the still-templated URI because currently the ClientHttpRequestInterceptor
* currently only gives us the means to retrieve the substituted URI.
*
* @author Jon Schneider
*/
@Aspect
public class RestTemplateUrlTemplateCapturingAspect {
@Around("execution(* org.springframework.web.client.RestOperations+.*(String, ..))")
public Object captureUrlTemplate(ProceedingJoinPoint joinPoint) throws Throwable {
try {
String urlTemplate = (String) joinPoint.getArgs()[0];
RestTemplateUrlTemplateHolder.setRestTemplateUrlTemplate(urlTemplate);
return joinPoint.proceed();
}
finally {
RestTemplateUrlTemplateHolder.clear();
}
}
}

Some files were not shown because too many files have changed in this diff Show More