- Single Sign On
-- Token Type in User Info
- Customizing the RestTemplate
- Resource Server
- Token Relay
@@ -621,467 +599,10 @@ and extensibility mechanism to cover others.
-Cloud Native Applications
-
-
-
-
Cloud Native is a style of application development that encourages easy adoption of best practices in the areas of continuous delivery and value-driven development. A related discipline is that of building 12-factor Apps in which development practices are aligned with delivery and operations goals, for instance by using declarative programming and management and monitoring. Spring Cloud facilitates these styles of development in a number of specific ways and the starting point is a set of features that all components in a distributed system either need or need easy access to when required.
-
-
-
Many of those features are covered by Spring Boot, which we build on in Spring Cloud. Some more are delivered by Spring Cloud as two libraries: Spring Cloud Context and Spring Cloud Commons. Spring Cloud Context provides utilities and special services for the ApplicationContext of a Spring Cloud application (bootstrap context, encryption, refresh scope and environment endpoints). Spring Cloud Commons is a set of abstractions and common classes used in different Spring Cloud implementations (eg. Spring Cloud Netflix vs. Spring Cloud Consul).
-
-
-
If you are getting an exception due to "Illegal key size" and you are using Sun’s JDK, you need to install the Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files. See the following links for more information:
-
-
-
-
Extract files into JDK/jre/lib/security folder (whichever version of JRE/JDK x64/x86 you are using).
-
-
-
-
-
-
Spring Cloud Context: Application Context Services
-
-
-
Spring Boot has an opinionated view of how to build an application
-with Spring: for instance it has conventional locations for common
-configuration file, and endpoints for common management and monitoring
-tasks. Spring Cloud builds on top of that and adds a few features that
-probably all components in a system would use or occasionally need.
-
-
-
The Bootstrap Application Context
-
-
A Spring Cloud application operates by creating a "bootstrap"
-context, which is a parent context for the main application. Out of
-the box it is responsible for loading configuration properties from
-the external sources, and also decrypting properties in the local
-external configuration files. The two contexts share an Environment
-which is the source of external properties for any Spring
-application. Bootstrap properties are added with high precedence, so
-they cannot be overridden by local configuration.
-
-
-
The bootstrap context uses a different convention for locating
-external configuration than the main application context, so instead
-of application.yml (or .properties) you use bootstrap.yml,
-keeping the external configuration for bootstrap and main context
-nicely separate. Example:
-
-
-
bootstrap.yml
-
-
spring:
- application:
- name: foo
- cloud:
- config:
- uri: ${SPRING_CONFIG_URI:http://localhost:8888}
-
-
-
-
It is a good idea to set the spring.application.name (in
-bootstrap.yml or application.yml) if your application needs any
-application-specific configuration from the server.
-
-
-
You can disable the bootstrap process completely by setting
-spring.cloud.bootstrap.enabled=false (e.g. in System properties).
-
-
-
-
Application Context Hierarchies
-
-
If you build an application context from SpringApplication or
-SpringApplicationBuilder, then the Bootstrap context is added as a
-parent to that context. It is a feature of Spring that child contexts
-inherit property sources and profiles from their parent, so the "main"
-application context will contain additional property sources, compared
-to building the same context without Spring Cloud Config. The
-additional property sources are:
-
-
-
--
-
"bootstrap": an optional CompositePropertySource appears with high
-priority if any PropertySourceLocators are found in the Bootstrap
-context, and they have non-empty properties. An example would be
-properties from the Spring Cloud Config Server. See
-below for instructions
-on how to customize the contents of this property source.
-
--
-
"applicationConfig: [classpath:bootstrap.yml]" (and friends if
-Spring profiles are active). If you have a bootstrap.yml (or
-properties) then those properties are used to configure the Bootstrap
-context, and then they get added to the child context when its parent
-is set. They have lower precedence than the application.yml (or
-properties) and any other property sources that are added to the child
-as a normal part of the process of creating a Spring Boot
-application. See below for
-instructions on how to customize the contents of these property
-sources.
-
-
-
-
-
Because of the ordering rules of property sources the "bootstrap"
-entries take precedence, but note that these do not contain any data
-from bootstrap.yml, which has very low precedence, but can be used
-to set defaults.
-
-
-
You can extend the context hierarchy by simply setting the parent
-context of any ApplicationContext you create, e.g. using its own
-interface, or with the SpringApplicationBuilder convenience methods
-(parent(), child() and sibling()). The bootstrap context will be
-the parent of the most senior ancestor that you create yourself.
-Every context in the hierarchy will have its own "bootstrap" property
-source (possibly empty) to avoid promoting values inadvertently from
-parents down to their descendants. Every context in the hierarchy can
-also (in principle) have a different spring.application.name and
-hence a different remote property source if there is a Config
-Server. Normal Spring application context behaviour rules apply to
-property resolution: properties from a child context override those in
-the parent, by name and also by property source name (if the child has
-a property source with the same name as the parent, the one from the
-parent is not included in the child).
-
-
-
Note that the SpringApplicationBuilder allows you to share an
-Environment amongst the whole hierarchy, but that is not the
-default. Thus, sibling contexts in particular do not need to have the
-same profiles or property sources, even though they will share common
-things with their parent.
-
-
-
-
Changing the Location of Bootstrap Properties
-
-
The bootstrap.yml (or .properties) location can be specified using
-`spring.cloud.bootstrap.name (default "bootstrap") or
-spring.cloud.bootstrap.location (default empty), e.g. in System
-properties. Those properties behave like the spring.config.*
-variants with the same name, in fact they are used to set up the
-bootstrap ApplicationContext by setting those properties in its
-Environment. If there is an active profile (from
-spring.profiles.active or through the Environment API in the
-context you are building) then properties in that profile will be
-loaded as well, just like in a regular Spring Boot app, e.g. from
-bootstrap-development.properties for a "development" profile.
-
-
-
-
Customizing the Bootstrap Configuration
-
-
The bootstrap context can be trained to do anything you like by adding
-entries to /META-INF/spring.factories under the key
-org.springframework.cloud.bootstrap.BootstrapConfiguration. This is
-a comma-separated list of Spring @Configuration classes which will
-be used to create the context. Any beans that you want to be available
-to the main application context for autowiring can be created here,
-and also there is a special contract for @Beans of type
-ApplicationContextInitializer. Classes can be marked with an @Order
-if you want to control the startup sequence (the default order is
-"last").
-
-
-
-
-|
- Warning
- |
-
-Be careful when adding custom BootstrapConfiguration that the
-classes you add are not @ComponentScanned by mistake into your
-"main" application context, where they might not be needed.
-Use a separate package name for boot configuration classes that is
-not already covered by your @ComponentScan or @SpringBootApplication
-annotated configuration classes.
- |
-
-
-
-
-
The bootstrap process ends by injecting initializers into the main
-SpringApplication instance (i.e. the normal Spring Boot startup
-sequence, whether it is running as a standalone app or deployed in an
-application server). First a bootstrap context is created from the
-classes found in spring.factories and then all @Beans of type
-ApplicationContextInitializer are added to the main
-SpringApplication before it is started.
-
-
-
-
Customizing the Bootstrap Property Sources
-
-
The default property source for external configuration added by the
-bootstrap process is the Config Server, but you can add additional
-sources by adding beans of type PropertySourceLocator to the
-bootstrap context (via spring.factories). You could use this to
-insert additional properties from a different server, or from a
-database, for instance.
-
-
-
As an example, consider the following trivial custom locator:
-
-
-
-
@Configuration
-public class CustomPropertySourceLocator implements PropertySourceLocator {
-
- @Override
- public PropertySource<?> locate(Environment environment) {
- return new MapPropertySource("customProperty",
- Collections.<String, Object>singletonMap("property.from.sample.custom.source", "worked as intended"));
- }
-
-}
-
-
-
-
The Environment that is passed in is the one for the
-ApplicationContext about to be created, i.e. the one that we are
-supplying additional property sources for. It will already have its
-normal Spring Boot-provided property sources, so you can use those to
-locate a property source specific to this Environment (e.g. by
-keying it on the spring.application.name, as is done in the default
-Config Server property source locator).
-
-
-
If you create a jar with this class in it and then add a
-META-INF/spring.factories containing:
-
-
-
-
org.springframework.cloud.bootstrap.BootstrapConfiguration=sample.custom.CustomPropertySourceLocator
-
-
-
-
then the "customProperty" PropertySource will show up in any
-application that includes that jar on its classpath.
-
-
-
-
Environment Changes
-
-
The application will listen for an EnvironmentChangedEvent and react
-to the change in a couple of standard ways (additional
-ApplicationListeners can be added as @Beans by the user in the
-normal way). When an EnvironmentChangedEvent is observed it will
-have a list of key values that have changed, and the application will
-use those to:
-
-
-
-
Note that the Config Client does not by default poll for changes in
-the Environment, and generally we would not recommend that approach
-for detecting changes (although you could set it up with a
-@Scheduled annotation). If you have a scaled-out client application
-then it is better to broadcast the EnvironmentChangedEvent to all
-the instances instead of having them polling for changes (e.g. using
-the Spring Cloud
-Bus).
-
-
-
The EnvironmentChangedEvent covers a large class of refresh use
-cases, as long as you can actually make a change to the Environment
-and publish the event (those APIs are public and part of core
-Spring). You can verify the changes are bound to
-@ConfigurationProperties beans by visiting the /configprops
-endpoint (normal Spring Boot Actuator feature). For instance a
-DataSource can have its maxPoolSize changed at runtime (the
-default DataSource created by Spring Boot is an
-@ConfigurationProperties bean) and grow capacity
-dynamically. Re-binding @ConfigurationProperties does not cover
-another large class of use cases, where you need more control over the
-refresh, and where you need a change to be atomic over the whole
-ApplicationContext. To address those concerns we have
-@RefreshScope.
-
-
-
-
Refresh Scope
-
-
A Spring @Bean that is marked as @RefreshScope will get special
-treatment when there is a configuration change. This addresses the
-problem of stateful beans that only get their configuration injected
-when they are initialized. For instance if a DataSource has open
-connections when the database URL is changed via the Environment, we
-probably want the holders of those connections to be able to complete
-what they are doing. Then the next time someone borrows a connection
-from the pool he gets one with the new URL.
-
-
-
Refresh scope beans are lazy proxies that initialize when they are
-used (i.e. when a method is called), and the scope acts as a cache of
-initialized values. To force a bean to re-initialize on the next
-method call you just need to invalidate its cache entry.
-
-
-
The RefreshScope is a bean in the context and it has a public method
-refreshAll() to refresh all beans in the scope by clearing the
-target cache. There is also a refresh(String) method to refresh an
-individual bean by name. This functionality is exposed in the
-/refresh endpoint (over HTTP or JMX).
-
-
-
-
-|
- Note
- |
-
-@RefreshScope works (technically) on an @Configuration
-class, but it might lead to surprising behaviour: e.g. it does not
-mean that all the @Beans defined in that class are themselves
-@RefreshScope. Specifically, anything that depends on those beans
-cannot rely on them being updated when a refresh is initiated, unless
-it is itself in @RefreshScope (in which it will be rebuilt on a
-refresh and its dependencies re-injected, at which point they will be
-re-initialized from the refreshed @Configuration).
- |
-
-
-
-
-
-
Encryption and Decryption
-
-
The Config Client has an Environment pre-processor for decrypting
-property values locally. It follows the same rules as the Config
-Server, and has the same external configuration via encrypt.*. Thus
-you can use encrypted values in the form {cipher}* and as long as
-there is a valid key then they will be decrypted before the main
-application context gets the Environment. To use the encryption
-features in a client you need to include Spring Security RSA in your
-classpath (Maven co-ordinates
-"org.springframework.security:spring-security-rsa") and you also need
-the full strength JCE extensions in your JVM.
-
-
-
-
-
Endpoints
-
-
For a Spring Boot Actuator application there are some additional management endpoints:
-
-
-
--
-
POST to /env to update the Environment and rebind @ConfigurationProperties and log levels
-
--
-
/refresh for re-loading the boot strap context and refreshing the @RefreshScope beans
-
--
-
/restart for closing the ApplicationContext and restarting it (disabled by default)
-
--
-
/pause and /resume for calling the Lifecycle methods (stop() and start() on the ApplicationContext)
-
-
-
-
-
-
-
-
Spring Cloud Commons: Common Abstractions
-
-
-
Patterns such as service discovery, load balancing and circuit breakers lend themselves to a common abstraction layer that can be consumed by all Spring Cloud clients, independent of the implementation (e.g. discovery via Eureka or Consul).
-
-
-
Spring RestTemplate as a Load Balancer Client
-
-
You can use Ribbon indirectly via an autoconfigured RestTemplate
-when RestTemplate is on the classpath and a LoadBalancerClient bean is defined):
-
-
-
-
public class MyClass {
- @Autowired
- private RestTemplate restTemplate;
-
- public String doOtherStuff() {
- String results = restTemplate.getForObject("http://stores/stores", String.class);
- return results;
- }
-}
-
-
-
-
The URI needs to use a virtual host name (ie. service name, not a host name).
-The Ribbon client is used to create a full physical address. See
-{github-code}/spring-cloud-netflix-core/src/main/java/org/springframework/cloud/netflix/ribbon/RibbonAutoConfiguration.java[RibbonAutoConfiguration]
-for details of how the RestTemplate is set up.
-
-
-
-
Multiple RestTemplate objects
-
-
If you want a RestTemplate that is not load balanced, create a RestTemplate
-bean and inject it as normal. To access the load balanced RestTemplate use
-the provided `@LoadBalanced Qualifier:
-
-
-
-
public class MyClass {
- @Autowired
- private RestTemplate restTemplate;
-
- @Autowired
- @LoadBalanced
- private RestTemplate loadBalanced;
-
- public String doOtherStuff() {
- return loadBalanced.getForObject("http://stores/stores", String.class);
- }
-
- public String doStuff() {
- return restTemplate.getForObject("http://example.com", String.class);
- }
-}
-
-
-
-
-
Spring Cloud Config
-
-
Spring Cloud Config provides server and client-side support for externalized configuration in a distributed system. With the Config Server you have a central place to manage external properties for applications across all environments. The concepts on both client and server map identically to the Spring Environment and PropertySource abstractions, so they fit very well with Spring applications, but can be used with any application running in any language. As an application moves through the deployment pipeline from dev to test and into production you can manage the configuration between those environments and be certain that applications have everything they need to run when they migrate. The default implementation of the server storage backend uses git so it easily supports labelled versions of configuration environments, as well as being accessible to a wide range of tooling for managing the content. It is easy to add alternative implementations and plug them in with Spring configuration.
-
-
+Spring Cloud Config provides server and client-side support for externalized configuration in a distributed system. With the Config Server you have a central place to manage external properties for applications across all environments. The concepts on both client and server map identically to the Spring
Environment and
PropertySource abstractions, so they fit very well with Spring applications, but can be used with any application running in any language. As an application moves through the deployment pipeline from dev to test and into production you can manage the configuration between those environments and be certain that applications have everything they need to run when they migrate. The default implementation of the server storage backend uses git so it easily supports labelled versions of configuration environments, as well as being accessible to a wide range of tooling for managing the content. It is easy to add alternative implementations and plug them in with Spring configuration.
@@ -1162,7 +683,7 @@ from a git repository (which must be provided):
Boot application that depends on spring-cloud-config-client (e.g. see
the test cases for the config-client, or the sample app). The most
convenient way to add the dependency is via a Spring Boot starter
-
org.springframework.cloud:spring-cloud-starter-config. There is also a
+
org.springframework.cloud:spring-cloud-starter. There is also a
parent pom and BOM (
spring-cloud-starter-parent) for Maven users and a
Spring IO version management properties file for Gradle and Spring CLI
users. Example Maven configuration:
@@ -1173,7 +694,7 @@ users. Example Maven configuration:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
- <version>1.2.3.RELEASE</version>
+ <version>1.1.7.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
@@ -1182,7 +703,7 @@ users. Example Maven configuration:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-parent</artifactId>
- <version>1.0.1.RELEASE</version>
+ <version>1.0.0.BUILD-SNAPSHOT</version>
<type>pom</type>
<scope>import</scope>
</dependency>
@@ -1192,7 +713,7 @@ users. Example Maven configuration:
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-starter-config</artifactId>
+ <artifactId>spring-cloud-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
@@ -1374,17 +895,17 @@ repositories:
spring:
cloud:
config:
- server:
- git:
- uri: https://github.com/spring-cloud-samples/config-repo
- repos:
- simple: https://github.com/pattern1/config-repo
+ server:
+ git:
+ uri: https://github.com/spring-cloud-samples/config-repo
+ repos:
+ simple: https://github.com/pattern1/config-repo
special:
pattern: pattern*,*pattern1*
- uri: https://github.com/pattern2/config-repo
- local:
+ uri: https://github.com/pattern2/config-repo
+ local:
pattern: local*
- uri: file:/home/configsvc/config-repo
+ uri: file:/home/configsvc/config-repo
@@ -1396,59 +917,6 @@ pattern format is a comma-separated list of application names with
wildcards.
-
Every repository can also optionally store config files in
-sub-directories, and patterns to search for those directories can be
-specified as searchPaths. For example at the top level:
-
-
-
-
spring:
- cloud:
- config:
- server:
- git:
- uri: https://github.com/spring-cloud-samples/config-repo
- searchPaths: foo,bar*
-
-
-
-
In this example the server searches for config files in the top level
-and in the "foo/" sub-directory and also any sub-directory whose name
-begins with "bar".
-
-
-
By default the server clones remote repositories when configuration
-is first requested. The server can be configured to clone the repositories
-at startup. For example at the top level:
-
-
-
-
spring:
- cloud:
- config:
- server:
- git:
- uri: https://git/common/config-repo.git
- repos:
- team-a:
- pattern: team-a-*
- cloneOnStart: true
- uri: http://git/team-a/config-repo.git
- team-b:
- pattern: team-b-*
- cloneOnStart: false
- uri: http://git/team-b/config-repo.git
- team-c:
- pattern: team-c-*
- uri: http://git/team-a/config-repo.git
-
-
-
-
In this example the server clones team-a’s config-repo on startup before it
-accepts any requests. All other repositories will not be cloned until
-configuration from the repository is requested.
-
-
To use HTTP basic authentication on the remote repository add the
"username" and "password" properties separately (not in the URL),
e.g.
@@ -1458,9 +926,9 @@ e.g.
spring:
cloud:
config:
- server:
- git:
- uri: https://github.com/spring-cloud-samples/config-repo
+ server:
+ git:
+ uri: https://github.com/spring-cloud-samples/config-repo
username: trolley
password: strongpassword
@@ -1468,7 +936,7 @@ e.g.
If you don’t use HTTPS and user credentials, SSH should also work out
of the box when you store keys in the default directories (~/.ssh)
-and the uri points to an SSH location,
+and the uri is points to an SSH location,
e.g. "git@github.com:configuration/cloud-configuration". The
repository is accessed using JGit, so any documentation you find on
that should be applicable.
@@ -1484,36 +952,6 @@ system (any static URL you want to point to with
profile just launch the Config Server with
"spring.profiles.active=native".
-
-
-
-|
- Warning
- |
-
-The default value of the searchLocations is identical to a
-local Spring Boot application (so
-[classpath:/, classpath:/config, file:./, file:./config]) which will
-expose the application.properties from the server to all clients.
- |
-
-
-
-
-
-
-|
- Tip
- |
-
-A filesystem backend is great for getting started quickly and
-for testing. To use it in production you need to be sure that the
-file system is reliable, and shared across all instances of the
-Config Server.
- |
-
-
-
This repository implementation maps the {label} parameter of the
HTTP resource to a suffix on the search path, so properties files are
@@ -1524,37 +962,6 @@ Spring Environment).
-
Health Indicator
-
-
Config Server comes with a Health Indicator that checks if the configured
-EnvironmentRepository is working. By default it asks the EnvironmentRepository
-for an application named app, the default profile and the default
-label provided by the EnvironmentRepository implementation.
-
-
-
You can configure the Health Indicator to check more applications
-along with custom profiles and custom labels, e.g.
-
-
-
-
spring:
- cloud:
- config:
- server:
- health:
- repositories:
- myservice:
- label: mylabel
- myservice-dev:
- name: myservice
- profiles: development
-
-
-
-
You can disable the Health Indicator by setting spring.cloud.config.server.health.enabled=false.
-
-
-
Security
You are free to secure your Config Server in any way that makes sense
@@ -1573,7 +980,7 @@ on how to do that).
-
Encryption and Decryption
+
Encryption and Decryption
@@ -1591,13 +998,15 @@ in the JRE lib/security directory with the ones that you downloaded).
-
If the remote property sources contain encryted content
+
The server exposes /encrypt and /decrypt endpoints (on the
+assumption that these will be secured and only accessed by authorized
+agents). If the remote property sources contain encryted content
(values starting with {cipher}) they will be decrypted before
sending to clients over HTTP. The main advantage of this set up is
that the property values don’t have to be in plain text when they are
"at rest" (e.g. in a git repository). If a value cannot be decrypted
it is replaced with an empty string, largely to prevent cipher text
-being used as a password and accidentally leaking.
+being used as a password in Spring Boot autconfigured HTTP basic.
If you are setting up a remote config repository for config client
@@ -1610,7 +1019,7 @@ instance:
spring:
datasource:
username: dbuser
- password: '{cipher}FKSAJDFGYOS8F7GLHAKERGFHLSAJ'
+ password: {cipher}FKSAJDFGYOS8F7GLHAKERGFHLSAJ
@@ -1618,9 +1027,7 @@ instance:
secret password is protected.
-
The server also exposes /encrypt and /decrypt endpoints (on the
-assumption that these will be secured and only accessed by authorized
-agents). If you are editing a remote config file you can use the Config Server
+
If you are editing a remote config file you can use the Config Server
to encrypt values by POSTing to the /encrypt endpoint, e.g.
@@ -1642,25 +1049,7 @@ mysecret
Take the encypted value and add the {cipher} prefix before you put
it in the YAML or properties file, and before you commit and push it
-to a remote, potentially insecure store. The /encypt and /decrypt
-endpoints also both accept paths of the form /*/{name}/{profiles}
-which can be used to control cryptography per application (name)
-and profile when clients call into the main Environment resource.
-
-
-
-
-|
- Note
- |
-
-to control the cryptography in this granular way you must also
-provide a @Bean of type TextEncryptorLocator that creates a
-different encryptor per name and profiles. The one that is provided
-by default does not do this.
- |
-
-
+to a remote, potentially insecure store.
The spring command line client (with Spring Cloud CLI extensions
@@ -1699,7 +1088,9 @@ it is just a single property value to configure.
To configure a symmetric key you just need to set encrypt.key to a
secret String (or use an enviroment variable ENCRYPT_KEY to keep it
-out of plain text configuration files).
+out of plain text configuration files). You can also POST a key value
+to the
/key endpoint (but that won’t change any existing encrypted
+values in remote repositories).
To configure an asymmetric key you can either set the key as a
@@ -1754,64 +1145,12 @@ your application.yml for the Config Server:
encrypt:
keyStore:
location: classpath:/server.jks
- password: letmein
alias: mytestkey
- secret: changeme
+ password: letmein
-
Using Multiple Keys and Key Rotation
-
-
In addition to the {cipher} prefix in encrypted property values, the
-Config Server looks for {name:value} prefixes (zero or many) before
-the start of the (Base64 encoded) cipher text. The keys are passed to
-a TextEncryptorLocator which can do whatever logic it needs to
-locate a TextEncryptor for the cipher. If you have configured a
-keystore (encrypt.keystore.location) the default locator will look
-for keys in the store with aliases as supplied by the "key" prefix,
-i.e. with a cipher text like this:
-
-
-
-
foo:
- bar: `{cipher}{key:testkey}...`
-
-
-
-
the locator will look for a key named "testkey". A secret can also be
-supplied via a {secret:…} value in the prefix, but if it is not
-the default is to use the keystore password (which is what you get
-when you build a keytore and don’t specify a secret). If you do
-supply a secret it is recommended that you also encrypt the secrets
-using a custom SecretLocator.
-
-
-
Key rotation is hardly ever necessary on cryptographic grounds if the
-keys are only being used to encrypt a few bytes of configuration data
-(i.e. they are not being used elsewhere), but occasionally you might
-need to change the keys if there is a security breach for instance. In
-that case all the clients would need to change their source config
-files (e.g. in git) and use a new {key:…} prefix in all the
-ciphers, checking beforehand of course that the key alias is available
-in the Config Server keystore.
-
-
-
-
-|
- Tip
- |
-
-the {name:value} prefixes can also be added to plaintext posted
-to the /encrypt endpoint, if you want to let the Config Server
-handle all encryption as well as decryption.
- |
-
-
-
-
-
Embedding the Config Server
The Config Server runs best as a standalone application, but if you
@@ -1821,12 +1160,7 @@ need to you can embed it in another application. Just use the
to serve the resources under a prefix. The prefix should start but not
end with a "/". It is applied to the @RequestMappings in the Config
Server (i.e. underneath the Spring Boot prefixes server.servletPath
-and server.contextPath). Another optional property that can be
-useful in this case is spring.cloud.config.server.bootstrap which is
-a flag to indicate that the server should configure itself from its
-own remote repository. The flag is off by default because it can delay
-startup, but when embedded in another application it makes sense to
-initialize the same way as any other application.
+and
server.contextPath).
@@ -1889,9 +1223,140 @@ an Exception.
+
Environment Changes
+
+
The application will listen for an EnvironmentChangedEvent and react
+to the change in a couple of standard ways (additional
+ApplicationListeners can be added as @Beans by the user in the
+normal way). When an EnvironmentChangedEvent is observed it will
+have a list of key values that have changed, and the application will
+use those to:
+
+
+
+
Note that the Config Client does not by default poll for changes in
+the Environment, and generally we would not recommend that approach
+for detecting changes (although you could set it up with a
+@Scheduled annotation). If you have a scaled-out client application
+then it is better to broadcast the EnvironmentChangedEvent to all
+the instances instead of having them polling for changes (e.g. using
+the Spring Cloud
+Bus).
+
+
+
The EnvironmentChangedEvent covers a large class of refresh use
+cases, as long as you can actually make a change to the Environment
+and publish the event (those APIs are public and part of core
+Spring). You can verify the changes are bound to
+@ConfigurationProperties beans by visiting the /configprops
+endpoint (normal Spring Boot Actuator feature). For instance a
+DataSource can have its maxPoolSize changed at runtime (the
+default DataSource created by Spring Boot is an
+@ConfigurationProperties bean) and grow capacity
+dynamically. Re-binding @ConfigurationProperties does not cover
+another large class of use cases, where you need more control over the
+refresh, and where you need a change to be atomic over the whole
+ApplicationContext. To address those concerns we have
+@RefreshScope.
+
+
+
+
Refresh Scope
+
+
A Spring @Bean that is marked as @RefreshScope will get special
+treatment when there is a configuration change. This addresses the
+problem of stateful beans that only get their configuration injected
+when they are initialized. For instance if a DataSource has open
+connections when the database URL is changed via the Environment, we
+probably want the holders of those connections to be able to complete
+what they are doing. Then the next time someone borrows a connection
+from the pool he gets one with the new URL.
+
+
+
Refresh scope beans are lazy proxies that initialize when they are
+used (i.e. when a method is called), and the scope acts as a cache of
+initialized values. To force a bean to re-initialize on the next
+method call you just need to invalidate its cache entry.
+
+
+
The RefreshScope is a bean in the context and it has a public method
+refreshAll() to refresh all beans in the scope by clearing the
+target cache. There is also a refresh(String) method to refresh an
+individual bean by name. This functionality is exposed in the
+/refresh endpoint (over HTTP or JMX).
+
+
+
+
+|
+ Note
+ |
+
+@RefreshScope works (technically) on an @Configuration
+class, but it might lead to surprising behaviour: e.g. it does not
+mean that all the @Beans defined in that class are themselves
+@RefreshScope. Specifically, anything that depends on those beans
+cannot rely on them being updated when a refresh is initiated, unless
+it is itself in @RefreshScope (in which it will be rebuilt on a
+refresh and its dependencies re-injected, at which point they will be
+re-initialized from the refreshed @Configuration).
+ |
+
+
+
+
+
+
Encryption and Decryption
+
+
The Config Client has an Environment pre-processor for decrypting
+property values locally. It follows the same rules as the Config
+Server, and has the same external configuration via encrypt.*. Thus
+you can use encrypted values in the form {cipher}* and as long as
+there is a valid key then they will be decrypted before the main
+application context gets the Environment. To use the encryption
+features in a client you need to include Spring Security RSA in your
+classpath (Maven co-ordinates
+"org.springframework.security:spring-security-rsa") and you also need
+the full strength JCE extensions in your JVM (google it and download
+from Oracle).
+
+
+
+
Endpoints
+
+
For a Spring Boot Actuator application there are some additional management endpoints:
+
+
+
+-
+
POST to /env to update the Environment and rebind @ConfigurationProperties and log levels
+
+-
+
/refresh for re-loading the boot strap context and refreshing the @RefreshScope beans
+
+-
+
/restart for closing the ApplicationContext and restarting it (disabled by default)
+
+-
+
/pause and /resume for calling the Lifecycle methods (stop() and start() on the ApplicationContext)
+
+
+
+
+
Locating Remote Configuration Resources
-
The Config Service serves property sources from /{name}/{env}/{label}, where the default bindings in the client app are
+
The Config Service serves property sources from /{name}/{env}/{label}, where the default bindings in the
+client app are
@@ -1911,11 +1376,201 @@ an Exception.
(where * is "name", "env" or "label"). The "label" is useful for
rolling back to previous versions of configuration; with the default
Config Server implementation it can be a git label, branch name or
-commit id. Label can also be provided as a comma-separated list, in
-which case the items in the list are tried on-by-one until one succeeds.
-This can be useful when working on a feature branch, for instance,
-when you might want to align the config label with your branch, but
-make it optional (e.g. spring.cloud.config.label=myfeature,develop).
+commit id.
+
+
+
+
The Bootstrap Application Context
+
+
The Config Client operates by creating a "bootstrap" application
+context, which is a parent context for the main application. Out of
+the box it is responsible for loading configuration properties from
+the Config Server, and also decrypting properties in the local
+external configuration files. The two contexts share an Environment
+which is the source of external properties for any Spring
+application. Bootstrap properties are added with high precedence, so
+they cannot be overridden by local configuration.
+
+
+
The bootstrap context uses a different convention for locating
+external configuration than the main application context, so instead
+of application.yml (or .properties) you use bootstrap.yml,
+keeping the external configuration for bootstrap and main context
+nicely separate. Example:
+
+
+
bootstrap.yml
+
+
spring:
+ application:
+ name: foo
+ cloud:
+ config:
+ uri: ${SPRING_CONFIG_URI:http://localhost:8888}
+
+
+
+
It is a good idea to set the spring.application.name (in
+bootstrap.yml or application.yml) if your application needs any
+application-specific configuration from the server.
+
+
+
You can disable the bootstrap process completely by setting
+spring.cloud.bootstrap.enabled=false (e.g. in System properties).
+
+
+
+
Application Context Hierarchies
+
+
If you build an application context from SpringApplication or
+SpringApplicationBuilder, then the Bootstrap context is added as a
+parent to that context. It is a feature of Spring that child contexts
+inherit property sources and profiles from their parent, so the "main"
+application context will contain additional property sources, compared
+to building the same context without Spring Cloud Config. The
+additional property sources are:
+
+
+
+-
+
"bootstrap": an optional CompositePropertySource appears with high
+priority if any PropertySourceLocators are found in the Bootstrap
+context, and they have non-empty properties. An example would be
+properties from the Spring Cloud Config Server. See
+below for instructions
+on how to customize the contents of this property source.
+
+-
+
"applicationConfig: [classpath:bootstrap.yml]" (and friends if
+Spring profiles are active). If you have a bootstrap.yml (or
+properties) then those properties are used to configure the Bootstrap
+context, and then they get added to the child context when its parent
+is set. They have lower precedence than the application.yml (or
+properties) and any other property sources that are added to the child
+as a normal part of the process of creating a Spring Boot
+application. See below for
+instructions on how to customize the contents of these property
+sources.
+
+
+
+
+
Because of the ordering rules of property sources the "bootstrap"
+entries take precedence, but note that these do not contain any data
+from bootstrap.yml, which has very low precedence, but can be used
+to set defaults.
+
+
+
You can extend the context hierarchy by simply setting the parent
+context of any ApplicationContext you create, e.g. using its own
+interface, or with the SpringApplicationBuilder convenience methods
+(parent(), child() and sibling()). The bootstrap context will be
+the parent of the most senior ancestor that you create yourself.
+Every context in the hierarchy will have its own "bootstrap" property
+source (possibly empty) to avoid promoting values inadvertently from
+parents down to their descendants. Every context in the hierarchy can
+also (in principle) have a different spring.application.name and
+hence a different remote property source if there is a Config
+Server. Normal Spring application context behaviour rules apply to
+property resolution: properties from a child context override those in
+the parent, by name and also by property source name (if the child has
+a property source with the same name as the parent, the one from the
+parent is not included in the child).
+
+
+
Note that the SpringApplicationBuilder allows you to share an
+Environment amongst the whole hierarchy, but that is not the
+default. Thus, sibling contexts in particular do not need to have the
+same profiles or property sources, even though they will share common
+things with their parent.
+
+
+
+
Changing the Location of Bootstrap Properties
+
+
The bootstrap.yml (or .properties) location can be specified using
+`spring.cloud.bootstrap.name (default "bootstrap") or
+spring.cloud.bootstrap.location (default empty), e.g. in System
+properties. Those properties behave like the spring.config.*
+variants with the same name, in fact they are used to set up the
+bootstrap ApplicationContext by setting those properties in its
+Environment. If there is an active profile (from
+spring.profiles.active or through the Environment API in the
+context you are building) then properties in that profile will be
+loaded as well, just like in a regular Spring Boot app, e.g. from
+bootstrap-development.properties for a "development" profile.
+
+
+
+
Customizing the Bootstrap Configuration
+
+
The bootstrap context can be trained to do anything you like by adding
+entries to /META-INF/spring.factories under the key
+org.springframework.cloud.bootstrap.BootstrapConfiguration. This is
+a comma-separated list of Spring @Configuration classes which will
+be used to create the context. Any beans that you want to be available
+to the main application context for autowiring can be created here,
+and also there is a special contract for @Beans of type
+ApplicationContextInitializer.
+
+
+
The bootstrap process ends by injecting initializers into the main
+SpringApplication instance (i.e. the normal Spring Boot startup
+sequence, whether it is running as a standalone app or deployed in an
+application server). First a bootstrap context is created from the
+classes found in spring.factories and then all @Beans of type
+ApplicationContextInitializer are added to the main
+SpringApplication before it is started.
+
+
+
+
Customizing the Bootstrap Property Sources
+
+
The default property source for external configuration added by the
+bootstrap process is the Config Server, but you can add additional
+sources by adding beans of type PropertySourceLocator to the
+bootstrap context (via spring.factories). You could use this to
+insert additional properties from a different server, or from a
+database, for instance.
+
+
+
As an example, consider the following trivial custom locator:
+
+
+
+
@Configuration
+public class CustomPropertySourceLocator implements PropertySourceLocator {
+
+ @Override
+ public PropertySource<?> locate(Environment environment) {
+ return new MapPropertySource("customProperty",
+ Collections.<String, Object>singletonMap("property.from.sample.custom.source", "worked as intended"));
+ }
+
+}
+
+
+
+
The Environment that is passed in is the one for the
+ApplicationContext about to be created, i.e. the one that we are
+supplying additional property sources for. It will already have its
+normal Spring Boot-provided property sources, so you can use those to
+locate a property source specific to this Environment (e.g. by
+keying it on the spring.application.name, as is done in the default
+Config Server property source locator).
+
+
+
If you create a jar with this class in it and then add a
+META-INF/spring.factories containing:
+
+
+
+
org.springframework.cloud.bootstrap.BootstrapConfiguration=sample.custom.CustomPropertySourceLocator
+
+
+
+
then the "customProperty" PropertySource will show up in any
+application that includes that jar on its classpath.
@@ -1997,7 +1652,7 @@ Intelligent Routing (Zuul) and Client Side Load Balancing (Ribbon).
Registering with Eureka
-
When a client registers with Eureka, it provides meta-data about itself
+
When a client registers with Eureka, it provide meta-data about itself
such as host and port, health indicator URL, home page etc. Eureka
receives heartbeat messages from each instance belonging to a service.
If the heartbeat fails over a configurable timetable, the instance is
@@ -2106,9 +1761,9 @@ application, so it’s helpful if they are accurate.
eureka:
instance:
- hostname: ${vcap.application.uris[0]}
- nonSecurePort: 80
metadataMap:
+ hostname: ${vcap.application.uris[0]}
+ nonSecurePort: 80
instanceId: ${vcap.application.instance_id:${spring.application.name}:${spring.application.instance_id:${server.port}}}
@@ -2131,7 +1786,7 @@ application, so it’s helpful if they are accurate.
-
With this metadata, and multiple service instances deployed on
+
With this meatdata, and multiple service instances deployed on
localhost, the random value will kick in there to make the instance
unique. In Cloudfoundry the spring.application.instance_id will be
populated automatically in a Spring Boot Actuator application, so the
@@ -2143,9 +1798,7 @@ random value will not be needed.
Using the DiscoveryClient
Once you have an app that is @EnableEurekaClient you can use it to
-discover service instances from the Eureka Server. One way to do that is to use the native
-com.netflix.discovery.DiscoveryClient (as opposed to the Spring
-Cloud DiscoveryClient), e.g.
+discover service instances from the
Eureka Server. One way to do that is to use the native
DiscoveryClient, e.g.
@@ -2178,7 +1831,7 @@ another SmartLifecycle with higher phase.
-
Alternatives to the native Netflix DiscoveryClient
+
Alternatives to the DiscoveryClient
You don’t have to use the raw Netflix DiscoveryClient and usually it
is more convenient to use it behind a wrapper of some sort. Spring
@@ -2190,25 +1843,6 @@ can simply set <client>.ribbon.listOfServers to a comma-separ
list of physical addresses (or hostnames), where <client> is the ID
of the client.
-
-
You can also use the org.springframework.cloud.client.discovery.DiscoveryClient
-which provides a simple API for discovery clients that is not specific
-to Netflix, e.g.
-
-
-
-
@Autowired
-private DiscoveryClient discoveryClient;
-
-public String serviceUrl() {
- List<ServiceInstance> list = client.getInstances("STORES");
- if (list != null && list.size() > 0 ) {
- return list.get(0).getUri();
- }
- return null;
-}
-
-
Why is it so Slow to Register a Service?
@@ -2231,11 +1865,12 @@ assumptions about the lease renewal period.
Service Discovery: Eureka Server
-
Example eureka server (e.g. using spring-cloud-starter-eureka-server to set up the classpath):
+
Example eureka server:
-
@SpringBootApplication
+@Configuration
+@EnableAutoConfiguration
@EnableEurekaServer
public class Application {
@@ -2304,32 +1939,34 @@ springBoot {
-
+
|
- Tip
+Note
|
- Due to Gradle’s dependency resolution rules and the lack of a parent bom feature, simply depending on spring-cloud-starter-eureka-server can cause failures on application startup. To remedy this the Spring dependency management plugin must be added and the Spring cloud starter parent bom must be imported like so:
+ The Eureka server is tied to log4j and doesn’t work with logback,
+so the dependency configuration
+has to be tweaked compared to a normal Spring Boot app. The
+spring-cloud-starter-eureka-server does this for you, but if you
+add logback transitively through another dependency you will need to
+exclude it manually, e.g. in Maven
- build.gradle
+ pom.xml
- buildscript {
- dependencies {
- classpath "io.spring.gradle:dependency-management-plugin:0.4.0.RELEASE"
- }
-}
-
-apply plugin: "io.spring.dependency-management"
-
-dependencyManagement {
- imports {
- mavenBom 'org.springframework.cloud:spring-cloud-starter-parent:1.0.0.RELEASE'
- }
-}
+ <dependency>
+ <groupId>org.springframework.boot</groupId>
+ <artifactId>spring-boot-starter-web</artifactId>
+ <exclusions>
+ <exclusion>
+ <artifactId>spring-boot-starter-logging</artifactId>
+ <groupId>org.springframework.boot</groupId>
+ </exclusion>
+ </exclusions>
+</dependency>
|
@@ -2477,8 +2114,9 @@ IP Address rather than its hostname.
-
@SpringBootApplication
-@EnableCircuitBreaker
+@Configuration
+@EnableAutoConfiguration
+@EnableHystrix
public class Application {
public static void main(String[] args) {
@@ -2516,30 +2154,6 @@ attribute with a list of @HystrixProperty annotations. See
for more details. See the Hystrix wiki
for details on the properties available.
-
-
Propagating the Security Context or using Spring Scopes
-
-
If you want some thread local context to propagate into a @HystrixCommand the default declaration will not work because it executes the command in a thread pool (in case of timeouts). You can switch Hystrix to use the same thread as the caller using some configuration, or directly in the annotation, by asking it to use a different "Isolation Strategy". For example:
-
-
-
-
@HystrixCommand(fallbackMethod = "stubMyService",
- commandProperties = {
- @HystrixProperty(name="execution.isolation.strategy", value="SEMAPHORE")
- }
-)
-...
-
-
-
-
The same thing applies if you are using @SessionScope or @RequestScope. You will know when you need to do this because of a runtime exception that says it can’t find the scoped context.
-
-
-
In particular you might be interested
-
-
-
-
Health Indicator
The state of the connected circuit breakers are also exposed in the
/health endpoint of the calling application.
@@ -2557,7 +2171,6 @@ for details on the properties available.
}
-
Hystrix Metrics Stream
@@ -2592,10 +2205,10 @@ for details on the properties available.
Turbine
-
Looking at an individual instances Hystrix data is not very useful in terms of the overall health of the system. Turbine is an application that aggregates all of the relevant /hystrix.stream endpoints into a combined /turbine.stream for use in the Hystrix Dashboard. Individual instances are located via Eureka. Running Turbine is as simple as annotating your main class with the @EnableTurbine annotation (e.g. using spring-cloud-starter-turbine to set up the classpath). All of the documented configuration properties from the Turbine 1 wiki apply. The only difference is that the turbine.instanceUrlSuffix does not need the port prepended as this is handled automatically unless turbine.instanceInsertPort=false.
+
Looking at an individual instances Hystrix data is not very useful in terms of the overall health of the system. Turbine is an application that aggregates all of the relevant /hystrix.stream endpoints into a combined /turbine.stream for use in the Hystrix Dashboard. Individual instances are located via Eureka. Running Turbine is as simple as annotating your main class with the @EnableTurbine annotation. All of the documented configuration properties from the Turbine 1 wiki apply. The only difference is that the turbine.instanceUrlSuffix does not need the port prepended as this is handled automatically unless turbine.instanceInsertPort=false.
-
The configuration key turbine.appConfig is a list of eureka serviceIds that turbine will use to lookup instances. The turbine stream is then used in the Hystrix dashboard using a url that looks like: http://my.turbine.sever:8080/turbine.stream?cluster=<CLUSTERNAME> (the cluster parameter can be omitted if the name is "default"). The cluster parameter must match an entry in turbine.aggregator.clusterConfig. Values returned from eureka are uppercase, thus we expect this example to work if there is an app registered with Eureka called "customers":
+
Configuration key turbine.appConfig is a list of eureka serviceId’s that turbine will use to lookup instances. The turbine stream is then used in the Hystrix dashboard using a url that looks like: http://my.turbine.sever:8080/turbine.stream?cluster=<CLUSTERNAME> (the cluster parameter can be omitted if the name is "default"). The cluster parameter must match an entry in turbine.aggregator.clusterConfig. Value returned from eureka are uppercase, thus we expect this example to work if there is an app registered with Eureka called "customers":
@@ -2606,22 +2219,7 @@ for details on the properties available.
-
The clusterName can be customized by a SPEL expression in turbine.clusterNameExpression with root an instance of InstanceInfo. The default value is appName, which means that the Eureka serviceId ends up as the cluster key (i.e. the InstanceInfo for customers has an appName of "CUSTOMERS"). A different example would be turbine.clusterNameExpression=aSGName, which would get the cluster name from the AWS ASG name. Another example:
-
-
-
-
turbine:
- aggregator:
- clusterConfig: SYSTEM,USER
- appConfig: customers,stores,ui,admin
- clusterNameExpression: metadata.cluster
-
-
-
-
In this case, the cluster name from 4 services is pulled from their metadata map, and is expected to have values that include "SYSTEM" and "USER".
-
-
-
To use the "default" cluster for all apps you need a string literal expression (with single quotes):
+
The clusterName can be customized by a SPEL expression in turbine.clusterNameExpression. For example, turbine.clusterNameExpression=aSGName would get the cluster name from the AWS ASG name. To use the "default" cluster for all apps you need a string literal expression (with single quotes):
@@ -2682,7 +2280,7 @@ so if you are using
@FeignClient then this section also applies.
A central concept in Ribbon is that of the named client. Each load
balancer is part of an ensemble of components that work together to
-contact a remote server on demand, and the ensemble has a name that
+contact a remote server on demend, and the ensemble has a name that
you give it as an application developer (e.g. using the @FeignClient
annotation). Spring Cloud creates a new ensemble as an
ApplicationContext on demand for each named client using
@@ -2717,24 +2315,6 @@ public class TestConfiguration {
RibbonClientConfiguration together with any in FooConfiguration
(where the latter generally will override the former).
-
-
-
-|
- Warning
- |
-
-The FooConfiguration has to be @Configuration but take
-care that it is not in a @ComponentScan for the main application
-context, otherwise it will be shared by all the @RibbonClients. If
-you use @ComponentScan (or @SpringBootApplication) you need to
-take steps to avoid it being included (for instance put it in a
-separate, non-overlapping package, or specify the packages to scan
-explicitly in the @ComponentScan).
- |
-
-
-
Spring Cloud Netflix provides the following beans by default for ribbon
(BeanType beanName: ClassName):
@@ -2823,21 +2403,6 @@ configuration like this
-
Example: Disable Eureka use in Ribbon
-
-
Setting the property ribbon.eureka.enabled = false will explicitly
-disable the use of Eureka in Ribbon.
-
-
-
application.yml
-
-
ribbon:
- eureka:
- enabled: false
-
-
-
-
Using the Ribbon API Directly
You can also use the LoadBalancerClient directly. Example:
@@ -2857,6 +2422,33 @@ disable the use of Eureka in Ribbon.
+
+
Spring RestTemplate as a Ribbon Client
+
+
You can use Ribbon indirectly via an autoconfigured RestTemplate
+(provided Spring Cloud and Ribbon are both on the classpath):
+
+
+
+
public class MyClass {
+ @Autowired
+ private RestTemplate restTemplate;
+
+ public String doOtherStuff() {
+ String results = restTemplate.getForObject("http://stores/stores", String.class);
+ return results;
+ }
+}
+
+
+
+
The URI is inspected to see if it has a full host name, or a virtual
+one. If it is virtual the Ribbon client is used to create a full
+physical address. See
+RibbonAutoConfiguration
+for details of how the RestTemplate is set up.
+
+
@@ -3057,8 +2649,8 @@ and the serviceId independently:
This means that http calls to "/myusers" get forwarded to the
"users_service" service. The route has to have a "path" which can be
-specified as an ant-style pattern, so "/myusers/*" only matches one
-level, but "/myusers/**" matches hierarchically.
+specified as an ant-style pattern, so "/myusers/
" only matches one
+level, but "/myusers/*" matches hierarchically.
The location of the backend can be specified as either a "serviceId"
@@ -3075,30 +2667,6 @@ level, but "/myusers/**" matches hierarchically.
-
These simple url-routes doesn’t get executed as HystrixCommand nor can you loadbalance multiple url with Ribbon.
-To achieve this specify a service-route and configure a Ribbon client for the
-serviceId (this currently requires disabling Eureka support in Ribbon:
-see above for more information), e.g.
-
-
-
application.yml
-
-
zuul:
- routes:
- users:
- path: /myusers/**
- serviceId: users
-
-ribbon:
- eureka:
- enabled: false
-
-users:
- ribbon:
- listOfServers: example.com,google.com
-
-
-
To add a prefix to all mappings, set zuul.prefix to a value, such as
/api. The proxy prefix is stripped from the request before the
request is forwarded by default (switch this behaviour off with
@@ -3139,47 +2707,11 @@ server if you set a default route ("/"), for example zuul.route.home:
-
Uploading Files through Zuul
-
-
If you @EnableZuulProxy you can use the proxy paths to
-upload files and it should just work as long as the files
-are small. For large files there is an alternative path
-which bypasses the Spring DispatcherServlet (to
-avoid multipart processing) in "/zuul/". I.e. if
-zuul.routes.customers=/customers/* then you can
-POST large files to "/zuul/customers/*". The servlet
-path is externalized via zuul.servletPath. Extremely
-large files will also require elevated timeout settings
-if the proxy route takes you through a Ribbon load
-balancer, e.g.
-
-
-
application.yml
-
-
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds: 60000
-ribbon:
- ConnectTimeout: 3000
- ReadTimeout: 60000
-
-
-
-
Note that for streaming to work with large files, you need to use chunked encoding in the request (which some browsers
-do not do by default). E.g. on the command line:
-
-
-
-
$ curl -v -H "Transfer-Encoding: chunked" \
- -F "file=@mylarge.iso" localhost:9999/zuul/simple/file
-
-
-
-
Plain Embedded Zuul
You can also run a Zuul server without the proxying, or switch on parts of the proxying platform selectively, if you
use @EnableZuulServer (instead of @EnableZuulProxy). Any beans that you add to the application of type ZuulFilter
-will be installed automatically, as they are with @EnableZuulProxy, but without any of the proxy filters being added
-automatically.
+will be installed automatically.
In this case the routes into the Zuul server are
@@ -3199,18 +2731,6 @@ still specified by configuring "zuul.routes.*", but there is no service discover
-
Disable Zuul Filters
-
-
Zuul for Spring Cloud comes with a number of ZuulFilter beans enabled by default
-in both proxy and server mode. See the zuul filters package for the
-possible filters that are enabled. If you want to disable one, simply set
-zuul.<SimpleClassName>.<filterType>.disable=true. By convention, the package after
-filters is the Zuul filter type. For example to disable
-org.springframework.cloud.netflix.zuul.filters.post.SendResponseFilter set
-zuul.SendResponseFilter.post.disable=true.
-
-
-
Polyglot support with Sidecar
Do you have non-jvm languages you want to take advantage of Eureka, Ribbon and
@@ -3322,12 +2842,7 @@ info:
Spring Cloud Bus
-
-
Spring Cloud Bus links nodes of a distributed system with a lightweight message broker. This can then be used to broadcast state changes (e.g. configuration changes) or other management instructions. A key idea is that the Bus is like a distributed Actuator for a Spring Boot application that is scaled out, but it can also be used as a communication channel between apps. The only implementation currently is with an AMQP broker as the transport, but the same basic feature set (and some more depending on the transport) is on the roadmap for other transports.
-
-
+Spring Cloud Bus links nodes of a distributed system with a lightweight message broker. This can then be used to broadcast state changes (e.g. configuration changes) or other management instructions. A key idea is that the Bus is like a distributed Actuator for a Spring Boot application that is scaled out, but it can also be used as a communication channel between apps. The only implementation currently is with an AMQP broker as the transport, but the same basic feature set (and some more depending on the transport) is on the roadmap for other transports.
@@ -3353,30 +2868,6 @@ info:
-
Addressing an Instance
-
-
-
The HTTP endpoints accept a "destination" parameter, e.g. "/bus/refresh?destination=customers:9000", where the destination is an ApplicationContext ID. If the ID is owned by an instance on the Bus then it will process the message and all other instances will ignore it. Spring Boot sets the ID for you in the ContextIdApplicationContextInitializer to a combination of the spring.application.name, active profiles and server.port by default.
-
-
-
-
-
Addressing all instances of a service
-
-
-
The "destination" parameter is used in a Spring PathMatcher (with the path separator as a colon :) to determine if an instance will process the message. Using the example from above, "/bus/refresh?destination=customers:**" will target all instances of the "customers" service regardless of the profiles and ports set as the ApplicationContext ID.
-
-
-
-
-
Application Context ID must be unique
-
-
-
The bus tries to eliminate processing an event twice, once from the original ApplicationEvent and once from the queue. To do this, it checks the sending application context id againts the current application context id. If multiple instances of a service have the same application context id, events will not be processed. Running on a local machine, each service will be on a different port and that will be part of the application context id. Cloud Foundry supplies an index to differentiate. To ensure that the application context id is the unique, set spring.application.index to something unique for each instance of a service. For example, in lattice, set spring.application.index=${INSTANCE_INDEX} in application.properties (or bootstrap.properties if using configserver).
-
-
-
-
Customizing the AMQP ConnectionFactory
@@ -3398,15 +2889,8 @@ and annotate them
@BusConnectionFactory and
@Primary r
Spring Boot Cloud CLI
-
-
Spring Boot CLI provides Spring Boot command line features for
-Spring Cloud. You can write Groovy scripts to run Spring Cloud component applications
-(e.g. @EnableEurekaServer). You can also easily do things like encryption and decryption to support Spring Cloud
-Config clients with secret configuration values.
-
-
+Spring Boot command line features for
+
Spring Cloud.
@@ -3421,7 +2905,7 @@ sure you have
$ spring version
-Spring CLI v1.2.3.RELEASE
+Spring CLI v1.2.1.RELEASE
@@ -3429,8 +2913,8 @@ Spring CLI v1.2.3.RELEASE
-
$ gvm install springboot 1.2.3.RELEASE
-$ gvm use springboot 1.2.3.RELEASE
+
$ gvm install springboot 1.2.1.RELEASE
+$ gvm use springboot 1.2.1.RELEASE
@@ -3439,9 +2923,11 @@ $ gvm use springboot 1.2.3.RELEASE
$ mvn install
-$ spring install org.springframework.cloud:spring-cloud-cli:1.0.2.RELEASE
+$ spring install org.springframework.cloud:spring-cloud-cli:1.0.0.BUILD-SNAPSHOT
+
+
Encryption and Decryption
@@ -3460,84 +2946,11 @@ in the JRE lib/security directory with the ones that you downloaded).
-
-
Writing Groovy Scripts and Running Applications
-
-
-
Spring Cloud CLI has support for most of the Spring Cloud declarative
-features, such as the @Enable* class of annotations. For example,
-here is a fully functional Eureka server
-
-
-
app.groovy
-
-
@EnableEurekaServer
-class Eureka {}
-
-
-
-
which you can run from the command line like this
-
-
-
-
$ spring run app.groovy
-
-
-
-
To include additional dependencies, often it suffices just to add the
-appropriate feature-enabling annotation, e.g. @EnableConfigServer,
-@EnableOAuth2Sso or @EnableEurekaClient. To manually include a
-dependency you can use a @Grab with the special "Spring Boot" short
-style artifact co-ordinates, i.e. with just the artifact ID (no need
-for group or version information), e.g. to set up a client app to
-listen on AMQP for management events from the Spring CLoud Bus:
-
-
-
app.groovy
-
-
@Grab('spring-cloud-starter-bus-amqp')
-@RestController
-class Service {
- @RequestMapping('/')
- def home() { [message: 'Hello'] }
-}
-
-
-
-
-
-
Encryption and Decryption
-
-
-
The Spring Cloud CLI comes with an "encrypt" and a "decrypt"
-command. Both accept arguments in the same form with a key specified
-as a mandatory "--key", e.g.
-
-
-
-
$ spring encrypt mysecret --key foo
-682bc583f4641835fa2db009355293665d2647dade3375c0ee201de2a49f7bda
-$ spring decrypt --key foo 682bc583f4641835fa2db009355293665d2647dade3375c0ee201de2a49f7bda
-mysecret
-
-
-
-
To use a key in a file (e.g. an RSA public key for encyption) prepend
-the key value with "@" and provide the file path, e.g.
-
-
-
-
$ spring encrypt mysecret --key @${HOME}/.ssh/id_rsa.pub
-AQAjPgt3eFZQXwt8tsHAVv/QHiY5sI2dRcR+...
-
-
-
Spring Cloud Security
-
-
Spring Cloud Security offers a set of primitives for building secure
+Spring Cloud Security offers a set of primitives for building secure
applications and services with minimum fuss. A declarative model which
can be heavily configured externally (or centrally) lends itself to
the implementation of large systems of co-operating, remote components,
@@ -3545,11 +2958,7 @@ usually with a central indentity management service. It is also extremely
easy to use in a service platform like Cloud Foundry. Building on
Spring Boot and Spring Security OAuth2 we can quickly create systems that
implement common patterns like single sign on, token relay and token
-exchange.
-
-
+exchange.
@@ -3611,17 +3020,16 @@ configuration:
application.yml
-
spring:
- oauth2:
- client:
- clientId: bd1c0a783ccdd1c9b9e4
- clientSecret: 1a9030fbca47a5b2c28e92f19050bb77824b5ad1
- accessTokenUri: https://github.com/login/oauth/access_token
- userAuthorizationUri: https://github.com/login/oauth/authorize
- clientAuthenticationScheme: form
- resource:
- userInfoUri: https://api.github.com/user
- preferTokenInfo: false
+
spring.oauth2:
+ client:
+ clientId: bd1c0a783ccdd1c9b9e4
+ clientSecret: 1a9030fbca47a5b2c28e92f19050bb77824b5ad1
+ tokenUri: https://github.com/login/oauth/access_token
+ authorizationUri: https://github.com/login/oauth/authorize
+ authenticationScheme: form
+ resource:
+ userInfoUri: https://api.github.com/user
+ preferTokenInfo: false
@@ -3681,11 +3089,10 @@ class Application {
application.yml
-
spring:
- oauth2:
- resource:
- userInfoUri: https://api.github.com/user
- preferTokenInfo: false
+
oauth2:
+ resource:
+ userInfoUri: https://api.github.com/user
+ preferTokenInfo: false
@@ -3769,16 +3176,6 @@ of
AuthorizationCodeResourceDetails so all its properties can be sp
-
Token Type in User Info
-
-
Google (and certain other 3rd party identity providers) is more strict
-about the token type name that is sent in the headers to the user info
-endpoint. The default is "Bearer" which suits most providers and
-matches the spec, but if you need to change it you can set
-spring.oauth2.resource.tokenType.
-
-
-
Customizing the RestTemplate
The SSO (and Resource Server) features use an OAuth2RestTemplate
@@ -4017,7 +3414,7 @@ correct header.
traditional app), and that in turn triggers some autoconfiguration for
a
ZuulFilter, which itself is activated because Zuul is on the
classpath (via
@EnableZuulProxy). The
-{github}/tree/master/src/main/java/org/springframework/cloud/security/oauth2/proxy/OAuth2TokenRelayFilter.java[filter]
+
filter
just extracts an access token from the currently authenticated user,
and puts it in a request header for the downstream requests.
@@ -4081,15 +3478,15 @@ relay if there is a token available, and passthru otherwise.
See
-{github}/tree/master/src/main/java/org/springframework/cloud/security/oauth2/proxy/ProxyAuthenticationProperties[
-ProxyAuthenticationProperties] for full details.
+
+ProxyAuthenticationProperties for full details.