mirror of
https://github.com/spring-cloud/spring-cloud-netflix.git
synced 2026-09-20 00:59:01 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
66d347cfc6 |
@@ -10,4 +10,3 @@ target/
|
||||
_site/
|
||||
.idea
|
||||
*.iml
|
||||
.factorypath
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
-Xmx1024m -XX:CICompilerCount=1 -XX:TieredStopAtLevel=1 -Djava.security.egd=file:/dev/./urandom
|
||||
@@ -1 +0,0 @@
|
||||
-DaltSnapshotDeploymentRepository=repo.spring.io::default::https://repo.spring.io/libs-snapshot-local -P spring
|
||||
Vendored
BIN
Binary file not shown.
-1
@@ -1 +0,0 @@
|
||||
distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.3.9/apache-maven-3.3.9-bin.zip
|
||||
+5
-5
@@ -15,7 +15,7 @@
|
||||
<repository>
|
||||
<id>spring-snapshots</id>
|
||||
<name>Spring Snapshots</name>
|
||||
<url>https://repo.spring.io/libs-snapshot-local</url>
|
||||
<url>http://repo.spring.io/libs-snapshot-local</url>
|
||||
<snapshots>
|
||||
<enabled>true</enabled>
|
||||
</snapshots>
|
||||
@@ -23,7 +23,7 @@
|
||||
<repository>
|
||||
<id>spring-milestones</id>
|
||||
<name>Spring Milestones</name>
|
||||
<url>https://repo.spring.io/libs-milestone-local</url>
|
||||
<url>http://repo.spring.io/libs-milestone-local</url>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
@@ -31,7 +31,7 @@
|
||||
<repository>
|
||||
<id>spring-releases</id>
|
||||
<name>Spring Releases</name>
|
||||
<url>https://repo.spring.io/release</url>
|
||||
<url>http://repo.spring.io/release</url>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
@@ -41,7 +41,7 @@
|
||||
<pluginRepository>
|
||||
<id>spring-snapshots</id>
|
||||
<name>Spring Snapshots</name>
|
||||
<url>https://repo.spring.io/libs-snapshot-local</url>
|
||||
<url>http://repo.spring.io/libs-snapshot-local</url>
|
||||
<snapshots>
|
||||
<enabled>true</enabled>
|
||||
</snapshots>
|
||||
@@ -49,7 +49,7 @@
|
||||
<pluginRepository>
|
||||
<id>spring-milestones</id>
|
||||
<name>Spring Milestones</name>
|
||||
<url>https://repo.spring.io/libs-milestone-local</url>
|
||||
<url>http://repo.spring.io/libs-milestone-local</url>
|
||||
<snapshots>
|
||||
<enabled>false</enabled>
|
||||
</snapshots>
|
||||
|
||||
+1
-14
@@ -1,26 +1,13 @@
|
||||
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
|
||||
script:
|
||||
- ./docs/src/main/asciidoc/ghpages.sh
|
||||
- git status
|
||||
- ls -a
|
||||
- '[ "${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'
|
||||
script: mvn --settings .settings.xml deploy -nsu -Dmaven.test.redirectTestOutputToFile=true
|
||||
env:
|
||||
global:
|
||||
- GIT_NAME="Dave Syer"
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
require 'asciidoctor'
|
||||
require 'erb'
|
||||
require './src/main/ruby/readme.rb'
|
||||
|
||||
options = {:mkdirs => true, :safe => :unsafe, :attributes => ['linkcss', 'allow-uri-read']}
|
||||
options = {:mkdirs => true, :safe => :unsafe, :attributes => 'linkcss'}
|
||||
|
||||
guard 'shell' do
|
||||
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'))
|
||||
watch(/^src\/[A-Za-z].*\.adoc$/) {|m|
|
||||
SpringCloud::Build.render_file('src/main/asciidoc/README.adoc', :to_file => './README.adoc')
|
||||
Asciidoctor.render_file('src/main/asciidoc/spring-cloud-netflix.adoc', options.merge(:to_dir => 'target/generated-docs'))
|
||||
}
|
||||
end
|
||||
|
||||
+4
-179
@@ -1,12 +1,11 @@
|
||||
// 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]
|
||||
|
||||
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),
|
||||
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).
|
||||
|
||||
|
||||
@@ -18,180 +17,6 @@ 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 Spring 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 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
|
||||
|
||||
== Building
|
||||
|
||||
:jdkversion: 1.8
|
||||
|
||||
=== Basic Compile and Test
|
||||
|
||||
To build the source you will need to install
|
||||
https://maven.apache.org/run-maven/index.html[Apache Maven] v3.0.6 or above and 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
|
||||
----
|
||||
|
||||
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`
|
||||
|
||||
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.
|
||||
|
||||
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
|
||||
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
|
||||
https://www.fig.sh/[Fig] to run them in Docker containers.
|
||||
|
||||
=== Documentation
|
||||
|
||||
The spring-cloud-build module has a "docs" profile, and if you switch
|
||||
that on it will try to build asciidoc sources from
|
||||
`src/main/asciidoc`. As part of that process it will look for a
|
||||
`README.adoc` and process it by loading all the includes, but not
|
||||
parsing or rendering it, just copying it to `${main.basedir}`
|
||||
(defaults to `${basedir}`, i.e. the root of the project). If there are
|
||||
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 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
|
||||
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
|
||||
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/[m2eclipe] eclipse plugin for maven support. Other IDEs and tools
|
||||
should also work without issue.
|
||||
|
||||
==== Importing into eclipse with m2eclipse
|
||||
We recommend the https://eclipse.org/m2e/[m2eclipe] eclipse plugin when working with
|
||||
eclipse. If you don't already have m2eclipse installed it is available from the "eclipse
|
||||
marketplace".
|
||||
|
||||
==== 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
|
||||
----
|
||||
|
||||
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](https://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.
|
||||
|
||||
=== 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
|
||||
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
|
||||
Cloud Build] project. If using IntelliJ, you can use the
|
||||
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
|
||||
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).
|
||||
* 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).
|
||||
@@ -0,0 +1,22 @@
|
||||
## TODO List
|
||||
|
||||
- [x] Example front end app (currently in sandbox)
|
||||
- [x] Example back end service (currently in sandbox)
|
||||
- [x] Use platform config
|
||||
- [x] Hystrix integration (hystrix-javanica)
|
||||
- [x] Feign use spring message converters
|
||||
- [x] Ribbon (static server list)
|
||||
- [x] Eureka boot app (Service registration)
|
||||
- [x] Eureka (apache -> tomcat) see https://github.com/cfregly/fluxcapacitor/wiki/NetflixOSS-FAQ#eureka-service-discovery-load-balancer and https://groups.google.com/forum/?fromgroups#!topic/eureka_netflix/g3p2r7gHnN0
|
||||
- [x] Archaius bridge to spring environment
|
||||
- [x] Ribbon (Client side load balancing) (Eureka integration)
|
||||
- [x] Remove need for *-eureka.properties
|
||||
- [ ] Use spring boot values as defaults where appropriate
|
||||
- [x] Synchronous removal of service from eureka on shutdown
|
||||
- [x] Refresh log levels dynamically
|
||||
- [x] Router (Zuul) integrated using hystrix/ribbon/eureka
|
||||
- [ ] Better observable example
|
||||
- [ ] Distributed refresh environment via platform bus
|
||||
- [x] Metrics aggregation (turbine)
|
||||
- [x] Use Eureka for instance discovery rather than static list see https://github.com/Netflix/Turbine/blob/master/turbine-contrib/src/main/java/com/netflix/turbine/discovery/EurekaInstanceDiscovery.java
|
||||
- [ ] Configure InstanceDiscovery.impl using auto config/config props
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
/* Asciidoctor default stylesheet | MIT License | https://asciidoctor.org */
|
||||
/* Asciidoctor default stylesheet | MIT License | http://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}
|
||||
|
||||
+2
-2
@@ -17,6 +17,6 @@ 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 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
|
||||
* 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
|
||||
|
||||
|
||||
+27
-38
@@ -1,55 +1,44 @@
|
||||
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<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">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-netflix-docs</artifactId>
|
||||
<version>1.0.0.M1</version>
|
||||
<parent>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-build</artifactId>
|
||||
<version>1.0.4.RELEASE</version>
|
||||
<version>1.0.0.M1</version>
|
||||
<relativePath />
|
||||
</parent>
|
||||
<artifactId>spring-cloud-netflix-docs</artifactId>
|
||||
<packaging>pom</packaging>
|
||||
<name>Spring Cloud Netflix Docs</name>
|
||||
<version>1.0.8.BUILD-SNAPSHOT</version>
|
||||
<description>Spring Cloud Docs</description>
|
||||
<properties>
|
||||
<docs.main>spring-cloud-netflix</docs.main>
|
||||
<docs.main>spring-cloud-netflix</docs.main>
|
||||
<main.basedir>${basedir}/..</main.basedir>
|
||||
<docs.whitelisted.branches>1.0.x,1.1.x</docs.whitelisted.branches>
|
||||
</properties>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<artifactId>maven-deploy-plugin</artifactId>
|
||||
<configuration>
|
||||
<skip>true</skip>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<profiles>
|
||||
<profiles>
|
||||
<profile>
|
||||
<id>docs</id>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.asciidoctor</groupId>
|
||||
<artifactId>asciidoctor-maven-plugin</artifactId>
|
||||
<inherited>false</inherited>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-antrun-plugin</artifactId>
|
||||
<inherited>false</inherited>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>build-helper-maven-plugin</artifactId>
|
||||
<inherited>false</inherited>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.asciidoctor</groupId>
|
||||
<artifactId>asciidoctor-maven-plugin</artifactId>
|
||||
<inherited>false</inherited>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-antrun-plugin</artifactId>
|
||||
<inherited>false</inherited>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.codehaus.mojo</groupId>
|
||||
<artifactId>build-helper-maven-plugin</artifactId>
|
||||
<inherited>false</inherited>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</profile>
|
||||
</profiles>
|
||||
</profiles>
|
||||
</project>
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
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]
|
||||
|
||||
include::intro.adoc[]
|
||||
|
||||
@@ -10,13 +9,6 @@ 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 Spring 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 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
|
||||
|
||||
== Building
|
||||
|
||||
include::https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/docs/src/main/asciidoc/building-jdk8.adoc[]
|
||||
|
||||
== Contributing
|
||||
|
||||
include::https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/docs/src/main/asciidoc/contributing.adoc[]
|
||||
|
||||
@@ -1,330 +1,46 @@
|
||||
#!/bin/bash -x
|
||||
|
||||
set -e
|
||||
git remote set-url --push origin `git config remote.origin.url | sed -e 's/^git:/https:/'`
|
||||
|
||||
# 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 ! (git remote set-branches --add origin gh-pages && git fetch -q); then
|
||||
echo "No gh-pages, 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}]"
|
||||
}
|
||||
if ! [ -d docs/target/generated-docs ]; then
|
||||
echo "No gh-pages sources in docs/target/generated-docs, so not syncing"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Stash any outstanding changes
|
||||
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
|
||||
}
|
||||
###################################################################
|
||||
git diff-index --quiet HEAD
|
||||
dirty=$?
|
||||
if [ "$dirty" != "0" ]; then git stash; fi
|
||||
|
||||
# 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
|
||||
# Switch to gh-pages branch to sync it with master
|
||||
###################################################################
|
||||
git checkout 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
|
||||
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") || ("${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
|
||||
cp -rf $f .
|
||||
git add -A $file
|
||||
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
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2,11 +2,11 @@
|
||||
|
||||
base_dir = File.join(File.dirname(__FILE__),'../../..')
|
||||
src_dir = File.join(base_dir, "/src/main/asciidoc")
|
||||
require 'asciidoctor'
|
||||
require File.join(File.dirname(__FILE__), 'readme.rb')
|
||||
require 'optparse'
|
||||
|
||||
options = {}
|
||||
file = "#{src_dir}/README.adoc"
|
||||
input = "#{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=='-' }
|
||||
@@ -14,17 +14,6 @@ OptionParser.new do |o|
|
||||
o.parse!
|
||||
end
|
||||
|
||||
file = ARGV[0] if ARGV.length>0
|
||||
input = ARGV[0] if ARGV.length>0
|
||||
|
||||
srcDir = File.dirname(file)
|
||||
out = "// Do not edit this file (e.g. go instead to docs/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
|
||||
SpringCloud::Build.render_file(input, options)
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
require 'open-uri'
|
||||
|
||||
module SpringCloud
|
||||
module Build
|
||||
|
||||
IncludeDirectiveRx = /^\\?include::([^\[]+)\[(.*?)\]$/
|
||||
|
||||
class << self
|
||||
|
||||
def process_include out, src, target, attrs
|
||||
unless target.include?(':') || target.start_with?('/')
|
||||
target = File.join(src, target)
|
||||
end
|
||||
open(target) do |file|
|
||||
file.each do |line|
|
||||
self.process(out, File.dirname(target), line)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def process out, src, line
|
||||
if ((escaped = line.start_with?('\\include::')) || line.start_with?('include::')) && (match = IncludeDirectiveRx.match(line))
|
||||
if escaped
|
||||
out << line[1..-1]
|
||||
else
|
||||
self.process_include out, src, match[1], match[2].strip
|
||||
end
|
||||
else
|
||||
out << line
|
||||
end
|
||||
end
|
||||
|
||||
def render_file file, options = {}
|
||||
|
||||
srcDir = File.dirname(file)
|
||||
out = ["// Do not edit this file (e.g. go instead to src/main/asciidoc)\n","\n"]
|
||||
File.new(file).each do |line|
|
||||
self.process(out, srcDir, line)
|
||||
end
|
||||
|
||||
unless options[:to_file]
|
||||
puts out
|
||||
else
|
||||
File.open(options[:to_file],'w+') do |file|
|
||||
out.each { |line| file.write(line) }
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
@@ -1,295 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<profiles version="12">
|
||||
<profile kind="CodeFormatterProfile" name="Spring Cloud Java Conventions" version="12">
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_ellipsis" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_imports" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_javadoc_comments" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indentation.size" value="8"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.disabling_tag" value="@formatter:off"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation" value="2"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_enum_constants" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_imports" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_package" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_binary_operator" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.indent_root_tags" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.enabling_tag" value="@formatter:on"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.compiler.problem.enumIdentifier" value="error"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_block" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.line_length" value="90"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.use_on_off_tags" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_method_declaration" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_binary_expression" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_lambda_body" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.compact_else_if" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.compiler.problem.assertIdentifier" value="error"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_binary_operator" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_unary_operator" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_ellipsis" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_line_comments" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.align_type_members_on_columns" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_assignment" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression" value="80"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block_in_case" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_header" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode" value="enabled"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_method_declaration" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.join_wrapped_lines" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_resources_in_try" value="80"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.compiler.source" value="1.8"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.tabulation.size" value="4"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_source_code" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_field" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer" value="2"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_method" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.compiler.codegen.targetPlatform" value="1.8"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_switch" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_html" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_if" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_empty_lines" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_unary_operator" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_label" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_member_type" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.format_block_comments" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line" value="false"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_body" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiple_fields" value="16"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_array_initializer" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.wrap_before_binary_operator" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.compiler.compliance" value="1.8"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_constant" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.brace_position_for_type_declaration" value="end_of_line"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_package" value="0"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.join_lines_in_comments" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.comment.indent_parameter_description" value="true"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement" value="insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.tabulation.char" value="tab"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_import_groups" value="1"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.lineSplit" value="90"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation" value="do not insert"/>
|
||||
<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch" value="insert"/>
|
||||
</profile>
|
||||
</profiles>
|
||||
@@ -1,389 +0,0 @@
|
||||
eclipse.preferences.version=1
|
||||
org.eclipse.jdt.core.codeComplete.argumentPrefixes=
|
||||
org.eclipse.jdt.core.codeComplete.argumentSuffixes=
|
||||
org.eclipse.jdt.core.codeComplete.fieldPrefixes=
|
||||
org.eclipse.jdt.core.codeComplete.fieldSuffixes=
|
||||
org.eclipse.jdt.core.codeComplete.localPrefixes=
|
||||
org.eclipse.jdt.core.codeComplete.localSuffixes=
|
||||
org.eclipse.jdt.core.codeComplete.staticFieldPrefixes=
|
||||
org.eclipse.jdt.core.codeComplete.staticFieldSuffixes=
|
||||
org.eclipse.jdt.core.codeComplete.staticFinalFieldPrefixes=
|
||||
org.eclipse.jdt.core.codeComplete.staticFinalFieldSuffixes=
|
||||
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
|
||||
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
|
||||
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
|
||||
org.eclipse.jdt.core.compiler.compliance=1.6
|
||||
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
|
||||
org.eclipse.jdt.core.compiler.debug.localVariable=generate
|
||||
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
|
||||
org.eclipse.jdt.core.compiler.doc.comment.support=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.annotationSuperInterface=warning
|
||||
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.autoboxing=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.comparingIdentical=warning
|
||||
org.eclipse.jdt.core.compiler.problem.deadCode=warning
|
||||
org.eclipse.jdt.core.compiler.problem.deprecation=warning
|
||||
org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.discouragedReference=warning
|
||||
org.eclipse.jdt.core.compiler.problem.emptyStatement=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
|
||||
org.eclipse.jdt.core.compiler.problem.fallthroughCase=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.fatalOptionalError=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.fieldHiding=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.finalParameterBound=warning
|
||||
org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
|
||||
org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
|
||||
org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=warning
|
||||
org.eclipse.jdt.core.compiler.problem.includeNullInfoFromAsserts=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=warning
|
||||
org.eclipse.jdt.core.compiler.problem.incompleteEnumSwitch=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.invalidJavadoc=warning
|
||||
org.eclipse.jdt.core.compiler.problem.invalidJavadocTags=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsDeprecatedRef=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=default
|
||||
org.eclipse.jdt.core.compiler.problem.localVariableHiding=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=warning
|
||||
org.eclipse.jdt.core.compiler.problem.missingDeprecatedAnnotation=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.missingHashCodeMethod=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.missingJavadocComments=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=public
|
||||
org.eclipse.jdt.core.compiler.problem.missingJavadocTagDescription=return_tag
|
||||
org.eclipse.jdt.core.compiler.problem.missingJavadocTags=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.missingJavadocTagsMethodTypeParameters=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=private
|
||||
org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotation=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.missingOverrideAnnotationForInterfaceMethodImplementation=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.missingSerialVersion=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.missingSynchronizedOnInheritedMethod=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.noEffectAssignment=warning
|
||||
org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=warning
|
||||
org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.nullReference=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=warning
|
||||
org.eclipse.jdt.core.compiler.problem.parameterAssignment=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.potentialNullReference=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.rawTypeReference=warning
|
||||
org.eclipse.jdt.core.compiler.problem.redundantNullCheck=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.redundantSpecificationOfTypeArguments=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.redundantSuperinterface=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.reportMethodCanBePotentiallyStatic=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.reportMethodCanBeStatic=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=warning
|
||||
org.eclipse.jdt.core.compiler.problem.suppressOptionalErrors=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.suppressWarnings=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.typeParameterHiding=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unavoidableGenericTypeProblems=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.uncheckedTypeOperation=warning
|
||||
org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unhandledWarningToken=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unnecessaryElse=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionExemptExceptionAndThrowable=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionIncludeDocCommentReference=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.unusedImport=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unusedLabel=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unusedObjectAllocation=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
|
||||
org.eclipse.jdt.core.compiler.problem.unusedParameterIncludeDocCommentReference=enabled
|
||||
org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
|
||||
org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
|
||||
org.eclipse.jdt.core.compiler.problem.unusedWarningToken=warning
|
||||
org.eclipse.jdt.core.compiler.problem.varargsArgumentNeedCast=warning
|
||||
org.eclipse.jdt.core.compiler.source=1.6
|
||||
org.eclipse.jdt.core.formatter.align_type_members_on_columns=false
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation=0
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_assignment=0
|
||||
org.eclipse.jdt.core.formatter.alignment_for_binary_expression=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_compact_if=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_conditional_expression=80
|
||||
org.eclipse.jdt.core.formatter.alignment_for_enum_constants=0
|
||||
org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_method_declaration=0
|
||||
org.eclipse.jdt.core.formatter.alignment_for_multiple_fields=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_resources_in_try=80
|
||||
org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration=16
|
||||
org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch=16
|
||||
org.eclipse.jdt.core.formatter.blank_lines_after_imports=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_after_package=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_field=0
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration=0
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_imports=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_member_type=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_method=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_before_package=0
|
||||
org.eclipse.jdt.core.formatter.blank_lines_between_import_groups=1
|
||||
org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations=1
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_array_initializer=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_block=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_block_in_case=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_enum_constant=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_lambda_body=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_method_declaration=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_switch=end_of_line
|
||||
org.eclipse.jdt.core.formatter.brace_position_for_type_declaration=end_of_line
|
||||
org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment=false
|
||||
org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment=false
|
||||
org.eclipse.jdt.core.formatter.comment.format_block_comments=true
|
||||
org.eclipse.jdt.core.formatter.comment.format_header=false
|
||||
org.eclipse.jdt.core.formatter.comment.format_html=true
|
||||
org.eclipse.jdt.core.formatter.comment.format_javadoc_comments=true
|
||||
org.eclipse.jdt.core.formatter.comment.format_line_comments=true
|
||||
org.eclipse.jdt.core.formatter.comment.format_source_code=false
|
||||
org.eclipse.jdt.core.formatter.comment.indent_parameter_description=true
|
||||
org.eclipse.jdt.core.formatter.comment.indent_root_tags=false
|
||||
org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags=do not insert
|
||||
org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter=do not insert
|
||||
org.eclipse.jdt.core.formatter.comment.line_length=90
|
||||
org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries=true
|
||||
org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries=true
|
||||
org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments=false
|
||||
org.eclipse.jdt.core.formatter.compact_else_if=true
|
||||
org.eclipse.jdt.core.formatter.continuation_indentation=2
|
||||
org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer=2
|
||||
org.eclipse.jdt.core.formatter.disabling_tag=@formatter\:off
|
||||
org.eclipse.jdt.core.formatter.enabling_tag=@formatter\:on
|
||||
org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line=false
|
||||
org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column=true
|
||||
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header=true
|
||||
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header=true
|
||||
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header=true
|
||||
org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header=true
|
||||
org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases=true
|
||||
org.eclipse.jdt.core.formatter.indent_empty_lines=false
|
||||
org.eclipse.jdt.core.formatter.indent_statements_compare_to_block=true
|
||||
org.eclipse.jdt.core.formatter.indent_statements_compare_to_body=true
|
||||
org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases=true
|
||||
org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch=false
|
||||
org.eclipse.jdt.core.formatter.indentation.size=8
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_label=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_after_type_annotation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body=insert
|
||||
org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_binary_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_ellipsis=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_lambda_arrow=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_after_unary_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_binary_operator=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_ellipsis=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_lambda_arrow=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional=insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_semicolon=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_before_unary_operator=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration=do not insert
|
||||
org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation=do not insert
|
||||
org.eclipse.jdt.core.formatter.join_lines_in_comments=true
|
||||
org.eclipse.jdt.core.formatter.join_wrapped_lines=true
|
||||
org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line=false
|
||||
org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line=false
|
||||
org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line=false
|
||||
org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line=false
|
||||
org.eclipse.jdt.core.formatter.lineSplit=90
|
||||
org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column=false
|
||||
org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column=false
|
||||
org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body=0
|
||||
org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve=1
|
||||
org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line=true
|
||||
org.eclipse.jdt.core.formatter.tabulation.char=tab
|
||||
org.eclipse.jdt.core.formatter.tabulation.size=4
|
||||
org.eclipse.jdt.core.formatter.use_on_off_tags=false
|
||||
org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations=false
|
||||
org.eclipse.jdt.core.formatter.wrap_before_binary_operator=true
|
||||
org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch=true
|
||||
org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested=true
|
||||
File diff suppressed because one or more lines are too long
@@ -1,245 +0,0 @@
|
||||
#!/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' 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
|
||||
|
||||
exec "$JAVACMD" \
|
||||
$MAVEN_OPTS \
|
||||
-classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
|
||||
"-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
|
||||
${WRAPPER_LAUNCHER} ${MAVEN_ARGS} "$@"
|
||||
@@ -1,145 +0,0 @@
|
||||
@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%
|
||||
@@ -1,286 +1,223 @@
|
||||
<?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 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.5.BUILD-SNAPSHOT</version>
|
||||
<relativePath />
|
||||
</parent>
|
||||
<artifactId>spring-cloud-netflix</artifactId>
|
||||
<version>1.0.8.BUILD-SNAPSHOT</version>
|
||||
<packaging>pom</packaging>
|
||||
<name>Spring Cloud Netflix</name>
|
||||
<description>Spring Cloud Netflix</description>
|
||||
<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">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-netflix</artifactId>
|
||||
<version>1.0.0.M1</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.0.0.M1</version>
|
||||
<relativePath />
|
||||
<!-- lookup parent from repository -->
|
||||
</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>
|
||||
<developerConnection>scm:git:ssh://git@github.com/spring-cloud/spring-cloud-netflix.git</developerConnection>
|
||||
<tag>HEAD</tag>
|
||||
<tag>1.0.0.M1</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>8.1.1</feign.version>
|
||||
<hystrix.version>1.4.10</hystrix.version>
|
||||
<ribbon.version>2.0.0</ribbon.version>
|
||||
<zuul.version>1.0.28</zuul.version>
|
||||
<rxjava.version>1.0.11</rxjava.version>
|
||||
<java.version>1.7</java.version>
|
||||
<spring-cloud-netflix.version>1.0.8.BUILD-SNAPSHOT</spring-cloud-netflix.version>
|
||||
<spring-integration-dsl.version>1.0.0.RELEASE</spring-integration-dsl.version>
|
||||
<cloud-connectors.version>1.1.1.RELEASE</cloud-connectors.version>
|
||||
</properties>
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-eclipse-plugin</artifactId>
|
||||
<configuration>
|
||||
<useProjectReferences>false</useProjectReferences>
|
||||
<additionalConfig>
|
||||
<file>
|
||||
<name>.settings/org.eclipse.jdt.ui.prefs</name>
|
||||
<location>${main.basedir}/eclipse/org.eclipse.jdt.ui.prefs</location>
|
||||
</file>
|
||||
<file>
|
||||
<name>.settings/org.eclipse.jdt.core.prefs</name>
|
||||
<location>${main.basedir}/eclipse/org.eclipse.jdt.core.prefs</location>
|
||||
</file>
|
||||
</additionalConfig>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>1.7</source>
|
||||
<target>1.7</target>
|
||||
</configuration>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-netflix-dependencies</artifactId>
|
||||
<version>${spring-cloud-netflix.version}</version>
|
||||
<type>pom</type>
|
||||
<scope>import</scope>
|
||||
</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>
|
||||
<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.ribbon</groupId>
|
||||
<artifactId>ribbon-loadbalancer</artifactId>
|
||||
<version>${ribbon.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.reactivex</groupId>
|
||||
<artifactId>rxjava</artifactId>
|
||||
<version>${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>com.sun.jersey.contribs</groupId>
|
||||
<artifactId>jersey-apache-client4</artifactId>
|
||||
<version>1.11</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>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
<modules>
|
||||
<module>spring-cloud-netflix-dependencies</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-eureka-server</module>
|
||||
<module>spring-cloud-netflix-turbine</module>
|
||||
<module>spring-cloud-netflix-turbine-amqp</module>
|
||||
<module>spring-cloud-netflix-sidecar</module>
|
||||
<module>docs</module>
|
||||
</modules>
|
||||
|
||||
<modules>
|
||||
<module>spring-cloud-netflix-core</module>
|
||||
<module>spring-cloud-netflix-hystrix-dashboard</module>
|
||||
<module>spring-cloud-netflix-eureka-server</module>
|
||||
<module>spring-cloud-netflix-turbine</module>
|
||||
<module>spring-cloud-netflix-zuul</module>
|
||||
<module>docs</module>
|
||||
</modules>
|
||||
|
||||
<dependencyManagement>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-netflix-core</artifactId>
|
||||
<version>1.0.0.M1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-netflix-eureka-server</artifactId>
|
||||
<version>1.0.0.M1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-netflix-hystrix-dashboard</artifactId>
|
||||
<version>1.0.0.M1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-netflix-turbine</artifactId>
|
||||
<version>1.0.0.M1</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>
|
||||
</exclusions>
|
||||
</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>
|
||||
</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-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.turbine</groupId>
|
||||
<artifactId>turbine-core</artifactId>
|
||||
<version>${turbine.version}</version>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<groupId>javax.servlet</groupId>
|
||||
<artifactId>servlet-api</artifactId>
|
||||
</exclusion>
|
||||
<exclusion>
|
||||
<groupId>log4j</groupId>
|
||||
<artifactId>log4j</artifactId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.zuul</groupId>
|
||||
<artifactId>zuul-core</artifactId>
|
||||
<version>${zuul.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.12.6</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>
|
||||
</dependencies>
|
||||
</dependencyManagement>
|
||||
|
||||
<properties>
|
||||
<archaius.version>0.6.0</archaius.version>
|
||||
<eureka.version>1.1.135</eureka.version>
|
||||
<feign.version>6.1.2</feign.version>
|
||||
<hystrix.version>1.4.0-RC4</hystrix.version>
|
||||
<ribbon.version>0.3.13</ribbon.version>
|
||||
<turbine.version>0.4</turbine.version>
|
||||
<zuul.version>1.0.24</zuul.version>
|
||||
</properties>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -1,53 +1,27 @@
|
||||
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<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">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-netflix</artifactId>
|
||||
<version>1.0.8.BUILD-SNAPSHOT</version>
|
||||
<relativePath>..</relativePath>
|
||||
</parent>
|
||||
|
||||
<artifactId>spring-cloud-netflix-core</artifactId>
|
||||
<packaging>jar</packaging>
|
||||
<name>Spring Cloud Netflix Core</name>
|
||||
<description>Spring Cloud Netflix Core</description>
|
||||
<properties>
|
||||
<main.basedir>${basedir}/..</main.basedir>
|
||||
</properties>
|
||||
|
||||
<parent>
|
||||
<groupId>org.springframework.cloud</groupId>
|
||||
<artifactId>spring-cloud-netflix</artifactId>
|
||||
<version>1.0.0.M1</version>
|
||||
<relativePath>..</relativePath>
|
||||
</parent>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-configuration-processor</artifactId>
|
||||
<optional>true</optional>
|
||||
<artifactId>spring-boot-starter-web</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-autoconfigure</artifactId>
|
||||
</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-context</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>
|
||||
<optional>true</optional>
|
||||
<artifactId>spring-boot-starter-actuator</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.archaius</groupId>
|
||||
@@ -64,17 +38,6 @@
|
||||
<artifactId>eureka-core</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.ribbon</groupId>
|
||||
<artifactId>ribbon-loadbalancer</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<!-- Eureka core deps that are now optional -->
|
||||
<dependency>
|
||||
<groupId>com.thoughtworks.xstream</groupId>
|
||||
<artifactId>xstream</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.java.dev.rome</groupId>
|
||||
<artifactId>rome</artifactId>
|
||||
@@ -86,16 +49,12 @@
|
||||
<artifactId>feign-core</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.feign</groupId>
|
||||
<artifactId>feign-slf4j</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.feign</groupId>
|
||||
<artifactId>feign-ribbon</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<!--<dependency> <groupId>com.netflix.feign</groupId> <artifactId>feign-slf4j</artifactId>
|
||||
</dependency> -->
|
||||
<dependency>
|
||||
<groupId>com.netflix.hystrix</groupId>
|
||||
<artifactId>hystrix-core</artifactId>
|
||||
@@ -111,11 +70,6 @@
|
||||
<artifactId>hystrix-javanica</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.ribbon</groupId>
|
||||
<artifactId>ribbon</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.ribbon</groupId>
|
||||
<artifactId>ribbon-core</artifactId>
|
||||
@@ -126,42 +80,27 @@
|
||||
<artifactId>ribbon-eureka</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.ribbon</groupId>
|
||||
<artifactId>ribbon-httpclient</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.zuul</groupId>
|
||||
<artifactId>zuul-core</artifactId>
|
||||
<optional>true</optional>
|
||||
<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>io.reactivex</groupId>
|
||||
<artifactId>rxjava</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.sun.jersey.contribs</groupId>
|
||||
<artifactId>jersey-apache-client4</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.ribbon</groupId>
|
||||
<artifactId>ribbon-httpclient</artifactId>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.netflix.zuul</groupId>
|
||||
<artifactId>zuul-core</artifactId>
|
||||
<optional>true</optional>
|
||||
<exclusions>
|
||||
<exclusion>
|
||||
<artifactId>groovy-all</artifactId>
|
||||
<groupId>org.codehaus.groovy</groupId>
|
||||
</exclusion>
|
||||
</exclusions>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<!-- Only needed at compile time -->
|
||||
<scope>compile</scope>
|
||||
<optional>true</optional>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
@@ -169,14 +108,10 @@
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.h2database</groupId>
|
||||
<artifactId>h2</artifactId>
|
||||
<scope>test</scope>
|
||||
<groupId>org.neo4j</groupId>
|
||||
<artifactId>neo4j-cypher-compiler-2.1</artifactId>
|
||||
<version>2.1.2</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
||||
|
||||
+11
@@ -0,0 +1,11 @@
|
||||
package org.springframework.cloud.client;
|
||||
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
* TODO: name? Server? HostAndPort? Instance?
|
||||
*/
|
||||
public interface ServiceInstance {
|
||||
public String getHost();
|
||||
public int getPort();
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
package org.springframework.cloud.client.loadbalancer;
|
||||
|
||||
import org.springframework.cloud.client.ServiceInstance;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public interface LoadBalancerClient {
|
||||
/**
|
||||
* Choose a {@see ServiceInstance} from the LoadBalancer for the specified service
|
||||
* @param serviceId The serviceId to use to look up the LoadBalancer
|
||||
* @return
|
||||
*/
|
||||
public ServiceInstance choose(String serviceId);
|
||||
}
|
||||
+63
-179
@@ -1,206 +1,90 @@
|
||||
/*
|
||||
* 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.archaius;
|
||||
|
||||
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;
|
||||
import static com.netflix.config.ConfigurationManager.ENV_CONFIG_NAME;
|
||||
import static com.netflix.config.ConfigurationManager.SYS_CONFIG_NAME;
|
||||
import static com.netflix.config.ConfigurationManager.URL_CONFIG_NAME;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import javax.annotation.PreDestroy;
|
||||
|
||||
import lombok.extern.apachecommons.CommonsLog;
|
||||
|
||||
import org.apache.commons.configuration.AbstractConfiguration;
|
||||
import org.apache.commons.configuration.ConfigurationBuilder;
|
||||
import com.netflix.config.ConcurrentCompositeConfiguration;
|
||||
import com.netflix.config.ConfigurationManager;
|
||||
import com.netflix.config.DynamicURLConfiguration;
|
||||
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.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.actuate.endpoint.Endpoint;
|
||||
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.env.ConfigurableEnvironment;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
import com.netflix.config.AggregatedConfiguration;
|
||||
import com.netflix.config.ConcurrentCompositeConfiguration;
|
||||
import com.netflix.config.ConfigurationManager;
|
||||
import com.netflix.config.DeploymentContext;
|
||||
import com.netflix.config.DynamicPropertyFactory;
|
||||
import com.netflix.config.DynamicURLConfiguration;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
import static com.netflix.config.ConfigurationBasedDeploymentContext.DEPLOYMENT_APPLICATION_ID_PROPERTY;
|
||||
import static com.netflix.config.ConfigurationManager.*;
|
||||
import static com.netflix.config.ConfigurationManager.APPLICATION_PROPERTIES;
|
||||
import static com.netflix.config.ConfigurationManager.ENV_CONFIG_NAME;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
@Configuration
|
||||
@ConditionalOnClass({ ConcurrentCompositeConfiguration.class, ConfigurationBuilder.class })
|
||||
@CommonsLog
|
||||
public class ArchaiusAutoConfiguration {
|
||||
|
||||
private static final AtomicBoolean initialized = new AtomicBoolean(false);
|
||||
private static final Logger logger = LoggerFactory.getLogger(ArchaiusAutoConfiguration.class);
|
||||
private static final AtomicBoolean initialized = new AtomicBoolean(false);
|
||||
|
||||
@Autowired
|
||||
private ConfigurableEnvironment env;
|
||||
@Autowired
|
||||
ConfigurableEnvironment env;
|
||||
|
||||
@Autowired
|
||||
private List<AbstractConfiguration> externalConfigurations;
|
||||
@Bean
|
||||
ConfigurableEnvironmentConfiguration configurableEnvironmentConfiguration() {
|
||||
ConfigurableEnvironmentConfiguration envConfig = new ConfigurableEnvironmentConfiguration(env);
|
||||
configureArchaius(envConfig);
|
||||
return envConfig;
|
||||
}
|
||||
|
||||
@PreDestroy
|
||||
public void close() {
|
||||
setStatic(ConfigurationManager.class, "instance", null);
|
||||
setStatic(ConfigurationManager.class, "customConfigurationInstalled", false);
|
||||
setStatic(DynamicPropertyFactory.class, "config", null);
|
||||
setStatic(DynamicPropertyFactory.class, "initializedWithDefaultConfig", false);
|
||||
initialized.compareAndSet(true, false);
|
||||
}
|
||||
protected void configureArchaius(ConfigurableEnvironmentConfiguration envConfig) {
|
||||
if (initialized.compareAndSet(false, true)) {
|
||||
String appName = env.getProperty("spring.application.name");
|
||||
if (appName == null) {
|
||||
throw new IllegalStateException("spring.application.name may not be null");
|
||||
}
|
||||
//this is deprecated, but currently it seams the only way to set it initially
|
||||
System.setProperty(DEPLOYMENT_APPLICATION_ID_PROPERTY, appName);
|
||||
|
||||
@Bean
|
||||
public ConfigurableEnvironmentConfiguration configurableEnvironmentConfiguration() {
|
||||
ConfigurableEnvironmentConfiguration envConfig = new ConfigurableEnvironmentConfiguration(
|
||||
this.env);
|
||||
configureArchaius(envConfig);
|
||||
return envConfig;
|
||||
}
|
||||
//TODO: support for other DeploymentContexts
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnClass(Endpoint.class)
|
||||
protected static class ArchaiusEndpointConfiguration {
|
||||
@Bean
|
||||
protected ArchaiusEndpoint archaiusEndpoint() {
|
||||
return new ArchaiusEndpoint();
|
||||
}
|
||||
}
|
||||
ConcurrentCompositeConfiguration config = new ConcurrentCompositeConfiguration();
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnProperty(value = "archaius.propagate.environmentChangedEvent", matchIfMissing = true)
|
||||
@ConditionalOnClass(EnvironmentChangeEvent.class)
|
||||
protected static class PropagateEventsConfiguration implements
|
||||
ApplicationListener<EnvironmentChangeEvent> {
|
||||
@Autowired
|
||||
private Environment env;
|
||||
//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());
|
||||
}
|
||||
}*/
|
||||
config.addConfiguration(envConfig, ConfigurableEnvironmentConfiguration.class.getSimpleName());
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(EnvironmentChangeEvent event) {
|
||||
AbstractConfiguration manager = ConfigurationManager.getConfigInstance();
|
||||
for (String key : event.getKeys()) {
|
||||
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);
|
||||
boolean beforeUpdate = false;
|
||||
listener.configurationChanged(new ConfigurationEvent(source, type,
|
||||
key, value, beforeUpdate));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//below come from ConfigurationManager.createDefaultConfigInstance()
|
||||
try {
|
||||
DynamicURLConfiguration defaultURLConfig = new DynamicURLConfiguration();
|
||||
config.addConfiguration(defaultURLConfig, URL_CONFIG_NAME);
|
||||
} catch (Throwable e) {
|
||||
e.printStackTrace(); //TODO: log error
|
||||
}
|
||||
|
||||
protected void configureArchaius(ConfigurableEnvironmentConfiguration envConfig) {
|
||||
if (initialized.compareAndSet(false, true)) {
|
||||
String appName = this.env.getProperty("spring.application.name");
|
||||
if (appName == null) {
|
||||
appName = "application";
|
||||
log.warn("No spring.application.name found, defaulting to 'application'");
|
||||
}
|
||||
System.setProperty(DeploymentContext.ContextKey.appId.getKey(), appName);
|
||||
//TODO: sys/env above urls?
|
||||
if (!Boolean.getBoolean(DISABLE_DEFAULT_SYS_CONFIG)) {
|
||||
SystemConfiguration sysConfig = new SystemConfiguration();
|
||||
config.addConfiguration(sysConfig, SYS_CONFIG_NAME);
|
||||
}
|
||||
if (!Boolean.getBoolean(DISABLE_DEFAULT_ENV_CONFIG)) {
|
||||
EnvironmentConfiguration environmentConfiguration = new EnvironmentConfiguration();
|
||||
config.addConfiguration(environmentConfiguration, ENV_CONFIG_NAME);
|
||||
}
|
||||
|
||||
ConcurrentCompositeConfiguration config = new ConcurrentCompositeConfiguration();
|
||||
|
||||
// support to add other Configurations (Jdbc, DynamoDb, Zookeeper, jclouds,
|
||||
// etc...)
|
||||
if (externalConfigurations != null) {
|
||||
for (AbstractConfiguration externalConfig : externalConfigurations) {
|
||||
config.addConfiguration(externalConfig);
|
||||
}
|
||||
}
|
||||
config.addConfiguration(envConfig,
|
||||
ConfigurableEnvironmentConfiguration.class.getSimpleName());
|
||||
|
||||
// below come from ConfigurationManager.createDefaultConfigInstance()
|
||||
DynamicURLConfiguration defaultURLConfig = new DynamicURLConfiguration();
|
||||
try {
|
||||
config.addConfiguration(defaultURLConfig, URL_CONFIG_NAME);
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
log.error("Cannot create config from " + defaultURLConfig, ex);
|
||||
}
|
||||
|
||||
// TODO: sys/env above urls?
|
||||
if (!Boolean.getBoolean(DISABLE_DEFAULT_SYS_CONFIG)) {
|
||||
SystemConfiguration sysConfig = new SystemConfiguration();
|
||||
config.addConfiguration(sysConfig, SYS_CONFIG_NAME);
|
||||
}
|
||||
if (!Boolean.getBoolean(DISABLE_DEFAULT_ENV_CONFIG)) {
|
||||
EnvironmentConfiguration environmentConfiguration = new EnvironmentConfiguration();
|
||||
config.addConfiguration(environmentConfiguration, ENV_CONFIG_NAME);
|
||||
}
|
||||
|
||||
ConcurrentCompositeConfiguration appOverrideConfig = new ConcurrentCompositeConfiguration();
|
||||
config.addConfiguration(appOverrideConfig, APPLICATION_PROPERTIES);
|
||||
config.setContainerConfigurationIndex(config
|
||||
.getIndexOfConfiguration(appOverrideConfig));
|
||||
|
||||
addArchaiusConfiguration(config);
|
||||
}
|
||||
else {
|
||||
// TODO: reinstall ConfigurationManager
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
private static void setStatic(Class<?> type, String name, Object value) {
|
||||
// Hack a private static field
|
||||
Field field = ReflectionUtils.findField(type, name);
|
||||
ReflectionUtils.makeAccessible(field);
|
||||
ReflectionUtils.setField(field, null, value);
|
||||
}
|
||||
ConcurrentCompositeConfiguration appOverrideConfig = new ConcurrentCompositeConfiguration();
|
||||
config.addConfiguration(appOverrideConfig, APPLICATION_PROPERTIES);
|
||||
config.setContainerConfigurationIndex(config.getIndexOfConfiguration(appOverrideConfig));
|
||||
|
||||
ConfigurationManager.install(config);
|
||||
} else {
|
||||
//TODO: reinstall ConfigurationManager
|
||||
logger.warn("Netflix ConfigurationManager has already been installed, unable to re-install");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
-50
@@ -1,50 +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
|
||||
*
|
||||
* 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.archaius;
|
||||
|
||||
import org.apache.commons.configuration.AbstractConfiguration;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ConfigurableApplicationContext;
|
||||
|
||||
import com.netflix.config.ConfigurationManager;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public class ArchaiusDelegatingProxyUtils {
|
||||
|
||||
public static String APPLICATION_CONTEXT = ApplicationContext.class.getName();
|
||||
|
||||
public static <T> T getNamedInstance(Class<T> type, String name) {
|
||||
ApplicationContext context = (ApplicationContext) ConfigurationManager
|
||||
.getConfigInstance().getProperty(APPLICATION_CONTEXT);
|
||||
return context != null && context.containsBean(name) ? context
|
||||
.getBean(name, type) : null;
|
||||
}
|
||||
|
||||
public static <T> T getInstanceWithPrefix(Class<T> type, String prefix) {
|
||||
String name = prefix + type.getSimpleName();
|
||||
return getNamedInstance(type, name);
|
||||
}
|
||||
|
||||
public static void addApplicationContext(ConfigurableApplicationContext context) {
|
||||
AbstractConfiguration config = ConfigurationManager.getConfigInstance();
|
||||
config.clearProperty(APPLICATION_CONTEXT);
|
||||
config.setProperty(APPLICATION_CONTEXT, context);
|
||||
}
|
||||
|
||||
}
|
||||
-73
@@ -1,73 +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
|
||||
*
|
||||
* 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.archaius;
|
||||
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.apache.commons.configuration.AbstractConfiguration;
|
||||
import org.apache.commons.configuration.Configuration;
|
||||
import org.apache.commons.configuration.EnvironmentConfiguration;
|
||||
import org.apache.commons.configuration.SystemConfiguration;
|
||||
import org.springframework.boot.actuate.endpoint.AbstractEndpoint;
|
||||
|
||||
import com.netflix.config.ConcurrentCompositeConfiguration;
|
||||
import com.netflix.config.ConfigurationManager;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public class ArchaiusEndpoint extends AbstractEndpoint<Map<String, Object>> {
|
||||
|
||||
public ArchaiusEndpoint() {
|
||||
super("archaius");
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> invoke() {
|
||||
Map<String, Object> map = new LinkedHashMap<String, Object>();
|
||||
AbstractConfiguration config = ConfigurationManager.getConfigInstance();
|
||||
if (config instanceof ConcurrentCompositeConfiguration) {
|
||||
ConcurrentCompositeConfiguration composite = (ConcurrentCompositeConfiguration) config;
|
||||
for (Configuration item : composite.getConfigurations()) {
|
||||
append(map, item);
|
||||
}
|
||||
}
|
||||
else {
|
||||
append(map, config);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
private void append(Map<String, Object> map, Configuration config) {
|
||||
if (config instanceof ConfigurableEnvironmentConfiguration) {
|
||||
return;
|
||||
}
|
||||
if (config instanceof SystemConfiguration) {
|
||||
return;
|
||||
}
|
||||
if (config instanceof EnvironmentConfiguration) {
|
||||
return;
|
||||
}
|
||||
for (Iterator<String> iter = config.getKeys(); iter.hasNext();) {
|
||||
String key = iter.next();
|
||||
map.put(key, config.getProperty(key));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+76
-71
@@ -1,26 +1,13 @@
|
||||
/*
|
||||
* 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.archaius;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.commons.configuration.AbstractConfiguration;
|
||||
import org.springframework.core.env.CompositePropertySource;
|
||||
@@ -29,74 +16,92 @@ import org.springframework.core.env.EnumerablePropertySource;
|
||||
import org.springframework.core.env.MutablePropertySources;
|
||||
import org.springframework.core.env.PropertySource;
|
||||
import org.springframework.core.env.StandardEnvironment;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class ConfigurableEnvironmentConfiguration extends AbstractConfiguration {
|
||||
ConfigurableEnvironment environment;
|
||||
|
||||
private final ConfigurableEnvironment environment;
|
||||
public ConfigurableEnvironmentConfiguration(ConfigurableEnvironment environment) {
|
||||
this.environment = environment;
|
||||
}
|
||||
|
||||
public ConfigurableEnvironmentConfiguration(ConfigurableEnvironment environment) {
|
||||
this.environment = environment;
|
||||
}
|
||||
@Override
|
||||
protected void addPropertyDirect(String key, Object value) {
|
||||
|
||||
@Override
|
||||
protected void addPropertyDirect(String key, Object value) {
|
||||
}
|
||||
|
||||
}
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return !getKeys().hasNext(); //TODO: find a better way to do this
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isEmpty() {
|
||||
return !getKeys().hasNext(); // TODO: find a better way to do this
|
||||
}
|
||||
@Override
|
||||
public boolean containsKey(String key) {
|
||||
return environment.containsProperty(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsKey(String key) {
|
||||
return this.environment.containsProperty(key);
|
||||
}
|
||||
@Override
|
||||
public Object getProperty(String key) {
|
||||
return environment.getProperty(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getProperty(String key) {
|
||||
return this.environment.getProperty(key);
|
||||
}
|
||||
@Override
|
||||
public Iterator<String> getKeys() {
|
||||
List<String> result = new ArrayList<>();
|
||||
for (Map.Entry<String, PropertySource<?>> entry : getPropertySources().entrySet()) {
|
||||
PropertySource<?> source = entry.getValue();
|
||||
if (source instanceof EnumerablePropertySource) {
|
||||
EnumerablePropertySource<?> enumerable = (EnumerablePropertySource<?>) source;
|
||||
for (String name : enumerable.getPropertyNames()) {
|
||||
result.add(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result.iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<String> getKeys() {
|
||||
List<String> result = new ArrayList<>();
|
||||
for (Map.Entry<String, PropertySource<?>> entry : getPropertySources().entrySet()) {
|
||||
PropertySource<?> source = entry.getValue();
|
||||
if (source instanceof EnumerablePropertySource) {
|
||||
EnumerablePropertySource<?> enumerable = (EnumerablePropertySource<?>) source;
|
||||
for (String name : enumerable.getPropertyNames()) {
|
||||
result.add(name);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result.iterator();
|
||||
}
|
||||
private Map<String, PropertySource<?>> getPropertySources() {
|
||||
Map<String, PropertySource<?>> map = new LinkedHashMap<String, PropertySource<?>>();
|
||||
MutablePropertySources sources = null;
|
||||
if (this.environment != null
|
||||
&& this.environment instanceof ConfigurableEnvironment) {
|
||||
sources = ((ConfigurableEnvironment) this.environment).getPropertySources();
|
||||
}
|
||||
else {
|
||||
sources = new StandardEnvironment().getPropertySources();
|
||||
}
|
||||
for (PropertySource<?> source : sources) {
|
||||
extract("", map, source);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
private Map<String, PropertySource<?>> getPropertySources() {
|
||||
Map<String, PropertySource<?>> map = new LinkedHashMap<>();
|
||||
MutablePropertySources sources = (this.environment != null ? this.environment
|
||||
.getPropertySources() : new StandardEnvironment().getPropertySources());
|
||||
for (PropertySource<?> source : sources) {
|
||||
extract("", map, source);
|
||||
}
|
||||
return map;
|
||||
}
|
||||
|
||||
private void extract(String root, Map<String, PropertySource<?>> map,
|
||||
PropertySource<?> source) {
|
||||
if (source instanceof CompositePropertySource) {
|
||||
for (PropertySource<?> nest : ((CompositePropertySource) source)
|
||||
.getPropertySources()) {
|
||||
extract(source.getName() + ":", map, nest);
|
||||
}
|
||||
}
|
||||
else {
|
||||
map.put(root + source.getName(), source);
|
||||
}
|
||||
}
|
||||
private void extract(String root, Map<String, PropertySource<?>> map,
|
||||
PropertySource<?> source) {
|
||||
if (source instanceof CompositePropertySource) {
|
||||
Set<PropertySource<?>> nested = getNestedPropertySources((CompositePropertySource) source);
|
||||
for (PropertySource<?> nest : nested) {
|
||||
extract(source.getName() + ":", map, nest);
|
||||
}
|
||||
}
|
||||
else {
|
||||
map.put(root + source.getName(), source);
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Set<PropertySource<?>> getNestedPropertySources(CompositePropertySource source) {
|
||||
try {
|
||||
Field field = ReflectionUtils.findField(CompositePropertySource.class,
|
||||
"propertySources");
|
||||
field.setAccessible(true);
|
||||
return (Set<PropertySource<?>>) field.get(source);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
return Collections.emptySet();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
-72
@@ -1,72 +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
|
||||
*
|
||||
* 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.config;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.cloud.context.scope.refresh.RefreshScopeRefreshedEvent;
|
||||
import org.springframework.cloud.netflix.eureka.EurekaDiscoveryClientConfiguration;
|
||||
import org.springframework.context.ApplicationListener;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import com.netflix.appinfo.ApplicationInfoManager;
|
||||
import com.netflix.appinfo.EurekaInstanceConfig;
|
||||
import com.netflix.discovery.DiscoveryManager;
|
||||
import com.netflix.discovery.EurekaClientConfig;
|
||||
|
||||
/**
|
||||
* Bootstrap configuration for a config client that wants to lookup the config server via
|
||||
* discovery.
|
||||
*
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@ConditionalOnBean({ EurekaDiscoveryClientConfiguration.class })
|
||||
@ConditionalOnProperty(value = "spring.cloud.config.discovery.enabled", matchIfMissing = false)
|
||||
@Configuration
|
||||
public class DiscoveryClientConfigServiceAutoConfiguration
|
||||
implements ApplicationListener<RefreshScopeRefreshedEvent> {
|
||||
|
||||
@Autowired
|
||||
private EurekaClientConfig clientConfig;
|
||||
|
||||
@Autowired
|
||||
private EurekaInstanceConfig instanceConfig;
|
||||
|
||||
@Autowired
|
||||
private EurekaDiscoveryClientConfiguration lifecycle;
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
this.lifecycle.stop();
|
||||
if (DiscoveryManager.getInstance().getDiscoveryClient() != null) {
|
||||
DiscoveryManager.getInstance().getDiscoveryClient().shutdown();
|
||||
}
|
||||
ApplicationInfoManager.getInstance().initComponent(this.instanceConfig);
|
||||
DiscoveryManager.getInstance().initComponent(this.instanceConfig,
|
||||
this.clientConfig);
|
||||
this.lifecycle.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(RefreshScopeRefreshedEvent arg0) {
|
||||
init();
|
||||
}
|
||||
|
||||
}
|
||||
-131
@@ -1,131 +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
|
||||
*
|
||||
* 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.config;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.cloud.client.ServiceInstance;
|
||||
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.ApplicationContext;
|
||||
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;
|
||||
import com.netflix.discovery.DiscoveryManager;
|
||||
|
||||
import lombok.extern.apachecommons.CommonsLog;
|
||||
|
||||
/**
|
||||
* Bootstrap configuration for a config client that wants to lookup the config
|
||||
* server via discovery.
|
||||
*
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@ConditionalOnClass({ DiscoveryClient.class, ConfigServicePropertySourceLocator.class })
|
||||
@ConditionalOnProperty(value = "spring.cloud.config.discovery.enabled", matchIfMissing = false)
|
||||
@Configuration
|
||||
@EnableDiscoveryClient
|
||||
@Import(EurekaClientAutoConfiguration.class)
|
||||
@CommonsLog
|
||||
public class DiscoveryClientConfigServiceBootstrapConfiguration implements SmartApplicationListener {
|
||||
|
||||
private HeartbeatMonitor monitor = new HeartbeatMonitor();
|
||||
|
||||
@Autowired
|
||||
private ConfigClientProperties config;
|
||||
|
||||
@Autowired
|
||||
private org.springframework.cloud.client.discovery.DiscoveryClient client;
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext context;
|
||||
|
||||
@Override
|
||||
public void onApplicationEvent(ApplicationEvent event) {
|
||||
if (event instanceof ContextRefreshedEvent
|
||||
&& ((ContextRefreshedEvent) event).getApplicationContext() == context) {
|
||||
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 = DiscoveryManager.getInstance().getDiscoveryClient()
|
||||
.getNextServerFromEureka(this.config.getDiscovery().getServiceId(), false);
|
||||
String url = getHomePage(server);
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
private String getHomePage(InstanceInfo server) {
|
||||
List<ServiceInstance> instances = client.getInstances(this.config.getDiscovery().getServiceId());
|
||||
if (instances==null || instances.isEmpty()) {
|
||||
return server.getHomePageUrl();
|
||||
}
|
||||
return instances.get(0).getUri().toString() + "/";
|
||||
}
|
||||
|
||||
}
|
||||
-59
@@ -1,59 +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
|
||||
*
|
||||
* 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.config;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.cloud.config.server.ConfigServerProperties;
|
||||
import org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.netflix.discovery.DiscoveryClient;
|
||||
|
||||
/**
|
||||
* Extra configuration for config server if it happens to be a Eureka instance.
|
||||
*
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@Configuration
|
||||
@EnableConfigurationProperties
|
||||
@ConditionalOnClass({ EurekaInstanceConfigBean.class, DiscoveryClient.class,
|
||||
ConfigServerProperties.class })
|
||||
public class EurekaClientConfigServerAutoConfiguration {
|
||||
|
||||
@Autowired(required = false)
|
||||
private EurekaInstanceConfigBean instance;
|
||||
|
||||
@Autowired(required = false)
|
||||
private ConfigServerProperties server;
|
||||
|
||||
@PostConstruct
|
||||
public void init() {
|
||||
if (this.instance == null || this.server == null) {
|
||||
return;
|
||||
}
|
||||
String prefix = this.server.getPrefix();
|
||||
if (StringUtils.hasText(prefix)) {
|
||||
this.instance.getMetadataMap().put("configPath", prefix);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+51
-75
@@ -1,25 +1,5 @@
|
||||
/*
|
||||
* 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.endpoint;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.boot.actuate.endpoint.Endpoint;
|
||||
@@ -31,70 +11,66 @@ import org.springframework.web.context.ServletContextAware;
|
||||
import org.springframework.web.servlet.ModelAndView;
|
||||
import org.springframework.web.servlet.mvc.ServletWrappingController;
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
/**
|
||||
* TODO: move to spring-boot?
|
||||
* User: spencergibb
|
||||
* Date: 4/24/14
|
||||
* Time: 9:13 PM
|
||||
*/
|
||||
public abstract class ServletWrappingEndpoint implements InitializingBean,
|
||||
ApplicationContextAware, ServletContextAware, MvcEndpoint {
|
||||
ApplicationContextAware, ServletContextAware, MvcEndpoint {
|
||||
|
||||
// TODO: move to spring-boot?
|
||||
protected String path;
|
||||
protected boolean sensitive;
|
||||
protected boolean enabled = true;
|
||||
|
||||
private String path;
|
||||
protected final ServletWrappingController controller = new ServletWrappingController();
|
||||
|
||||
private boolean sensitive;
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
this.controller.afterPropertiesSet();
|
||||
}
|
||||
|
||||
private boolean enabled = true;
|
||||
@Override
|
||||
public void setServletContext(ServletContext servletContext) {
|
||||
this.controller.setServletContext(servletContext);
|
||||
}
|
||||
|
||||
private final ServletWrappingController controller = new ServletWrappingController();
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
|
||||
this.controller.setApplicationContext(applicationContext);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
this.controller.afterPropertiesSet();
|
||||
}
|
||||
protected ServletWrappingEndpoint(Class<?> servletClass, String servletName, String path,
|
||||
boolean sensitive, boolean enabled) {
|
||||
controller.setServletClass(servletClass);
|
||||
controller.setServletName(servletName);
|
||||
this.path = path;
|
||||
this.sensitive = sensitive;
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setServletContext(ServletContext servletContext) {
|
||||
this.controller.setServletContext(servletContext);
|
||||
}
|
||||
@RequestMapping("**")
|
||||
public ModelAndView handle(HttpServletRequest request, HttpServletResponse response) throws Exception {
|
||||
return this.controller.handleRequest(request, response);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext applicationContext)
|
||||
throws BeansException {
|
||||
this.controller.setApplicationContext(applicationContext);
|
||||
}
|
||||
@Override
|
||||
public String getPath() {
|
||||
return path;
|
||||
}
|
||||
|
||||
protected ServletWrappingEndpoint(Class<?> servletClass, String servletName,
|
||||
String path, boolean sensitive, boolean enabled) {
|
||||
this.controller.setServletClass(servletClass);
|
||||
this.controller.setServletName(servletName);
|
||||
this.path = path;
|
||||
this.sensitive = sensitive;
|
||||
this.enabled = enabled;
|
||||
}
|
||||
|
||||
@RequestMapping("**")
|
||||
public ModelAndView handle(HttpServletRequest request, HttpServletResponse response)
|
||||
throws Exception {
|
||||
return this.controller.handleRequest(request, response);
|
||||
}
|
||||
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public ServletWrappingController getController() {
|
||||
return controller;
|
||||
}
|
||||
@Override
|
||||
public String getPath() {
|
||||
return this.path;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSensitive() {
|
||||
return this.sensitive;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends Endpoint<?>> getEndpointType() {
|
||||
return null;
|
||||
}
|
||||
@Override
|
||||
public boolean isSensitive() {
|
||||
return sensitive;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<? extends Endpoint<?>> getEndpointType() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
-217
@@ -1,217 +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
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.eureka;
|
||||
|
||||
import 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 id = calculateId(info, instanceId);
|
||||
info = new InstanceInfo.Builder(info).setDataCenterInfo(
|
||||
new InstanceIdDataCenterInfo(id)).build();
|
||||
source = info;
|
||||
}
|
||||
super.marshal(source, writer, context);
|
||||
}
|
||||
|
||||
String calculateId(InstanceInfo info, String instanceId) {
|
||||
String old = info.getId();
|
||||
if (old.endsWith(instanceId)) {
|
||||
return old;
|
||||
}
|
||||
if (instanceId.startsWith(old)) {
|
||||
return instanceId;
|
||||
}
|
||||
return old + ":" + instanceId;
|
||||
}
|
||||
|
||||
@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 id = calculateId(info, instanceId);
|
||||
info = new InstanceInfo.Builder(info).setDataCenterInfo(
|
||||
new InstanceIdDataCenterInfo(id)).build();
|
||||
obj = info;
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
-47
@@ -1,47 +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
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.eureka;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
import com.netflix.appinfo.ApplicationInfoManager;
|
||||
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);
|
||||
}
|
||||
if (ApplicationInfoManager.getInstance().getInfo() == null) {
|
||||
ApplicationInfoManager.getInstance().initComponent(this.instanceConfig);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+23
@@ -0,0 +1,23 @@
|
||||
package org.springframework.cloud.netflix.eureka;
|
||||
|
||||
import com.netflix.discovery.DiscoveryManager;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class DiscoveryManagerIntitializer {
|
||||
|
||||
@Autowired
|
||||
private EurekaClientConfigBean clientConfig;
|
||||
|
||||
@Autowired
|
||||
private EurekaInstanceConfigBean instanceConfig;
|
||||
|
||||
|
||||
public synchronized void init() {
|
||||
if (DiscoveryManager.getInstance().getDiscoveryClient() == null) {
|
||||
DiscoveryManager.getInstance().initComponent(instanceConfig, clientConfig);
|
||||
}
|
||||
}
|
||||
}
|
||||
+5
-14
@@ -1,11 +1,11 @@
|
||||
/*
|
||||
* Copyright 2013-2015 the original author or authors.
|
||||
* 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
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* 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,
|
||||
@@ -13,33 +13,24 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.eureka;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Inherited;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
/**
|
||||
* Convenience annotation for clients to enable Eureka discovery configuration
|
||||
* (specifically). Use this (optionally) in case you want discovery and know for sure that
|
||||
* it is Eureka you want. All it does is turn on discovery and let the autoconfiguration
|
||||
* find the eureka classes if they are available (i.e. you need Eureka on the classpath as
|
||||
* well).
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @author Spencer Gibb
|
||||
*
|
||||
*/
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Inherited
|
||||
@EnableDiscoveryClient
|
||||
@Import(EurekaClientConfiguration.class)
|
||||
public @interface EnableEurekaClient {
|
||||
|
||||
}
|
||||
|
||||
+8
-74
@@ -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
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* 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,
|
||||
@@ -13,103 +13,37 @@
|
||||
* 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.ConditionalOnExpression;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||
import org.springframework.boot.autoconfigure.condition.SearchStrategy;
|
||||
import org.springframework.boot.builder.ParentContextApplicationContextInitializer;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.cloud.client.CommonsClientAutoConfiguration;
|
||||
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, CommonsClientAutoConfiguration.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));
|
||||
}
|
||||
@ConditionalOnExpression("${eureka.client.enabled:true}")
|
||||
public class EurekaClientAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(value=EurekaClientConfig.class, search = SearchStrategy.CURRENT)
|
||||
@ConditionalOnMissingBean(EurekaClientConfig.class)
|
||||
public EurekaClientConfigBean eurekaClientConfigBean() {
|
||||
return new EurekaClientConfigBean();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(value=EurekaInstanceConfig.class, search = SearchStrategy.CURRENT)
|
||||
@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()));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
return new EurekaInstanceConfigBean();
|
||||
}
|
||||
}
|
||||
|
||||
+28
-42
@@ -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
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* 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,
|
||||
@@ -13,7 +13,6 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.eureka;
|
||||
|
||||
import java.util.ArrayList;
|
||||
@@ -22,26 +21,24 @@ import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
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;
|
||||
@@ -56,10 +53,6 @@ public class EurekaClientConfigBean implements EurekaClientConfig {
|
||||
|
||||
private String proxyHost;
|
||||
|
||||
private String proxyUserName;
|
||||
|
||||
private String proxyPassword;
|
||||
|
||||
private int eurekaServerReadTimeoutSeconds = 8;
|
||||
|
||||
private int eurekaServerConnectTimeoutSeconds = 5;
|
||||
@@ -84,15 +77,12 @@ public class EurekaClientConfigBean implements EurekaClientConfig {
|
||||
|
||||
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>();
|
||||
private Map<String,String> serviceUrl = new HashMap<String, String>();
|
||||
|
||||
{
|
||||
this.serviceUrl.put(DEFAULT_ZONE, DEFAULT_URL);
|
||||
serviceUrl.put(DEFAULT_ZONE, "http://localhost:8761/v2/");
|
||||
}
|
||||
|
||||
private boolean gZipContent = true;
|
||||
@@ -115,49 +105,45 @@ public class EurekaClientConfigBean implements EurekaClientConfig {
|
||||
|
||||
private boolean fetchRegistry = true;
|
||||
|
||||
private String dollarReplacement = "_-";
|
||||
|
||||
private String escapeCharReplacement = "__";
|
||||
|
||||
@Override
|
||||
public boolean shouldGZipContent() {
|
||||
return this.gZipContent;
|
||||
return gZipContent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldUseDnsForFetchingServiceUrls() {
|
||||
return this.useDnsForFetchingServiceUrls;
|
||||
return useDnsForFetchingServiceUrls;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldRegisterWithEureka() {
|
||||
return this.registerWithEureka;
|
||||
return registerWithEureka;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldPreferSameZoneEureka() {
|
||||
return this.preferSameZoneEureka;
|
||||
return preferSameZoneEureka;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldLogDeltaDiff() {
|
||||
return this.logDeltaDiff;
|
||||
return logDeltaDiff;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldDisableDelta() {
|
||||
return this.disableDelta;
|
||||
return disableDelta;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String fetchRegistryForRemoteRegions() {
|
||||
return this.fetchRemoteRegionsRegistry;
|
||||
return fetchRemoteRegionsRegistry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getAvailabilityZones(String region) {
|
||||
String value = this.availabilityZones.get(region);
|
||||
if (value == null) {
|
||||
String value = availabilityZones.get(region);
|
||||
if (value==null) {
|
||||
value = DEFAULT_ZONE;
|
||||
}
|
||||
return value.split(",");
|
||||
@@ -165,25 +151,25 @@ public class EurekaClientConfigBean implements EurekaClientConfig {
|
||||
|
||||
@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(","));
|
||||
}
|
||||
String serviceUrls = serviceUrl.get(myZone);
|
||||
if (serviceUrls == null || serviceUrls.isEmpty()) {
|
||||
serviceUrls = serviceUrl.get("default");
|
||||
}
|
||||
if (serviceUrls != null) {
|
||||
return Arrays.asList(serviceUrls.split(","));
|
||||
}
|
||||
|
||||
return new ArrayList<>();
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldFilterOnlyUpInstances() {
|
||||
return this.filterOnlyUpInstances;
|
||||
return filterOnlyUpInstances;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldFetchRegistry() {
|
||||
return this.fetchRegistry;
|
||||
return fetchRegistry;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+158
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
* 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 javax.annotation.PreDestroy;
|
||||
import javax.management.MBeanServer;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.context.embedded.EmbeddedServletContainerInitializedEvent;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.cloud.netflix.servo.ServoMetricReader;
|
||||
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 com.netflix.appinfo.ApplicationInfoManager;
|
||||
import com.netflix.appinfo.EurekaInstanceConfig;
|
||||
import com.netflix.appinfo.InstanceInfo.InstanceStatus;
|
||||
import com.netflix.discovery.DiscoveryClient;
|
||||
import com.netflix.discovery.DiscoveryManager;
|
||||
import com.netflix.discovery.EurekaClientConfig;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
@Configuration
|
||||
@EnableConfigurationProperties
|
||||
@ConditionalOnClass(EurekaClientConfig.class)
|
||||
@ConditionalOnExpression("${eureka.client.enabled:true}")
|
||||
public class EurekaClientConfiguration implements SmartLifecycle, Ordered {
|
||||
|
||||
private static final Logger logger = LoggerFactory
|
||||
.getLogger(EurekaClientConfiguration.class);
|
||||
|
||||
private boolean running;
|
||||
|
||||
private int order = 0;
|
||||
|
||||
private int port = 0;
|
||||
|
||||
@Autowired
|
||||
private EurekaClientConfigBean clientConfig;
|
||||
|
||||
@Autowired
|
||||
private EurekaInstanceConfigBean instanceConfig;
|
||||
|
||||
@PreDestroy
|
||||
public void close() {
|
||||
logger.info("Removing application {} from eureka", instanceConfig.getAppname());
|
||||
DiscoveryManager.getInstance().shutdownComponent();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
if (port != 0) {
|
||||
instanceConfig.setNonSecurePort(port);
|
||||
discoveryManagerIntitializer().init();
|
||||
logger.info("Registering application {} with eureka with status UP",
|
||||
instanceConfig.getAppname());
|
||||
ApplicationInfoManager.getInstance().setInstanceStatus(InstanceStatus.UP);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
logger.info("Unregistering application {} with eureka with status OUT_OF_SERVICE",
|
||||
instanceConfig.getAppname());
|
||||
ApplicationInfoManager.getInstance().setInstanceStatus(InstanceStatus.OUT_OF_SERVICE);
|
||||
running = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRunning() {
|
||||
return running;
|
||||
}
|
||||
|
||||
@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 order;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(DiscoveryManagerIntitializer.class)
|
||||
public DiscoveryManagerIntitializer discoveryManagerIntitializer() {
|
||||
return new DiscoveryManagerIntitializer();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Lazy
|
||||
@Scope(proxyMode = ScopedProxyMode.TARGET_CLASS)
|
||||
public DiscoveryClient discoveryClient() {
|
||||
return DiscoveryManager.getInstance().getDiscoveryClient();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
@ConditionalOnBean(MBeanServer.class)
|
||||
public EurekaHealthIndicator eurekaHealthIndicator(MBeanServer server,
|
||||
EurekaInstanceConfig config) {
|
||||
return new EurekaHealthIndicator(discoveryClient(),
|
||||
new ServoMetricReader(server), config);
|
||||
}
|
||||
|
||||
@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
|
||||
EurekaClientConfiguration.this.port = event.getEmbeddedServletContainer()
|
||||
.getPort();
|
||||
EurekaClientConfiguration.this.start();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
-149
@@ -1,149 +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
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.eureka;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cloud.client.DefaultServiceInstance;
|
||||
import org.springframework.cloud.client.ServiceInstance;
|
||||
import org.springframework.cloud.client.discovery.DiscoveryClient;
|
||||
|
||||
import com.netflix.appinfo.InstanceInfo;
|
||||
import com.netflix.discovery.shared.Application;
|
||||
import com.netflix.discovery.shared.Applications;
|
||||
|
||||
import static com.netflix.appinfo.InstanceInfo.PortType.*;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class EurekaDiscoveryClient implements DiscoveryClient {
|
||||
|
||||
public static final String DESCRIPTION = "Spring Cloud Eureka Discovery Client";
|
||||
|
||||
@Autowired
|
||||
private EurekaInstanceConfigBean config;
|
||||
|
||||
@Autowired
|
||||
private com.netflix.discovery.DiscoveryClient discovery;
|
||||
|
||||
@Override
|
||||
public String description() {
|
||||
return DESCRIPTION;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServiceInstance getLocalServiceInstance() {
|
||||
return new ServiceInstance() {
|
||||
@Override
|
||||
public String getServiceId() {
|
||||
return EurekaDiscoveryClient.this.config.getAppname();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHost() {
|
||||
return EurekaDiscoveryClient.this.config.getHostname();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPort() {
|
||||
return EurekaDiscoveryClient.this.config.getNonSecurePort();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSecure() {
|
||||
return EurekaDiscoveryClient.this.config.getSecurePortEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public URI getUri() {
|
||||
return DefaultServiceInstance.getUri(this);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ServiceInstance> getInstances(String serviceId) {
|
||||
List<InstanceInfo> infos = this.discovery.getInstancesByVipAddress(serviceId,
|
||||
false);
|
||||
List<ServiceInstance> instances = new ArrayList<ServiceInstance>();
|
||||
for (InstanceInfo info : infos) {
|
||||
instances.add(new EurekaServiceInstance(info));
|
||||
}
|
||||
return instances;
|
||||
}
|
||||
|
||||
static class EurekaServiceInstance implements ServiceInstance {
|
||||
private InstanceInfo instance;
|
||||
|
||||
EurekaServiceInstance(InstanceInfo instance) {
|
||||
this.instance = instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getServiceId() {
|
||||
return this.instance.getAppName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHost() {
|
||||
return this.instance.getHostName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPort() {
|
||||
// assume if secure is enabled, that is the default
|
||||
if (!this.instance.isPortEnabled(SECURE)) {
|
||||
return this.instance.getPort();
|
||||
}
|
||||
return this.instance.getSecurePort();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSecure() {
|
||||
return this.instance.isPortEnabled(SECURE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public URI getUri() {
|
||||
return DefaultServiceInstance.getUri(this);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getServices() {
|
||||
Applications applications = this.discovery.getApplications();
|
||||
if (applications == null) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
List<Application> registered = applications.getRegisteredApplications();
|
||||
List<String> names = new ArrayList<String>();
|
||||
for (Application app : registered) {
|
||||
if (app.getInstances().isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
names.add(app.getName().toLowerCase());
|
||||
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
}
|
||||
-240
@@ -1,240 +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
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.eureka;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
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.CompositeMetricReader;
|
||||
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 DiscoveryManagerInitializer discoveryManagerInitializer;
|
||||
|
||||
@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) {
|
||||
this.discoveryManagerInitializer.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 DOWN");
|
||||
if (ApplicationInfoManager.getInstance().getInfo() != null) {
|
||||
ApplicationInfoManager.getInstance().setInstanceStatus(
|
||||
InstanceStatus.DOWN);
|
||||
}
|
||||
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) {
|
||||
stop();
|
||||
callback.run();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getOrder() {
|
||||
return this.order;
|
||||
}
|
||||
|
||||
@Configuration
|
||||
protected static class DiscoveryManagerInitializerConfiguration {
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(DiscoveryManagerInitializer.class)
|
||||
public DiscoveryManagerInitializer discoveryManagerInitializer() {
|
||||
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 {
|
||||
|
||||
@Autowired
|
||||
private List<MetricReader> metricReaders = Collections.emptyList();
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public EurekaHealthIndicator eurekaHealthIndicator(
|
||||
com.netflix.discovery.DiscoveryClient eurekaDiscoveryClient, EurekaInstanceConfig config) {
|
||||
CompositeMetricReader metrics = new CompositeMetricReader(this.metricReaders.toArray(new MetricReader[0]));
|
||||
return new EurekaHealthIndicator(eurekaDiscoveryClient, metrics, config);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+17
-23
@@ -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
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* 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,
|
||||
@@ -13,7 +13,6 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.eureka;
|
||||
|
||||
import java.util.Collections;
|
||||
@@ -22,10 +21,10 @@ import java.util.Map;
|
||||
|
||||
import org.springframework.boot.actuate.health.Health;
|
||||
import org.springframework.boot.actuate.health.Health.Builder;
|
||||
import org.springframework.boot.actuate.health.HealthIndicator;
|
||||
import org.springframework.boot.actuate.health.Status;
|
||||
import org.springframework.boot.actuate.metrics.Metric;
|
||||
import org.springframework.boot.actuate.metrics.reader.MetricReader;
|
||||
import org.springframework.cloud.client.discovery.health.DiscoveryHealthIndicator;
|
||||
|
||||
import com.netflix.appinfo.EurekaInstanceConfig;
|
||||
import com.netflix.discovery.DiscoveryClient;
|
||||
@@ -34,17 +33,18 @@ import com.netflix.discovery.shared.Applications;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class EurekaHealthIndicator implements DiscoveryHealthIndicator {
|
||||
public class EurekaHealthIndicator implements HealthIndicator {
|
||||
|
||||
private final DiscoveryClient discovery;
|
||||
private EurekaInstanceConfig instanceConfig;
|
||||
|
||||
private final MetricReader metrics;
|
||||
|
||||
private final EurekaInstanceConfig instanceConfig;
|
||||
private MetricReader metrics;
|
||||
|
||||
private int failCount = 0;
|
||||
|
||||
private DiscoveryClient discovery;
|
||||
|
||||
public EurekaHealthIndicator(DiscoveryClient discovery, MetricReader metrics,
|
||||
EurekaInstanceConfig instanceConfig) {
|
||||
super();
|
||||
@@ -53,11 +53,6 @@ public class EurekaHealthIndicator implements DiscoveryHealthIndicator {
|
||||
this.instanceConfig = instanceConfig;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "eureka";
|
||||
}
|
||||
|
||||
@Override
|
||||
public Health health() {
|
||||
Builder builder = Health.unknown();
|
||||
@@ -67,29 +62,28 @@ public class EurekaHealthIndicator implements DiscoveryHealthIndicator {
|
||||
}
|
||||
|
||||
private Status getStatus(Builder builder) {
|
||||
Status status = new Status(this.discovery.getInstanceRemoteStatus().toString(),
|
||||
Status status = new Status(discovery.getInstanceRemoteStatus().toString(),
|
||||
"Remote status from Eureka server");
|
||||
@SuppressWarnings("unchecked")
|
||||
Metric<Number> value = (Metric<Number>) this.metrics
|
||||
.findOne("counter.servo.discoveryclient_failed");
|
||||
Metric<Number> value = (Metric<Number>) metrics
|
||||
.findOne("counter.servo.DiscoveryClient_Failed");
|
||||
if (value != null) {
|
||||
int renewalPeriod = this.instanceConfig.getLeaseRenewalIntervalInSeconds();
|
||||
int renewalPeriod = instanceConfig.getLeaseRenewalIntervalInSeconds();
|
||||
int latest = value.getValue().intValue();
|
||||
builder.withDetail("failCount", latest);
|
||||
builder.withDetail("renewalPeriod", renewalPeriod);
|
||||
if (this.failCount < latest) {
|
||||
if (failCount < latest) {
|
||||
status = new Status("UP", "Eureka discovery client is reporting failures");
|
||||
this.failCount = latest;
|
||||
}
|
||||
else {
|
||||
status = new Status("UP", "No new failures in Eureka discovery client");
|
||||
failCount = latest;
|
||||
} else {
|
||||
status = new Status("UP", "No new failures in Eureka discovery client");
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
private Map<String, Object> getApplications() {
|
||||
Applications applications = this.discovery.getApplications();
|
||||
Applications applications = discovery.getApplications();
|
||||
if (applications == null) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
|
||||
+44
-67
@@ -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
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* 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,
|
||||
@@ -13,7 +13,6 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.eureka;
|
||||
|
||||
import java.net.InetAddress;
|
||||
@@ -33,121 +32,99 @@ 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)
|
||||
|
||||
@Getter(AccessLevel.PRIVATE) @Setter(AccessLevel.PRIVATE)
|
||||
private String[] hostInfo = initHostInfo();
|
||||
|
||||
@Value("${spring.application.name:unknown}")
|
||||
private String appname = "unknown";
|
||||
private String appname = "unknown";
|
||||
|
||||
private String appGroupName;
|
||||
private String appGroupName;
|
||||
|
||||
private boolean instanceEnabledOnit;
|
||||
|
||||
private boolean instanceEnabledOnit;
|
||||
@Value("${server.port:${SERVER_PORT:${PORT:8080}}}")
|
||||
private int nonSecurePort = 80;
|
||||
|
||||
private int nonSecurePort = 80;
|
||||
private int securePort = 443;
|
||||
|
||||
private int securePort = 443;
|
||||
private boolean nonSecurePortEnabled = true;
|
||||
|
||||
private boolean nonSecurePortEnabled = true;
|
||||
private boolean securePortEnabled;
|
||||
|
||||
private boolean securePortEnabled;
|
||||
private int leaseRenewalIntervalInSeconds = 30;
|
||||
|
||||
private int leaseRenewalIntervalInSeconds = 30;
|
||||
|
||||
private int leaseExpirationDurationInSeconds = 90;
|
||||
private int leaseExpirationDurationInSeconds = 90;
|
||||
|
||||
@Value("${spring.application.name:unknown}")
|
||||
private String virtualHostName;
|
||||
private String virtualHostName;
|
||||
|
||||
private String secureVirtualHostName;
|
||||
private String secureVirtualHostName;
|
||||
|
||||
private String aSGName;
|
||||
private String aSGName;
|
||||
|
||||
private Map<String, String> metadataMap = new HashMap<>();
|
||||
private Map<String, String> metadataMap = new HashMap<>();
|
||||
|
||||
private DataCenterInfo dataCenterInfo = new IdentifyingDataCenterInfo();
|
||||
private DataCenterInfo dataCenterInfo = new DataCenterInfo() {
|
||||
@Getter @Setter
|
||||
private Name name = Name.MyOwn;
|
||||
};
|
||||
|
||||
private String ipAddress = this.hostInfo[0];
|
||||
private String ipAddress = hostInfo[0];
|
||||
|
||||
private String statusPageUrlPath = "/info";
|
||||
private String statusPageUrlPath = "/info";
|
||||
|
||||
private String statusPageUrl;
|
||||
private String statusPageUrl;
|
||||
|
||||
private String homePageUrlPath = "/";
|
||||
private String homePageUrlPath = "/";
|
||||
|
||||
private String homePageUrl;
|
||||
private String homePageUrl;
|
||||
|
||||
private String healthCheckUrlPath = "/health";
|
||||
private String healthCheckUrlPath = "/health";
|
||||
|
||||
private String healthCheckUrl;
|
||||
private String healthCheckUrl;
|
||||
|
||||
private String secureHealthCheckUrl;
|
||||
private String secureHealthCheckUrl;
|
||||
|
||||
private String namespace = "eureka";
|
||||
|
||||
private String hostname = this.hostInfo[1];
|
||||
private String namespace = "eureka";
|
||||
|
||||
private String hostname = hostInfo[1];
|
||||
|
||||
private boolean preferIpAddress = false;
|
||||
|
||||
private InstanceStatus initialStatus = InstanceStatus.UP;
|
||||
|
||||
|
||||
public String getHostname() {
|
||||
return this.preferIpAddress ? this.ipAddress : this.hostname;
|
||||
return preferIpAddress ? ipAddress : hostname;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean getSecurePortEnabled() {
|
||||
return this.securePortEnabled;
|
||||
return 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;
|
||||
info[1] = InetAddress.getLocalHost().getHostName();
|
||||
} catch (UnknownHostException e) {
|
||||
logger.error("Cannot get host info", e);
|
||||
}
|
||||
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();
|
||||
}
|
||||
|
||||
return preferIpAddress ? ipAddress : hostname;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+50
-76
@@ -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
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* 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,
|
||||
@@ -13,29 +13,26 @@
|
||||
* 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 lombok.Data;
|
||||
|
||||
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;
|
||||
@@ -46,13 +43,17 @@ public class EurekaServerConfigBean implements EurekaServerConfig {
|
||||
|
||||
private int eIPBindingRetryIntervalMs = 5 * MINUTES;
|
||||
|
||||
private boolean enableSelfPreservation = true;
|
||||
private boolean enableSelfPreservation = true;
|
||||
@Override
|
||||
public boolean shouldEnableSelfPreservation() {
|
||||
return enableSelfPreservation;
|
||||
}
|
||||
|
||||
private double renewalPercentThreshold = 0.85;
|
||||
|
||||
private int renewalThresholdUpdateIntervalMs = 15 * MINUTES;
|
||||
private int renewalThresholdUpdateIntervalMs = 10 * MINUTES;
|
||||
|
||||
private int peerEurekaNodesUpdateIntervalMs = 10 * MINUTES;
|
||||
private int peerEurekaNodesUpdateIntervalMs = 15 * MINUTES;
|
||||
|
||||
private int numberOfReplicationRetries = 5;
|
||||
|
||||
@@ -84,7 +85,11 @@ public class EurekaServerConfigBean implements EurekaServerConfig {
|
||||
|
||||
private long responseCacheUpdateIntervalMs = 30 * 1000;
|
||||
|
||||
private boolean disableDelta;
|
||||
private boolean disableDelta;
|
||||
@Override
|
||||
public boolean shouldDisableDelta() {
|
||||
return disableDelta;
|
||||
}
|
||||
|
||||
private long maxIdleThreadInMinutesAgeForStatusReplication = 10;
|
||||
|
||||
@@ -94,7 +99,11 @@ public class EurekaServerConfigBean implements EurekaServerConfig {
|
||||
|
||||
private int maxElementsInStatusReplicationPool = 10000;
|
||||
|
||||
private boolean syncWhenTimestampDiffers = true;
|
||||
private boolean syncWhenTimestampDiffers = true;
|
||||
@Override
|
||||
public boolean shouldSyncWhenTimestampDiffers() {
|
||||
return syncWhenTimestampDiffers;
|
||||
}
|
||||
|
||||
private int registrySyncRetries = 5;
|
||||
|
||||
@@ -108,9 +117,17 @@ public class EurekaServerConfigBean implements EurekaServerConfig {
|
||||
|
||||
private int maxTimeForReplication = 30000;
|
||||
|
||||
private boolean primeAwsReplicaConnections = true;
|
||||
private boolean primeAwsReplicaConnections = true;
|
||||
@Override
|
||||
public boolean shouldPrimeAwsReplicaConnections() {
|
||||
return primeAwsReplicaConnections;
|
||||
}
|
||||
|
||||
private boolean disableDeltaForRemoteRegions;
|
||||
private boolean disableDeltaForRemoteRegions;
|
||||
@Override
|
||||
public boolean shouldDisableDeltaForRemoteRegions() {
|
||||
return disableDeltaForRemoteRegions;
|
||||
}
|
||||
|
||||
private int remoteRegionConnectTimeoutMs = 1000;
|
||||
|
||||
@@ -122,13 +139,26 @@ public class EurekaServerConfigBean implements EurekaServerConfig {
|
||||
|
||||
private int remoteRegionConnectionIdleTimeoutSeconds = 30;
|
||||
|
||||
private boolean gZipContentFromRemoteRegion = true;
|
||||
private boolean gZipContentFromRemoteRegion = true;
|
||||
@Override
|
||||
public boolean shouldGZipContentFromRemoteRegion() {
|
||||
return gZipContentFromRemoteRegion;
|
||||
}
|
||||
|
||||
private Map<String, String> remoteRegionUrlsWithName = new HashMap<String, String>();
|
||||
|
||||
private String[] remoteRegionUrls;
|
||||
private String[] remoteRegionUrls;
|
||||
|
||||
private Map<String, Set<String>> remoteRegionAppWhitelist;
|
||||
@Override
|
||||
public Set<String> getRemoteRegionAppWhitelist(String regionName) {
|
||||
if (null == regionName) {
|
||||
regionName = "global";
|
||||
} else {
|
||||
regionName = regionName.trim().toLowerCase();
|
||||
}
|
||||
return remoteRegionAppWhitelist.get(regionName);
|
||||
}
|
||||
|
||||
private int remoteRegionRegistryFetchInterval = 30;
|
||||
|
||||
@@ -137,72 +167,16 @@ public class EurekaServerConfigBean implements EurekaServerConfig {
|
||||
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;
|
||||
return disableTransparentFallbackToOtherRegion;
|
||||
}
|
||||
|
||||
private boolean batchReplication;
|
||||
|
||||
@Override
|
||||
public boolean shouldBatchReplication() {
|
||||
return this.batchReplication;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean shouldLogIdentityHeaders() {
|
||||
return this.logIdentityHeaders;
|
||||
return batchReplication;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
+9
-7
@@ -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
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* 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,
|
||||
@@ -13,8 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.eureka.server.advice;
|
||||
package org.springframework.cloud.netflix.eureka.advice;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
@@ -24,11 +23,11 @@ import org.springframework.util.ReflectionUtils;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
public class PiggybackMethodInterceptor implements MethodInterceptor {
|
||||
|
||||
private Object delegate;
|
||||
|
||||
private Class<?>[] types;
|
||||
|
||||
public PiggybackMethodInterceptor(Object delegate, Class<?>... types) {
|
||||
@@ -44,10 +43,10 @@ public class PiggybackMethodInterceptor implements MethodInterceptor {
|
||||
}
|
||||
|
||||
private void invokeAfter(Method method, Object[] arguments) throws Exception {
|
||||
for (Class<?> type : this.types) {
|
||||
for (Class<?> type : types) {
|
||||
Method target = getTarget(type, method);
|
||||
if (target != null) {
|
||||
target.invoke(this.delegate, arguments);
|
||||
target.invoke(delegate, arguments);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -56,7 +55,10 @@ public class PiggybackMethodInterceptor implements MethodInterceptor {
|
||||
private Method getTarget(Class<?> type, Method method) {
|
||||
Method target = ReflectionUtils.findMethod(type, method.getName(),
|
||||
method.getParameterTypes());
|
||||
return target;
|
||||
if (target != null) {
|
||||
return target;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
package org.springframework.cloud.netflix.eureka.event;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper=false)
|
||||
@SuppressWarnings("serial")
|
||||
public class EurekaInstanceCanceledEvent extends ApplicationEvent {
|
||||
private String appName;
|
||||
private String serverId;
|
||||
boolean replication;
|
||||
|
||||
public EurekaInstanceCanceledEvent(Object source, String appName, String serverId, boolean replication) {
|
||||
super(source);
|
||||
this.appName = appName;
|
||||
this.serverId = serverId;
|
||||
this.replication = replication;
|
||||
}
|
||||
}
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
package org.springframework.cloud.netflix.eureka.event;
|
||||
|
||||
import com.netflix.appinfo.InstanceInfo;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper=false)
|
||||
@SuppressWarnings("serial")
|
||||
public class EurekaInstanceRegisteredEvent extends ApplicationEvent {
|
||||
private InstanceInfo instanceInfo;
|
||||
private int leaseDuration;
|
||||
boolean replication;
|
||||
|
||||
public EurekaInstanceRegisteredEvent(Object source, InstanceInfo instanceInfo, int leaseDuration, boolean replication) {
|
||||
super(source);
|
||||
this.instanceInfo = instanceInfo;
|
||||
this.leaseDuration = leaseDuration;
|
||||
this.replication = replication;
|
||||
}
|
||||
}
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
package org.springframework.cloud.netflix.eureka.event;
|
||||
|
||||
import com.netflix.appinfo.InstanceInfo;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper=false)
|
||||
@SuppressWarnings("serial")
|
||||
public class EurekaInstanceRenewedEvent extends ApplicationEvent {
|
||||
private String appName;
|
||||
private String serverId;
|
||||
private InstanceInfo instanceInfo;
|
||||
boolean replication;
|
||||
|
||||
public EurekaInstanceRenewedEvent(Object source, String appName, String serverId, InstanceInfo instanceInfo, boolean replication) {
|
||||
super(source);
|
||||
this.appName = appName;
|
||||
this.serverId = serverId;
|
||||
this.instanceInfo = instanceInfo;
|
||||
this.replication = replication;
|
||||
}
|
||||
}
|
||||
+3
-3
@@ -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
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* 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,
|
||||
@@ -13,8 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.eureka.server.event;
|
||||
package org.springframework.cloud.netflix.eureka.event;
|
||||
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
|
||||
@@ -22,6 +21,7 @@ import com.netflix.eureka.EurekaServerConfig;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class EurekaRegistryAvailableEvent extends ApplicationEvent {
|
||||
+3
-3
@@ -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
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* 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,
|
||||
@@ -13,8 +13,7 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.eureka.server.event;
|
||||
package org.springframework.cloud.netflix.eureka.event;
|
||||
|
||||
import org.springframework.context.ApplicationEvent;
|
||||
|
||||
@@ -22,6 +21,7 @@ import com.netflix.eureka.EurekaServerConfig;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
@SuppressWarnings("serial")
|
||||
public class EurekaServerStartedEvent extends ApplicationEvent {
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
package org.springframework.cloud.netflix.eureka.event;
|
||||
|
||||
import static com.google.common.collect.Iterables.tryFind;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
import com.google.common.base.Predicate;
|
||||
import com.netflix.appinfo.InstanceInfo;
|
||||
import com.netflix.discovery.shared.Application;
|
||||
import com.netflix.eureka.PeerAwareInstanceRegistry;
|
||||
import com.netflix.eureka.lease.LeaseManager;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class LeaseManagerMessageBroker implements LeaseManager<InstanceInfo> {
|
||||
private static final Logger logger = LoggerFactory.getLogger(LeaseManagerMessageBroker.class);
|
||||
|
||||
@Autowired
|
||||
private ApplicationContext ctxt;
|
||||
|
||||
@Override
|
||||
public void register(InstanceInfo info, int leaseDuration, boolean isReplication) {
|
||||
logger.debug("register {}, vip {}, leaseDuration {}, isReplication {}",
|
||||
info.getAppName(), info.getVIPAddress(), leaseDuration, isReplication);
|
||||
//TODO: what to publish from info (whole object?)
|
||||
ctxt.publishEvent(new EurekaInstanceRegisteredEvent(this, info, leaseDuration, isReplication));
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean cancel(String appName, String serverId, boolean isReplication) {
|
||||
logger.debug("cancel {}, serverId {}, isReplication {}", appName, serverId, isReplication);
|
||||
ctxt.publishEvent(new EurekaInstanceCanceledEvent(this, appName, serverId, isReplication));
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean renew(final String appName, final String serverId, boolean isReplication) {
|
||||
logger.debug("renew {}, serverId {}, isReplication {}", appName, serverId, isReplication);
|
||||
List<Application> applications = PeerAwareInstanceRegistry.getInstance().getSortedApplications();
|
||||
Optional<Application> app = tryFind(applications, new Predicate<Application>() {
|
||||
@Override
|
||||
public boolean apply(@Nullable Application input) {
|
||||
return input.getName().equals(appName);
|
||||
}
|
||||
});
|
||||
|
||||
if (app.isPresent()) {
|
||||
Optional<InstanceInfo> info = tryFind(app.get().getInstances(), new Predicate<InstanceInfo>() {
|
||||
@Override
|
||||
public boolean apply(@Nullable InstanceInfo input) {
|
||||
return input.getHostName().equals(serverId);
|
||||
}
|
||||
});
|
||||
ctxt.publishEvent(new EurekaInstanceRenewedEvent(this, appName, serverId, info.orNull(), isReplication));
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void evict() {}
|
||||
}
|
||||
-74
@@ -1,74 +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
|
||||
*
|
||||
* 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.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
/**
|
||||
* Scans for interfaces that declare they are feign clients (via {@link FeignClient
|
||||
* <code>@FeignClient</code>}). Configures component scanning directives for use with
|
||||
* {@link org.springframework.context.annotation.Configuration
|
||||
* <code>@Configuration</code>} classes.
|
||||
*
|
||||
* @author Spencer Gibb
|
||||
* @author Dave Syer
|
||||
* @since 1.0
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.TYPE)
|
||||
@Documented
|
||||
@Import({ FeignClientsConfiguration.class, FeignClientsRegistrar.class })
|
||||
public @interface EnableFeignClients {
|
||||
|
||||
/**
|
||||
* Alias for the {@link #basePackages()} attribute. Allows for more concise annotation
|
||||
* declarations e.g.: {@code @ComponentScan("org.my.pkg")} instead of
|
||||
* {@code @ComponentScan(basePackages="org.my.pkg")}.
|
||||
* @return the array of 'basePackages'.
|
||||
*/
|
||||
String[] value() default {};
|
||||
|
||||
/**
|
||||
* Base packages to scan for annotated components.
|
||||
* <p>
|
||||
* {@link #value()} is an alias for (and mutually exclusive with) this attribute.
|
||||
* <p>
|
||||
* Use {@link #basePackageClasses()} for a type-safe alternative to String-based
|
||||
* package names.
|
||||
*
|
||||
* @return the array of 'basePackages'.
|
||||
*/
|
||||
String[] basePackages() default {};
|
||||
|
||||
/**
|
||||
* Type-safe alternative to {@link #basePackages()} for specifying the packages to
|
||||
* scan for annotated components. The package of each class specified will be scanned.
|
||||
* <p>
|
||||
* Consider creating a special no-op marker class or interface in each package that
|
||||
* serves no purpose other than being referenced by this attribute.
|
||||
*
|
||||
* @return the array of 'basePackageClasses'.
|
||||
*/
|
||||
Class<?>[] basePackageClasses() default {};
|
||||
|
||||
}
|
||||
+23
-24
@@ -1,37 +1,36 @@
|
||||
/*
|
||||
* 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 feign.Contract;
|
||||
import feign.Logger;
|
||||
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.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import feign.Feign;
|
||||
import org.springframework.cloud.netflix.archaius.ArchaiusAutoConfiguration;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
* @author Julien Roy
|
||||
*/
|
||||
@Configuration
|
||||
@ConditionalOnClass(Feign.class)
|
||||
@AutoConfigureAfter(ArchaiusAutoConfiguration.class)
|
||||
@Import(FeignClientsConfiguration.class)
|
||||
public class FeignAutoConfiguration {
|
||||
@Bean
|
||||
SpringDecoder feignDecoder() {
|
||||
return new SpringDecoder();
|
||||
}
|
||||
|
||||
@Bean
|
||||
SpringEncoder feignEncoder() {
|
||||
return new SpringEncoder();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Logger feignLogger() {
|
||||
//return new Slf4jLogger(); //TODO pass Client classname in
|
||||
return new Logger.JavaLogger();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Contract feignContract() {
|
||||
return new SpringMvcContract();
|
||||
}
|
||||
}
|
||||
|
||||
+103
@@ -0,0 +1,103 @@
|
||||
package org.springframework.cloud.netflix.feign;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.xml.transform.Source;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.converter.ByteArrayHttpMessageConverter;
|
||||
import org.springframework.http.converter.HttpMessageConverter;
|
||||
import org.springframework.http.converter.ResourceHttpMessageConverter;
|
||||
import org.springframework.http.converter.StringHttpMessageConverter;
|
||||
import org.springframework.http.converter.feed.AtomFeedHttpMessageConverter;
|
||||
import org.springframework.http.converter.feed.RssChannelHttpMessageConverter;
|
||||
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
|
||||
import org.springframework.http.converter.support.AllEncompassingFormHttpMessageConverter;
|
||||
import org.springframework.http.converter.xml.Jaxb2RootElementHttpMessageConverter;
|
||||
import org.springframework.http.converter.xml.SourceHttpMessageConverter;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class FeignBase {
|
||||
public static final boolean romePresent =
|
||||
ClassUtils.isPresent("com.sun.syndication.feed.WireFeed", FeignBase.class.getClassLoader());
|
||||
|
||||
public static final boolean jaxb2Present =
|
||||
ClassUtils.isPresent("javax.xml.bind.Binder", FeignBase.class.getClassLoader());
|
||||
|
||||
public static final boolean jackson2Present =
|
||||
ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper", FeignBase.class.getClassLoader()) &&
|
||||
ClassUtils.isPresent("com.fasterxml.jackson.core.JsonGenerator", FeignBase.class.getClassLoader());
|
||||
|
||||
public static final boolean jacksonPresent =
|
||||
ClassUtils.isPresent("org.codehaus.jackson.map.ObjectMapper", FeignBase.class.getClassLoader()) &&
|
||||
ClassUtils.isPresent("org.codehaus.jackson.JsonGenerator", FeignBase.class.getClassLoader());
|
||||
|
||||
protected final List<HttpMessageConverter<?>> messageConverters = new ArrayList<HttpMessageConverter<?>>();
|
||||
|
||||
public FeignBase() {
|
||||
addDefaultConverters(messageConverters);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new instance of the {@link SpringDecoder} using the given list of
|
||||
* {@link HttpMessageConverter} to use
|
||||
* @param messageConverters the list of {@link HttpMessageConverter} to use
|
||||
*/
|
||||
public FeignBase(List<HttpMessageConverter<?>> messageConverters) {
|
||||
Assert.notEmpty(messageConverters, "'messageConverters' must not be empty");
|
||||
this.messageConverters.addAll(messageConverters);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
protected void addDefaultConverters(List<HttpMessageConverter<?>> messageConverters) {
|
||||
messageConverters.add(new ByteArrayHttpMessageConverter());
|
||||
messageConverters.add(new StringHttpMessageConverter());
|
||||
messageConverters.add(new ResourceHttpMessageConverter());
|
||||
messageConverters.add(new SourceHttpMessageConverter<Source>());
|
||||
messageConverters.add(new AllEncompassingFormHttpMessageConverter());
|
||||
|
||||
if (romePresent) {
|
||||
messageConverters.add(new AtomFeedHttpMessageConverter());
|
||||
messageConverters.add(new RssChannelHttpMessageConverter());
|
||||
}
|
||||
if (jaxb2Present) {
|
||||
messageConverters.add(new Jaxb2RootElementHttpMessageConverter());
|
||||
}
|
||||
if (jackson2Present) {
|
||||
messageConverters.add(new MappingJackson2HttpMessageConverter());
|
||||
}
|
||||
else if (jacksonPresent) {
|
||||
messageConverters.add(new org.springframework.http.converter.json.MappingJacksonHttpMessageConverter());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the message body converters to use.
|
||||
* <p>These converters are used to convert from and to HTTP requests and responses.
|
||||
*/
|
||||
public void setMessageConverters(List<HttpMessageConverter<?>> messageConverters) {
|
||||
Assert.notEmpty(messageConverters, "'messageConverters' must not be empty");
|
||||
this.messageConverters.clear();
|
||||
this.messageConverters.addAll(messageConverters);
|
||||
}
|
||||
|
||||
public List<HttpMessageConverter<?>> getMessageConverters() {
|
||||
return messageConverters;
|
||||
}
|
||||
|
||||
protected HttpHeaders getHttpHeaders(Map<String, Collection<String>> headers) {
|
||||
HttpHeaders httpHeaders = new HttpHeaders();
|
||||
for (Map.Entry<String, Collection<String>> entry : headers.entrySet()) {
|
||||
httpHeaders.put(entry.getKey(), new ArrayList<>(entry.getValue()));
|
||||
}
|
||||
return httpHeaders;
|
||||
}
|
||||
|
||||
}
|
||||
-55
@@ -1,55 +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
|
||||
*
|
||||
* 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.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
/**
|
||||
* 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
|
||||
* used to load balance the backend requests, and the load balancer can be configured
|
||||
* using a <code>@RibbonClient</code> with the same name (i.e. value) as the feign client.
|
||||
*
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface FeignClient {
|
||||
|
||||
/**
|
||||
* The serviceId with optional protocol prefix. Synonym for {@link #serviceId()
|
||||
* serviceId}. Either serviceId or url must be specified but not both.
|
||||
*/
|
||||
String value() default "";
|
||||
|
||||
/**
|
||||
* The serviceId with optional protocol prefix. Synonym for {@link #value() value}.
|
||||
* Either serviceId or url must be specified but not both.
|
||||
*/
|
||||
String serviceId() default "";
|
||||
|
||||
/**
|
||||
* An absolute URL or resolvable hostname (the protocol is optional).
|
||||
*/
|
||||
String url() default "";
|
||||
|
||||
}
|
||||
-155
@@ -1,155 +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
|
||||
*
|
||||
* 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.util.Map;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.FactoryBean;
|
||||
import org.springframework.beans.factory.InitializingBean;
|
||||
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import feign.Client;
|
||||
import feign.Contract;
|
||||
import feign.Feign;
|
||||
import feign.Logger;
|
||||
import feign.Request;
|
||||
import feign.RequestInterceptor;
|
||||
import feign.Retryer;
|
||||
import feign.codec.Decoder;
|
||||
import feign.codec.Encoder;
|
||||
import feign.codec.ErrorDecoder;
|
||||
import feign.slf4j.Slf4jLogger;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
class FeignClientFactoryBean implements FactoryBean<Object>, InitializingBean, ApplicationContextAware {
|
||||
|
||||
private Class<?> type;
|
||||
|
||||
private String name;
|
||||
|
||||
private String url;
|
||||
|
||||
private ApplicationContext context;
|
||||
|
||||
@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");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext context) throws BeansException {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
protected Feign.Builder feign() {
|
||||
// @formatter:off
|
||||
Feign.Builder builder = Feign.builder()
|
||||
// required values
|
||||
.logger(get(Logger.class))
|
||||
.encoder(get(Encoder.class))
|
||||
.decoder(get(Decoder.class))
|
||||
.contract(get(Contract.class));
|
||||
// @formatter:on
|
||||
|
||||
// optional values
|
||||
Logger.Level level = getOptional(Logger.Level.class);
|
||||
if (level != null) {
|
||||
builder.logLevel(level);
|
||||
}
|
||||
Retryer retryer = getOptional(Retryer.class);
|
||||
if (retryer != null) {
|
||||
builder.retryer(retryer);
|
||||
}
|
||||
ErrorDecoder errorDecoder = getOptional(ErrorDecoder.class);
|
||||
if (errorDecoder != null) {
|
||||
builder.errorDecoder(errorDecoder);
|
||||
}
|
||||
Request.Options options = getOptional(Request.Options.class);
|
||||
if (options != null) {
|
||||
builder.options(options);
|
||||
}
|
||||
Map<String, RequestInterceptor> requestInterceptors = this.context.getBeansOfType(RequestInterceptor.class);
|
||||
if (requestInterceptors != null) {
|
||||
builder.requestInterceptors(requestInterceptors.values());
|
||||
}
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
protected <T> T get(Class<T> type) {
|
||||
return this.context.getBean(type);
|
||||
}
|
||||
|
||||
protected <T> T getOptional(Class<T> type) {
|
||||
try {
|
||||
return this.context.getBean(type);
|
||||
} catch (NoSuchBeanDefinitionException e) {
|
||||
//ignore
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected <T> T loadBalance(Feign.Builder builder, Class<T> type, String schemeName) {
|
||||
builder.logger(new Slf4jLogger(type)); // TODO: how to have choice here?
|
||||
Client client = getOptional(Client.class);
|
||||
if (client != null) {
|
||||
return builder.client(client).target(type, schemeName);
|
||||
}
|
||||
|
||||
throw new IllegalStateException("No Feign Client for loadBalancing defined. Did you forget to include spring-cloud-starter-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);
|
||||
}
|
||||
if (StringUtils.hasText(this.url) && !this.url.startsWith("http")) {
|
||||
this.url = "http://" + this.url;
|
||||
}
|
||||
return feign().target(this.type, this.url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class<?> getObjectType() {
|
||||
return this.type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSingleton() {
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
-64
@@ -1,64 +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
|
||||
*
|
||||
* 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.beans.factory.ObjectFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
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 feign.Contract;
|
||||
import feign.Logger;
|
||||
import feign.codec.Decoder;
|
||||
import feign.codec.Encoder;
|
||||
import feign.slf4j.Slf4jLogger;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@Configuration
|
||||
public class FeignClientsConfiguration {
|
||||
|
||||
@Autowired
|
||||
private ObjectFactory<HttpMessageConverters> messageConverters;
|
||||
|
||||
@Bean
|
||||
public Decoder feignDecoder() {
|
||||
return new ResponseEntityDecoder(new SpringDecoder(messageConverters));
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Encoder feignEncoder() {
|
||||
return new SpringEncoder(messageConverters);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Logger feignLogger() {
|
||||
return new Slf4jLogger();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public Contract feignContract() {
|
||||
return new SpringMvcContract();
|
||||
}
|
||||
|
||||
}
|
||||
-200
@@ -1,200 +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
|
||||
*
|
||||
* 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.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
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.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.context.ResourceLoaderAware;
|
||||
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
|
||||
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
import org.springframework.core.type.AnnotationMetadata;
|
||||
import org.springframework.core.type.filter.AnnotationTypeFilter;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ClassUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class FeignClientsRegistrar implements ImportBeanDefinitionRegistrar,
|
||||
ResourceLoaderAware, BeanClassLoaderAware {
|
||||
|
||||
// patterned after Spring Integration IntegrationComponentScanRegistrar
|
||||
|
||||
private ResourceLoader resourceLoader;
|
||||
|
||||
private ClassLoader classLoader;
|
||||
|
||||
public FeignClientsRegistrar() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setResourceLoader(ResourceLoader resourceLoader) {
|
||||
this.resourceLoader = resourceLoader;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setBeanClassLoader(ClassLoader classLoader) {
|
||||
this.classLoader = classLoader;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata,
|
||||
BeanDefinitionRegistry registry) {
|
||||
|
||||
Set<String> basePackages = getBasePackages(importingClassMetadata);
|
||||
|
||||
ClassPathScanningCandidateComponentProvider scanner = getScanner();
|
||||
scanner.addIncludeFilter(new AnnotationTypeFilter(FeignClient.class));
|
||||
scanner.setResourceLoader(this.resourceLoader);
|
||||
|
||||
for (String basePackage : basePackages) {
|
||||
Set<BeanDefinition> candidateComponents = scanner
|
||||
.findCandidateComponents(basePackage);
|
||||
for (BeanDefinition candidateComponent : candidateComponents) {
|
||||
if (candidateComponent instanceof AnnotatedBeanDefinition) {
|
||||
// verify annotated class is an interface
|
||||
AnnotatedBeanDefinition beanDefinition = (AnnotatedBeanDefinition) candidateComponent;
|
||||
AnnotationMetadata annotationMetadata = beanDefinition.getMetadata();
|
||||
Assert.isTrue(annotationMetadata.isInterface(),
|
||||
"@FeignClient can only be specified on an interface");
|
||||
|
||||
BeanDefinitionHolder holder = createBeanDefinition(annotationMetadata);
|
||||
BeanDefinitionReaderUtils.registerBeanDefinition(holder, registry);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private BeanDefinitionHolder createBeanDefinition(
|
||||
AnnotationMetadata annotationMetadata) {
|
||||
Map<String, Object> attributes = annotationMetadata
|
||||
.getAnnotationAttributes(FeignClient.class.getCanonicalName());
|
||||
|
||||
String className = annotationMetadata.getClassName();
|
||||
BeanDefinitionBuilder definition = BeanDefinitionBuilder
|
||||
.genericBeanDefinition(FeignClientFactoryBean.class);
|
||||
validate(attributes);
|
||||
definition.addPropertyValue("url", getUrl(attributes));
|
||||
definition.addPropertyValue("name", getServiceId(attributes));
|
||||
definition.addPropertyValue("type", className);
|
||||
|
||||
String beanName = StringUtils.uncapitalize(className.substring(className
|
||||
.lastIndexOf(".") + 1));
|
||||
return new BeanDefinitionHolder(definition.getBeanDefinition(), beanName);
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
||||
private String getServiceId(Map<String, Object> attributes) {
|
||||
String name = (String) attributes.get("name");
|
||||
if (!StringUtils.hasText(name)) {
|
||||
name = (String) attributes.get("value");
|
||||
}
|
||||
if (!StringUtils.hasText(name)) {
|
||||
return "";
|
||||
}
|
||||
String host = null;
|
||||
try {
|
||||
host = new URI("http://" + name).getHost();
|
||||
}
|
||||
catch (URISyntaxException e) {
|
||||
}
|
||||
Assert.state(host != null, "Service id not legal hostname (" + name + ")");
|
||||
return name;
|
||||
}
|
||||
|
||||
private String getUrl(Map<String, Object> attributes) {
|
||||
return (String) attributes.get("url");
|
||||
}
|
||||
|
||||
protected ClassPathScanningCandidateComponentProvider getScanner() {
|
||||
return new ClassPathScanningCandidateComponentProvider(false) {
|
||||
|
||||
@Override
|
||||
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])) {
|
||||
try {
|
||||
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);
|
||||
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
protected Set<String> getBasePackages(AnnotationMetadata importingClassMetadata) {
|
||||
Map<String, Object> attributes = importingClassMetadata
|
||||
.getAnnotationAttributes(EnableFeignClients.class.getCanonicalName());
|
||||
|
||||
Set<String> basePackages = new HashSet<>();
|
||||
for (String pkg : (String[]) attributes.get("value")) {
|
||||
if (StringUtils.hasText(pkg)) {
|
||||
basePackages.add(pkg);
|
||||
}
|
||||
}
|
||||
for (String pkg : (String[]) attributes.get("basePackages")) {
|
||||
if (StringUtils.hasText(pkg)) {
|
||||
basePackages.add(pkg);
|
||||
}
|
||||
}
|
||||
for (Class<?> clazz : (Class[]) attributes.get("basePackageClasses")) {
|
||||
basePackages.add(ClassUtils.getPackageName(clazz));
|
||||
}
|
||||
|
||||
if (basePackages.isEmpty()) {
|
||||
basePackages.add(ClassUtils.getPackageName(importingClassMetadata
|
||||
.getClassName()));
|
||||
}
|
||||
return basePackages;
|
||||
}
|
||||
|
||||
}
|
||||
+59
@@ -0,0 +1,59 @@
|
||||
package org.springframework.cloud.netflix.feign;
|
||||
|
||||
import feign.Contract;
|
||||
import feign.Feign;
|
||||
import feign.Logger;
|
||||
import feign.codec.Decoder;
|
||||
import feign.codec.Encoder;
|
||||
import feign.ribbon.LoadBalancingTarget;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cloud.netflix.ribbon.ServerListInitializer;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.cloud.netflix.archaius.ConfigurableEnvironmentConfiguration;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
@Configuration
|
||||
public class FeignConfigurer {
|
||||
@Autowired
|
||||
ConfigurableEnvironmentConfiguration envConfig; //FIXME: howto enforce this?
|
||||
|
||||
@Autowired
|
||||
ServerListInitializer serverListInitializer;
|
||||
|
||||
@Autowired
|
||||
Decoder decoder;
|
||||
|
||||
@Autowired
|
||||
Encoder encoder;
|
||||
|
||||
@Autowired
|
||||
Logger logger;
|
||||
|
||||
@Autowired
|
||||
Contract contract;
|
||||
|
||||
protected Feign.Builder feign() {
|
||||
//ConfigurationManager.getConfigInstance().setProperty("exampleBackend.ribbon.listOfServers", "localhost:7080");
|
||||
//exampleBackend.ribbon.NIWSServerListClassName=my.package.MyServerList
|
||||
return Feign.builder()
|
||||
.logger(logger)
|
||||
.encoder(encoder)
|
||||
.decoder(decoder)
|
||||
.contract(contract);
|
||||
}
|
||||
|
||||
protected <T> T loadBalance(Class<T> type, String schemeName) {
|
||||
return loadBalance(feign(), type, schemeName);
|
||||
}
|
||||
|
||||
protected <T> T loadBalance(Feign.Builder builder, Class<T> type, String schemeName) {
|
||||
String name = URI.create(schemeName).getHost();
|
||||
serverListInitializer.initialize(name);
|
||||
return builder.target(LoadBalancingTarget.create(type, schemeName));
|
||||
}
|
||||
|
||||
}
|
||||
+88
@@ -0,0 +1,88 @@
|
||||
package org.springframework.cloud.netflix.feign;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.client.ClientHttpResponse;
|
||||
import org.springframework.http.converter.HttpMessageConverter;
|
||||
import org.springframework.web.client.HttpMessageConverterExtractor;
|
||||
|
||||
import feign.FeignException;
|
||||
import feign.Response;
|
||||
import feign.codec.DecodeException;
|
||||
import feign.codec.Decoder;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class SpringDecoder extends FeignBase implements Decoder {
|
||||
|
||||
public SpringDecoder() {
|
||||
}
|
||||
|
||||
public SpringDecoder(List<HttpMessageConverter<?>> messageConverters) {
|
||||
super(messageConverters);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object decode(final Response response, Type type) throws IOException,
|
||||
DecodeException, FeignException {
|
||||
if (type instanceof Class) {
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
HttpMessageConverterExtractor<?> extractor = new HttpMessageConverterExtractor(
|
||||
(Class<?>) type, getMessageConverters());
|
||||
|
||||
Object data = extractor.extractData(new FeignResponseAdapter(response));
|
||||
return data;
|
||||
}
|
||||
throw new DecodeException("type is not an instance of Class: " + type);
|
||||
}
|
||||
|
||||
private class FeignResponseAdapter implements ClientHttpResponse {
|
||||
private final Response response;
|
||||
|
||||
private FeignResponseAdapter(Response response) {
|
||||
this.response = response;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpStatus getStatusCode() throws IOException {
|
||||
return HttpStatus.valueOf(response.status());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRawStatusCode() throws IOException {
|
||||
return response.status();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStatusText() throws IOException {
|
||||
return response.reason();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
try {
|
||||
response.body().close();
|
||||
}
|
||||
catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getBody() throws IOException {
|
||||
return response.body().asInputStream();
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpHeaders getHeaders() {
|
||||
return getHttpHeaders(response.headers());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
+36
-59
@@ -1,57 +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.feign;
|
||||
|
||||
package org.springframework.cloud.netflix.feign.support;
|
||||
|
||||
import static org.springframework.cloud.netflix.feign.support.FeignUtils.getHttpHeaders;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.lang.reflect.Type;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Collection;
|
||||
|
||||
import lombok.extern.apachecommons.CommonsLog;
|
||||
|
||||
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.HttpMessageConverter;
|
||||
import com.google.common.base.Charsets;
|
||||
|
||||
import feign.RequestTemplate;
|
||||
import feign.codec.EncodeException;
|
||||
import feign.codec.Encoder;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpOutputMessage;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.converter.HttpMessageConverter;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
@CommonsLog
|
||||
public class SpringEncoder implements Encoder {
|
||||
public class SpringEncoder extends FeignBase implements Encoder {
|
||||
private static final Logger logger = LoggerFactory.getLogger(SpringEncoder.class);
|
||||
|
||||
private ObjectFactory<HttpMessageConverters> messageConverters;
|
||||
public SpringEncoder() {
|
||||
}
|
||||
|
||||
public SpringEncoder(ObjectFactory<HttpMessageConverters> messageConverters) {
|
||||
this.messageConverters = messageConverters;
|
||||
public SpringEncoder(List<HttpMessageConverter<?>> messageConverters) {
|
||||
super(messageConverters);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void encode(Object requestBody, Type bodyType, RequestTemplate request)
|
||||
public void encode(Object requestBody, RequestTemplate request)
|
||||
throws EncodeException {
|
||||
// template.body(conversionService.convert(object, String.class));
|
||||
if (requestBody != null) {
|
||||
@@ -64,17 +46,16 @@ public class SpringEncoder implements Encoder {
|
||||
requestContentType = MediaType.valueOf(type);
|
||||
}
|
||||
|
||||
for (HttpMessageConverter<?> messageConverter : this.messageConverters
|
||||
.getObject().getConverters()) {
|
||||
for (HttpMessageConverter<?> messageConverter : getMessageConverters()) {
|
||||
if (messageConverter.canWrite(requestType, requestContentType)) {
|
||||
if (log.isDebugEnabled()) {
|
||||
if (logger.isDebugEnabled()) {
|
||||
if (requestContentType != null) {
|
||||
log.debug("Writing [" + requestBody + "] as \""
|
||||
logger.debug("Writing [" + requestBody + "] as \""
|
||||
+ requestContentType + "\" using ["
|
||||
+ messageConverter + "]");
|
||||
}
|
||||
else {
|
||||
log.debug("Writing [" + requestBody + "] using ["
|
||||
logger.debug("Writing [" + requestBody + "] using ["
|
||||
+ messageConverter + "]");
|
||||
}
|
||||
|
||||
@@ -86,16 +67,16 @@ public class SpringEncoder implements Encoder {
|
||||
HttpMessageConverter<Object> copy = (HttpMessageConverter<Object>) messageConverter;
|
||||
copy.write(requestBody, requestContentType, outputMessage);
|
||||
}
|
||||
catch (IOException ex) {
|
||||
throw new EncodeException("Error converting request body", ex);
|
||||
catch (IOException e) {
|
||||
throw new EncodeException("Error converting request body", e);
|
||||
}
|
||||
request.body(outputMessage.getOutputStream().toByteArray(),
|
||||
Charset.forName("UTF-8")); // TODO: set charset
|
||||
Charsets.UTF_8); // TODO: set charset
|
||||
return;
|
||||
}
|
||||
}
|
||||
String message = "Could not write request: no suitable HttpMessageConverter "
|
||||
+ "found for request type [" + requestType.getName() + "]";
|
||||
String message = "Could not write request: no suitable HttpMessageConverter found for request type ["
|
||||
+ requestType.getName() + "]";
|
||||
if (requestContentType != null) {
|
||||
message += " and content type [" + requestContentType + "]";
|
||||
}
|
||||
@@ -104,10 +85,8 @@ public class SpringEncoder implements Encoder {
|
||||
}
|
||||
|
||||
private class FeignOutputMessage implements HttpOutputMessage {
|
||||
|
||||
private final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
|
||||
private final RequestTemplate request;
|
||||
final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
|
||||
RequestTemplate request;
|
||||
|
||||
private FeignOutputMessage(RequestTemplate request) {
|
||||
this.request = request;
|
||||
@@ -115,18 +94,16 @@ public class SpringEncoder implements Encoder {
|
||||
|
||||
@Override
|
||||
public OutputStream getBody() throws IOException {
|
||||
return this.outputStream;
|
||||
return outputStream;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpHeaders getHeaders() {
|
||||
return getHttpHeaders(this.request.headers());
|
||||
return getHttpHeaders(request.headers());
|
||||
}
|
||||
|
||||
public ByteArrayOutputStream getOutputStream() {
|
||||
return this.outputStream;
|
||||
return outputStream;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+84
@@ -0,0 +1,84 @@
|
||||
package org.springframework.cloud.netflix.feign;
|
||||
|
||||
import static feign.Util.checkState;
|
||||
import static feign.Util.emptyToNull;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
|
||||
import feign.Contract;
|
||||
import feign.MethodMetadata;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class SpringMvcContract extends Contract.BaseContract {
|
||||
static final String ACCEPT = "Accept";
|
||||
static final String CONTENT_TYPE = "Content-Type";
|
||||
|
||||
@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());
|
||||
|
||||
//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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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", method.getName(), fieldName,
|
||||
values == null ? null : Arrays.asList(values));
|
||||
}
|
||||
|
||||
private void checkOne(Method method, Object[] values, String fieldName) {
|
||||
checkState(values != null && values.length == 1,
|
||||
"Method %s can only contain 1 %s field. Found: %s", method.getName(), fieldName,
|
||||
values == null ? null : Arrays.asList(values));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean processAnnotationsOnParameter(MethodMetadata data, Annotation[] annotations, int paramIndex) {
|
||||
//TODO: support spring parameter annotations?
|
||||
return false;
|
||||
}
|
||||
}
|
||||
-47
@@ -1,47 +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
|
||||
*
|
||||
* 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.ribbon.LBClient;
|
||||
import feign.ribbon.LBClientFactory;
|
||||
import org.springframework.util.ConcurrentReferenceHashMap;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* LBClientFactory that caches entries created.
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class CachingLBClientFactory implements LBClientFactory {
|
||||
|
||||
private volatile Map<String, LBClient> cache = new ConcurrentReferenceHashMap<>();
|
||||
private final LBClientFactory delegate;
|
||||
|
||||
public CachingLBClientFactory(LBClientFactory delegate) {
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LBClient create(String clientName) {
|
||||
if (cache.containsKey(clientName)) {
|
||||
return cache.get(clientName);
|
||||
}
|
||||
LBClient client = delegate.create(clientName);
|
||||
cache.put(clientName, client);
|
||||
return client;
|
||||
}
|
||||
}
|
||||
-63
@@ -1,63 +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
|
||||
*
|
||||
* 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.ribbon.RibbonClient;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.cloud.netflix.feign.FeignAutoConfiguration;
|
||||
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import com.netflix.loadbalancer.ILoadBalancer;
|
||||
|
||||
import feign.Client;
|
||||
import feign.Feign;
|
||||
|
||||
/**
|
||||
* Autoconfiguration to be activated if Feign is in use and needs to be use Ribbon as a
|
||||
* load balancer.
|
||||
*
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@ConditionalOnClass({ ILoadBalancer.class, Feign.class })
|
||||
@Configuration
|
||||
@AutoConfigureBefore(FeignAutoConfiguration.class)
|
||||
public class FeignRibbonClientAutoConfiguration {
|
||||
|
||||
@Autowired
|
||||
private SpringClientFactory factory;
|
||||
|
||||
@Bean
|
||||
public SpringLBClientFactory springLBClientFactory() {
|
||||
return new SpringLBClientFactory(factory);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public CachingLBClientFactory cachingLBClientFactory() {
|
||||
return new CachingLBClientFactory(springLBClientFactory());
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public Client feignRibbonClient() {
|
||||
return RibbonClient.builder().lbClientFactory(cachingLBClientFactory()).build();
|
||||
}
|
||||
}
|
||||
-164
@@ -1,164 +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
|
||||
*
|
||||
* 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 java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
import com.netflix.client.AbstractLoadBalancerAwareClient;
|
||||
import com.netflix.client.ClientException;
|
||||
import com.netflix.client.ClientRequest;
|
||||
import com.netflix.client.IResponse;
|
||||
import com.netflix.client.RequestSpecificRetryHandler;
|
||||
import com.netflix.client.RetryHandler;
|
||||
import com.netflix.client.config.CommonClientConfigKey;
|
||||
import com.netflix.client.config.IClientConfig;
|
||||
import com.netflix.loadbalancer.ILoadBalancer;
|
||||
|
||||
import feign.Client;
|
||||
import feign.Request;
|
||||
import feign.RequestTemplate;
|
||||
import feign.Response;
|
||||
|
||||
public class RibbonLoadBalancer
|
||||
extends
|
||||
AbstractLoadBalancerAwareClient<RibbonLoadBalancer.RibbonRequest, RibbonLoadBalancer.RibbonResponse> {
|
||||
|
||||
private final Client delegate;
|
||||
|
||||
private final int connectTimeout;
|
||||
|
||||
private final int readTimeout;
|
||||
|
||||
private final IClientConfig clientConfig;
|
||||
|
||||
public RibbonLoadBalancer(Client delegate, ILoadBalancer lb,
|
||||
IClientConfig clientConfig) {
|
||||
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);
|
||||
}
|
||||
|
||||
@Override
|
||||
public RibbonResponse execute(RibbonRequest request, IClientConfig configOverride)
|
||||
throws IOException {
|
||||
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);
|
||||
}
|
||||
Response response = this.delegate.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)) {
|
||||
return new RequestSpecificRetryHandler(true, true, this.getRetryHandler(),
|
||||
requestConfig);
|
||||
}
|
||||
if (!request.toRequest().method().equals("GET")) {
|
||||
return new RequestSpecificRetryHandler(true, false, this.getRetryHandler(),
|
||||
requestConfig);
|
||||
}
|
||||
else {
|
||||
return new RequestSpecificRetryHandler(true, true, this.getRetryHandler(),
|
||||
requestConfig);
|
||||
}
|
||||
}
|
||||
|
||||
static class RibbonRequest extends ClientRequest implements Cloneable {
|
||||
|
||||
private final Request request;
|
||||
|
||||
RibbonRequest(Request request, URI uri) {
|
||||
this.request = request;
|
||||
setUri(uri);
|
||||
}
|
||||
|
||||
Request toRequest() {
|
||||
return new RequestTemplate().method(this.request.method())
|
||||
.append(getUri().toASCIIString()).headers(this.request.headers())
|
||||
.body(this.request.body(), this.request.charset()).request();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object clone() {
|
||||
return new RibbonRequest(this.request, getUri());
|
||||
}
|
||||
}
|
||||
|
||||
static class RibbonResponse implements IResponse {
|
||||
|
||||
private final URI uri;
|
||||
private final Response response;
|
||||
|
||||
RibbonResponse(URI uri, Response response) {
|
||||
this.uri = uri;
|
||||
this.response = response;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getPayload() throws ClientException {
|
||||
return this.response.body();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPayload() {
|
||||
return this.response.body() != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSuccess() {
|
||||
return this.response.status() == 200;
|
||||
}
|
||||
|
||||
@Override
|
||||
public URI getRequestedURI() {
|
||||
return this.uri;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Collection<String>> getHeaders() {
|
||||
return this.response.headers();
|
||||
}
|
||||
|
||||
Response toResponse() {
|
||||
return this.response;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
if (this.response != null && this.response.body() != null) {
|
||||
this.response.body().close();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
-42
@@ -1,42 +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
|
||||
*
|
||||
* 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 com.netflix.client.config.IClientConfig;
|
||||
import com.netflix.loadbalancer.ILoadBalancer;
|
||||
import feign.ribbon.LBClient;
|
||||
import feign.ribbon.LBClientFactory;
|
||||
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class SpringLBClientFactory implements LBClientFactory {
|
||||
|
||||
private final SpringClientFactory factory;
|
||||
|
||||
public SpringLBClientFactory(SpringClientFactory factory) {
|
||||
this.factory = factory;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LBClient create(String clientName) {
|
||||
IClientConfig config = factory.getClientConfig(clientName);
|
||||
ILoadBalancer lb = factory.getLoadBalancer(clientName);
|
||||
return LBClient.create(lb, config);
|
||||
}
|
||||
}
|
||||
-38
@@ -1,38 +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
|
||||
*
|
||||
* 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.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.http.HttpHeaders;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class FeignUtils {
|
||||
|
||||
static HttpHeaders getHttpHeaders(Map<String, Collection<String>> headers) {
|
||||
HttpHeaders httpHeaders = new HttpHeaders();
|
||||
for (Map.Entry<String, Collection<String>> entry : headers.entrySet()) {
|
||||
httpHeaders.put(entry.getKey(), new ArrayList<>(entry.getValue()));
|
||||
}
|
||||
return httpHeaders;
|
||||
}
|
||||
|
||||
}
|
||||
-70
@@ -1,70 +0,0 @@
|
||||
|
||||
package org.springframework.cloud.netflix.feign.support;
|
||||
|
||||
import feign.FeignException;
|
||||
import feign.Response;
|
||||
import feign.codec.Decoder;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.ResponseEntity;
|
||||
import org.springframework.util.LinkedMultiValueMap;
|
||||
import org.springframework.util.MultiValueMap;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.ParameterizedType;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.LinkedList;
|
||||
|
||||
/**
|
||||
* Decoder adds compatibility for Spring MVC's ResponseEntity to any
|
||||
* other decoder via composition.
|
||||
* @author chadjaros
|
||||
*/
|
||||
@Slf4j
|
||||
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(type instanceof ParameterizedType &&
|
||||
((ParameterizedType) type).getRawType().equals(ResponseEntity.class)) {
|
||||
|
||||
type = ((ParameterizedType) type).getActualTypeArguments()[0];
|
||||
Object decodedObject = decoder.decode(response, type);
|
||||
|
||||
Class<?> clazz = null;
|
||||
if (decodedObject != null) {
|
||||
clazz = decodedObject.getClass();
|
||||
}
|
||||
return createResponse(
|
||||
clazz,
|
||||
decodedObject,
|
||||
response);
|
||||
}
|
||||
else {
|
||||
return decoder.decode(response, type);
|
||||
}
|
||||
}
|
||||
|
||||
private <T> ResponseEntity<T> createResponse(Class<T> clazz, 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)));
|
||||
}
|
||||
|
||||
T retVal = null;
|
||||
if (clazz != null && instance != null) {
|
||||
retVal = clazz.cast(instance);
|
||||
}
|
||||
return new ResponseEntity<>(retVal, headers,
|
||||
HttpStatus.valueOf(response.status()));
|
||||
}
|
||||
}
|
||||
-108
@@ -1,108 +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
|
||||
*
|
||||
* 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 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 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 feign.FeignException;
|
||||
import feign.Response;
|
||||
import feign.codec.DecodeException;
|
||||
import feign.codec.Decoder;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class SpringDecoder implements Decoder {
|
||||
|
||||
private ObjectFactory<HttpMessageConverters> messageConverters;
|
||||
|
||||
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) {
|
||||
@SuppressWarnings({ "unchecked", "rawtypes" })
|
||||
HttpMessageConverterExtractor<?> extractor = new HttpMessageConverterExtractor(
|
||||
type, this.messageConverters.getObject().getConverters());
|
||||
|
||||
return extractor.extractData(new FeignResponseAdapter(response));
|
||||
}
|
||||
throw new DecodeException(
|
||||
"type is not an instance of Class or ParameterizedType: " + type);
|
||||
}
|
||||
|
||||
private class FeignResponseAdapter implements ClientHttpResponse {
|
||||
|
||||
private final Response response;
|
||||
|
||||
private FeignResponseAdapter(Response response) {
|
||||
this.response = response;
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpStatus getStatusCode() throws IOException {
|
||||
return HttpStatus.valueOf(this.response.status());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRawStatusCode() throws IOException {
|
||||
return this.response.status();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStatusText() throws IOException {
|
||||
return this.response.reason();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
try {
|
||||
this.response.body().close();
|
||||
}
|
||||
catch (IOException ex) {
|
||||
// Ignore exception on close...
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getBody() throws IOException {
|
||||
return this.response.body().asInputStream();
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpHeaders getHeaders() {
|
||||
return getHttpHeaders(this.response.headers());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
-225
@@ -1,225 +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
|
||||
*
|
||||
* 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 feign.Contract;
|
||||
import feign.MethodMetadata;
|
||||
import org.springframework.web.bind.annotation.PathVariable;
|
||||
import org.springframework.web.bind.annotation.RequestHeader;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Map;
|
||||
|
||||
import static feign.Util.checkState;
|
||||
import static feign.Util.emptyToNull;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class SpringMvcContract extends Contract.BaseContract {
|
||||
|
||||
private static final String ACCEPT = "Accept";
|
||||
|
||||
private static final String CONTENT_TYPE = "Content-Type";
|
||||
|
||||
@Override
|
||||
public MethodMetadata parseAndValidatateMetadata(Method method) {
|
||||
MethodMetadata md = super.parseAndValidatateMetadata(method);
|
||||
|
||||
RequestMapping classAnnotation = method.getDeclaringClass().getAnnotation(RequestMapping.class);
|
||||
if (classAnnotation != null) {
|
||||
// Prepend path from class annotation if specified
|
||||
if (classAnnotation.value().length > 0) {
|
||||
String pathValue = emptyToNull(classAnnotation.value()[0]);
|
||||
checkState(pathValue != null, "RequestMapping.value() was empty on type %s",
|
||||
method.getDeclaringClass().getName());
|
||||
if (!pathValue.startsWith("/")) {
|
||||
pathValue = "/" + pathValue;
|
||||
}
|
||||
md.template().insert(0, pathValue);
|
||||
}
|
||||
|
||||
// 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 (!(methodAnnotation instanceof RequestMapping)) {
|
||||
return;
|
||||
}
|
||||
|
||||
RequestMapping methodMapping = RequestMapping.class.cast(methodAnnotation);
|
||||
// HTTP Method
|
||||
checkOne(method, methodMapping.method(), "method");
|
||||
data.template().method(methodMapping.method()[0].name());
|
||||
|
||||
// path
|
||||
checkAtMostOne(method, methodMapping.value(), "value");
|
||||
if(methodMapping.value().length > 0) {
|
||||
String pathValue = emptyToNull(methodMapping.value()[0]);
|
||||
if (pathValue != null) {
|
||||
// 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);
|
||||
}
|
||||
|
||||
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",
|
||||
method.getName(), fieldName,
|
||||
values == null ? null : Arrays.asList(values));
|
||||
}
|
||||
|
||||
private void checkOne(Method method, Object[] values, String fieldName) {
|
||||
checkState(values != null && values.length == 1,
|
||||
"Method %s can only contain 1 %s field. Found: %s", method.getName(),
|
||||
fieldName, values == null ? null : Arrays.asList(values));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean processAnnotationsOnParameter(MethodMetadata data,
|
||||
Annotation[] annotations, int paramIndex) {
|
||||
boolean isHttpAnnotation = false;
|
||||
// TODO: support spring parameter annotations?
|
||||
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);
|
||||
}
|
||||
}
|
||||
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; }
|
||||
*/
|
||||
|
||||
}
|
||||
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;
|
||||
}
|
||||
for (Collection<V> entry : values) {
|
||||
if (entry.contains(search)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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 colon = header.indexOf(':');
|
||||
md.template().header(header.substring(0, colon),
|
||||
header.substring(colon + 2));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+32
-33
@@ -1,45 +1,44 @@
|
||||
/*
|
||||
* 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.hystrix;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Inherited;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import org.springframework.context.annotation.AdviceMode;
|
||||
import org.springframework.context.annotation.Import;
|
||||
import org.springframework.core.Ordered;
|
||||
|
||||
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
|
||||
import java.lang.annotation.*;
|
||||
|
||||
/**
|
||||
* Convenience annotation for clients to enable Hystrix circuit breakers (specifically).
|
||||
* Use this (optionally) in case you want discovery and know for sure that it is Hystrix
|
||||
* you want. All it does is turn on circuit breakers and let the autoconfiguration find
|
||||
* the Hystrix classes if they are available (i.e. you need Hystrix on the classpath as
|
||||
* well).
|
||||
*
|
||||
* @author Dave Syer
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@Inherited
|
||||
@EnableCircuitBreaker
|
||||
@Import(HystrixConfigurationSelector.class)
|
||||
public @interface EnableHystrix {
|
||||
/**
|
||||
* Indicate whether subclass-based (CGLIB) proxies are to be created ({@code true}) as
|
||||
* opposed to standard Java interface-based proxies ({@code false}). The default is
|
||||
* {@code false}. <strong>Applicable only if {@link #mode()} is set to
|
||||
* {@link org.springframework.context.annotation.AdviceMode#PROXY}</strong>.
|
||||
* <p>Note that setting this attribute to {@code true} will affect <em>all</em>
|
||||
* Spring-managed beans requiring proxying, not just those marked with
|
||||
* {@code @Transactional}. For example, other beans marked with Spring's
|
||||
* {@code @Async} annotation will be upgraded to subclass proxying at the same
|
||||
* time. This approach has no negative impact in practice unless one is explicitly
|
||||
* expecting one type of proxy vs another, e.g. in tests.
|
||||
*/
|
||||
boolean proxyTargetClass() default false;
|
||||
|
||||
}
|
||||
/**
|
||||
* Indicate how transactional advice should be applied. The default is
|
||||
* {@link org.springframework.context.annotation.AdviceMode#PROXY}.
|
||||
* @see org.springframework.context.annotation.AdviceMode
|
||||
*/
|
||||
AdviceMode mode() default AdviceMode.PROXY;
|
||||
|
||||
/**
|
||||
* Indicate the ordering of the execution of the transaction advisor
|
||||
* when multiple advices are applied at a specific joinpoint.
|
||||
* The default is {@link org.springframework.core.Ordered#LOWEST_PRECEDENCE}.
|
||||
*/
|
||||
int order() default Ordered.LOWEST_PRECEDENCE;
|
||||
}
|
||||
-61
@@ -1,61 +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
|
||||
*
|
||||
* 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.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.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import com.netflix.hystrix.Hystrix;
|
||||
|
||||
/**
|
||||
* Auto configuration for Hystrix.
|
||||
*
|
||||
* @author Christian Dupuis
|
||||
*/
|
||||
@Configuration
|
||||
@ConditionalOnClass({ Hystrix.class, HealthIndicator.class })
|
||||
@AutoConfigureAfter({ HealthIndicatorAutoConfiguration.class })
|
||||
@ConditionalOnProperty(value = "health.hystrix.enabled", matchIfMissing = true)
|
||||
public class HystrixAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
public HystrixHealthIndicator hystrixHealthIndicator() {
|
||||
return new HystrixHealthIndicator();
|
||||
}
|
||||
|
||||
@ConfigurationProperties("health.hystrix")
|
||||
public static class Health {
|
||||
/**
|
||||
* Flag to inidicate that the hystrix health indicator should be installed.
|
||||
*/
|
||||
boolean enabled;
|
||||
|
||||
public boolean isEnabled() {
|
||||
return enabled;
|
||||
}
|
||||
|
||||
public void setEnabled(boolean enabled) {
|
||||
this.enabled = enabled;
|
||||
}
|
||||
}
|
||||
}
|
||||
+47
-69
@@ -1,87 +1,84 @@
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
* 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 java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import org.apache.catalina.core.ApplicationContext;
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.actuate.endpoint.Endpoint;
|
||||
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.context.SmartLifecycle;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.ImportAware;
|
||||
import org.springframework.core.Ordered;
|
||||
import org.springframework.core.annotation.AnnotationAttributes;
|
||||
import org.springframework.core.type.AnnotationMetadata;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.CollectionUtils;
|
||||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import com.netflix.hystrix.Hystrix;
|
||||
import com.netflix.hystrix.contrib.javanica.aop.aspectj.HystrixCommandAspect;
|
||||
import com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsPoller;
|
||||
import com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsPoller.MetricsAsJsonPollerListener;
|
||||
import com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsStreamServlet;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
* @author Christian Dupuis
|
||||
*/
|
||||
@Configuration
|
||||
public class HystrixCircuitBreakerConfiguration {
|
||||
public class HystrixConfiguration implements ImportAware {
|
||||
|
||||
private AnnotationAttributes enableHystrix;
|
||||
|
||||
@Bean
|
||||
public HystrixCommandAspect hystrixCommandAspect() {
|
||||
HystrixCommandAspect hystrixCommandAspect() {
|
||||
return new HystrixCommandAspect();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public HystrixShutdownHook hystrixShutdownHook() {
|
||||
return new HystrixShutdownHook();
|
||||
// TODO: add enable/disable
|
||||
// TODO: make it @ConditionalOnWebApp (need a nested class)
|
||||
public HystrixStreamEndpoint hystrixStreamEndpoint() {
|
||||
return new HystrixStreamEndpoint();
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnProperty(value = "hystrix.stream.endpoint.enabled", matchIfMissing = true)
|
||||
@ConditionalOnWebApplication
|
||||
@ConditionalOnClass({ Endpoint.class, HystrixMetricsStreamServlet.class })
|
||||
protected static class HystrixWebConfiguration {
|
||||
@Override
|
||||
public void setImportMetadata(AnnotationMetadata importMetadata) {
|
||||
this.enableHystrix = AnnotationAttributes.fromMap(importMetadata
|
||||
.getAnnotationAttributes(EnableHystrix.class.getName(), false));
|
||||
Assert.notNull(
|
||||
this.enableHystrix,
|
||||
"@EnableHystrix is not present on importing class "
|
||||
+ importMetadata.getClassName());
|
||||
}
|
||||
|
||||
@Bean
|
||||
public HystrixStreamEndpoint hystrixStreamEndpoint() {
|
||||
return new HystrixStreamEndpoint();
|
||||
@Autowired(required = false)
|
||||
void setConfigurers(Collection<HystrixConfigurer> configurers) {
|
||||
if (CollectionUtils.isEmpty(configurers)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (configurers.size() > 1) {
|
||||
throw new IllegalStateException(
|
||||
"Only one HystrixConfigurer may exist");
|
||||
}
|
||||
// TODO: create CircuitBreakerConfigurer API
|
||||
// CircuitBreakerConfigurer configurer = configurers.iterator().next();
|
||||
// this.txManager = configurer.annotationDrivenTransactionManager();
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnClass({ HystrixMetricsPoller.class, GaugeService.class })
|
||||
@ConditionalOnClass(GaugeService.class)
|
||||
protected static class HystrixMetricsPollerConfiguration implements SmartLifecycle {
|
||||
|
||||
private static Log logger = LogFactory
|
||||
.getLog(HystrixMetricsPollerConfiguration.class);
|
||||
|
||||
@Autowired(required = false)
|
||||
@Autowired
|
||||
private GaugeService gauges;
|
||||
|
||||
private ObjectMapper mapper = new ObjectMapper();
|
||||
@@ -93,29 +90,25 @@ public class HystrixCircuitBreakerConfiguration {
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
if (this.gauges == null) {
|
||||
return;
|
||||
}
|
||||
MetricsAsJsonPollerListener listener = new MetricsAsJsonPollerListener() {
|
||||
@Override
|
||||
public void handleJsonMetric(String json) {
|
||||
try {
|
||||
@SuppressWarnings("unchecked")
|
||||
Map<String, Object> map = HystrixMetricsPollerConfiguration.this.mapper
|
||||
.readValue(json, Map.class);
|
||||
Map<String, Object> map = mapper.readValue(json, Map.class);
|
||||
if (map != null && map.containsKey("type")) {
|
||||
addMetrics(map, "hystrix.");
|
||||
}
|
||||
}
|
||||
catch (IOException ex) {
|
||||
catch (IOException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
this.poller = new HystrixMetricsPoller(listener, 2000);
|
||||
poller = new HystrixMetricsPoller(listener, 2000);
|
||||
// start polling and it will write directly to the listener
|
||||
this.poller.start();
|
||||
poller.start();
|
||||
logger.info("Starting poller");
|
||||
}
|
||||
|
||||
@@ -131,10 +124,10 @@ public class HystrixCircuitBreakerConfiguration {
|
||||
String prefix = prefixBuilder.toString();
|
||||
for (String key : map.keySet()) {
|
||||
Object value = map.get(key);
|
||||
if (!this.reserved.contains(key)) {
|
||||
if (!reserved.contains(key)) {
|
||||
if (value instanceof Number) {
|
||||
String name = prefix + "." + key;
|
||||
this.gauges.submit(name, ((Number) value).doubleValue());
|
||||
gauges.submit(name, ((Number) value).doubleValue());
|
||||
}
|
||||
else if (value instanceof Map) {
|
||||
@SuppressWarnings("unchecked")
|
||||
@@ -147,14 +140,14 @@ public class HystrixCircuitBreakerConfiguration {
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
if (this.poller != null) {
|
||||
this.poller.shutdown();
|
||||
if (poller != null) {
|
||||
poller.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRunning() {
|
||||
return this.poller != null ? this.poller.isRunning() : false;
|
||||
return poller!=null ? poller.isRunning() : false;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -169,26 +162,11 @@ public class HystrixCircuitBreakerConfiguration {
|
||||
|
||||
@Override
|
||||
public void stop(Runnable callback) {
|
||||
if (this.poller != null) {
|
||||
this.poller.shutdown();
|
||||
if (poller != null) {
|
||||
poller.shutdown();
|
||||
}
|
||||
callback.run();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* {@link DisposableBean} that makes sure that Hystrix internal state is cleared when
|
||||
* {@link ApplicationContext} shuts down.
|
||||
*/
|
||||
private class HystrixShutdownHook implements DisposableBean {
|
||||
|
||||
@Override
|
||||
public void destroy() throws Exception {
|
||||
// Just call Hystrix to reset thread pool etc.
|
||||
Hystrix.reset();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
package org.springframework.cloud.netflix.hystrix;
|
||||
|
||||
import org.springframework.context.annotation.AdviceMode;
|
||||
import org.springframework.context.annotation.AdviceModeImportSelector;
|
||||
import org.springframework.context.annotation.AutoProxyRegistrar;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class HystrixConfigurationSelector extends AdviceModeImportSelector<EnableHystrix> {
|
||||
/**
|
||||
* The name of the AspectJ transaction management @{@code Configuration} class.
|
||||
*/
|
||||
private static final String TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME =
|
||||
"org.springframework.transaction.aspectj.AspectJTransactionManagementConfiguration";
|
||||
|
||||
@Override
|
||||
protected String[] selectImports(AdviceMode adviceMode) {
|
||||
switch (adviceMode) {
|
||||
case PROXY:
|
||||
return new String[]{AutoProxyRegistrar.class.getName(), HystrixConfiguration.class.getName()};
|
||||
case ASPECTJ:
|
||||
return new String[]{TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME};
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
+7
@@ -0,0 +1,7 @@
|
||||
package org.springframework.cloud.netflix.hystrix;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public interface HystrixConfigurer {
|
||||
}
|
||||
-26
@@ -1,26 +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
|
||||
*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public interface HystrixConstants {
|
||||
|
||||
String HYSTRIX_STREAM_NAME = "spring.cloud.hystrix.stream";
|
||||
|
||||
}
|
||||
-68
@@ -1,68 +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
|
||||
*
|
||||
* 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 java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.boot.actuate.health.AbstractHealthIndicator;
|
||||
import org.springframework.boot.actuate.health.Health.Builder;
|
||||
import org.springframework.boot.actuate.health.HealthIndicator;
|
||||
import org.springframework.boot.actuate.health.Status;
|
||||
|
||||
import com.netflix.hystrix.HystrixCircuitBreaker;
|
||||
import com.netflix.hystrix.HystrixCommandMetrics;
|
||||
|
||||
/**
|
||||
* A {@link HealthIndicator} implementation for Hystrix circuit breakers.
|
||||
* <p>
|
||||
* This default implementation will not change the system state (e.g. <code>OK</code>) but
|
||||
* includes all open circuits by name.
|
||||
*
|
||||
* @author Christian Dupuis
|
||||
*/
|
||||
public class HystrixHealthIndicator extends AbstractHealthIndicator {
|
||||
|
||||
private static final Status CIRCUIT_OPEN = new Status("CIRCUIT_OPEN");
|
||||
|
||||
@Override
|
||||
protected void doHealthCheck(Builder builder) throws Exception {
|
||||
List<String> openCircuitBreakers = new ArrayList<String>();
|
||||
|
||||
// Collect all open circuit breakers from Hystrix
|
||||
for (HystrixCommandMetrics metrics : HystrixCommandMetrics.getInstances()) {
|
||||
HystrixCircuitBreaker circuitBreaker = HystrixCircuitBreaker.Factory
|
||||
.getInstance(metrics.getCommandKey());
|
||||
if (circuitBreaker != null && circuitBreaker.isOpen()) {
|
||||
openCircuitBreakers.add(metrics.getCommandGroup().name() + "::"
|
||||
+ metrics.getCommandKey().name());
|
||||
}
|
||||
}
|
||||
|
||||
// If there is at least one open circuit report OUT_OF_SERVICE adding the command
|
||||
// group
|
||||
// and key name
|
||||
if (openCircuitBreakers.size() > 0) {
|
||||
builder.status(CIRCUIT_OPEN).withDetail("openCircuitBreakers",
|
||||
openCircuitBreakers);
|
||||
}
|
||||
else {
|
||||
builder.up();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+6
-22
@@ -1,19 +1,3 @@
|
||||
/*
|
||||
* 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
|
||||
*
|
||||
* 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.cloud.netflix.endpoint.ServletWrappingEndpoint;
|
||||
@@ -21,13 +5,13 @@ import org.springframework.cloud.netflix.endpoint.ServletWrappingEndpoint;
|
||||
import com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsStreamServlet;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
* User: spencergibb
|
||||
* Date: 4/22/14
|
||||
* Time: 3:16 PM
|
||||
*/
|
||||
public class HystrixStreamEndpoint extends ServletWrappingEndpoint {
|
||||
|
||||
public HystrixStreamEndpoint() {
|
||||
super(HystrixMetricsStreamServlet.class, "hystrixStream", "/hystrix.stream",
|
||||
false, true);
|
||||
}
|
||||
|
||||
public HystrixStreamEndpoint() {
|
||||
super(HystrixMetricsStreamServlet.class, "hystrixStream", "hystrix.stream", false, true);
|
||||
}
|
||||
}
|
||||
|
||||
+37
-79
@@ -1,94 +1,52 @@
|
||||
/*
|
||||
* 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.ribbon;
|
||||
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
|
||||
import org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration;
|
||||
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 java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
|
||||
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalancerAutoConfiguration;
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
|
||||
import org.springframework.cloud.client.loadbalancer.RestTemplateCustomizer;
|
||||
import org.springframework.cloud.netflix.eureka.EurekaClientAutoConfiguration;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.web.client.RestTemplate;
|
||||
|
||||
import com.netflix.client.IClient;
|
||||
import com.netflix.client.http.HttpRequest;
|
||||
|
||||
/**
|
||||
* Auto configuration for Ribbon (client side load balancing).
|
||||
*
|
||||
* @author Spencer Gibb
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@Configuration
|
||||
@ConditionalOnClass({ IClient.class, RestTemplate.class })
|
||||
@RibbonClients
|
||||
@AutoConfigureAfter(EurekaClientAutoConfiguration.class)
|
||||
@AutoConfigureBefore(LoadBalancerAutoConfiguration.class)
|
||||
public class RibbonAutoConfiguration {
|
||||
|
||||
@Autowired(required = false)
|
||||
private List<RibbonClientSpecification> configurations = new ArrayList<>();
|
||||
|
||||
|
||||
@Bean
|
||||
public SpringClientFactory springClientFactory() {
|
||||
SpringClientFactory factory = new SpringClientFactory();
|
||||
factory.setConfigurations(this.configurations);
|
||||
return factory;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(LoadBalancerClient.class)
|
||||
public LoadBalancerClient loadBalancerClient() {
|
||||
return new RibbonLoadBalancerClient(springClientFactory());
|
||||
}
|
||||
|
||||
@Configuration
|
||||
@ConditionalOnClass(HttpRequest.class)
|
||||
protected static class RibbonClientConfig {
|
||||
|
||||
@Autowired
|
||||
private SpringClientFactory springClientFactory;
|
||||
|
||||
@Autowired
|
||||
private LoadBalancerClient loadBalancerClient;
|
||||
|
||||
@Bean
|
||||
public RestTemplateCustomizer restTemplateCustomizer() {
|
||||
return new RestTemplateCustomizer() {
|
||||
@Override
|
||||
public void customize(RestTemplate restTemplate) {
|
||||
restTemplate.setRequestFactory(ribbonClientHttpRequestFactory());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RibbonClientHttpRequestFactory ribbonClientHttpRequestFactory() {
|
||||
return new RibbonClientHttpRequestFactory(springClientFactory, loadBalancerClient);
|
||||
}
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(RestTemplate.class)
|
||||
public RestTemplate restTemplate(RibbonInterceptor ribbonInterceptor) {
|
||||
RestTemplate restTemplate = new RestTemplate();
|
||||
List<ClientHttpRequestInterceptor> list = new ArrayList<>();
|
||||
list.add(ribbonInterceptor);
|
||||
restTemplate.setInterceptors(list);
|
||||
return restTemplate;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean(LoadBalancerClient.class)
|
||||
public LoadBalancerClient loadBalancerClient() {
|
||||
return new RibbonLoadBalancerClient();
|
||||
}
|
||||
|
||||
@Bean
|
||||
public RibbonInterceptor ribbonInterceptor(LoadBalancerClient loadBalancerClient) {
|
||||
return new RibbonInterceptor(loadBalancerClient);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public ServerListInitializer serverListInitializer() {
|
||||
return new ServerListInitializer() {
|
||||
@Override
|
||||
public void initialize(String serviceId) {
|
||||
//no-op
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
-68
@@ -1,68 +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
|
||||
*
|
||||
* 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.ribbon;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
import com.netflix.loadbalancer.ILoadBalancer;
|
||||
import com.netflix.loadbalancer.IRule;
|
||||
import com.netflix.loadbalancer.ServerListFilter;
|
||||
|
||||
/**
|
||||
* Declarative configuration for a ribbon client. Add this annotation to any
|
||||
* <code>@Configuration</code> and then inject a {@link SpringClientFactory} to access the
|
||||
* client that is created.
|
||||
*
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@Configuration
|
||||
@Import(RibbonClientConfigurationRegistrar.class)
|
||||
@Target(ElementType.TYPE)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
public @interface RibbonClient {
|
||||
|
||||
/**
|
||||
* Synonym for name (the name of the client)
|
||||
*
|
||||
* @see #name()
|
||||
*/
|
||||
String value() default "";
|
||||
|
||||
/**
|
||||
* The name of the ribbon client, uniquely identifying a set of client resources,
|
||||
* including a load balancer.
|
||||
*/
|
||||
String name() default "";
|
||||
|
||||
/**
|
||||
* A custom <code>@Configuration</code> for the ribbon client. Can contain override
|
||||
* <code>@Bean</code> definition for the pieces that make up the client, for instance
|
||||
* {@link ILoadBalancer}, {@link ServerListFilter}, {@link IRule}.
|
||||
*
|
||||
* @see RibbonClientConfiguration for the defaults
|
||||
*/
|
||||
Class<?>[] configuration() default {};
|
||||
|
||||
}
|
||||
-157
@@ -1,157 +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
|
||||
*
|
||||
* 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.ribbon;
|
||||
|
||||
import org.apache.http.client.params.ClientPNames;
|
||||
import org.apache.http.client.params.CookiePolicy;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Lazy;
|
||||
|
||||
import com.netflix.client.config.DefaultClientConfigImpl;
|
||||
import com.netflix.client.config.IClientConfig;
|
||||
import com.netflix.loadbalancer.ConfigurationBasedServerList;
|
||||
import com.netflix.loadbalancer.ILoadBalancer;
|
||||
import com.netflix.loadbalancer.IPing;
|
||||
import com.netflix.loadbalancer.IRule;
|
||||
import com.netflix.loadbalancer.LoadBalancerBuilder;
|
||||
import com.netflix.loadbalancer.NoOpPing;
|
||||
import com.netflix.loadbalancer.Server;
|
||||
import com.netflix.loadbalancer.ServerList;
|
||||
import com.netflix.loadbalancer.ServerListFilter;
|
||||
import com.netflix.loadbalancer.ZoneAvoidanceRule;
|
||||
import com.netflix.loadbalancer.ZoneAwareLoadBalancer;
|
||||
import com.netflix.niws.client.http.RestClient;
|
||||
import com.netflix.servo.monitor.Monitors;
|
||||
import com.sun.jersey.api.client.Client;
|
||||
import com.sun.jersey.client.apache4.ApacheHttpClient4;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@SuppressWarnings("deprecation")
|
||||
@Configuration
|
||||
@EnableConfigurationProperties
|
||||
public class RibbonClientConfiguration {
|
||||
|
||||
@Value("${ribbon.client.name}")
|
||||
private String name = "client";
|
||||
|
||||
// TODO: maybe re-instate autowired load balancers: identified by name they could be
|
||||
// associated with ribbon clients
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public IClientConfig ribbonClientConfig() {
|
||||
DefaultClientConfigImpl config = new DefaultClientConfigImpl();
|
||||
config.loadProperties(this.name);
|
||||
return config;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public IRule ribbonRule(IClientConfig config) {
|
||||
ZoneAvoidanceRule rule = new ZoneAvoidanceRule();
|
||||
rule.initWithNiwsConfig(config);
|
||||
return rule;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public IPing ribbonPing(IClientConfig config) {
|
||||
// TODO: use PingUrl
|
||||
return new NoOpPing();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public ServerList<Server> ribbonServerList(IClientConfig config) {
|
||||
ConfigurationBasedServerList serverList = new ConfigurationBasedServerList();
|
||||
serverList.initWithNiwsConfig(config);
|
||||
return serverList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a Netflix {@link RestClient} integrated with Ribbon if none already exists in the
|
||||
* application context. It is not required for Ribbon to work properly and is therefore
|
||||
* created lazily if ever another component requires it.
|
||||
*
|
||||
* @param config the configuration to use by the underlying Ribbon instance
|
||||
* @param loadBalancer the load balancer to use by the underlying Ribbon instance
|
||||
* @return a {@link RestClient} instances backed by Ribbon
|
||||
*/
|
||||
@Bean
|
||||
@Lazy
|
||||
@ConditionalOnMissingBean
|
||||
public RestClient ribbonRestClient(IClientConfig config, ILoadBalancer loadBalancer) {
|
||||
RestClient client = new OverrideRestClient(config);
|
||||
client.setLoadBalancer(loadBalancer);
|
||||
Monitors.registerObject("Client_" + this.name, client);
|
||||
return client;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public ILoadBalancer ribbonLoadBalancer(IClientConfig config,
|
||||
ServerList<Server> serverList, ServerListFilter<Server> serverListFilter,
|
||||
IRule rule, IPing ping) {
|
||||
ZoneAwareLoadBalancer<Server> balancer = LoadBalancerBuilder.newBuilder()
|
||||
.withClientConfig(config).withRule(rule).withPing(ping)
|
||||
.withServerListFilter(serverListFilter).withDynamicServerList(serverList)
|
||||
.buildDynamicServerListLoadBalancer();
|
||||
return balancer;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public ServerListFilter<Server> ribbonServerListFilter(IClientConfig config) {
|
||||
ZonePreferenceServerListFilter filter = new ZonePreferenceServerListFilter();
|
||||
filter.initWithNiwsConfig(config);
|
||||
return filter;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public RibbonLoadBalancerContext ribbonLoadBalancerContext(
|
||||
ILoadBalancer loadBalancer, IClientConfig config) {
|
||||
return new RibbonLoadBalancerContext(loadBalancer, config);
|
||||
}
|
||||
|
||||
static class OverrideRestClient extends RestClient {
|
||||
|
||||
protected OverrideRestClient(IClientConfig ncc) {
|
||||
super();
|
||||
initWithNiwsConfig(ncc);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Client apacheHttpClientSpecificInitialization() {
|
||||
ApacheHttpClient4 apache = (ApacheHttpClient4) super
|
||||
.apacheHttpClientSpecificInitialization();
|
||||
apache.getClientHandler()
|
||||
.getHttpClient()
|
||||
.getParams()
|
||||
.setParameter(ClientPNames.COOKIE_POLICY, CookiePolicy.IGNORE_COOKIES);
|
||||
return apache;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
-88
@@ -1,88 +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
|
||||
*
|
||||
* 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.ribbon;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
|
||||
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
|
||||
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
|
||||
import org.springframework.core.annotation.AnnotationAttributes;
|
||||
import org.springframework.core.type.AnnotationMetadata;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public class RibbonClientConfigurationRegistrar implements ImportBeanDefinitionRegistrar {
|
||||
|
||||
@Override
|
||||
public void registerBeanDefinitions(AnnotationMetadata metadata,
|
||||
BeanDefinitionRegistry registry) {
|
||||
Map<String, Object> attrs = metadata.getAnnotationAttributes(
|
||||
RibbonClients.class.getName(), true);
|
||||
if (attrs != null && attrs.containsKey("value")) {
|
||||
AnnotationAttributes[] clients = (AnnotationAttributes[]) attrs.get("value");
|
||||
for (AnnotationAttributes client : clients) {
|
||||
registerClientConfiguration(registry, getClientName(client),
|
||||
client.get("configuration"));
|
||||
}
|
||||
}
|
||||
if (attrs != null && attrs.containsKey("defaultConfiguration")) {
|
||||
String name;
|
||||
if (metadata.hasEnclosingClass()) {
|
||||
name = "default." + metadata.getEnclosingClassName();
|
||||
} else {
|
||||
name = "default." + metadata.getClassName();
|
||||
}
|
||||
registerClientConfiguration(registry, name,
|
||||
attrs.get("defaultConfiguration"));
|
||||
}
|
||||
Map<String, Object> client = metadata.getAnnotationAttributes(
|
||||
RibbonClient.class.getName(), true);
|
||||
String name = getClientName(client);
|
||||
if (name != null) {
|
||||
registerClientConfiguration(registry, name, client.get("configuration"));
|
||||
}
|
||||
}
|
||||
|
||||
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)) {
|
||||
return value;
|
||||
}
|
||||
throw new IllegalStateException(
|
||||
"Either 'name' or 'value' must be provided in @RibbonClient");
|
||||
}
|
||||
|
||||
private void registerClientConfiguration(BeanDefinitionRegistry registry,
|
||||
Object name, Object configuration) {
|
||||
BeanDefinitionBuilder builder = BeanDefinitionBuilder
|
||||
.genericBeanDefinition(RibbonClientSpecification.class);
|
||||
builder.addConstructorArgValue(name);
|
||||
builder.addConstructorArgValue(configuration);
|
||||
registry.registerBeanDefinition(name + ".RibbonClientSpecification",
|
||||
builder.getBeanDefinition());
|
||||
}
|
||||
|
||||
}
|
||||
-196
@@ -1,196 +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
|
||||
*
|
||||
* 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.ribbon;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.URI;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.springframework.cloud.client.ServiceInstance;
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
|
||||
import org.springframework.http.HttpHeaders;
|
||||
import org.springframework.http.HttpMethod;
|
||||
import org.springframework.http.HttpStatus;
|
||||
import org.springframework.http.client.AbstractClientHttpRequest;
|
||||
import org.springframework.http.client.AbstractClientHttpResponse;
|
||||
import org.springframework.http.client.ClientHttpRequest;
|
||||
import org.springframework.http.client.ClientHttpRequestFactory;
|
||||
import org.springframework.http.client.ClientHttpResponse;
|
||||
|
||||
import com.netflix.client.config.IClientConfig;
|
||||
import com.netflix.client.http.HttpRequest;
|
||||
import com.netflix.client.http.HttpResponse;
|
||||
import com.netflix.niws.client.http.RestClient;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class RibbonClientHttpRequestFactory implements ClientHttpRequestFactory {
|
||||
|
||||
private final SpringClientFactory clientFactory;
|
||||
|
||||
private LoadBalancerClient loadBalancer;
|
||||
|
||||
public RibbonClientHttpRequestFactory(SpringClientFactory clientFactory, LoadBalancerClient loadBalancer) {
|
||||
this.clientFactory = clientFactory;
|
||||
this.loadBalancer = loadBalancer;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
public ClientHttpRequest createRequest(URI originalUri, HttpMethod httpMethod)
|
||||
throws IOException {
|
||||
String serviceId = originalUri.getHost();
|
||||
ServiceInstance instance = loadBalancer.choose(serviceId);
|
||||
if (instance == null) {
|
||||
throw new IllegalStateException("No instances available for "+serviceId);
|
||||
}
|
||||
URI uri = loadBalancer.reconstructURI(instance, originalUri);
|
||||
//@formatter:off
|
||||
IClientConfig clientConfig = clientFactory.getClientConfig(instance.getServiceId());
|
||||
RestClient client = clientFactory.getClient(instance.getServiceId(), RestClient.class);
|
||||
HttpRequest.Verb verb = HttpRequest.Verb.valueOf(httpMethod.name());
|
||||
//@formatter:on
|
||||
return new RibbonHttpRequest(uri, verb, client, clientConfig);
|
||||
}
|
||||
|
||||
public class RibbonHttpRequest extends AbstractClientHttpRequest {
|
||||
|
||||
private HttpRequest.Builder builder;
|
||||
private URI uri;
|
||||
private HttpRequest.Verb verb;
|
||||
private RestClient client;
|
||||
private IClientConfig config;
|
||||
private ByteArrayOutputStream outputStream = null;
|
||||
|
||||
public RibbonHttpRequest(URI uri, HttpRequest.Verb verb, RestClient client,
|
||||
IClientConfig config) {
|
||||
this.uri = uri;
|
||||
this.verb = verb;
|
||||
this.client = client;
|
||||
this.config = config;
|
||||
this.builder = HttpRequest.newBuilder().uri(uri).verb(verb);
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpMethod getMethod() {
|
||||
return HttpMethod.valueOf(verb.name());
|
||||
}
|
||||
|
||||
@Override
|
||||
public URI getURI() {
|
||||
return uri;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected OutputStream getBodyInternal(HttpHeaders headers) throws IOException {
|
||||
if (outputStream == null) {
|
||||
outputStream = new ByteArrayOutputStream();
|
||||
}
|
||||
return outputStream;
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("deprecation")
|
||||
protected ClientHttpResponse executeInternal(HttpHeaders headers)
|
||||
throws IOException {
|
||||
try {
|
||||
addHeaders(headers);
|
||||
if (outputStream != null) {
|
||||
outputStream.close();
|
||||
builder.entity(outputStream.toByteArray());
|
||||
}
|
||||
HttpRequest request = builder.build();
|
||||
HttpResponse response = client.execute(request, config);
|
||||
return new RibbonHttpResponse(response);
|
||||
} catch (Exception e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
|
||||
//TODO: fix stats, now that execute is not called
|
||||
// use execute here so stats are collected
|
||||
/*return loadBalancer.execute(this.config.getClientName(), new LoadBalancerRequest<ClientHttpResponse>() {
|
||||
@Override
|
||||
public ClientHttpResponse apply(ServiceInstance instance) throws Exception {
|
||||
}
|
||||
});*/
|
||||
}
|
||||
|
||||
private void addHeaders(HttpHeaders headers) {
|
||||
for (String name : headers.keySet()) {
|
||||
// apache http RequestContent pukes if there is a body and
|
||||
// the dynamic headers are already present
|
||||
if (!isDynamic(name) || outputStream == null) {
|
||||
List<String> values = headers.get(name);
|
||||
for (String value : values) {
|
||||
builder.header(name, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isDynamic(String name) {
|
||||
return name.equals("Content-Length") || name.equals("Transfer-Encoding");
|
||||
}
|
||||
}
|
||||
|
||||
public class RibbonHttpResponse extends AbstractClientHttpResponse {
|
||||
|
||||
private HttpResponse response;
|
||||
private HttpHeaders httpHeaders;
|
||||
|
||||
public RibbonHttpResponse(HttpResponse response) {
|
||||
this.response = response;
|
||||
this.httpHeaders = new HttpHeaders();
|
||||
List<Map.Entry<String, String>> headers = response.getHttpHeaders()
|
||||
.getAllHeaders();
|
||||
for (Map.Entry<String, String> header : headers) {
|
||||
this.httpHeaders.add(header.getKey(), header.getValue());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public InputStream getBody() throws IOException {
|
||||
return response.getInputStream();
|
||||
}
|
||||
|
||||
@Override
|
||||
public HttpHeaders getHeaders() {
|
||||
return this.httpHeaders;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getRawStatusCode() throws IOException {
|
||||
return response.getStatus();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getStatusText() throws IOException {
|
||||
return HttpStatus.valueOf(response.getStatus()).name();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
response.close();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
-33
@@ -1,33 +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
|
||||
*
|
||||
* 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.ribbon;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@Data
|
||||
@AllArgsConstructor
|
||||
public class RibbonClientSpecification {
|
||||
|
||||
private String name;
|
||||
|
||||
private Class<?>[] configuration;
|
||||
|
||||
}
|
||||
-45
@@ -1,45 +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
|
||||
*
|
||||
* 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.ribbon;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.context.annotation.Import;
|
||||
|
||||
/**
|
||||
* Convenience annotation that allows user to combine multiple <code>@RibbonClient</code>
|
||||
* annotations on a single class (including in Java 7).
|
||||
*
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@Configuration
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target({ ElementType.TYPE })
|
||||
@Documented
|
||||
@Import(RibbonClientConfigurationRegistrar.class)
|
||||
public @interface RibbonClients {
|
||||
|
||||
RibbonClient[] value() default {};
|
||||
|
||||
Class<?>[] defaultConfiguration() default {};
|
||||
|
||||
}
|
||||
+44
@@ -0,0 +1,44 @@
|
||||
package org.springframework.cloud.netflix.ribbon;
|
||||
|
||||
import org.springframework.cloud.client.ServiceInstance;
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
|
||||
import org.springframework.http.HttpRequest;
|
||||
import org.springframework.http.client.ClientHttpRequestExecution;
|
||||
import org.springframework.http.client.ClientHttpRequestInterceptor;
|
||||
import org.springframework.http.client.ClientHttpResponse;
|
||||
import org.springframework.http.client.support.HttpRequestWrapper;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class RibbonInterceptor implements ClientHttpRequestInterceptor {
|
||||
|
||||
private LoadBalancerClient loadBalancer;
|
||||
|
||||
public RibbonInterceptor(LoadBalancerClient loadBalancer) {
|
||||
this.loadBalancer = loadBalancer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution) throws IOException {
|
||||
HttpRequestWrapper wrapper = new HttpRequestWrapper(request) {
|
||||
@Override
|
||||
public URI getURI() {
|
||||
URI originalUri = super.getURI();
|
||||
String serviceName = originalUri.getHost();
|
||||
ServiceInstance instance = loadBalancer.choose(serviceName);
|
||||
URI uri = UriComponentsBuilder.fromUri(originalUri)
|
||||
.host(instance.getHost())
|
||||
.port(instance.getPort())
|
||||
.build()
|
||||
.toUri();
|
||||
return uri;
|
||||
}
|
||||
};
|
||||
return execution.execute(wrapper, body);
|
||||
}
|
||||
}
|
||||
+30
-135
@@ -1,150 +1,45 @@
|
||||
/*
|
||||
* 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.ribbon;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.springframework.cloud.client.DefaultServiceInstance;
|
||||
import org.springframework.cloud.client.ServiceInstance;
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalancerRequest;
|
||||
import org.springframework.util.Assert;
|
||||
import org.springframework.util.ReflectionUtils;
|
||||
|
||||
import com.netflix.client.ClientFactory;
|
||||
import com.netflix.loadbalancer.ILoadBalancer;
|
||||
import com.netflix.loadbalancer.Server;
|
||||
import com.netflix.loadbalancer.ServerStats;
|
||||
import com.netflix.servo.monitor.Stopwatch;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.cloud.client.ServiceInstance;
|
||||
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public class RibbonLoadBalancerClient implements LoadBalancerClient {
|
||||
@Autowired
|
||||
private ServerListInitializer serverListInitializer;
|
||||
|
||||
private SpringClientFactory clientFactory;
|
||||
@Override
|
||||
public ServiceInstance choose(String serviceId) {
|
||||
serverListInitializer.initialize(serviceId);
|
||||
ILoadBalancer loadBalancer = ClientFactory.getNamedLoadBalancer(serviceId);
|
||||
Server server = loadBalancer.chooseServer(null);
|
||||
if (server == null) {
|
||||
throw new IllegalStateException("Unable to locate ILoadBalancer for service: "+ serviceId);
|
||||
}
|
||||
return new RibbonServer(server);
|
||||
}
|
||||
|
||||
public RibbonLoadBalancerClient(SpringClientFactory clientFactory) {
|
||||
this.clientFactory = clientFactory;
|
||||
}
|
||||
private class RibbonServer implements ServiceInstance {
|
||||
private Server server;
|
||||
|
||||
@Override
|
||||
public URI reconstructURI(ServiceInstance instance, URI original) {
|
||||
Assert.notNull(instance, "instance can not be null");
|
||||
String serviceId = instance.getServiceId();
|
||||
RibbonLoadBalancerContext context = this.clientFactory
|
||||
.getLoadBalancerContext(serviceId);
|
||||
Server server = new Server(instance.getHost(), instance.getPort());
|
||||
return context.reconstructURIWithServer(server, original);
|
||||
}
|
||||
private RibbonServer(Server server) {
|
||||
this.server = server;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ServiceInstance choose(String serviceId) {
|
||||
Server server = getServer(serviceId);
|
||||
if (server == null) {
|
||||
return null;
|
||||
}
|
||||
return new RibbonServer(serviceId, server);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> T execute(String serviceId, LoadBalancerRequest<T> request) {
|
||||
ILoadBalancer loadBalancer = getLoadBalancer(serviceId);
|
||||
RibbonLoadBalancerContext context = this.clientFactory
|
||||
.getLoadBalancerContext(serviceId);
|
||||
Server server = getServer(loadBalancer);
|
||||
RibbonServer ribbonServer = new RibbonServer(serviceId, server);
|
||||
|
||||
ServerStats serverStats = context.getServerStats(server);
|
||||
context.noteOpenConnection(serverStats);
|
||||
Stopwatch tracer = context.getExecuteTracer().start();
|
||||
|
||||
try {
|
||||
T returnVal = request.apply(ribbonServer);
|
||||
recordStats(context, tracer, serverStats, returnVal, null);
|
||||
return returnVal;
|
||||
}
|
||||
catch (Exception ex) {
|
||||
recordStats(context, tracer, serverStats, null, ex);
|
||||
ReflectionUtils.rethrowRuntimeException(ex);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void recordStats(RibbonLoadBalancerContext context, Stopwatch tracer,
|
||||
ServerStats serverStats, Object entity, Throwable exception) {
|
||||
tracer.stop();
|
||||
long duration = tracer.getDuration(TimeUnit.MILLISECONDS);
|
||||
context.noteRequestCompletion(serverStats, entity, exception, duration, null/* errorHandler */);
|
||||
}
|
||||
|
||||
protected Server getServer(String serviceId) {
|
||||
return getServer(getLoadBalancer(serviceId));
|
||||
}
|
||||
|
||||
protected Server getServer(ILoadBalancer loadBalancer) {
|
||||
if (loadBalancer == null) {
|
||||
return null;
|
||||
}
|
||||
return loadBalancer.chooseServer("default"); //TODO: better handling of key
|
||||
}
|
||||
|
||||
protected ILoadBalancer getLoadBalancer(String serviceId) {
|
||||
return this.clientFactory.getLoadBalancer(serviceId);
|
||||
}
|
||||
|
||||
protected static class RibbonServer implements ServiceInstance {
|
||||
private String serviceId;
|
||||
private Server server;
|
||||
|
||||
protected RibbonServer(String serviceId, Server server) {
|
||||
this.serviceId = serviceId;
|
||||
this.server = server;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getServiceId() {
|
||||
return this.serviceId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getHost() {
|
||||
return this.server.getHost();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPort() {
|
||||
return this.server.getPort();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isSecure() {
|
||||
return false; //TODO: howto determine https from ribbon Server
|
||||
}
|
||||
|
||||
@Override
|
||||
public URI getUri() {
|
||||
return DefaultServiceInstance.getUri(this);
|
||||
}
|
||||
|
||||
public Server getServer() {
|
||||
return this.server;
|
||||
}
|
||||
}
|
||||
@Override
|
||||
public String getHost() {
|
||||
return server.getHost();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getPort() {
|
||||
return server.getPort();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
-65
@@ -1,65 +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
|
||||
*
|
||||
* 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.ribbon;
|
||||
|
||||
import com.netflix.client.RetryHandler;
|
||||
import com.netflix.client.config.IClientConfig;
|
||||
import com.netflix.loadbalancer.ILoadBalancer;
|
||||
import com.netflix.loadbalancer.LoadBalancerContext;
|
||||
import com.netflix.loadbalancer.ServerStats;
|
||||
import com.netflix.servo.monitor.Timer;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class RibbonLoadBalancerContext extends LoadBalancerContext {
|
||||
public RibbonLoadBalancerContext(ILoadBalancer lb) {
|
||||
super(lb);
|
||||
}
|
||||
|
||||
public RibbonLoadBalancerContext(ILoadBalancer lb, IClientConfig clientConfig) {
|
||||
super(lb, clientConfig);
|
||||
}
|
||||
|
||||
public RibbonLoadBalancerContext(ILoadBalancer lb, IClientConfig clientConfig,
|
||||
RetryHandler handler) {
|
||||
super(lb, clientConfig, handler);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void noteOpenConnection(ServerStats serverStats) {
|
||||
super.noteOpenConnection(serverStats);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Timer getExecuteTracer() {
|
||||
return super.getExecuteTracer();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void noteRequestCompletion(ServerStats stats, Object response, Throwable e,
|
||||
long responseTime) {
|
||||
super.noteRequestCompletion(stats, response, e, responseTime);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void noteRequestCompletion(ServerStats stats, Object response, Throwable e,
|
||||
long responseTime, RetryHandler errorHandler) {
|
||||
super.noteRequestCompletion(stats, response, e, responseTime, errorHandler);
|
||||
}
|
||||
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
package org.springframework.cloud.netflix.ribbon;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public interface ServerListInitializer {
|
||||
public void initialize(String serviceId);
|
||||
}
|
||||
-189
@@ -1,189 +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
|
||||
*
|
||||
* 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.ribbon;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.springframework.beans.BeanUtils;
|
||||
import org.springframework.beans.BeansException;
|
||||
import org.springframework.beans.factory.BeanFactoryUtils;
|
||||
import org.springframework.beans.factory.DisposableBean;
|
||||
import org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration;
|
||||
import org.springframework.context.ApplicationContext;
|
||||
import org.springframework.context.ApplicationContextAware;
|
||||
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
|
||||
import org.springframework.core.env.MapPropertySource;
|
||||
|
||||
import com.netflix.client.IClient;
|
||||
import com.netflix.client.IClientConfigAware;
|
||||
import com.netflix.client.config.IClientConfig;
|
||||
import com.netflix.loadbalancer.ILoadBalancer;
|
||||
|
||||
/**
|
||||
* A factory that creates client, load balancer and client configuration instances. 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 SpringClientFactory implements DisposableBean, ApplicationContextAware {
|
||||
|
||||
private Map<String, AnnotationConfigApplicationContext> contexts = new ConcurrentHashMap<>();
|
||||
|
||||
private Map<String, RibbonClientSpecification> configurations = new ConcurrentHashMap<>();
|
||||
|
||||
private ApplicationContext parent;
|
||||
|
||||
@Override
|
||||
public void setApplicationContext(ApplicationContext parent) throws BeansException {
|
||||
this.parent = parent;
|
||||
}
|
||||
|
||||
public void setConfigurations(List<RibbonClientSpecification> configurations) {
|
||||
for (RibbonClientSpecification client : configurations) {
|
||||
this.configurations.put(client.getName(), client);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void destroy() {
|
||||
Collection<AnnotationConfigApplicationContext> values = this.contexts.values();
|
||||
this.contexts.clear();
|
||||
for (AnnotationConfigApplicationContext context : values) {
|
||||
context.close();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the rest client associated with the name.
|
||||
* @throws RuntimeException if any error occurs
|
||||
*/
|
||||
public <C extends IClient<?, ?>> C getClient(String name, Class<C> clientClass) {
|
||||
return getInstance(name, clientClass);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the load balancer associated with the name.
|
||||
* @throws RuntimeException if any error occurs
|
||||
*/
|
||||
public ILoadBalancer getLoadBalancer(String name) {
|
||||
return getInstance(name, ILoadBalancer.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the client config associated with the name.
|
||||
* @throws RuntimeException if any error occurs
|
||||
*/
|
||||
public IClientConfig getClientConfig(String name) {
|
||||
return getInstance(name, IClientConfig.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the load balancer context associated with the name.
|
||||
* @throws RuntimeException if any error occurs
|
||||
*/
|
||||
public RibbonLoadBalancerContext getLoadBalancerContext(String serviceId) {
|
||||
return getInstance(serviceId, RibbonLoadBalancerContext.class);
|
||||
}
|
||||
|
||||
private AnnotationConfigApplicationContext getContext(String name) {
|
||||
if (!this.contexts.containsKey(name)) {
|
||||
synchronized (this.contexts) {
|
||||
if (!this.contexts.containsKey(name)) {
|
||||
this.contexts.put(name, createContext(name));
|
||||
}
|
||||
}
|
||||
}
|
||||
return this.contexts.get(name);
|
||||
}
|
||||
|
||||
private AnnotationConfigApplicationContext createContext(String name) {
|
||||
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
|
||||
if (this.configurations.containsKey(name)) {
|
||||
for (Class<?> configuration : this.configurations.get(name)
|
||||
.getConfiguration()) {
|
||||
context.register(configuration);
|
||||
}
|
||||
}
|
||||
for (Entry<String, RibbonClientSpecification> entry : this.configurations
|
||||
.entrySet()) {
|
||||
if (entry.getKey().startsWith("default.")) {
|
||||
for (Class<?> configuration : entry.getValue().getConfiguration()) {
|
||||
context.register(configuration);
|
||||
}
|
||||
}
|
||||
}
|
||||
context.register(PropertyPlaceholderAutoConfiguration.class,
|
||||
RibbonClientConfiguration.class);
|
||||
context.getEnvironment()
|
||||
.getPropertySources()
|
||||
.addFirst(
|
||||
new MapPropertySource("ribbon",
|
||||
Collections.<String, Object> singletonMap(
|
||||
"ribbon.client.name", name)));
|
||||
if (this.parent != null) {
|
||||
// Uses Environment from parent as well as beans
|
||||
context.setParent(this.parent);
|
||||
}
|
||||
context.refresh();
|
||||
return context;
|
||||
}
|
||||
|
||||
private <C> C instantiateWithConfig(AnnotationConfigApplicationContext context,
|
||||
Class<C> clazz, IClientConfig config) {
|
||||
C result = null;
|
||||
if (IClientConfigAware.class.isAssignableFrom(clazz)) {
|
||||
IClientConfigAware obj = (IClientConfigAware) BeanUtils.instantiate(clazz);
|
||||
obj.initWithNiwsConfig(config);
|
||||
@SuppressWarnings("unchecked")
|
||||
C value = (C) obj;
|
||||
result = value;
|
||||
}
|
||||
else {
|
||||
try {
|
||||
if (clazz.getConstructor(IClientConfig.class) != null) {
|
||||
result = clazz.getConstructor(IClientConfig.class)
|
||||
.newInstance(config);
|
||||
}
|
||||
else {
|
||||
result = BeanUtils.instantiate(clazz);
|
||||
}
|
||||
}
|
||||
catch (Throwable ex) {
|
||||
// NOPMD
|
||||
}
|
||||
}
|
||||
context.getAutowireCapableBeanFactory().autowireBean(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
private <C> C getInstance(String name, Class<C> type) {
|
||||
AnnotationConfigApplicationContext context = getContext(name);
|
||||
if (BeanFactoryUtils.beanNamesForTypeIncludingAncestors(context, type).length > 0) {
|
||||
return context.getBean(type);
|
||||
}
|
||||
IClientConfig config = getInstance(name, IClientConfig.class);
|
||||
return instantiateWithConfig(context, type, config);
|
||||
}
|
||||
|
||||
}
|
||||
-69
@@ -1,69 +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
|
||||
*
|
||||
* 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.ribbon;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import lombok.Data;
|
||||
import lombok.EqualsAndHashCode;
|
||||
|
||||
import com.netflix.client.config.IClientConfig;
|
||||
import com.netflix.config.ConfigurationManager;
|
||||
import com.netflix.config.DeploymentContext.ContextKey;
|
||||
import com.netflix.loadbalancer.Server;
|
||||
import com.netflix.loadbalancer.ZoneAffinityServerListFilter;
|
||||
|
||||
/**
|
||||
* A filter that actively prefers the local zone (as defined by the deployment context, or
|
||||
* the Eureka instance metadata).
|
||||
*
|
||||
* @author Dave Syer
|
||||
*/
|
||||
@Data
|
||||
@EqualsAndHashCode(callSuper = false)
|
||||
public class ZonePreferenceServerListFilter extends ZoneAffinityServerListFilter<Server> {
|
||||
|
||||
private String zone;
|
||||
|
||||
@Override
|
||||
public void initWithNiwsConfig(IClientConfig niwsClientConfig) {
|
||||
super.initWithNiwsConfig(niwsClientConfig);
|
||||
if (ConfigurationManager.getDeploymentContext() != null) {
|
||||
this.zone = ConfigurationManager.getDeploymentContext().getValue(
|
||||
ContextKey.zone);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Server> getFilteredListOfServers(List<Server> servers) {
|
||||
List<Server> output = super.getFilteredListOfServers(servers);
|
||||
if (this.zone != null && output.size() == servers.size()) {
|
||||
List<Server> local = new ArrayList<Server>();
|
||||
for (Server server : output) {
|
||||
if (this.zone.equalsIgnoreCase(server.getZone())) {
|
||||
local.add(server);
|
||||
}
|
||||
}
|
||||
if (!local.isEmpty()) {
|
||||
return local;
|
||||
}
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
}
|
||||
-113
@@ -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
|
||||
*
|
||||
* 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.ribbon.eureka;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import com.netflix.appinfo.InstanceInfo;
|
||||
import com.netflix.client.config.CommonClientConfigKey;
|
||||
import com.netflix.client.config.IClientConfig;
|
||||
import com.netflix.loadbalancer.Server;
|
||||
import com.netflix.loadbalancer.ServerList;
|
||||
import com.netflix.niws.loadbalancer.DiscoveryEnabledServer;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*/
|
||||
public class DomainExtractingServerList implements ServerList<DiscoveryEnabledServer> {
|
||||
|
||||
private ServerList<DiscoveryEnabledServer> list;
|
||||
|
||||
private IClientConfig clientConfig;
|
||||
|
||||
private boolean approximateZoneFromHostname;
|
||||
|
||||
public DomainExtractingServerList(ServerList<DiscoveryEnabledServer> list,
|
||||
IClientConfig clientConfig, boolean approximateZoneFromHostname) {
|
||||
this.list = list;
|
||||
this.clientConfig = clientConfig;
|
||||
this.approximateZoneFromHostname = approximateZoneFromHostname;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DiscoveryEnabledServer> getInitialListOfServers() {
|
||||
List<DiscoveryEnabledServer> servers = setZones(this.list
|
||||
.getInitialListOfServers());
|
||||
return servers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<DiscoveryEnabledServer> getUpdatedListOfServers() {
|
||||
List<DiscoveryEnabledServer> servers = setZones(this.list
|
||||
.getUpdatedListOfServers());
|
||||
return servers;
|
||||
}
|
||||
|
||||
private List<DiscoveryEnabledServer> setZones(List<DiscoveryEnabledServer> servers) {
|
||||
List<DiscoveryEnabledServer> result = new ArrayList<>();
|
||||
boolean isSecure = this.clientConfig.getPropertyAsBoolean(
|
||||
CommonClientConfigKey.IsSecure, Boolean.TRUE);
|
||||
boolean shouldUseIpAddr = this.clientConfig.getPropertyAsBoolean(
|
||||
CommonClientConfigKey.UseIPAddrForServer, Boolean.FALSE);
|
||||
for (DiscoveryEnabledServer server : servers) {
|
||||
result.add(new DomainExtractingServer(server, isSecure, shouldUseIpAddr,
|
||||
this.approximateZoneFromHostname));
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class DomainExtractingServer extends DiscoveryEnabledServer {
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private String id;
|
||||
|
||||
public DomainExtractingServer(DiscoveryEnabledServer server, boolean useSecurePort,
|
||||
boolean useIpAddr, boolean approximateZoneFromHostname) {
|
||||
// host and port are set in super()
|
||||
super(server.getInstanceInfo(), useSecurePort, useIpAddr);
|
||||
if (server.getInstanceInfo().getMetadata().containsKey("zone")) {
|
||||
setZone(server.getInstanceInfo().getMetadata().get("zone"));
|
||||
}
|
||||
else if (approximateZoneFromHostname) {
|
||||
setZone(ZoneUtils.extractApproximateZone(server.getHost()));
|
||||
}
|
||||
else {
|
||||
setZone(server.getZone());
|
||||
}
|
||||
setId(extractId(server));
|
||||
setAlive(server.isAlive());
|
||||
setReadyToServe(server.isReadyToServe());
|
||||
}
|
||||
|
||||
private String extractId(Server server) {
|
||||
if (server instanceof DiscoveryEnabledServer) {
|
||||
DiscoveryEnabledServer enabled = (DiscoveryEnabledServer) server;
|
||||
InstanceInfo instance = enabled.getInstanceInfo();
|
||||
if (instance.getMetadata().containsKey("instanceId")) {
|
||||
return instance.getMetadata().get("instanceId");
|
||||
}
|
||||
}
|
||||
return super.getId();
|
||||
}
|
||||
}
|
||||
-150
@@ -1,150 +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
|
||||
*
|
||||
* 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.ribbon.eureka;
|
||||
|
||||
import static com.netflix.client.config.CommonClientConfigKey.DeploymentContextBasedVipAddresses;
|
||||
import static com.netflix.client.config.CommonClientConfigKey.EnableZoneAffinity;
|
||||
|
||||
import javax.annotation.PostConstruct;
|
||||
|
||||
import lombok.extern.apachecommons.CommonsLog;
|
||||
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
|
||||
import org.springframework.cloud.netflix.eureka.EurekaInstanceConfigBean;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
import com.netflix.client.config.IClientConfig;
|
||||
import com.netflix.config.ConfigurationManager;
|
||||
import com.netflix.config.DeploymentContext.ContextKey;
|
||||
import com.netflix.config.DynamicPropertyFactory;
|
||||
import com.netflix.config.DynamicStringProperty;
|
||||
import com.netflix.discovery.EurekaClientConfig;
|
||||
import com.netflix.loadbalancer.IPing;
|
||||
import com.netflix.loadbalancer.ServerList;
|
||||
import com.netflix.niws.loadbalancer.DiscoveryEnabledNIWSServerList;
|
||||
import com.netflix.niws.loadbalancer.NIWSDiscoveryPing;
|
||||
|
||||
/**
|
||||
* Preprocessor that configures defaults for eureka-discovered ribbon clients. Such as:
|
||||
* <code>@zone</code>, NIWSServerListClassName, DeploymentContextBasedVipAddresses,
|
||||
* NFLoadBalancerRuleClassName, NIWSServerListFilterClassName and more
|
||||
*
|
||||
* @author Spencer Gibb
|
||||
* @author Dave Syer
|
||||
* @author Ryan Baxter
|
||||
*/
|
||||
@Configuration
|
||||
@CommonsLog
|
||||
public class EurekaRibbonClientConfiguration {
|
||||
|
||||
@Value("${ribbon.eureka.approximateZoneFromHostname:false}")
|
||||
private boolean approximateZoneFromHostname = false;
|
||||
|
||||
@Value("${ribbon.client.name}")
|
||||
private String serviceId = "client";
|
||||
|
||||
protected static final String VALUE_NOT_SET = "__not__set__";
|
||||
|
||||
protected static final String DEFAULT_NAMESPACE = "ribbon";
|
||||
|
||||
@Autowired(required = false)
|
||||
private EurekaClientConfig clientConfig;
|
||||
|
||||
@Autowired
|
||||
private EurekaInstanceConfigBean eurekaConfig;
|
||||
|
||||
public EurekaRibbonClientConfiguration() {
|
||||
}
|
||||
|
||||
public EurekaRibbonClientConfiguration(EurekaClientConfig clientConfig,
|
||||
String serviceId, EurekaInstanceConfigBean eurekaConfig,
|
||||
boolean approximateZoneFromHostname) {
|
||||
this.clientConfig = clientConfig;
|
||||
this.serviceId = serviceId;
|
||||
this.eurekaConfig = eurekaConfig;
|
||||
this.approximateZoneFromHostname = approximateZoneFromHostname;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public IPing ribbonPing(IClientConfig config) {
|
||||
NIWSDiscoveryPing ping = new NIWSDiscoveryPing();
|
||||
ping.initWithNiwsConfig(config);
|
||||
return ping;
|
||||
}
|
||||
|
||||
@Bean
|
||||
@ConditionalOnMissingBean
|
||||
public ServerList<?> ribbonServerList(IClientConfig config) {
|
||||
DiscoveryEnabledNIWSServerList discoveryServerList = new DiscoveryEnabledNIWSServerList(
|
||||
config);
|
||||
DomainExtractingServerList serverList = new DomainExtractingServerList(
|
||||
discoveryServerList, config, this.approximateZoneFromHostname);
|
||||
return serverList;
|
||||
}
|
||||
|
||||
@PostConstruct
|
||||
public void preprocess() {
|
||||
String zone = ConfigurationManager.getDeploymentContext().getValue(
|
||||
ContextKey.zone);
|
||||
if (this.clientConfig != null && StringUtils.isEmpty(zone)) {
|
||||
if (approximateZoneFromHostname) {
|
||||
String approxZone = ZoneUtils.extractApproximateZone(eurekaConfig
|
||||
.getHostname());
|
||||
log.debug("Setting Zone To " + approxZone);
|
||||
ConfigurationManager.getDeploymentContext().setValue(ContextKey.zone,
|
||||
approxZone);
|
||||
}
|
||||
else {
|
||||
String[] zones = this.clientConfig.getAvailabilityZones(this.clientConfig
|
||||
.getRegion());
|
||||
String availabilityZone = zones != null && zones.length > 0 ? zones[0]
|
||||
: null;
|
||||
if (availabilityZone != null) {
|
||||
// You can set this with archaius.deployment.* (maybe requires
|
||||
// custom deployment context)?
|
||||
ConfigurationManager.getDeploymentContext().setValue(ContextKey.zone,
|
||||
availabilityZone);
|
||||
}
|
||||
}
|
||||
}
|
||||
setProp(this.serviceId, DeploymentContextBasedVipAddresses.key(), this.serviceId);
|
||||
setProp(this.serviceId, EnableZoneAffinity.key(), "true");
|
||||
}
|
||||
|
||||
protected void setProp(String serviceId, String suffix, String value) {
|
||||
// how to set the namespace properly?
|
||||
String key = getKey(serviceId, suffix);
|
||||
DynamicStringProperty property = getProperty(key);
|
||||
if (property.get().equals(VALUE_NOT_SET)) {
|
||||
ConfigurationManager.getConfigInstance().setProperty(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
protected DynamicStringProperty getProperty(String key) {
|
||||
return DynamicPropertyFactory.getInstance().getStringProperty(key, VALUE_NOT_SET);
|
||||
}
|
||||
|
||||
protected String getKey(String serviceId, String suffix) {
|
||||
return serviceId + "." + DEFAULT_NAMESPACE + "." + suffix;
|
||||
}
|
||||
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
package org.springframework.cloud.netflix.ribbon.eureka;
|
||||
|
||||
import com.netflix.config.ConfigurationManager;
|
||||
import com.netflix.niws.loadbalancer.DiscoveryEnabledNIWSServerList;
|
||||
import org.springframework.cloud.netflix.ribbon.ServerListInitializer;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class EurekaRibbonInitializer implements ServerListInitializer {
|
||||
|
||||
@Override
|
||||
public void initialize(String serviceId) {
|
||||
//TODO: should this look more like hibernate spring boot props?
|
||||
setProp(serviceId, "NIWSServerListClassName", DiscoveryEnabledNIWSServerList.class.getName());
|
||||
setProp(serviceId, "DeploymentContextBasedVipAddresses", serviceId); //FIXME: what should this be?
|
||||
}
|
||||
|
||||
protected void setProp(String serviceId, String suffix, String value) {
|
||||
//how to set the namespace properly?
|
||||
String namespace = "ribbon";
|
||||
ConfigurationManager.getConfigInstance().setProperty(serviceId + "."+ namespace +"." + suffix, value);
|
||||
}
|
||||
}
|
||||
+11
-11
@@ -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
|
||||
*
|
||||
* https://www.apache.org/licenses/LICENSE-2.0
|
||||
* 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,
|
||||
@@ -13,31 +13,31 @@
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.cloud.netflix.ribbon.eureka;
|
||||
|
||||
import com.netflix.niws.loadbalancer.DiscoveryEnabledNIWSServerList;
|
||||
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.ConditionalOnProperty;
|
||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
|
||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||
import org.springframework.cloud.netflix.ribbon.RibbonAutoConfiguration;
|
||||
import org.springframework.cloud.netflix.ribbon.RibbonClients;
|
||||
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
|
||||
import org.springframework.cloud.netflix.ribbon.ServerListInitializer;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
|
||||
import com.netflix.niws.loadbalancer.DiscoveryEnabledNIWSServerList;
|
||||
|
||||
/**
|
||||
* @author Dave Syer
|
||||
*
|
||||
*/
|
||||
@Configuration
|
||||
@EnableConfigurationProperties
|
||||
@ConditionalOnClass(DiscoveryEnabledNIWSServerList.class)
|
||||
@ConditionalOnBean(SpringClientFactory.class)
|
||||
@ConditionalOnProperty(value = "ribbon.eureka.enabled", matchIfMissing = true)
|
||||
@ConditionalOnExpression("${ribbon.eureka.enabled:true}")
|
||||
@AutoConfigureAfter(RibbonAutoConfiguration.class)
|
||||
@RibbonClients(defaultConfiguration = EurekaRibbonClientConfiguration.class)
|
||||
public class RibbonEurekaAutoConfiguration {
|
||||
|
||||
@Bean
|
||||
public ServerListInitializer serverListInitializer() {
|
||||
return new EurekaRibbonInitializer();
|
||||
}
|
||||
}
|
||||
|
||||
-44
@@ -1,44 +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
|
||||
*
|
||||
* 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.ribbon.eureka;
|
||||
|
||||
import org.springframework.util.StringUtils;
|
||||
|
||||
/**
|
||||
* Utility class for dealing with zones.
|
||||
* @author Ryan Baxter
|
||||
*
|
||||
*/
|
||||
public class ZoneUtils {
|
||||
|
||||
/**
|
||||
* Approximates Eureka zones from a host name. This method approximates the zone to be
|
||||
* everything after the first "." in the host name.
|
||||
* @param host The host name to extract the host name from
|
||||
* @return The approximate zone
|
||||
*/
|
||||
public static String extractApproximateZone(String host) {
|
||||
if (!host.contains(".")) {
|
||||
return host;
|
||||
}
|
||||
String[] split = StringUtils.split(host, ".");
|
||||
StringBuilder builder = new StringBuilder(split[1]);
|
||||
for (int i = 2; i < split.length; i++) {
|
||||
builder.append(".").append(split[i]);
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
}
|
||||
-114
@@ -1,114 +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
|
||||
*
|
||||
* 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.servo;
|
||||
|
||||
import com.netflix.servo.Metric;
|
||||
import com.netflix.servo.annotations.DataSourceType;
|
||||
import com.netflix.servo.monitor.MonitorConfig;
|
||||
import com.netflix.servo.tag.Tag;
|
||||
import com.netflix.servo.tag.TagList;
|
||||
|
||||
/**
|
||||
* @author Spencer Gibb
|
||||
*/
|
||||
public class DefaultServoMetricNaming implements ServoMetricNaming {
|
||||
private static final String JMX_DOMAIN_KEY = "JmxDomain";
|
||||
public static final String SERVO = "servo.";
|
||||
|
||||
@Override
|
||||
public String getName(Metric metric) {
|
||||
MonitorConfig config = metric.getConfig();
|
||||
TagList tags = config.getTags();
|
||||
|
||||
Tag domainTag = tags.getTag(JMX_DOMAIN_KEY);
|
||||
String name;
|
||||
if (domainTag != null) { // jmx metric
|
||||
name = handleJmxMetric(config, tags);
|
||||
}
|
||||
else {
|
||||
name = handleMetric(config, tags);
|
||||
}
|
||||
return name.toLowerCase();
|
||||
}
|
||||
|
||||
private String handleMetric(MonitorConfig config, TagList tags) {
|
||||
String type = cleanValue(tags.getTag(DataSourceType.KEY), false);
|
||||
String instanceName = cleanValue(tags.getTag("instance"), false);
|
||||
String name = cleanupIllegalCharacters(config.getName(), true);
|
||||
String statistic = cleanValue(tags.getTag("statistic"), false);
|
||||
|
||||
StringBuilder nameBuilder = new StringBuilder();
|
||||
if (type != null) {
|
||||
nameBuilder.append(type).append(".");
|
||||
}
|
||||
nameBuilder.append(SERVO);
|
||||
if (instanceName != null) {
|
||||
nameBuilder.append(instanceName).append(".");
|
||||
}
|
||||
if (name != null) {
|
||||
nameBuilder.append(name).append(".");
|
||||
}
|
||||
if (statistic != null) {
|
||||
nameBuilder.append(statistic).append(".");
|
||||
}
|
||||
// remove trailing "."
|
||||
nameBuilder.deleteCharAt(nameBuilder.lastIndexOf("."));
|
||||
return nameBuilder.toString();
|
||||
}
|
||||
|
||||
private String handleJmxMetric(MonitorConfig config, TagList tags) {
|
||||
String domain = cleanValue(tags.getTag(JMX_DOMAIN_KEY), true);
|
||||
String type = cleanValue(tags.getTag("Jmx.type"), false);
|
||||
String instanceName = cleanValue(tags.getTag("Jmx.instance"), false);
|
||||
String name = cleanValue(tags.getTag("Jmx.name"), true);
|
||||
String fieldName = cleanupIllegalCharacters(config.getName(), false);
|
||||
|
||||
StringBuilder nameBuilder = new StringBuilder();
|
||||
nameBuilder.append(domain).append(".");
|
||||
if (type != null) {
|
||||
nameBuilder.append(type).append(".");
|
||||
}
|
||||
nameBuilder.append(SERVO);
|
||||
if (instanceName != null) {
|
||||
nameBuilder.append(instanceName).append(".");
|
||||
}
|
||||
if (name != null) {
|
||||
nameBuilder.append(name).append(".");
|
||||
}
|
||||
if (fieldName != null) {
|
||||
nameBuilder.append(fieldName).append(".");
|
||||
}
|
||||
// remove trailing "."
|
||||
nameBuilder.deleteCharAt(nameBuilder.lastIndexOf("."));
|
||||
return nameBuilder.toString();
|
||||
}
|
||||
|
||||
private String cleanValue(Tag tag, boolean allowPeriodsInName) {
|
||||
if (tag == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return cleanupIllegalCharacters(tag.getValue(), allowPeriodsInName);
|
||||
}
|
||||
|
||||
private String cleanupIllegalCharacters(String s, boolean allowPeriodsInName) {
|
||||
if (!allowPeriodsInName) {
|
||||
s = s.replace(".", "_");
|
||||
}
|
||||
return s.replace(" ", "_");
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user