diff --git a/spring-cloud.html b/spring-cloud.html index 16c8b73f..b1847619 100644 --- a/spring-cloud.html +++ b/spring-cloud.html @@ -423,6 +423,7 @@ body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-b
  • The Bootstrap Application Context
  • Application Context Hierarchies
  • Changing the Location of Bootstrap Properties
  • +
  • Overriding the Values of Remote Properties
  • Customizing the Bootstrap Configuration
  • Customizing the Bootstrap Property Sources
  • Environment Changes
  • @@ -558,220 +559,54 @@ body.book #toc,body.book #preamble,body.book h1.sect0,body.book .sect1>h2{page-b
  • Spring Cloud Stream Reference Manual
  • -
  • Spring Cloud Bus - -
  • -
  • Spring Cloud Sleuth - -
  • -
  • Spring Cloud Consul - -
  • -
  • Spring Cloud Zookeeper - -
  • -
  • Spring Boot Cloud CLI - -
  • -
  • Spring Cloud Security - -
  • -
  • Spring Cloud for Cloud Foundry - -
  • -
  • Spring Cloud Cluster - -
  • -
  • Appendix: Compendium of Configuration Properties
  • @@ -894,7 +729,7 @@ 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.

    +they cannot be overridden by local configuration, by default.

    The bootstrap context uses a different convention for locating @@ -1007,6 +842,26 @@ loaded as well, just like in a regular Spring Boot app, e.g. from

    +

    Overriding the Values of Remote Properties

    +
    +

    The property sources that are added to you application by the +bootstrap context are often "remote" (e.g. from a Config Server), and +by default they cannot be overridden locally, except on the command +line. If you want to allow your applications to override the remote +properties with their own System properties or config files, the +remote property source has to grant it permission by setting +spring.cloud.config.allowOverride=true (it doesn’t work to set this +locally). Once that flag is set there are some finer grained settings +to control the location of the remote properties in relation to System +properties and the application’s local configuration: +spring.cloud.config.overrideNone=true to override with any local +property source, and +spring.cloud.config.overrideSystemProperties=false if only System +properties and env vars should override the remote settings, but not +the local config files.

    +
    +
    +

    Customizing the Bootstrap Configuration

    The bootstrap context can be trained to do anything you like by adding @@ -4557,6 +4412,9 @@ route, e.g.

    url: https://dowstream
    +
    +

    Sensitive headers can also be set globally setting zuul.sensitiveHeaders. If sensitiveHeaders is set on a route, this will override the global sensitiveHeaders setting.

    +
    @@ -5243,8 +5101,8 @@ After executing several requests against your service, you can gather some very
    -

    This section goes into more detail about how you can work with Spring Cloud Stream. It covers topics -such as creating and running stream applications.

    +

    This section goes into more detail about how you can work with Spring Cloud Stream. +It covers topics such as creating and running stream applications.

    @@ -5252,16 +5110,13 @@ such as creating and running stream applications.

    Introducing Spring Cloud Stream

    -

    Spring Cloud Stream is a framework for building message-driven microservices. -Spring Cloud Stream builds upon Spring Boot to create DevOps friendly microservice applications and Spring Integration to provide connectivity to message brokers. -Spring Cloud Stream provides an opinionated configuration of message brokers, introducing the concepts of persistent pub/sub semantics, consumer groups and partitions across several middleware vendors. -This opinionated configuration provides the basis to create stream processing applications.

    +

    Spring Cloud Stream is a framework for building message-driven microservice applications. +Spring Cloud Stream builds upon Spring Boot to create standalone, production-grade Spring applications, and uses Spring Integration to provide connectivity to message brokers. +It provides opinionated configuration of middleware from several vendors, introducing the concepts of persistent publish-subscribe semantics, consumer groups, and partitions.

    -

    By adding @EnableBinding to your main application, you get immediate connectivity to a message broker and by adding @StreamListener to a method, you will receive events for stream processing.

    -
    -
    -

    Here’s a sample sink application for receiving external messages:

    +

    You can add the @EnableBinding annotation to your application to get immediate connectivity to a message broker, and you can add @StreamListener to a method to cause it to receive events for stream processing. +The following is a simple sink application which receives external messages.

    @@ -5286,9 +5141,12 @@ public class TimerSource {
    -

    @EnableBinding is parameterized by one or more interfaces (in this case a single Sink interface), which declares input and/or output channels. -The interfaces Source, Sink and Processor are provided but you can define others. -Here’s the definition of Source:

    +

    The @EnableBinding annotation takes one or more interfaces as parameters (in this case, the parameter is a single Sink interface). +An interface declares input and/or output channels. +Spring Cloud Stream provides the interfaces Source, Sink, and Processor; you can also define your own interfaces.

    +
    +
    +

    The following is the definition of the Source interface:

    @@ -5301,9 +5159,12 @@ Here’s the definition of Source:

    -

    The @Input annotation is used to identify input channels (messages entering the app), and @Output is used to identify output channels (messages leaving the app). -These annotations are optionally parameterized by a channel name. If the name is not provided then the method name is used instead. -An implementation of the interface is created for you and can be used in the application context by autowiring it, e.g. into a test case:

    +

    The @Input annotation identifies an input channel, through which received messages enter the application; the @Output annotation identifies an output channel, through which published messages leave the application. +The @Input and @Output annotations can take a channel name as a parameter; if a name is not provided, the name of the annotated method will be used.

    +
    +
    +

    Spring Cloud Stream will create an implementation of the interface for you. +You can use this in the application by autowiring it, as in the following example of a test case.

    @@ -5326,34 +5187,40 @@ public class StreamApplicationTests {
    -

    Spring Cloud Stream Main Concepts

    +

    Main Concepts

    -

    Spring Cloud Stream provides a number of abstractions and primitives that simplify writing message-driven microservices. -In this section we will provide an overview of:

    +

    Spring Cloud Stream provides a number of abstractions and primitives that simplify the writing of message-driven microservice applications. +This section gives an overview of the following:

    • -

      Spring Cloud Stream application model together with the Binder abstraction

      +

      Spring Cloud Stream’s application model

    • -

      Persistent publish-subscribe and consumer group support

      +

      The Binder abstraction

    • -

      Partitioning

      +

      Persistent publish-subscribe support

    • -

      Pluggable Binder API

      +

      Consumer group support

      +
    • +
    • +

      Partitioning support

      +
    • +
    • +

      A pluggable Binder API

    -

    Application structure

    +

    Application Model

    -

    A Spring Cloud Stream application consists of a middleware-neutral core that communicates with the outside world through input and output channels. -The channels are managed and injected into it by the framework, and a Binder connects them to the external brokers. -Different Binder implementations exist for different types of middleware, such as Kafka, Rabbit MQ, Redis or Gemfire, and an extensible API allows you to write your own Binder. There is also TestSupportBinder that leaves the channel as-is so a test author can interact with the channels directly and easily assert on what is received.

    +

    A Spring Cloud Stream application consists of a middleware-neutral core. +The application communicates with the outside world through input and output channels injected into it by Spring Cloud Stream. +Channels are connected to external brokers through middleware-specific Binder implementations.

    @@ -5361,56 +5228,72 @@ Different Binder implementations exist for different types of middl
    Figure 4. Spring Cloud Stream Application
    -
    -

    Spring Cloud Stream uses Spring Boot for configuration, and the Binder makes it possible for Spring Cloud Stream applications to be flexible in terms of how it connects to the middleware. -For example, deployers can dynamically choose the destinations that these channels connect to at runtime (e.g. Kafka topics or Rabbit MQ exchanges). -This can be done through external configuration properties in any form that is supported by Spring Boot (application arguments, environment variables, application.yml files, etc). -Taking the sink example from the previous section, providing the spring.cloud.stream.bindings.input.destination=raw-sensor-data property to the application will cause it to read from the raw-sensor-data Kafka topic, or from a queue bound to the raw-sensor-data exchange in Rabbit MQ. See Binding properties for more information on the available binder properties you can configure. You are also able to configure middleware specific properties, see [binder-spe cific-configuration] for more information.

    -
    -
    -

    Spring Cloud Stream will automatically detect and use a binder that is found on the classpath, so you can easily use different types of middleware with the same code, just by including a different binder at build time. -For more complex use cases, Spring Cloud Stream also provides the ability of packaging multiple binders within the same application and choosing what type of binder should be used at runtime, and even if multiple binders should be used at runtime for different channels.

    -

    Fat JAR

    -

    Spring Cloud Stream applications can be run in standalone mode from your IDE for testing. To run in production you can create an executable (or "fat") JAR using the standard Spring Boot tooling provided for Maven or Gradle.

    +

    Spring Cloud Stream applications can be run in standalone mode from your IDE for testing. +To run a Spring Cloud Stream application in production, you can create an executable (or "fat") JAR by using the standard Spring Boot tooling provided for Maven or Gradle.

    -

    Persistent publish subscribe and consumer groups

    +

    The Binder Abstraction

    -

    Communication between different applications follows a publish-subscribe pattern, with data being broadcast through shared topics. -This can be seen in the following picture, which shows a typical deployment for a set of interacting Spring Cloud Stream applications.

    +

    Spring Cloud Stream provides Binder implementations for Kafka, Rabbit MQ, Redis, and Gemfire. +Spring Cloud Stream also includes a TestSupportBinder, which leaves a channel unmodified so that tests can interact with channels directly and reliably assert on what is received. +You can use the extensible API to write your own Binder.

    +
    +
    +

    Spring Cloud Stream uses Spring Boot for configuration, and the Binder abstraction makes it possible for a Spring Cloud Stream application to be flexible in how it connects to middleware. +For example, deployers can dynamically choose, at runtime, the destinations (e.g., the Kafka topics or RabbitMQ exchanges) to which channels connect. +Such configuration can be provided through external configuration properties and in any form supported by Spring Boot (including application arguments, environment variables, and application.yml or application.properties files). +In the sink example from the Introducing Spring Cloud Stream section, setting the application property spring.cloud.stream.bindings.input.destination to raw-sensor-data will cause it to read from the raw-sensor-data Kafka topic, or from a queue bound to the raw-sensor-data RabbitMQ exchange.

    +
    +
    +

    Spring Cloud Stream automatically detects and uses a binder found on the classpath. +You can easily use different types of middleware with the same code: just include a different binder at build time. +For more complex use cases, you can also package multiple binders with your application and have it choose the binder, and even whether to use different binders for different channels, at runtime.

    +
    +
    +
    +

    Persistent Publish-Subscribe Support

    +
    +

    Communication between applications follows a publish-subscribe model, where data is broadcast through shared topics. +This can be seen in the following figure, which shows a typical deployment for a set of interacting Spring Cloud Stream applications.

    -SCSt with binder +SCSt sensors
    -
    Figure 5. Spring Cloud Stream Application topologies
    +
    Figure 5. Spring Cloud Stream Publish-Subscribe
    -

    Data reported by sensors to an HTTP endpoint is sent to a common destination named raw-sensor-data, from where it is independently processed by a microservice that computes time windowed averages, as well as by a microservice that ingests the raw data into HDFS. -In order to do so, both applications will declare the topic as their input at runtime. -The publish-subscribe communication model reduces the complexity of both the producer and the consumer, and allows adding new applications to the topology without disrupting the existing flow. -For example, downstream from the average calculator we can have a component that calculates the highest temperature values in order to display and monitor them. -Later on, we can add an application that interprets the very same flow of averages for fault detection. -The fact that all the communication is done through shared topics rather than point to point queues reduces the coupling between microservices.

    +

    Data reported by sensors to an HTTP endpoint is sent to a common destination named raw-sensor-data. +From the destination, it is independently processed by a microservice application that computes time-windowed averages and by another microservice application that ingests the raw data into HDFS. +In order to process the data, both applications declare the topic as their input at runtime.

    +
    +
    +

    The publish-subscribe communication model reduces the complexity of both the producer and the consumer, and allows new applications to be added to the topology without disruption of the existing flow. +For example, downstream from the average-calculating application, you can add an application that calculates the highest temperature values for display and monitoring. +You can then add another application that interprets the same flow of averages for fault detection. +Doing all communication through shared topics rather than point-to-point queues reduces coupling between microservices.

    While the concept of publish-subscribe messaging is not new, Spring Cloud Stream takes the extra step of making it an opinionated choice for its application model. -It also makes it easy for users to work with it across different platform by using the native support of the middleware.

    +By using native middleware support, Spring Cloud Stream also simplifies use of the publish-subscribe model across different platforms.

    -
    -

    Consumer Groups

    +
    +
    +

    Consumer Groups

    -

    While the publish subscribe model ensures that it is easy to connect multiple application by sharing a topic, it is equally important to be able to scale up by creating multiple instances of a given application. -When doing so, the different instances would find themselves in a competing consumer relationship with each other: only one of the instances is expected to handle the message. -Spring Cloud Stream models this behavior through the concept of a consumer group, which is similar to (and inspired by) the notion of consumer groups in Kafka. -Each consumer binding can specify a group name such as spring.cloud.stream.bindings.input.group=hdfsWrite or spring.cloud.stream.bindings.input.group=average, as shown in the picture. -All groups that subscribe to a given destination will receive a copy of the published data, but only one member of the group will receive a given message from that destination. -By default, when a group is not specified, Spring Cloud Stream assigns the application to an anonymous, independent, single-member consumer group that will be in a publish-subscribe relationship with all the other consumer groups.

    +

    While the publish-subscribe model makes it easy to connect applications through shared topics, the ability to scale up by creating multiple instances of a given application is equally important. +When doing this, different instances of an application are placed in a competing consumer relationship, where only one of the instances is expected to handle a given message.

    +
    +
    +

    Spring Cloud Stream models this behavior through the concept of a consumer group. +(Spring Cloud Stream consumer groups are similar to and inspired by Kafka consumer groups.) +Each consumer binding can use the spring.cloud.stream.bindings.input.group property to specify a group name. +For the consumers shown in the following figure, this property would be set as spring.cloud.stream.bindings.input.group=hdfsWrite or spring.cloud.stream.bindings.input.group=average.

    @@ -5418,27 +5301,48 @@ By default, when a group is not specified, Spring Cloud Stream assigns the appli
    Figure 6. Spring Cloud Stream Consumer Groups
    +
    +

    All groups which subscribe to a given destination receive a copy of published data, but only one member of each group receives a given message from that destination. +By default, when a group is not specified, Spring Cloud Stream assigns the application to an anonymous and independent single-member consumer group that is in a publish-subscribe relationship with all other consumer groups.

    Durability

    -

    Consistent with the opinionated application model of Spring Cloud Stream, consumer group subscriptions are durable. -This is to say that the binder implementation will ensure that group subscriptions are persistent and, once at least one subscription for a group has been created, that group will receive messages, even if they are sent while all the applications of the group were stopped. -Anonymous subscriptions are non-durable by nature. For some binder implementations (e.g. Rabbit) it is possible to have non-durable group subscriptions.

    +

    Consistent with the opinionated application model of Spring Cloud Stream, consumer group subscriptions are durable. +That is, a binder implementation ensures that group subscriptions are persistent, and once at least one subscription for a group has been created, the group will receive messages, even if they are sent while all applications in the group are stopped.

    +
    +
    +
    + + + + +
    +
    Note
    +
    +
    +

    Anonymous subscriptions are non-durable by nature. +For some binder implementations (e.g., RabbitMQ), it is possible to have non-durable group subscriptions.

    +
    +

    In general, it is preferable to always specify a consumer group when binding an application to a given destination. -When scaling up a Spring Cloud Stream application, a consumer group must be specified for each of its input bindings, in order to prevent its instances from receiving duplicate messages (unless that behavior is desired, which is a less common use case).

    +When scaling up a Spring Cloud Stream application, you must specify a consumer group for each of its input bindings. +This prevents the application’s instances from receiving duplicate messages (unless that behavior is desired, which is unusual).

    -

    Partitioning

    +

    Partitioning Support

    -

    Spring Cloud Stream provides support for partitioning data between multiple instances of a given application. -In a partitioned scenario, one or more producer application instances will send data to multiple consumer application instances, ensuring that data with common characteristics is processed by the same consumer instance. -The physical communication medium (e.g. the broker topic) is viewed as structured into multiple partitions. -This happens regardless of whether the broker type is naturally partitioned (e.g. Kafka) or not (e.g. Rabbit), Spring Cloud Stream provides a common abstraction for implementing partitioned processing use cases in a uniform fashion.

    +

    Spring Cloud Stream provides support for partitioning data between multiple instances of a given application. +In a partitioned scenario, the physical communication medium (e.g., the broker topic) is viewed as being structured into multiple partitions. +One or more producer application instances send data to multiple consumer application instances and ensure that data identified by common characteristics are processed by the same consumer instance.

    +
    +
    +

    Spring Cloud Stream provides a common abstraction for implementing partitioned processing use cases in a uniform fashion. +Partitioning can thus be used whether the broker itself is naturally partitioned (e.g., Kafka) or not (e.g., RabbitMQ).

    @@ -5447,27 +5351,40 @@ This happens regardless of whether the broker type is naturally partitioned (e.g
    Figure 7. Spring Cloud Stream Partitioning
    -

    Partitioning is a critical concept in stateful processing, where ensuring that all the related data is processed together is critical for either performance or consistency. -For example, in the time-windowed average calculation example, it is important that measurements from the same sensor land in the same application instance.

    +

    Partitioning is a critical concept in stateful processing, where it is critiical, for either performance or consistency reasons, to ensure that all related data is processed together. +For example, in the time-windowed average calculation example, it is important that all measurements from any given sensor are processed by the same application instance.

    +
    + + + + + +
    +
    Note
    +
    -

    Setting up a partitioned processing scenario requires configuring both the data producing and the data consuming end.

    +

    To set up a partitioned processing scenario, you must configure both the data-producing and the data-consuming ends.

    +
    +
    -

    Programming model

    +

    Programming Model

    -

    This section will describe the programming model of Spring Cloud Stream, which consists from a number of predefined annotations that can be used to declare bound inputs and output channels, as well as how to listen to them.

    +

    This section describes Spring Cloud Stream’s programming model. +Spring Cloud Stream provides a number of predefined annotations for declaring bound input and output channels as well as how to listen to channels.

    -

    Declaring and binding channels

    +

    Declaring and Binding Channels

    -

    Triggering binding via @EnableBinding

    +

    Triggering Binding Via @EnableBinding

    -

    A Spring application becomes a Spring Cloud Stream application when the @EnableBinding annotation is applied to one of its configuration classes. @EnableBinding itself is meta-annotated with @Configuration, and triggers the configuration of Spring Cloud Stream infrastructure as follows:

    +

    You can turn a Spring application into a Spring Cloud Stream application by applying the @EnableBinding annotation to one of the application’s configuration classes. +The @EnableBinding annotation itself is meta-annotated with @Configuration and triggers the configuration of Spring Cloud Stream infrastructure:

    @@ -5482,7 +5399,7 @@ public @interface EnableBinding {
    -

    @EnableBinding can be parameterized with one or more interface classes, containing methods that represent bindable components (typically message channels).

    +

    The @EnableBinding annotation can take as parameters one or more interface classes that contain methods which represent bindable components (typically message channels).

    @@ -5491,8 +5408,11 @@ public @interface EnableBinding {
    Note
    -As of version 1.0, the only supported bindable component is the Spring Messaging MessageChannel and its extensions SubscribableChannel and PollableChannel. -It is intended for future versions to extend support to other types of components, using the same mechanism. In this documentation, we will continue to refer to channels. +
    +

    In Spring Cloud Stream 1.0, the only supported bindable components are the Spring Messaging MessageChannel and its extensions SubscribableChannel and PollableChannel. +Future versions should extend this support to other types of components, using the same mechanism. +In this documentation, we will continue to refer to channels.

    +
    @@ -5501,7 +5421,7 @@ It is intended for future versions to extend support to other types of component

    @Input and @Output

    -

    A Spring Cloud Stream application can have an arbitrary number of input and output channels defined as @Input and @Output methods in an interface, as follows:

    +

    A Spring Cloud Stream application can have an arbitrary number of input and output channels defined in an interface as @Input and @Output methods:

    @@ -5519,7 +5439,7 @@ It is intended for future versions to extend support to other types of component
    -

    Using this interface as a parameter to @EnableBinding, as in the following example, will trigger the creation of three bound channels named orders, hotDrinks and coldDrinks respectively.

    +

    Using this interface as a parameter to @EnableBinding will trigger the creation of three bound channels named orders, hotDrinks, and coldDrinks, respectively.

    @@ -5531,9 +5451,9 @@ public class CafeConfiguration {
    -
    Customizing channel names
    +
    Customizing Channel Names
    -

    Both @Input and @Output allow specifying a customized name for the channel, as follows:

    +

    Using the @Input and @Output annotations, you can specify a customized channel name for the channel, as shown in the following example:

    @@ -5545,46 +5465,46 @@ public class CafeConfiguration {
    -

    In this case, the name of the bound channel being created will be inboundOrders.

    +

    In this example, the created bound channel will be named inboundOrders.

    Source, Sink, and Processor
    -

    For ease of addressing the most common use cases that involve either an input or an output channel, or both, out of the box Spring Cloud Stream provides three predefined interfaces.

    +

    For easy addressing of the most common use cases, which involve either an input channel, an output channel, or both, Spring Cloud Stream provides three predefined interfaces out of the box.

    -

    Source can be used for applications that have a single outbound channel.

    +

    Source can be used for an application which has a single outbound channel.

    public interface Source {
     
    -	String OUTPUT = "output";
    +  String OUTPUT = "output";
     
    -	@Output(Source.OUTPUT)
    -	MessageChannel output();
    +  @Output(Source.OUTPUT)
    +  MessageChannel output();
     
     }
    -

    Sink can be used for applications that have a single inbound channel.

    +

    Sink can be used for an application which has a single inbound channel.

    public interface Sink {
     
    -	String INPUT = "input";
    +  String INPUT = "input";
     
    -	@Input(Sink.INPUT)
    -	SubscribableChannel input();
    +  @Input(Sink.INPUT)
    +  SubscribableChannel input();
     
     }
    -

    Processor can be used for applications that have both an inbound and an outbound channel.

    +

    Processor can be used for an application which has both an inbound channel and an outbound channel.

    @@ -5593,17 +5513,21 @@ public class CafeConfiguration {
    -

    There is no special handling for either of these interfaces in Spring Cloud Stream, besides of the fact that they are provided out of the box.

    +

    Spring Cloud Stream provides no special handling for any of these interfaces; they are only provided out of the box.

    -

    Accessing bound channels

    +

    Accessing Bound Channels

    -
    Injecting the bound interfaces
    +
    Injecting the Bound Interfaces
    -

    For each of the bound interfaces, Spring Cloud Stream will generate a bean that implements it, and for which invoking an @Input or @Output annotated method will return the bound channel. -For example, the bean in the following example will send a message on the output channel every time its hello method is invoked, using the injected Source bean, and invoking output() to retrieve the target channel.

    +

    For each bound interface, Spring Cloud Stream will generate a bean that implements the interface. +Invoking a @Input-annotated or @Output-annotated method of one of these beans will return the relevant bound channel.

    +
    +
    +

    The bean in the following example sends a message on the output channel when its hello method is invoked. +It invokes output() on the injected Source bean to retrieve the target channel.

    @@ -5618,16 +5542,16 @@ public class SendingBean { } public void sayHello(String name) { - source.output().send(MessageBuilder.withPayload(body).build()); - } + source.output().send(MessageBuilder.withPayload(body).build()); + } }
    -
    Injecting channels directly
    +
    Injecting Channels Directly
    -

    Bound channels can be also injected directly. For example:

    +

    Bound channels can be also injected directly:

    @@ -5642,13 +5566,14 @@ public class SendingBean { } public void sayHello(String name) { - output.send(MessageBuilder.withPayload(body).build()); - } + output.send(MessageBuilder.withPayload(body).build()); + } }
    -

    Note that if the name of the channel is customized on the declaring annotation, that name should be used instead of the method name. Considering this declaration:

    +

    If the name of the channel is customized on the declaring annotation, that name should be used instead of the method name. +Given the following declaration:

    @@ -5660,7 +5585,7 @@ public class SendingBean {
    -

    The channel will be injected as follows:

    +

    The channel will be injected as shown in the following example:

    @@ -5676,22 +5601,24 @@ public class SendingBean { } public void sayHello(String name) { - customOutput.send(MessageBuilder.withPayload(body).build()); - } + customOutput.send(MessageBuilder.withPayload(body).build()); + } }
    -

    Programming model

    +

    Producing and Consuming Messages

    -

    Spring Cloud Stream allows you to write applications by either using Spring Integration annotations or Spring Cloud Stream’s @StreamListener annotation which is modeled after other Spring Messaging annotations (e.g. @MessageMapping, @JmsListener, @RabbitListener, etc.) but add content type management and type coercion features.

    +

    You can write a Spring Cloud Stream application using either Spring Integration annotations or Spring Cloud Stream’s @StreamListener annotation. +The @StreamListener annotation is modeled after other Spring Messaging annotations (such as @MessageMapping, @JmsListener, @RabbitListener, etc.) but adds content type management and type coercion features.

    -
    Native Spring Integration support
    +
    Native Spring Integration Support
    -

    Due to the fact that Spring Cloud Stream is Spring Integration based, it completely inherits its foundation and infrastructure, as well as the component. For example, the output channel of a Source can be attached to a MessageSource, as follows:

    +

    Because Spring Cloud Stream is based on Spring Integration, Stream completely inherits Integration’s foundation and infrastructure as well as the component itself. +For example, you can attach the output channel of a Source to a MessageSource:

    @@ -5710,29 +5637,29 @@ public class TimerSource {
    -

    Or, the channels of a processor can be used in a transformer, as follows:

    +

    Or you can use a processor’s channels in a transformer:

    @EnableBinding(Processor.class)
     public class TransformProcessor {
    -	@Transformer(inputChannel = Processor.INPUT, outputChannel = Processor.OUTPUT)
    -	public Object transform(String message) {
    -		return message.toUpper();
    -	}
    +  @Transformer(inputChannel = Processor.INPUT, outputChannel = Processor.OUTPUT)
    +  public Object transform(String message) {
    +    return message.toUpper();
    +  }
     }
    -
    @StreamListener for automatic content type handling
    +
    Using @StreamListener for Automatic Content Type Handling
    -

    Complementary to the Spring Integration support, Spring Cloud Stream provides a @StreamListener annotation of its own modeled by the other similar Spring Messaging annotations (e.g. @MessageMapping, @JmsListener, @RabbitListener, etc.). -It provides a simpler model for handling inbound messages, especially for dealing with use cases that involve content type management and type coercion. -Spring Cloud Stream provides an extensible MessageConverter mechanism for handling data conversion by bound channels and, in this case, for dispatching to @StreamListener annotated methods.

    +

    Complementary to its Spring Integration support, Spring Cloud Stream provides its own @StreamListener annotation, modeled after other Spring Messaging annotations (e.g. @MessageMapping, @JmsListener, @RabbitListener, etc.). +The @StreamListener annotation provides a simpler model for handling inbound messages, especially when dealing with use cases that involve content type management and type coercion.

    -

    For example, an application that processes external Vote events can be declared as follows:

    +

    Spring Cloud Stream provides an extensible MessageConverter mechanism for handling data conversion by bound channels and for, in this case, dispatching to methods annotated with @StreamListener. +The following is an example of an application which processes external Vote events:

    @@ -5743,19 +5670,28 @@ public class VoteHandler { VotingService votingService; @StreamListener(Sink.INPUT) - public void handle(Vote vote) { - votingService.record(vote); - } + public void handle(Vote vote) { + votingService.record(vote); + } }
    -

    The distinction between this approach and a Spring Integration @ServiceActivator becomes relevant if one considers an inbound Message with a String payload and a contentType header of application/json. -For @StreamListener, the MessageConverter mechanism will use the contentType header to parse the String into a Vote object.

    +

    The distinction between @StreamListener and a Spring Integration @ServiceActivator is seen when considering an inbound Message that has a String payload and a contentType header of application/json. +In the case of @StreamListener, the MessageConverter mechanism will use the contentType header to parse the String payload into a Vote object.

    -

    Just as with the other Spring Messaging methods, method arguments can be annotated with @Payload, @Headers and @Header. -For methods that return data, @SendTo must be used for specifying the output binding destination for data returned by the methods as follows:

    +

    As with other Spring Messaging methods, method arguments can be annotated with @Payload, @Headers and @Header.

    +
    +
    + + + + + +
    +
    Note
    +
    +
    +

    For methods which return data, you must use the @SendTo annotation to specify the output binding destination for data returned by the method:

    @@ -5767,12 +5703,16 @@ public class TransformProcessor { @StreamListener(Processor.INPUT) @SendTo(Processor.OUTPUT) - public VoteResult handle(Vote vote) { - return votingService.record(vote); - } + public VoteResult handle(Vote vote) { + return votingService.record(vote); + } }
    +
    +
    @@ -5780,7 +5720,10 @@ public class TransformProcessor {
    Note
    -Content type headers can be set by external applications in the case of Rabbit MQ, and they are supported as part of an extended internal protocol by Spring Cloud Stream for any type of transport (even the ones that do not support headers normally, like Kafka). +
    +

    In the case of RabbitMQ, content type headers can be set by external applications. +Spring Cloud Stream supports them as part of an extended internal protocol used for any type of transport (including transports, such as Kafka, that do not normally support headers).

    +
    @@ -5791,9 +5734,8 @@ Content type headers can be set by external applications in the case of Rabbit M

    Binder SPI

    -

    As described above, Spring Cloud Stream provides a binder abstraction for connecting to physical destinations. This -section will provide more information about the main concepts behind the Binder SPI, its main components, as well as -details specific to different implementations.

    +

    Spring Cloud Stream provides a Binder abstraction for use in connecting to physical destinations. +This section provides information about the main concepts behind the Binder SPI, its main components, and implementation-specific details.

    Producers and Consumers

    @@ -5804,20 +5746,16 @@ details specific to different implementations.

    Figure 8. Producers and Consumers
    -

    A producer is any component that sends messages to a channel. That channel can be bound to an external message broker -via a Binder implementation for that broker. When invoking the bindProducer method, the first parameter is the name -of the destination within that broker. The second parameter is the local channel instance to which the producer will be -sending messages, and the third parameter contains properties to be used within the adapter that is created for that -channel, such as a partition key expression.

    +

    A producer is any component that sends messages to a channel. +The channel can be bound to an external message broker via a Binder implementation for that broker. +When invoking the bindProducer() method, the first parameter is the name of the destination within the broker, the second parameter is the local channel instance to which the producer will send messages, and the third parameter contains properties (such as a partition key expression) to be used within the adapter that is created for that channel.

    -

    A consumer is any component that receives messages from a channel. As with the producer, the consumer’s channel can be -bound to an external message broker, and the first parameter for the bindConsumer method is the destination name. -However, on the consumer side, a second parameter provides the name of a logical group of consumers. Each group -represented by consumer bindings for a given destination will receive a copy of each message that a producer sends to -that destination (i.e. pub/sub semantics). If there are multiple consumer instances bound using the same group name, -then messages will be load balanced across those consumer instances so that each message sent by a producer would only -be consumed by a single consumer instance within each group (i.e. queue semantics).

    +

    A consumer is any component that receives messages from a channel. +As with a producer, the consumer’s channel can be bound to an external message broker. +When invoking the bindConsumer() method, the first parameter is the destination name, and a second parameter provides the name of a logical group of consumers. +Each group that is represented by consumer bindings for a given destination receives a copy of each message that a producer sends to that destination (i.e., publish-subscribe semantics). +If there are multiple consumer instances bound using the same group name, then messages will be load-balanced across those consumer instances so that each message sent by a producer is consumed by only a single consumer instance within each group (i.e., queueing semantics).

    @@ -5829,9 +5767,9 @@ be consumed by a single consumer instance within each group (i.e. queue semantic
    Figure 9. Kafka Binder
    -

    The Kafka Binder implementation maps the destination to a Kafka topic, and the consumer group maps directly to the same -Kafka concept. Spring Cloud Stream does not use the high level consumer, but implements a similar concept for the -simple consumer.

    +

    The Kafka Binder implementation maps the destination to a Kafka topic. +The consumer group maps directly to the same Kafka concept. +Spring Cloud Stream does not use the high-level consumer, but implements a similar concept for the simple consumer.

    @@ -5843,22 +5781,24 @@ simple consumer.

    Figure 10. RabbitMQ Binder
    -

    The RabbitMQ Binder implementation maps the destination to a TopicExchange, and for each consumer group, a Queue -will be bound to that TopicExchange. Each consumer instance that binds will trigger creation of a corresponding -RabbitMQ Consumer instance for its group’s Queue.

    +

    The RabbitMQ Binder implementation maps the destination to a TopicExchange. +For each consumer group, a Queue will be bound to that TopicExchange. +Each consumer instance that binds will trigger creation of a corresponding RabbitMQ Consumer instance for its group’s Queue.

    -

    Configuration options

    +

    Configuration Options

    -

    Spring Cloud Stream supports general configuration options, as well as configuration for bindings and binders. Some binders allow additional properties for the bindings, supporting middleware-specific features.

    +

    Spring Cloud Stream supports general configuration options as well as configuration for bindings and binders. +Some binders allow additional binding properties to support middleware-specific features.

    -

    All configuration options can be provided to Spring Cloud Stream applications via all the mechanisms supported by Spring Boot: application arguments, environment variables, YML files etc.

    +

    Configuration options can be provided to Spring Cloud Stream applications via any mechanism supported by Spring Boot. +This includes application arguments, environment variables, and YAML or .properties files.

    Spring Cloud Stream Properties

    @@ -5866,56 +5806,80 @@ RabbitMQ Consumer instance for its group’s Queue.

    spring.cloud.stream.instanceCount
    -

    The number of deployed instances of the same application. Must be set for partitioning and with Kafka. Default value is 1.

    +

    The number of deployed instances of an application. +Must be set for partitioning and if using Kafka.

    +
    +

    Default: 1.

    +
    spring.cloud.stream.instanceIndex
    -

    The instance index of the application, a number from 0 to instanceCount-1. Used for partitioning and with Kafka. Automatically set in Cloud Foundry to match the instance index of the application.

    +

    The instance index of the application: a number from 0 to instanceCount-1. +Used for partitioning and with Kafka. +Automatically set in Cloud Foundry to match the application’s instance index.

    spring.cloud.stream.dynamicDestinations
    -

    A list of destinations that can be bound dynamically, for example in a dynamic routing scenario. Only listed destinations can be bound if set. Default empty, allowing any destination to be bound.

    +

    A list of destinations that can be bound dynamically (for example, in a dynamic routing scenario). +If set, only listed destinations can be bound.

    +
    +

    Default: empty (allowing any destination to be bound).

    +
    spring.cloud.stream.defaultBinder
    -

    The default binder to use, if there are multiple binders configured. See multiple binders.

    +

    The default binder to use, if multiple binders are configured. +See Multiple Binders on the Classpath.

    -

    Binding properties

    +

    Binding Properties

    -

    Binding properties are supplied using the format spring.cloud.stream.bindings.<channelName>.<property>=<value>.<channelName> represents the name of the channel being configured, e.g. output for a Source. -In what follows, we will indicate where the spring.cloud.stream.bindings.<channelName>. prefix is omitted and focus just on the property name, with the understanding that the prefix will be included at runtime.

    +

    Binding properties are supplied using the format spring.cloud.stream.bindings.<channelName>.<property>=<value>. +The <channelName> represents the name of the channel being configured (e.g., output for a Source).

    +
    +
    +

    In what follows, we indicate where we have omitted the spring.cloud.stream.bindings.<channelName>. prefix and focus just on the property name, with the understanding that the prefix will be included at runtime.

    -

    Properties for the use of Spring Cloud Stream

    +

    Properties for Use of Spring Cloud Stream

    The following binding properties are available for both input and output bindings and -must be prefixed with spring.cloud.stream.bindings.<channelName>. .

    +must be prefixed with spring.cloud.stream.bindings.<channelName>..

    destination
    -

    The target destination of channel on the bound middleware, e.g. Rabbit MQ exchange or -Kafka topic. If not set, the channel name will be used instead.

    +

    The target destination of a channel on the bound middleware (e.g., the RabbitMQ exchange or Kafka topic). +If not set, the channel name is used instead.

    group
    -

    The consumer group of the channel. This property applies only to inbound bindings. -By default it is null, and indicates an anonymous consumer. See consumer groups.

    +

    The consumer group of the channel. +Applies only to inbound bindings. +See Consumer Groups.

    +
    +

    Default: null (indicating an anonymous consumer).

    +
    contentType
    -

    The content type of the channel. By default it is null and no type -coercion is performed. See [content type management].

    +

    The content type of the channel. +//See [content type management].

    +
    +

    Default: null (so that no type coercion is performed).

    +
    binder
    -

    The binder used by this binding. By default, it is set to null and will -use the default binder, if one exists. See Multiple Binders on the Classpath for details.

    +

    The binder used by this binding. +See Multiple Binders on the Classpath for details.

    +
    +

    Default: null (the default binder will be used, if one exists).

    +
    @@ -5923,83 +5887,135 @@ use the default binder, if one exists. See Multiple

    Consumer properties

    -

    The following binding properties are available for input bindings only and must be prefixed with spring.cloud.stream.bindings.<channelName>.consumer:

    +

    The following binding properties are available for input bindings only and must be prefixed with spring.cloud.stream.bindings.<channelName>.consumer..

    concurrency
    -

    The concurrency of the inbound consumer. By default, set to 1.

    +

    The concurrency of the inbound consumer.

    +
    +

    Default: 1.

    +
    partitioned
    -

    Must be set to true if the consumer is receiving data from a partitioned -producer. By default it is set to false.

    +

    Whether the consumer receives data from a partitioned producer.

    +
    +

    Default: false.

    +
    +
    +
    headerMode
    +
    +

    When set to raw, disables header parsing on input. +Effective only for messaging middleware that does not support message headers natively and requires header embedding. +Useful when inbound data is coming from outside Spring Cloud Stream applications.

    +
    +

    Default: embeddedHeaders.

    +
    maxAttempts
    -

    The number of attempts of re-processing an inbound message. Default '3'. (Ignored by Kafka, currently).

    +

    The number of attempts of re-processing an inbound message. +Currently ignored by Kafka.

    +
    +

    Default: 3.

    +
    backOffInitialInterval
    -

    The backoff initial interval on retry. Default 1000.(Ignored by Kafka, currently).

    +

    The backoff initial interval on retry. +Currently ignored by Kafka.

    +
    +

    Default: 1000.

    +
    backOffMaxInterval
    -

    The maximum backoff interval. Default 10000.(Ignored by Kafka, currently).

    +

    The maximum backoff interval. +Currently ignored by Kafka.

    +
    +

    Default: 10000.

    +
    backOffMultiplier
    -

    The backoff multiplier. Default 2.0.

    +

    The backoff multiplier.

    +
    +

    Default: 2.0.

    +
    -

    Producer properties

    +

    Producer Properties

    -

    The following binding properties are available for output bindings only and must be prefixed with spring.cloud.stream.bindings.<channelName>.producer:

    +

    The following binding properties are available for output bindings only and must be prefixed with spring.cloud.stream.bindings.<channelName>.producer..

    partitionKeyExpression
    -

    A SpEL expression for partitioning outbound data. Default: null. If either this property is set or -partitionKeyExtractorClass is present, outbound data on this channel will be partitioned, -and partitionCount must be set to a value larger than 1 to be effective. -The two options are mutually exclusive. See Partitioning.

    +

    A SpEL expression that determines how to partition outbound data. +If set, or if partitionKeyExtractorClass is set, outbound data on this channel will be partitioned, and partitionCount must be set to a value greater than 1 to be effective. +The two options are mutually exclusive. +See Partitioning Support.

    +
    +

    Default: null.

    +
    partitionKeyExtractorClass
    -

    A PartitionKeyExtractorStrategy implementation. Default: null. If either this property is set or -partitionKeyExpression is present, outbound data on this channel will be partitioned, -and partitionCount must be set to a value larger than 1 to be effective. -The two options are mutually exclusive. See Partitioning.

    +

    A PartitionKeyExtractorStrategy implementation. +If set, or if partitionKeyExpression is set, outbound data on this channel will be partitioned, and partitionCount must be set to a value greater than 1 to be effective. +The two options are mutually exclusive. +See Partitioning Support.

    +
    +

    Default: null.

    +
    partitionSelectorClass
    -

    A PartitionSelectorStrategy implementation. Default null. Mutually exclusive with -partitionSelectorExpression. If none is set, the partition will be selected as the -hashCode(key) % partitionCount, where key is computed via either partitionKeyExpression -or partitionKeyExtractorClass.

    +

    A PartitionSelectorStrategy implementation. +Mutually exclusive with partitionSelectorExpression. +If neither is set, the partition will be selected as the hashCode(key) % partitionCount, where key is computed via either partitionKeyExpression or partitionKeyExtractorClass.

    +
    +

    Default: null.

    +
    partitionSelectorExpression
    -

    A SpEL expression for customizing partition selection. Default null. Mutually exclusive with -partitionSelectorClass. If none is set, the partition will be selected as the -hashCode(key) % partitionCount, where key is computed via either partitionKeyExpression -or partitionKeyExtractorClass.

    +

    A SpEL expression for customizing partition selection. +Mutually exclusive with partitionSelectorClass. +If neither is set, the partition will be selected as the hashCode(key) % partitionCount, where key is computed via either partitionKeyExpression or partitionKeyExtractorClass.

    +
    +

    Default: null.

    +
    partitionCount
    -

    The number of target partitions for the data, if partitioning is enabled. Default 1. Must be -set to a value higher than 1 if the producer is partitioned. On Kafka it is interpreted as a -hint, and the larger of this and the partition count of the target topic will be used instead.

    +

    The number of target partitions for the data, if partitioning is enabled. +Must be + set to a value greater than 1 if the producer is partitioned. +On Kafka, interpreted as a + hint; the larger of this and the partition count of the target topic is used instead.

    +
    +

    Default: 1.

    +
    requiredGroups
    -

    A comma separated list of groups that the producer must ensure message delivery even if they -start after it has been created (e.g. by pre-creating durable queues in Rabbit MQ).

    +

    A comma-separated list of groups to which the producer must ensure message delivery even if they start after it has been created (e.g., by pre-creating durable queues in RabbitMQ).

    +
    +
    headerMode
    +
    +

    When set to raw, disables header embedding on output. +Effective only for messaging middleware that does not support message headers natively and requires header embedding. +Useful when producing data for non-Spring Cloud Stream applications.

    +
    +

    Default: embeddedHeaders.

    +
    @@ -6008,112 +6024,141 @@ start after it has been created (e.g. by pre-creating durable queues in Rabbit M
    -

    Binder-specific configuration

    +

    Binder-Specific Configuration

    -

    This captures the binder, consumer and producer properties that are specific for several binder -implementations.

    +

    The following binder, consumer, and producer properties are specific to binder implementations.

    -

    Rabbit-specific settings

    +

    Rabbit-Specific Settings

    -

    Rabbit MQ Binder properties

    +

    RabbitMQ Binder Properties

    -

    The binder supports the all Spring Boot properties for Rabbit MQ configuration.

    +

    By default, the RabbitMQ binder uses Spring Boot’s ConnectionFactory, and it therefore supports all Spring Boot configuration options for RabbitMQ. +(For reference, consult the Spring Boot documentation.) RabbitMQ configuration options use the spring.rabbitmq prefix.

    -

    In addition to that, it also supports the following properties:

    +

    In addition to the Spring Boot options, the RabbitMQ binder supports the following properties:

    -
    spring.cloud.stream.rabbit.binder.addresses
    +
    spring.cloud.stream.rabbit.binder.adminAddresses
    -

    A comma-separated list of RabbitMQ server addresses (used only for clustering and in conjunction with nodes). Default empty. -spring.cloud.stream.rabbit.binder.adminAddresses. Default empty. - A comma-separated list of RabbitMQ management plugin URLs - only used when nodes contains more than one entry. Entries in this list must correspond to the corresponding entry in addresses. Default empty.

    +

    A comma-separated list of RabbitMQ management plugin URLs. +Only used when nodes contains more than one entry. +Each entry in this list must have a corresponding entry in spring.rabbitmq.addresses.

    +
    +

    Default: empty.

    +
    spring.cloud.stream.rabbit.binder.nodes
    -

    A comma-separated list of RabbitMQ node names; when more than one entry, used to locate the server address where a queue is located. Entries in this list must correspond to the corresponding entry in addresses. Default empty.

    -
    -
    spring.cloud.stream.rabbit.rabbit.username
    -
    -

    The user name. Default null.

    -
    -
    spring.cloud.stream.rabbit.binder.password
    -
    -

    The password. Default null.

    -
    -
    spring.cloud.stream.rabbit.binder.vhost
    -
    -

    The virtual host. Default null.

    -
    -
    spring.cloud.stream.rabbit.binder.useSSL
    -
    -

    True if Rabbit MQ should use SSL.

    -
    -
    spring.cloud.stream.rabbit.binder.sslPropertiesLocation
    -
    -

    The location of the SSL properties file, when certificate exchange is used.

    +

    A comma-separated list of RabbitMQ node names. +When more than one entry, used to locate the server address where a queue is located. +Each entry in this list must have a corresponding entry in spring.rabbitmq.addresses.

    +
    +

    Default: empty.

    +
    spring.cloud.stream.rabbit.binder.compressionLevel
    -

    Compression level for compressed bindings. Defaults to 1 (BEST_LEVEL). See java.util.zip.Deflater.

    +

    Compression level for compressed bindings. +See java.util.zip.Deflater.

    +
    +

    Default: 1 (BEST_LEVEL).

    +
    -

    Rabbit MQ Consumer Properties

    +

    RabbitMQ Consumer Properties

    The following properties are available for Rabbit consumers only and -must be prefixed with spring.cloud.stream.rabbit.bindings.<channelName>.consumer .

    +must be prefixed with spring.cloud.stream.rabbit.bindings.<channelName>.consumer..

    acknowledgeMode
    -

    The acknowledge mode. Default AUTO.

    +

    The acknowledge mode.

    +
    +

    Default: AUTO.

    +
    autoBindDlq
    -

    Whether to automatically declare the DLQ and bind it to the binder DLX. Default false.

    +

    Whether to automatically declare the DLQ and bind it to the binder DLX.

    +
    +

    Default: false.

    +
    durableSubscription
    -

    Whether subscription should be durable. Only effective if group is also set. Default true. -maxConcurrency: - Default 1. -prefetch: - Prefetch count. Default 1.

    +

    Whether subscription should be durable. +Only effective if group is also set.

    +
    +

    Default: true.

    +
    +
    +
    maxConcurrency
    +
    +

    Default: 1.

    +
    +
    prefetch
    +
    +

    Prefetch count.

    +
    +

    Default: 1.

    +
    prefix
    -

    A prefix to be added to the name of the destination and queues. Default "".

    +

    A prefix to be added to the name of the destination and queues.

    +
    +

    Default: "".

    +
    requeueRejected
    -

    Whether delivery failures should be requeued. Default true.

    +

    Whether delivery failures should be requeued.

    +
    +

    Default: true.

    +
    requestHeaderPatterns
    -

    The request headers to be transported. Default [STANDARD_REQUEST_HEADERS,'*'].

    +

    The request headers to be transported.

    +
    +

    Default: [STANDARD_REQUEST_HEADERS,'*'].

    +
    replyHeaderPatterns
    -

    The reply headers to be transported. Default [STANDARD_REQUEST_HEADERS,'*']

    +

    The reply headers to be transported.

    +
    +

    Default: [STANDARD_REQUEST_HEADERS,'*'].

    +
    republishToDlq
    -

    By default, failed messages after retries are exhausted are rejected. If a dead-letter queue (DLQ) is configured, rabbitmq will route the failed message (unchanged) to the DLQ. Setting this property to true instructs the bus to republish failed messages to the DLQ, with additional headers, including the exception message and stack trace from the cause of the final failure.

    +

    By default, messages which fail after retries are exhausted are rejected. +If a dead-letter queue (DLQ) is configured, RabbitMQ will route the failed message (unchanged) to the DLQ. +If set to true, the bus will republish failed messages to the DLQ with additional headers, including the exception message and stack trace from the cause of the final failure.

    transacted
    -

    Whether to use transacted channels. Default false.

    +

    Whether to use transacted channels.

    +
    +

    Default: false.

    +
    txSize
    -

    The number of deliveries between acks. Default 1.

    +

    The number of deliveries between acks.

    +
    +

    Default: 1.

    +
    @@ -6122,87 +6167,137 @@ prefetch:

    Rabbit Producer Properties

    The following properties are available for Rabbit producers only and -must be prefixed with spring.cloud.stream.rabbit.bindings.<channelName>.producer .

    +must be prefixed with spring.cloud.stream.rabbit.bindings.<channelName>.producer..

    autoBindDlq
    -

    Whether to automatically declare the DLQ and bind it to the binder DLX. Default false.

    +

    Whether to automatically declare the DLQ and bind it to the binder DLX.

    +
    +

    Default: false.

    +
    batchingEnabled
    -

    True to enable message batching by producers. Default false.

    +

    Whether to enable message batching by producers.

    +
    +

    Default: false.

    +
    batchSize
    -

    The number of message to buffer when batching is enabled. Default 100.

    +

    The number of messages to buffer when batching is enabled.

    +
    +

    Default: 100.

    +
    batchBufferLimit
    -

    Default 10000.

    +

    Default: 10000.

    batchTimeout
    -

    Default 5000.

    +

    Default: 5000.

    compress
    -

    Whether data should be compressed when sent. Default false.

    +

    Whether data should be compressed when sent.

    +
    +

    Default: false.

    +
    deliveryMode
    -

    Delivery mode. Default PERSISTENT.

    +

    Delivery mode.

    +
    +

    Default: PERSISTENT.

    +
    prefix
    -

    A prefix to be added to the name of the destination exchange. Default "".

    +

    A prefix to be added to the name of the destination exchange.

    +
    +

    Default: "".

    +
    requestHeaderPatterns
    -

    The request headers to be transported. Default [STANDARD_REQUEST_HEADERS,'*'].

    +

    The request headers to be transported.

    +
    +

    Default: [STANDARD_REQUEST_HEADERS,'*'].

    +
    replyHeaderPatterns
    -

    The reply headers to be transported. Default [STANDARD_REQUEST_HEADERS,'*']

    +

    The reply headers to be transported.

    +
    +

    Default: [STANDARD_REQUEST_HEADERS,'*'].

    +
    -

    Kafka-specific settings

    +

    Kafka-Specific Settings

    -

    Kafka binder properties

    +

    Kafka Binder Properties

    spring.cloud.stream.kafka.binder.brokers
    -

    A list of brokers that the Kafka binder will connect to. Default localhost.

    +

    A list of brokers to which the Kafka binder will connect.

    +
    +

    Default: localhost.

    +
    spring.cloud.stream.kafka.binder.defaultBrokerPort
    -

    The list of brokers allows to specify hosts with or without port information, i.e. host1,host2:port2. This configuration sets the default port when no port is configured in the broker list. Default 9092.

    +

    brokers allows hosts specified with or without port information (e.g., host1,host2:port2). +This sets the default port when no port is configured in the broker list.

    +
    +

    Default: 9092.

    +
    spring.cloud.stream.kafka.binder.zkNodes
    -

    A list of Zookeeper nodes for the Kafka binder to connect to. Default localhost.

    +

    A list of ZooKeeper nodes to which the Kafka binder can connect.

    +
    +

    Default: localhost.

    +
    spring.cloud.stream.kafka.binder.defaultZkPort
    -

    The list of Zookeeper nodes allows to specify hosts with or without port information, i.e. host1,host2:port2. This configuration sets the default port when no port is configured in the node list. Default 2181.

    +

    zkNodes allows hosts specified with or without port information (e.g., host1,host2:port2). +This sets the default port when no port is configured in the node list.

    +
    +

    Default: 2181.

    +
    spring.cloud.stream.kafka.binder.headers
    -

    The list of custom that will be transported by the binder. Default empty.

    +

    The list of custom headers that will be transported by the binder.

    +
    +

    Default: empty.

    +
    spring.cloud.stream.kafka.binder.offsetUpdateTimeWindow
    -

    The frequency in milliseconds with which offsets are saved. Ignored if 0. Default 10000.

    +

    The frequency, in milliseconds, with which offsets are saved. +Ignored if 0.

    +
    +

    Default: 10000.

    +
    spring.cloud.stream.kafka.binder.offsetUpdateCount
    -

    The frequency in number of updates, which which consumed offsets are persisted. Ignored if 0. Default 0. Mutually exclusive with offsetUpdateTimeWindow.

    +

    The frequency, in number of updates, which which consumed offsets are persisted. +Ignored if 0. +Mutually exclusive with offsetUpdateTimeWindow.

    +
    +

    Default: 0.

    +
    spring.cloud.stream.kafka.binder.requiredAcks
    @@ -6215,29 +6310,39 @@ must be prefixed with spring.cloud.stream.rabbit.bindings.<channelName&

    Kafka Consumer Properties

    The following properties are available for Kafka consumers only and -must be prefixed with spring.cloud.stream.kafka.bindings.<channelName>.consumer .

    +must be prefixed with spring.cloud.stream.kafka.bindings.<channelName>.consumer..

    autoCommitOffset
    -

    True to autocommit offsets when a message has been processed. If set to false, an Acknowledgment header will be available in the message headers for late acknowledgment. Default true.

    -
    -
    mode
    -
    -

    When set to raw, will disable header parsing on input. Useful when inbound data is coming from outside Spring Cloud Stream applications. Default embeddedHeaders.

    +

    Whether to autocommit offsets when a message has been processed. +If set to false, an Acknowledgment header will be available in the message headers for late acknowledgment.

    +
    +

    Default: true.

    +
    resetOffsets
    -

    True to reset offsets on the consumer to the value provided by startOffset. Default false.

    +

    Whether to reset offsets on the consumer to the value provided by startOffset.

    +
    +

    Default: false.

    +
    startOffset
    -

    The starting offset for new groups or when resetOffsets is true. Allowed values: earliest,latest. Defaults to null (equivalent to earliest).

    +

    The starting offset for new groups, or when resetOffsets is true. +Allowed values: earliest, latest.

    +
    +

    Default: null (equivalent to earliest).

    +
    minPartitionCount
    -

    The minimum number of partitions expected by the consumer if it creates the consumed topic automatically. Defaults to 1.

    +

    The minimum number of partitions expected by the consumer if it creates the consumed topic automatically.

    +
    +

    Default: 1.

    +
    @@ -6246,25 +6351,31 @@ must be prefixed with spring.cloud.stream.kafka.bindings.<channelName&g

    Kafka Producer Properties

    The following properties are available for Kafka producers only and -must be prefixed with spring.cloud.stream.kafka.bindings.<channelName>.producer .

    +must be prefixed with spring.cloud.stream.kafka.bindings.<channelName>.producer..

    bufferSize
    -

    This is an upper limit of how much data the Kafka Producer will attempt to batch before sending – specified in bytes. Default 16384.

    +

    Upper limit, in bytes, of how much data the Kafka producer will attempt to batch before sending.

    +
    +

    Default: 16384.

    +
    sync
    -

    Whether the producer is synchronous. Defaults to false.

    +

    Whether the producer is synchronous.

    +
    +

    Default: false.

    +
    batchTimeout
    -

    How long will the producer wait before sending in order to allow more messages to get accumulated in the same batch. Normally the producer will not wait at all, and simply send all the messages that accumulated while the previous send was in progress. A non-zero value may increase throughput at the expense of latency. Default 0.

    -
    -
    mode
    -
    -

    When set to raw, disable header propagation on output. Useful when producing data for non-Spring Cloud Stream applications. Default embeddedHeaders.

    +

    How long the producer will wait before sending in order to allow more messages to accumulate in the same batch. +(Normally the producer does not wait at all, and simply sends all the messages that accumulated while the previous send was in progress.) A non-zero value may increase throughput at the expense of latency.

    +
    +

    Default: 0.

    +
    @@ -6273,19 +6384,19 @@ must be prefixed with spring.cloud.stream.kafka.bindings.<channelName&g
    -

    Binder detection

    +

    Binder Detection

    -

    Spring Cloud Stream relies on implementations of the Binder SPI to perform the task of connecting channels to message -brokers. Each Binder implementation typically connects to one type of messaging system. Spring Cloud Stream provides -out of the box binders for Kafka, RabbitMQ and Redis.

    +

    Spring Cloud Stream relies on implementations of the Binder SPI to perform the task of connecting channels to message brokers. +Each Binder implementation typically connects to one type of messaging system. +Out of the box, Spring Cloud Stream provides binders for Kafka, RabbitMQ, and Redis.

    Classpath Detection

    -

    By default, Spring Cloud Stream relies on Spring Boot’s auto-configuration to configure the binding process. If a -single binder implementation is found on the classpath, Spring Cloud Stream will use it automatically. So, for example, -a Spring Cloud Stream project that aims to bind only to RabbitMQ can simply add the following dependency:

    +

    By default, Spring Cloud Stream relies on Spring Boot’s auto-configuration to configure the binding process. +If a single Binder implementation is found on the classpath, Spring Cloud Stream will use it automatically. +For example, a Spring Cloud Stream project that aims to bind only to RabbitMQ can simply add the following dependency:

    @@ -6299,7 +6410,8 @@ a Spring Cloud Stream project that aims to bind only to RabbitMQ can simply add

    Multiple Binders on the Classpath

    -

    When multiple binders are present on the classpath, the application must indicate which binder is to be used for each channel binding. Each binder configuration contains a META-INF/spring.binders, which is a simple properties file:

    +

    When multiple binders are present on the classpath, the application must indicate which binder is to be used for each channel binding. +Each binder configuration contains a META-INF/spring.binders, which is a simple properties file:

    @@ -6308,31 +6420,43 @@ org.springframework.cloud.stream.binder.rabbit.config.RabbitServiceAutoConfigura
    -

    Similar files exist for the other binder implementations (e.g. Kafka), and it is expected that custom binder -implementations will provide them, too. The key represents an identifying name for the binder implementation, whereas -the value is a comma-separated list of configuration classes that contain one and only one bean definition of the type -org.springframework.cloud.stream.binder.Binder.

    +

    Similar files exist for the other provided binder implementations (e.g., Kafka), and custom binder implementations are expected to provide them, as well. +The key represents an identifying name for the binder implementation, whereas the value is a comma-separated list of configuration classes that each contain one and only one bean definition of type org.springframework.cloud.stream.binder.Binder.

    -

    Selecting the binder can be done globally by either using the spring.cloud.stream.defaultBinder property, e.g. -spring.cloud.stream.defaultBinder=rabbit, or by individually configuring them on each channel binding.

    +

    Binder selection can either be performed globally, using the spring.cloud.stream.defaultBinder property (e.g., spring.cloud.stream.defaultBinder=rabbit) or individually, by configuring the binder on each channel binding. +For instance, a processor application which reads from Kafka and writes to RabbitMQ can specify the following configuration:

    +
    +
    +
    +
    spring.cloud.stream.bindings.input.binder=kafka
    +spring.cloud.stream.bindings.output.binder=rabbit
    -
    -

    For instance, a processor app that reads from Kafka and writes to Rabbit can specify the following configuration: -spring.cloud.stream.bindings.input.binder=kafka,spring.cloud.stream.bindings.output.binder=rabbit.

    Connecting to Multiple Systems

    -

    By default, binders share the Spring Boot auto-configuration of the application and create one instance of each binder -found on the classpath. In scenarios where an application should connect to more than one broker of the same type, -Spring Cloud Stream allows you to specify multiple binder configurations, with different environment settings. Please -note that turning on explicit binder configuration will disable the default binder configuration process altogether, so -all the binders in use must be included in the configuration.

    +

    By default, binders share the application’s Spring Boot auto-configuration, so that one instance of each binder found on the classpath will be created. +If your application should connect to more than one broker of the same type, you can specify multiple binder configurations, each with different environment settings.

    +
    +
    + + + + + +
    +
    Note
    +
    +
    +

    Turning on explicit binder configuration will disable the default binder configuration process altogether. +If you do this, all binders in use must be included in the configuration.

    +
    +
    -

    For example, this is the typical configuration for a processor that connects to two RabbitMQ broker instances:

    +

    For example, this is the typical configuration for a processor application which connects to two RabbitMQ broker instances:

    @@ -6368,8 +6492,8 @@ all the binders in use must be included in the configuration.

    Content Type and Transformation

    -

    Spring Cloud Stream allows to propagate information about the content type of the messages it produces by attaching by default a contentType header to outbound messages. -For middleware that does not directly support headers, Spring Cloud Stream provides its own mechanism of wrapping outbound messages in an envelope of its own, automatically. +

    To allow you to propagate information about the content type of produced messages, Spring Cloud Stream attaches, by default, a contentType header to outbound messages. +For middleware that does not directly support headers, Spring Cloud Stream provides its own mechanism of automatically wrapping outbound messages in an envelope of its own. For middleware that does support headers, Spring Cloud Stream applications may receive messages with a given content type from non-Spring Cloud Stream applications.

    @@ -6378,55 +6502,57 @@ For middleware that does support headers, Spring Cloud Stream applications may r
    • -

      through its contentType settings on inbound and outbound channels;

      +

      Through its contentType settings on inbound and outbound channels

    • -

      through its argument mapping done for @StreamListener-annotated methods.

      +

      Through its argument mapping performed for methods annotated with @StreamListener

    -
    -
    -

    Type converting message channels

    - -
    -
    -

    @StreamListener and conversion

    -
    -

    Inter-app Communication

    +

    Inter-Application Communication

    -

    Connecting multiple application instances

    +

    Connecting Multiple Application Instances

    -

    While Spring Cloud Stream makes it easy for individual boot apps to connect to messaging systems, the typical scenario for Spring Cloud Stream is the creation of multi-app pipelines, where microservice apps are sending data to each other. -This can be achieved by correlating the input and output destinations of adjacent apps, as in the following example.

    +

    While Spring Cloud Stream makes it easy for individual Spring Boot applications to connect to messaging systems, the typical scenario for Spring Cloud Stream is the creation of multi-application pipelines, where microservice applications send data to each other. +You can achieve this scenario by correlating the input and output destinations of adjacent applications.

    -

    Supposing that the design calls for the time-source app to send data to the log-sink app, we will use a -common destination named ticktock for bindings within both apps. time-source will set -spring.cloud.stream.bindings.output.destination=ticktock, and log-sink will set -spring.cloud.stream.bindings.input.destination=ticktock.

    +

    Supposing that a design calls for the Time Source application to send data to the Log Sink application, you can use a common destination named ticktock for bindings within both applications.

    +
    +
    +

    Time Source will set the following property:

    +
    +
    +
    +
    spring.cloud.stream.bindings.output.destination=ticktock
    +
    +
    +
    +

    Log Sink will set the following property:

    +
    +
    +
    +
    spring.cloud.stream.bindings.input.destination=ticktock
    +

    Instance Index and Instance Count

    -

    When scaling up Spring Cloud Stream applications, each instance can receive information about how many other instances -of the same application exist and what its own instance index is. This is done through the -spring.cloud.stream.instanceCount and spring.cloud.stream.instanceIndex properties. For example, if there are 3 -instances of the HDFS sink application, all three will have spring.cloud.stream.instanceCount set to 3, and the -applications will have spring.cloud.stream.instanceIndex set to 0, 1 and 2, respectively. When Spring Cloud Stream -applications are deployed via Spring Cloud Data Flow, these properties are configured automatically, but when Spring -Cloud Stream applications are launched independently, these properties must be set correctly. By default -spring.cloud.stream.instanceCount is 1, and spring.cloud.stream.instanceIndex is 0.

    +

    When scaling up Spring Cloud Stream applications, each instance can receive information about how many other instances of the same application exist and what its own instance index is. +Spring Cloud Stream does this through the spring.cloud.stream.instanceCount and spring.cloud.stream.instanceIndex properties. +For example, if there are three instances of a HDFS sink application, all three instances will have spring.cloud.stream.instanceCount set to 3, and the individual applications will have spring.cloud.stream.instanceIndex set to 0, 1, and 2, respectively.

    -

    Setting up the two properties correctly on scale up scenarios is important for addressing partitioning behavior in -general (see below), and they are always required by certain types of binders (e.g. the Kafka binder) in order to -ensure that data is split correctly across multiple consumer instances.

    +

    When Spring Cloud Stream applications are deployed via Spring Cloud Dataflow, these properties are configured automatically; when Spring Cloud Stream applications are launched independently, these properties must be set correctly. +By default, spring.cloud.stream.instanceCount is 1, and spring.cloud.stream.instanceIndex is 0.

    +
    +
    +

    In a scaled-up scenario, correct configuration of these two properties is important for addressing partitioning behavior (see below) in general, and the two properties are always required by certain binders (e.g., the Kafka binder) in order to ensure that data are split correctly across multiple consumer instances.

    @@ -6434,27 +6560,41 @@ ensure that data is split correctly across multiple consumer instances.

    Configuring Output Bindings for Partitioning

    -

    An output binding is configured to send partitioned data, by setting one and only one of its partitionKeyExpression -or partitionKeyExtractorClass properties, as well as its partitionCount property. For example, setting -spring.cloud.stream.bindings.output.partitionKeyExpression=payload.id,spring.cloud.stream.bindings.output.partitionCount=5 -is a valid and typical configuration.

    +

    An output binding is configured to send partitioned data by setting one and only one of its partitionKeyExpression or partitionKeyExtractorClass properties, as well as its partitionCount property. +For example, the following is a valid and typical configuration:

    +
    +
    +
    +
    spring.cloud.stream.bindings.output.partitionKeyExpression=payload.id
    +spring.cloud.stream.bindings.output.partitionCount=5
    +
    -

    Based on this configuration, the data will be sent to the target partition using the following logic. A partition key’s -value is calculated for each message sent to a partitioned output channel based on the partitionKeyExpression. The -partitionKeyExpression is a SpEL expression that is evaluated against the outbound message for extracting the -partitioning key. If a SpEL expression is not sufficient for your needs, you can instead calculate the partition key -value by setting the property partitionKeyExtractorClass. This class must implement the interface -org.springframework.cloud.stream.binder.PartitionKeyExtractorStrategy. While, in general, the SpEL expression should -suffice, more complex cases may use the custom implementation strategy.

    +

    Based on the above example configuration, data will be sent to the target partition using the following logic.

    -

    Once the message key is calculated, the partition selection process will determine the target partition as a value -between 0 and partitionCount - 1. The default calculation, applicable in most scenarios is based on the formula -key.hashCode() % partitionCount. This can be customized on the binding, either by setting a SpEL expression to be -evaluated against the key via the partitionSelectorExpression property, or by setting a -org.springframework.cloud.stream.binder.PartitionSelectorStrategy implementation via the partitionSelectorClass -property.

    +

    A partition key’s value is calculated for each message sent to a partitioned output channel based on the partitionKeyExpression. +The partitionKeyExpression is a SpEL expression which is evaluated against the outbound message for extracting the partitioning key.

    +
    +
    + + + + + +
    +
    Tip
    +
    +
    +

    If a SpEL expression is not sufficient for your needs, you can instead calculate the partition key value by setting the property partitionKeyExtractorClass to a class which implements the org.springframework.cloud.stream.binder.PartitionKeyExtractorStrategy interface. +While the SpEL expression should usually suffice, more complex cases may use the custom implementation strategy.

    +
    +
    +
    +
    +

    Once the message key is calculated, the partition selection process will determine the target partition as a value between 0 and partitionCount - 1. +The default calculation, applicable in most scenarios, is based on the formula key.hashCode() % partitionCount. +This can be customized on the binding, either by setting a SpEL expression to be evaluated against the key (via the partitionSelectorExpression property) or by setting a org.springframework.cloud.stream.binder.PartitionSelectorStrategy implementation (via the partitionSelectorClass property).

    Additional properties can be configured for more advanced scenarios, as described in the following section.

    @@ -6462,19 +6602,22 @@ property.

    Configuring Input Bindings for Partitioning
    -

    An input binding is configured to receive partitioned data by setting its partitioned property, as well as the -instance index and instance count properties on the app itself, as follows: -spring.cloud.stream.bindings.input.partitioned=true,spring.cloud.stream.instanceIndex=3,spring.cloud.stream.instanceCount=5. -The instance count value represents the total number of app instances between which the data needs to be partitioned, -whereas instance index must be a unique value across the multiple instances, between 0 and instanceCount - 1. The -instance index helps each app instance to identify the unique partition (or in the case of Kafka, the partition set) -from which it receives data. It is important that both values are set correctly in order to ensure that all the data is -consumed, and that the app instances receive mutually exclusive datasets.

    +

    An input binding is configured to receive partitioned data by setting its partitioned property, as well as the instanceIndex and instanceCount properties on the application itself, as in the following example:

    +
    +
    +
    +
    spring.cloud.stream.bindings.input.partitioned=true
    +spring.cloud.stream.instanceIndex=3
    +spring.cloud.stream.instanceCount=5
    +
    -

    While setting up multiple instances for partitioned data processing may be complex in the standalone case, Spring Cloud -Data Flow can simplify the process significantly, by populating both the input and output values correctly, as well as -relying on the runtime infrastructure to provide information about the instance index and instance count.

    +

    The instanceCount value represents the total number of application instances between which the data need to be partitioned, and the instanceIndex must be a unique value across the multiple instances, between 0 and instanceCount - 1. +The instance index helps each application instance to identify the unique partition (or, in the case of Kafka, the partition set) from which it receives data. +It is important to set both values correctly in order to ensure that all of the data is consumed and that the application instances receive mutually exclusive datasets.

    +
    +
    +

    While a scenario which using multiple instances for partitioned data processing may be complex to set up in a standalone case, Spring Cloud Dataflow can simplify the process significantly by populating both the input and output values correctly as well as relying on the runtime infrastructure to provide information about the instance index and instance count.

    @@ -6482,11 +6625,80 @@ relying on the runtime infrastructure to provide information about the instance
    +

    Testing

    +
    +
    +

    Spring Cloud Stream provides support for testing your microservice applications without connecting to a messaging system. +You can do that by using the TestSupportBinder. +This is useful especially for unit testing your microservices.

    +
    +
    +

    The TestSupportBinder allows users to interact with the bound channels and inspect what messages are sent and received by the application

    +
    +
    +

    For outbound message channels, the TestSupportBinder registers a single subscriber and retains the messages emitted by the application in a MessageCollector. +They can be retrieved during tests and have assertions made against them.

    +
    +
    +

    The user can also send messages to inbound message channels, so that the consumer application can consume the messages. +The following example shows how to test both input and output channels on a processor.

    +
    +
    +
    +
    @RunWith(SpringJUnit4ClassRunner.class)
    +@SpringApplicationConfiguration(classes = ExampleTest.MyProcessor.class)
    +@IntegrationTest({"server.port=-1"})
    +@DirtiesContext
    +public class ExampleTest {
    +
    +  @Autowired
    +  private Processor processor;
    +
    +  @Autowired
    +  private BinderFactory<MessageChannel> binderFactory;
    +
    +  @Autowired
    +  private MessageCollector messageCollector;
    +
    +  @Test
    +  @SuppressWarnings("unchecked")
    +  public void testWiring() {
    +    Message<String> message = new GenericMessage<>("hello");
    +    processor.input().send(message);
    +    Message<String> received = (Message<String>) messageCollector.forChannel(processor.output()).poll();
    +    assertThat(received.getPayload(), equalTo("hello world"));
    +  }
    +
    +
    +  @SpringBootApplication
    +  @EnableBinding(Processor.class)
    +  public static class MyProcessor {
    +
    +    @Autowired
    +    private Processor channels;
    +
    +    @Transformer(inputChannel = Processor.INPUT, outputChannel = Processor.OUTPUT)
    +    public String transform(String in) {
    +      return in + " world";
    +    }
    +  }
    +}
    +
    +
    +
    +

    In the example above, we are creating an application that has an input and an output channel, bound through the Processor interface. +The bound interface is injected into the test so we can have access to both channels. +We are sending a message on the input channel and we are using the MessageCollector provided by Spring Cloud Stream’s test support to capture the message has been sent to the output channel as a result. +Once we have received the message, we can validate that the component functions correctly.

    +
    +
    +
    +

    Health Indicator

    -

    Spring Cloud Stream provides a health indicator for the binders, registered under the name of binders. It can be -enabled or disabled using the management.health.binders.enabled property.

    +

    Spring Cloud Stream provides a health indicator for binders. +It is registered under the name of binders and can be enabled or disabled by setting the management.health.binders.enabled property.

    @@ -6494,7 +6706,7 @@ enabled or disabled using the management.health.binders.enabled pro

    Samples

    -

    For Spring Cloud Stream samples, please refer: https://github.com/spring-cloud/spring-cloud-stream-samples

    +

    For Spring Cloud Stream samples, please refer to the spring-cloud-stream-samples repository on GitHub.

    @@ -6502,9 +6714,12 @@ enabled or disabled using the management.health.binders.enabled pro

    Getting Started

    -

    To get started creating Spring Cloud Stream applications, head over to https://start.spring.io and create a new project named GreetingSource. -Select the Spring Boot Version to be 1.3.4 (SNAPSHOT as of the time of this release) and tick the checkbox for Stream Kafka as we will be using Kafka for messaging. -Next create a new class GreetingSource in the same package as the class GreetingSourceApplication with the following code:

    +

    To get started with creating Spring Cloud Stream applications, visit the Spring Initializr and create a new Maven project named "GreetingSource". +Select Spring Boot version 1.3.4 SNAPSHOT and search or tick the checkbox for Stream Kafka (we will be using Kafka for messaging).

    +
    +
    +

    Next, create a new class, GreetingSource, in the same package as the GreetingSourceApplication class. +Give it the following code:

    @@ -6523,8 +6738,8 @@ public class GreetingSource {
    -

    The annotation @EnableBinding is what triggers the creation of Spring Integration infrastructure components. -Specifically, it will create a Kafka Connection Factory, Kafka Outbound Channel Adapter, and the Message Channel defined inside the Source interface.

    +

    The @EnableBinding annotation is what triggers the creation of Spring Integration infrastructure components. +Specifically, it will create a Kafka connection factory, a Kafka outbound channel adapter, and the message channel defined inside the Source interface:

    @@ -6539,26 +6754,34 @@ Specifically, it will create a Kafka Connection Factory, Kafka Outbound Channel
    -

    Furthermore, the auto configuration creates a default poller so that the greet method will be invoked once a second. -The standard Spring Integration InboundChannelAdapter annotation sends a message to the source’s output channel using the return value as the payload of the message.

    +

    The auto-configuration also creates a default poller, so that the greet() method will be invoked once per second. +The standard Spring Integration @InboundChannelAdapter annotation sends a message to the source’s output channel, using the return value as the payload of the message.

    -

    To test drive this setup run a Kafka Message Broker. An easy way to do this is using a docker image.

    +

    To test-drive this setup, run a Kafka message broker. +An easy way to do this is to use a Docker image:

    -
    # on mac
    -docker run -p 2181:2181 -p 9092:9092 --env ADVERTISED_HOST=`docker-machine ip \`docker-machine active\`` --env ADVERTISED_PORT=9092 spotify/kafka
    +
    # On OS X
    +$ docker run -p 2181:2181 -p 9092:9092 --env ADVERTISED_HOST=`docker-machine ip \`docker-machine active\`` --env ADVERTISED_PORT=9092 spotify/kafka
     
    -# on linux
    -docker run -p 2181:2181 -p 9092:9092 --env ADVERTISED_HOST=localhost --env ADVERTISED_PORT=9092 spotify/kafka
    +# On Linux +$ docker run -p 2181:2181 -p 9092:9092 --env ADVERTISED_HOST=localhost --env ADVERTISED_PORT=9092 spotify/kafka
    -

    Build the application using ./mvnw clean package

    +

    Build the application:

    +
    +
    +
    +
    ./mvnw clean package
    +
    -

    The consumer application is coded in a similar manner, go back to https://start.spring.io and create a new project named LoggerSink. Then create a new class LoggingSink in the same package as the class LoggingSinkApplication with the following code

    +

    The consumer application is coded in a similar manner. +Go back to Initializr and create another project, named LoggingSink. +Then create a new class, LoggingSink, in the same package as the class LoggingSinkApplication and with the following code:

    @@ -6577,10 +6800,16 @@ public class LoggingSink {
    -

    Build the application using ./mvnw clean package

    +

    Build the application:

    +
    +
    +
    +
    ./mvnw clean package
    +
    -

    To connect the Source application to the Sink application, each application needs to share the same destination name. Starting up both applications as shown below you will see the consumer application printing ‘hello world’ and the timestamp to the console.

    +

    To connect the GreetingSource application to the LoggingSink application, each application must share the same destination name. +Starting up both applications as shown below, you will see the consumer application printing "hello world" and a timestamp to the console:

    @@ -6592,10 +6821,10 @@ java -jar target/LoggingSink-0.0.1-SNAPSHOT.jar --server.port=8090 --spring.clou
    -

    The different server port is avoid collisions of the http port used to service the boot actuator endpoints.

    +

    (The different server port prevents collisions of the HTTP port used to service the Spring Boot Actuator endpoints in the two applications.)

    -

    The output of the logging sink will look something like

    +

    The output of the LoggingSink application will look something like the following:

    @@ -6605,108 +6834,89 @@ hello world 1458595076731 hello world 1458595077732 hello world 1458595078733 hello world 1458595079734 -hello world 1458595080735 -
    -
    -
    -
    -

    Spring Cloud Bus

    -
    -
    +hello world 1458595080735 + += Spring Cloud Bus +:github: https://github.com/spring-cloud/spring-cloud-config +:githubmaster: {github}/tree/master +:docslink: {githubmaster}/docs/src/main/asciidoc +:toc: + 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. + + + +== Quick Start + +Spring Cloud Bus works by adding Spring Boot autconfiguration if it detects itself on the classpath. All you need to do to enable the bus is to add `spring-cloud-starter-bus-amqp` to your dependency management and Spring Cloud takes care of the rest. Make sure RabbitMQ is available and configured to provide a `ConnectionFactory`: running on localhost you shouldn't have to do anything, but if you are running remotely use Spring Cloud Connectors, or Spring Boot conventions to define the broker credentials, e.g. + +.application.yml
    -
    -

    Quick Start

    -
    -

    Spring Cloud Bus works by adding Spring Boot autconfiguration if it detects itself on the classpath. All you need to do to enable the bus is to add spring-cloud-starter-bus-amqp to your dependency management and Spring Cloud takes care of the rest. Make sure RabbitMQ is available and configured to provide a ConnectionFactory: running on localhost you shouldn’t have to do anything, but if you are running remotely use Spring Cloud Connectors, or Spring Boot conventions to define the broker credentials, e.g.

    -
    -
    -
    application.yml
    -
    -
    spring:
    +

    spring: rabbitmq: host: mybroker.com port: 5672 username: user - password: secret

    + password: secret

    -
    -
    -

    The bus currently supports sending messages to all nodes listening or all nodes for a particular service (as defined by Eureka). More selector criteria will be added in the future (ie. only service X nodes in data center Y, etc…​). The http endpoints are under the /bus/* actuator namespace. There are currently two implemented. The first, /bus/env, sends key/values pairs to update each nodes Spring Environment. The second, /bus/refresh, will reload each application’s configuration, just as if they had all been pinged on their /refresh endpoint.

    -
    -
    -
    -
    -

    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 Message Broker

    -
    -
    -

    Spring Cloud Bus uses -Spring Cloud Stream to +

    +
    +
    The bus currently supports sending messages to all nodes listening or all nodes for a particular service (as defined by Eureka).  More selector criteria will be added in the future (ie. only service X nodes in data center Y, etc...). The http endpoints are under the `/bus/*` actuator namespace.  There are currently two implemented.  The first, `/bus/env`, sends key/values pairs to update each nodes Spring Environment.  The second, `/bus/refresh`, will reload each application's configuration, just as if they had all been pinged on their `/refresh` endpoint.
    +
    +== 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 Message Broker
    +
    +Spring Cloud Bus uses
    +https://cloud.spring.io/spring-cloud-stream[Spring Cloud Stream] to
     broadcast the messages so to get messages to flow you only need to
     include the binder implementation of your choice in the
     classpath. There are convenient starters specifically for the bus with
     AMQP (RabbitMQ) and Kafka
    -(spring-cloud-starter-bus-[amqp,kafka]). Generally speaking
    +(`spring-cloud-starter-bus-[amqp,kafka]`). Generally speaking
     Spring Cloud Stream relies on Spring Boot autoconfiguration
     conventions for configuring middleware, so for instance the AMQP
    -broker address can be changed with spring.rabbitmq.*
    +broker address can be changed with `spring.rabbitmq.{asterisk}`
     configuration properties. Spring Cloud Bus has a handful of native
    -configuration properties in spring.cloud.bus.*
    -(e.g. spring.cloud.bus.destination is the name of the topic to use
    -the the externall middleware). Normally the defaults will suffice.

    -
    -
    -

    To lean more about how to customize the message broker settings -consult the Spring Cloud Stream documentation.

    -
    -
    -
    -
    -

    Tracing Bus Events

    -
    -
    -

    Bus events (subclasses of RemoteApplicationEvent) can be traced by -setting spring.cloud.bus.trace.enabled=true. If you do this then the -Spring Boot TraceRepository (if it is present) will show each event +configuration properties in `spring.cloud.bus.{asterisk}` +(e.g. `spring.cloud.bus.destination` is the name of the topic to use +the the externall middleware). Normally the defaults will suffice. + +To lean more about how to customize the message broker settings +consult the Spring Cloud Stream documentation. + +== Tracing Bus Events + +Bus events (subclasses of `RemoteApplicationEvent`) can be traced by +setting `spring.cloud.bus.trace.enabled=true`. If you do this then the +Spring Boot `TraceRepository` (if it is present) will show each event sent and all the acks from each service instance. Example (from the -/trace endpoint):

    +`/trace` endpoint): + +[source,json]
    -
    -
    -
    {
    +
    +
    +

    { "timestamp": "2015-11-26T10:24:44.411+0000", "info": { "signal": "spring.cloud.bus.ack", "type": "RefreshRemoteApplicationEvent", "id": "c4d374b7-58ea-4928-a312-31984def293b", "origin": "stores:8081", - "destination": "*:**" + "destination": ":" } }, { @@ -6716,7 +6926,7 @@ sent and all the acks from each service instance. Example (from the "type": "RefreshRemoteApplicationEvent", "id": "c4d374b7-58ea-4928-a312-31984def293b", "origin": "customers:9000", - "destination": "*:**" + "destination": ":" } }, { @@ -6726,409 +6936,252 @@ sent and all the acks from each service instance. Example (from the "type": "RefreshRemoteApplicationEvent", "id": "c4d374b7-58ea-4928-a312-31984def293b", "origin": "customers:9000", - "destination": "*:**" + "destination": ":*" } -} +}

    -
    -
    -

    This trace shows that a RefreshRemoteApplicationEvent was sent from -customers:9000, broadcast to all services, and it was received -(acked) by customers:9000 and stores:8081.

    -
    -
    -

    To handle the ack signals yourself you could add an @EventListener -for the AckRemoteApplicationEvent and SentApplicationEvent types +

    +
    +
    This trace shows that a `RefreshRemoteApplicationEvent` was sent from
    +`customers:9000`, broadcast to all services, and it was received
    +(acked) by `customers:9000` and `stores:8081`.
    +
    +To handle the ack signals yourself you could add an `@EventListener`
    +for the `AckRemoteApplicationEvent` and `SentApplicationEvent` types
     to your app (and enable tracing). Or you could tap into the
    -TraceRepository and mine the data from there.

    -
    -
    - - - - - -
    -
    Note
    -
    -Any Bus application can trace acks, but sometimes it will be +`TraceRepository` and mine the data from there. + +NOTE: Any Bus application can trace acks, but sometimes it will be useful to do this in a central service that can do more complex queries on the data. Or forward it to a specialized tracing service. -
    -
    -
    -
    -
    -

    Broadcasting Your Own Events

    -
    -
    -

    The Bus can carry any event of type RemoteApplicationEvent, but the + +== Broadcasting Your Own Events + +The Bus can carry any event of type `RemoteApplicationEvent`, but the default transport is JSON and the deserializer needs to know which types are going to be used ahead of time. To register a new type you -can use @JsonTypeName on your custom class.

    -
    -
    -
    -

    Spring Cloud Sleuth

    -
    -
    -
    -

    Adrian Cole, Spencer Gibb, Marcin Grzejszczak, Dave Syer -:doctype: book

    -
    -
    -

    Spring Cloud Sleuth implements a distributed tracing solution for Spring Cloud.

    -
    -
    -
    -
    -

    Terminology

    -
    -

    Spring Cloud Sleuth borrows Dapper’s terminology.

    -
    -
    -

    Span: The basic unit of work. For example, sending an RPC is a new span, as is sending a response to an -RPC. Span’s are identified by a unique 64-bit ID for the span and another 64-bit ID for the trace the span +can use `@JsonTypeName` on your custom class. + +:github-tag: master +:github-repo: spring-cloud/spring-cloud-sleuth +:github-raw: http://raw.github.com/{github-repo}/{github-tag} +:github-code: http://github.com/{github-repo}/tree/{github-tag} +:toc: left + +Spring Cloud Sleuth +==================== +Adrian Cole, Spencer Gibb, Marcin Grzejszczak, Dave Syer +:doctype: book + +Spring Cloud Sleuth implements a distributed tracing solution for http://cloud.spring.io[Spring Cloud]. + +=== Terminology + +Spring Cloud Sleuth borrows http://research.google.com/pubs/pub36356.html[Dapper's] terminology. + +*Span:* The basic unit of work. For example, sending an RPC is a new span, as is sending a response to an +RPC. Span's are identified by a unique 64-bit ID for the span and another 64-bit ID for the trace the span is a part of. Spans also have other data, such as descriptions, timestamped events, key-value -annotations (tags), the ID of the span that caused them, and process ID’s (normally IP address).

    -
    -
    -

    Spans are started and stopped, and they keep track of their timing information. Once you create a -span, you must stop it at some point in the future.

    -
    -
    -

    Trace: A set of spans forming a tree-like structure. For example, if you are running a distributed -big-data store, a trace might be formed by a put request.

    -
    -
    -

    Annotation: is used to record existence of an event in time. Some of the core annotations used to define -the start and stop of a request are:

    -
    -
    -
      -
    • -

      cs - Client Sent - The client has made a request. This annotation depicts the start of the span.

      -
    • -
    • -

      sr - Server Received - The server side got the request and will start processing it. -If one subtracts the cs timestamp from this timestamp one will receive the network latency.

      -
    • -
    • -

      ss - Server Sent - Annotated upon completion of request processing (when the response -got sent back to the client). If one subtracts the sr timestamp from this timestamp one -will receive the time needed by the server side to process the request.

      -
    • -
    • -

      cr - Client Received - Signifies the end of the span. The client has successfully received the -response from the server side. If one subtracts the cs timestamp from this timestamp one -will receive the whole time needed by the client to receive the response from the server.

      -
    • -
    -
    -
    -

    Visualization of what Span and Trace will look in a system together with the Zipkin annotations:

    -
    -
    -
    -Trace Info propagation -
    -
    -
    -

    Each color of a note signifies a span (7 spans - from A to G). If you have such information in the note:

    -
    -
    -
    -
    Trace Id = X
    +annotations (tags), the ID of the span that caused them, and process ID's (normally IP address).
    +
    +Spans are started and stopped, and they keep track of their timing information.  Once you create a
    +span, you must stop it at some point in the future.
    +
    +*Trace:* A set of spans forming a tree-like structure.  For example, if you are running a distributed
    +big-data store, a trace might be formed by a put request.
    +
    +*Annotation:*  is used to record existence of an event in time. Some of the core annotations used to define
    +the start and stop of a request are:
    +
    +    - *cs* - Client Sent - The client has made a request. This annotation depicts the start of the span.
    +    - *sr* - Server Received -  The server side got the request and will start processing it.
    +    If one subtracts the cs timestamp from this timestamp one will receive the network latency.
    +    - *ss* - Server Sent -  Annotated upon completion of request processing (when the response
    +    got sent back to the client). If one subtracts the sr timestamp from this timestamp one
    +    will receive the time needed by the server side to process the request.
    +    - *cr* - Client Received - Signifies the end of the span. The client has successfully received the
    +    response from the server side. If one subtracts the cs timestamp from this timestamp one
    +    will receive the whole time needed by the client to receive the response from the server.
    +
    +Visualization of what *Span* and *Trace* will look in a system together with the Zipkin annotations:
    +
    +image::https://raw.githubusercontent.com/spring-cloud/spring-cloud-sleuth/master/docs/src/main/asciidoc/images/trace-id.png[Trace Info propagation]
    +
    +Each color of a note signifies a span (7 spans - from *A* to *G*). If you have such information in the note:
    +
    +[source]
    +Trace Id = X
     Span Id = D
    -Client Sent
    -
    -
    -
    -

    That means that the current span has Trace-Id set to X, Span-Id set to D. It also has emitted - Client Sent event.

    -
    -
    -

    This is how the visualization of the parent / child relationship of spans would look like:

    -
    -
    -
    -Parent child relationship -
    -
    -
    -
    -

    Purpose

    -
    -

    In the following sections the example from the image above will be taken into consideration.

    -
    -
    -

    Distributed tracing with Zipkin

    -
    -

    Altogether there are 10 spans . If you go to traces in Zipkin you will see this number:

    -
    -
    -
    -Traces -
    -
    -
    -

    However if you pick a particular trace then you will see 7 spans:

    -
    -
    -
    -Traces Info propagation -
    -
    -
    - - - - - -
    -
    Note
    -
    -When picking a particular trace you will see merged spans. That means that if there were 2 spans sent to +Client Sent + +That means that the current span has *Trace-Id* set to *X*, *Span-Id* set to *D*. It also has emitted + *Client Sent* event. + +This is how the visualization of the parent / child relationship of spans would look like: + +image::https://raw.githubusercontent.com/spring-cloud/spring-cloud-sleuth/master/docs/src/main/asciidoc/images/parents.png[Parent child relationship] + +=== Purpose + +In the following sections the example from the image above will be taken into consideration. + +==== Distributed tracing with Zipkin + +Altogether there are *10 spans* . If you go to traces in Zipkin you will see this number: + +image::https://raw.githubusercontent.com/spring-cloud/spring-cloud-sleuth/master/docs/src/main/asciidoc/images/zipkin-traces.png[Traces] + +However if you pick a particular trace then you will see *7 spans*: + +image::https://raw.githubusercontent.com/spring-cloud/spring-cloud-sleuth/master/docs/src/main/asciidoc/images/zipkin-ui.png[Traces Info propagation] + +NOTE: When picking a particular trace you will see merged spans. That means that if there were 2 spans sent to Zipkin with Server Received and Server Sent / Client Received and Client Sent annotations then they will presented as a single span. -
    -
    -
    -

    In the image depicting the visualization of what Span and Trace is you can see 20 -colorful labels. How does it happen that in Zipkin 10 spans are received?

    -
    -
    -
      -
    • -

      2 span A labels signify span started and closed. Upon closing a single span is sent to Zipkin.

      -
    • -
    • -

      4 span B labels are in fact are single span with 4 annotations. However this span is composed of -two separate instances. One sent from service 1 and one from service 2. So in fact two span instances will be sent -to Zipkin and merged there.

      -
    • -
    • -

      2 span C labels signify span started and closed. Upon closing a single span is sent to Zipkin.

      -
    • -
    • -

      4 span B labels are in fact are single span with 4 annotations. However this span is composed of -two separate instances. One sent from service 2 and one from service 3. So in fact two span instances will be sent -to Zipkin and merged there.

      -
    • -
    • -

      2 span E labels signify span started and closed. Upon closing a single span is sent to Zipkin.

      -
    • -
    • -

      4 span B labels are in fact are single span with 4 annotations. However this span is composed of -two separate instances. One sent from service 2 and one from service 4. So in fact two span instances will be sent -to Zipkin and merged there.

      -
    • -
    • -

      2 span G labels signify span started and closed. Upon closing a single span is sent to Zipkin.

      -
    • -
    -
    -
    -

    So 1 span from A, 2 spans from B, 1 span from C, 2 spans from D, 1 span from E, 2 spans from F and 1 from G. -Altogether 10 spans.

    -
    -
    -
    -

    Log correlation

    -
    -

    When grepping the logs of those four applications by trace id equal to e.g. 2485ec27856c56f4 one would get the following:

    -
    -
    -
    -
    service1.log:2016-02-26 11:15:47.561  INFO [service1,2485ec27856c56f4,2485ec27856c56f4,true] 68058 --- [nio-8081-exec-1] i.s.c.sleuth.docs.service1.Application   : Hello from service1. Calling service2
    +
    +In the image depicting the visualization of what *Span* and *Trace* is you can see 20
    +colorful labels. How does it happen that in Zipkin 10 spans are received?
    +
    +    - 2 span *A* labels signify span started and closed. Upon closing a single span is sent to Zipkin.
    +    - 4 span *B* labels are in fact are single span with 4 annotations. However this span is composed of
    +        two separate instances. One sent from service 1 and one from service 2. So in fact two span instances will be sent
    +        to Zipkin and merged there.
    +    - 2 span *C* labels signify span started and closed. Upon closing a single span is sent to Zipkin.
    +    - 4 span *B* labels are in fact are single span with 4 annotations. However this span is composed of
    +        two separate instances. One sent from service 2 and one from service 3. So in fact two span instances will be sent
    +        to Zipkin and merged there.
    +    - 2 span *E* labels signify span started and closed. Upon closing a single span is sent to Zipkin.
    +    - 4 span *B* labels are in fact are single span with 4 annotations. However this span is composed of
    +        two separate instances. One sent from service 2 and one from service 4. So in fact two span instances will be sent
    +        to Zipkin and merged there.
    +    - 2 span *G* labels signify span started and closed. Upon closing a single span is sent to Zipkin.
    +
    +So 1 span from *A*, 2 spans from *B*, 1 span from *C*, 2 spans from *D*, 1 span from *E*, 2 spans from *F* and 1 from *G*.
    +Altogether *10* spans.
    +
    +.Click Pivotal Web Services icon to see it live!
    +[caption="Click Pivotal Web Services icon to see it live!"]
    +image:pws.png["Zipkin deployed on Pivotal Web Services", link="http://docssleuth-zipkin-server.cfapps.io/", width=150, height=74]
    +
    +The dependency graph in Zipkin would look like this:
    +
    +image::https://raw.githubusercontent.com/spring-cloud/spring-cloud-sleuth/master/docs/src/main/asciidoc/images/dependencies.png[Dependencies]
    +
    +.Click Pivotal Web Services icon to see it live!
    +[caption="Click Pivotal Web Services icon to see it live!"]
    +image:pws.png["Zipkin deployed on Pivotal Web Services", link="http://docssleuth-zipkin-server.cfapps.io/dependency", width=150, height=74]
    +
    +
    +==== Log correlation
    +
    +When grepping the logs of those four applications by trace id equal to e.g. `2485ec27856c56f4` one would get the following:
    +
    +[source]
    +service1.log:2016-02-26 11:15:47.561  INFO [service1,2485ec27856c56f4,2485ec27856c56f4,true] 68058 --- [nio-8081-exec-1] i.s.c.sleuth.docs.service1.Application   : Hello from service1. Calling service2
     service2.log:2016-02-26 11:15:47.710  INFO [service2,2485ec27856c56f4,9aa10ee6fbde75fa,true] 68059 --- [nio-8082-exec-1] i.s.c.sleuth.docs.service2.Application   : Hello from service2. Calling service3 and then service4
     service3.log:2016-02-26 11:15:47.895  INFO [service3,2485ec27856c56f4,1210be13194bfe5,true] 68060 --- [nio-8083-exec-1] i.s.c.sleuth.docs.service3.Application   : Hello from service3
     service2.log:2016-02-26 11:15:47.924  INFO [service2,2485ec27856c56f4,9aa10ee6fbde75fa,true] 68059 --- [nio-8082-exec-1] i.s.c.sleuth.docs.service2.Application   : Got response from service3 [Hello from service3]
     service4.log:2016-02-26 11:15:48.134  INFO [service4,2485ec27856c56f4,1b1845262ffba49d,true] 68061 --- [nio-8084-exec-1] i.s.c.sleuth.docs.service4.Application   : Hello from service4
     service2.log:2016-02-26 11:15:48.156  INFO [service2,2485ec27856c56f4,9aa10ee6fbde75fa,true] 68059 --- [nio-8082-exec-1] i.s.c.sleuth.docs.service2.Application   : Got response from service4 [Hello from service4]
    -service1.log:2016-02-26 11:15:48.182  INFO [service1,2485ec27856c56f4,2485ec27856c56f4,true] 68058 --- [nio-8081-exec-1] i.s.c.sleuth.docs.service1.Application   : Got response from service2 [Hello from service2, response from service3 [Hello from service3] and from service4 [Hello from service4]]
    -
    -
    -
    -

    If you’re using a log aggregating tool like Kibana, -Splunk etc. you can order the events that took place. An example of -Kibana would look like this:

    -
    -
    -
    -Log correlation with Kibana -
    -
    -
    -

    If you want to use Logstash here is the Grok pattern for Logstash:

    -
    -
    -
    -
    filter {
    +service1.log:2016-02-26 11:15:48.182  INFO [service1,2485ec27856c56f4,2485ec27856c56f4,true] 68058 --- [nio-8081-exec-1] i.s.c.sleuth.docs.service1.Application   : Got response from service2 [Hello from service2, response from service3 [Hello from service3] and from service4 [Hello from service4]]
    +
    +If you're using a log aggregating tool like https://www.elastic.co/products/kibana[Kibana],
    +http://www.splunk.com/[Splunk] etc. you can order the events that took place. An example of
    +Kibana would look like this:
    +
    +image::https://raw.githubusercontent.com/spring-cloud/spring-cloud-sleuth/master/docs/src/main/asciidoc/images/kibana.png[Log correlation with Kibana]
    +
    +If you want to use https://www.elastic.co/guide/en/logstash/current/index.html[Logstash] here is the Grok pattern for Logstash:
    +
    +[source]
    +filter {
            # pattern matching logback pattern
            grok {
                   match => { "message" => "%{TIMESTAMP_ISO8601:timestamp}\s+%{LOGLEVEL:severity}\s+\[%{DATA:service},%{DATA:trace},%{DATA:span},%{DATA:exportable}\]\s+%{DATA:pid}---\s+\[%{DATA:thread}\]\s+%{DATA:class}\s+:\s+%{GREEDYDATA:rest}" }
            }
    -}
    -
    -
    -
    - - - - - -
    -
    Note
    -
    -If you want to use Grok together with the logs from Cloud Foundry you have to use this pattern: -
    -
    -
    -
    -
    filter {
    +}
    +
    +NOTE: If you want to use Grok together with the logs from Cloud Foundry you have to use this pattern:
    +[source]
    +filter {
            # pattern matching logback pattern
            grok {
                   match => { "message" => "(?m)OUT\s+%{TIMESTAMP_ISO8601:timestamp}\s+%{LOGLEVEL:severity}\s+\[%{DATA:service},%{DATA:trace},%{DATA:span},%{DATA:exportable}\]\s+%{DATA:pid}---\s+\[%{DATA:thread}\]\s+%{DATA:class}\s+:\s+%{GREEDYDATA:rest}" }
            }
    -}
    +} + +=== Adding to the project + +In general if you want to profit only from Spring Cloud Sleuth without the Zipkin integration just add +the *spring-cloud-starter-sleuth* module to your project. + +If you want both Sleuth and Zipkin just add the *spring-cloud-starter-zipkin* dependency. + +== Features + +* Adds trace and span ids to the Slf4J MDC, so you can extract all the logs from a given trace or span in a log aggregator. Example logs: ++
    -
    -
    -
    -

    Adding to the project

    -
    -

    In general if you want to profit only from Spring Cloud Sleuth without the Zipkin integration just add -the spring-cloud-starter-sleuth module to your project.

    -
    -

    If you want both Sleuth and Zipkin just add the spring-cloud-starter-zipkin dependency.

    +

    2016-02-02 15:30:57.902 INFO [bar,6bfd228dc00d216b,6bfd228dc00d216b,false] 23030 --- [nio-8081-exec-3] …​ +2016-02-02 15:30:58.372 ERROR [bar,6bfd228dc00d216b,6bfd228dc00d216b,false] 23030 --- [nio-8081-exec-3] …​ +2016-02-02 15:31:01.936 INFO [bar,46ab0d418373cbc9,46ab0d418373cbc9,false] 23030 --- [nio-8081-exec-4] …​

    -
    -
    -

    Features

    -
    -
    -
      -
    • -

      Adds trace and span ids to the Slf4J MDC, so you can extract all the logs from a given trace or span in a log aggregator. Example logs:

      -
      2016-02-02 15:30:57.902  INFO [bar,6bfd228dc00d216b,6bfd228dc00d216b,false] 23030 --- [nio-8081-exec-3] ...
      -2016-02-02 15:30:58.372 ERROR [bar,6bfd228dc00d216b,6bfd228dc00d216b,false] 23030 --- [nio-8081-exec-3] ...
      -2016-02-02 15:31:01.936  INFO [bar,46ab0d418373cbc9,46ab0d418373cbc9,false] 23030 --- [nio-8081-exec-4] ...
      -
      -
      -
      -

      notice the [appname,traceId,spanId,exportable] entries from the MDC:

      -
      -
      -
        -
      • -

        spanId - the id of a specific operation that took place

        -
      • -
      • -

        appname - the name of the application that logged the span

        -
      • -
      • -

        traceId - the id of the latency graph that contains the span

        -
      • -
      • -

        exportable - whether the log should be exported to Zipkin or not. When would you like the span not to be -exportable? In the case in which you want to wrap some operation in a Span and have it written to the logs -only.

        -
      • -
      -
      -
    • -
    • -

      Provides an abstraction over common distributed tracing data models: traces, spans (forming a DAG), annotations, -key-value annotations. Loosely based on HTrace, but Zipkin (Dapper) compatible.

      -
    • -
    • -

      Sleuth records timing information to aid in latency analysis. Using sleuth, you can pinpoint causes of -latency in your applications. Sleuth is written to not log too much, and to not cause your production application to crash.

      -
      -
        -
      • -

        propagates structural data about your call-graph in-band, and the rest out-of-band.

        -
      • -
      • -

        includes opinionated instrumentation of layers such as HTTP

        -
      • -
      • -

        includes sampling policy to manage volume

        -
      • -
      • -

        can report to a Zipkin system for query and visualization

        -
      • -
      -
      -
    • -
    • -

      Instruments common ingress and egress points from Spring applications (servlet filter, async endpoints, -rest template, scheduled actions, message channels, zuul filters, feign client).

      -
    • -
    • -

      Sleuth includes default logic to join a trace across http or messaging boundaries. For example, http propagation +

      +
      +notice the `[appname,traceId,spanId,exportable]` entries from the MDC:
      +
      +    - *spanId* - the id of a specific operation that took place
      +    - *appname* - the name of the application that logged the span
      +    - *traceId* - the id of the latency graph that contains the span
      +    - *exportable* - whether the log should be exported to Zipkin or not. When would you like the span not to be
      +    exportable? In the case in which you want to wrap some operation in a Span and have it written to the logs
      +    only.
      +
      +* Provides an abstraction over common distributed tracing data models: traces, spans (forming a DAG), annotations,
      +key-value annotations. Loosely based on HTrace, but Zipkin (Dapper) compatible.
      +
      +* Sleuth records timing information to aid in latency analysis. Using sleuth, you can pinpoint causes of
      +latency in your applications. Sleuth is written to not log too much, and to not cause your production application to crash.
      +  - propagates structural data about your call-graph in-band, and the rest out-of-band.
      +  - includes opinionated instrumentation of layers such as HTTP
      +  - includes sampling policy to manage volume
      +  - can report to a Zipkin system for query and visualization
      +
      +* Instruments common ingress and egress points from Spring applications (servlet filter, async endpoints,
      +rest template, scheduled actions, message channels, zuul filters, feign client).
      +
      +* Sleuth includes default logic to join a trace across http or messaging boundaries. For example, http propagation
       works via Zipkin-compatible request headers. This propagation logic is defined and customized via
      -SpanInjector and SpanExtractor implementations.

      -
    • -
    • -

      Provides simple metrics of accepted / dropped spans.

      -
    • -
    • -

      If spring-cloud-sleuth-zipkin then the app will generate and collect Zipkin-compatible traces. +`SpanInjector` and `SpanExtractor` implementations. + +* Provides simple metrics of accepted / dropped spans. + +* If `spring-cloud-sleuth-zipkin` then the app will generate and collect Zipkin-compatible traces. By default it sends them via HTTP to a Zipkin server on localhost (port 9411). -Configure the location of the service using spring.zipkin.baseUrl.

      -
    • -
    • -

      If spring-cloud-sleuth-stream then the app will generate and collect traces via Spring Cloud Stream. +Configure the location of the service using `spring.zipkin.baseUrl`. + +* If `spring-cloud-sleuth-stream` then the app will generate and collect traces via https://github.com/spring-cloud/spring-cloud-stream[Spring Cloud Stream]. Your app automatically becomes a producer of tracer messages that are sent over your broker of choice -(e.g. RabbitMQ, Apache Kafka, Redis).

      -
    • -
    -
    -
    - - - - - -
    -
    Important
    -
    -If using Zipkin or Stream, configure the percentage of spans exported using spring.sleuth.sampler.percentage -(default 0.1, i.e. 10%). Otherwise you might think that Sleuth is not working cause it’s omitting some spans. -
    -
    -
    - - - - - -
    -
    Note
    -
    -the SLF4J MDC is always set and logback users will immediately see the trace and span ids in logs per the example +(e.g. RabbitMQ, Apache Kafka, Redis). + +IMPORTANT: If using Zipkin or Stream, configure the percentage of spans exported using `spring.sleuth.sampler.percentage` +(default 0.1, i.e. 10%). *Otherwise you might think that Sleuth is not working cause it's omitting some spans.* + +NOTE: the SLF4J MDC is always set and logback users will immediately see the trace and span ids in logs per the example above. Other logging systems have to configure their own formatter to get the same result. The default is - logging.pattern.level set to %clr(%5p) %clr([${spring.application.name:},%X{X-B3-TraceId:-},%X{X-B3-SpanId:-},%X{X-Span-Export:-}]){yellow} + `logging.pattern.level` set to `%clr(%5p) %clr([${spring.application.name:},%X{X-B3-TraceId:-},%X{X-B3-SpanId:-},%X{X-Span-Export:-}]){yellow}` (this is a Spring Boot feature for logback users). - This means that if you’re not using SLF4J this pattern WILL NOT be automatically applied. -
    -
    -
    -
    -
    -

    Sampling

    -
    -
    -

    In distributed tracing the data volumes can be very high so sampling -can be important (you usually don’t need to export all spans to get a + *This means that if you're not using SLF4J this pattern WILL NOT be automatically applied*. + +== Sampling + +In distributed tracing the data volumes can be very high so sampling +can be important (you usually don't need to export all spans to get a good picture of what is happening). Spring Cloud Sleuth has a -Sampler strategy that you can implement to take control of the +`Sampler` strategy that you can implement to take control of the sampling algorithm. Samplers do not stop span (correlation) ids from being generated, but they do prevent the tags and events being attached and exported. By default you get a strategy that continues to @@ -7137,238 +7190,156 @@ non-exportable. If all your apps run with this sampler you will see traces in logs, but not in any remote store. For testing the default is often enough, and it probably is all you need if you are only using the logs (e.g. with an ELK aggregator). If you are exporting span data -to Zipkin or Spring Cloud Stream, there is also an AlwaysSampler -that exports everything and a PercentageBasedSampler that samples a -fixed fraction of spans.

    +to Zipkin or Spring Cloud Stream, there is also an `AlwaysSampler` +that exports everything and a `PercentageBasedSampler` that samples a +fixed fraction of spans. + +NOTE: the `PercentageBasedSampler` is the default if you are using +`spring-cloud-sleuth-zipkin` or `spring-cloud-sleuth-stream`. You can +configure the exports using `spring.sleuth.sampler.percentage`. + +A sampler can be installed just by creating a bean definition, e.g: + +[source,java]
    -
    - - - - - -
    -
    Note
    -
    -the PercentageBasedSampler is the default if you are using -spring-cloud-sleuth-zipkin or spring-cloud-sleuth-stream. You can -configure the exports using spring.sleuth.sampler.percentage. -
    -

    A sampler can be installed just by creating a bean definition, e.g:

    -
    -
    -
    -
    @Bean
    +

    @Bean public Sampler defaultSampler() { return new AlwaysSampler(); -}

    -
    -
    -
    -
    -
    -

    Instrumentation

    -
    -
    -

    Spring Cloud Sleuth instruments all your Spring application -automatically, so you shouldn’t have to do anything to activate -it. The instrumentation is added using a variety of technologies -according to the stack that is available, e.g. for a servlet web -application we use a Filter, and for Spring Integration we use -ChannelInterceptors.

    -
    -
    -

    You can customize the keys used in span tags. To limit the volume of -span data, by default an HTTP request will be tagged only with a -handful of metadata like the status code, host and URL. You can add -request headers by configuring spring.sleuth.keys.http.headers (a -list of header names).

    -
    -
    - - - - - -
    -
    Note
    -
    -Remember that tags are only collected and exported if there is a -Sampler that allows it (by default there is not, so there is no -danger of accidentally collecting too much data without configuring -something). -
    -
    -
    - - - - - -
    -
    Note
    -
    -Currently the instrumentation in Spring Cloud Sleuth is eager - it means that -we’re actively trying to pass the tracing context between threads. Also timing events -are captured even when sleuth isn’t exporting data to a tracing system. -This approach may change in the future towards being lazy on this matter. -
    -
    -
    -
    -
    -

    Span lifecycle

    -
    -
    -

    You can do the following operations on the Span by means of Tracer interface:

    -
    -
    -
      -
    • -

      start - when you start a span its name is assigned and start timestamp is recorded.

      -
    • -
    • -

      close - the span gets finished (the end time of the span is recorded) and if -the span is exportable then it will be eligible for collection to Zipkin. -The span is also removed from the current thread.

      -
    • -
    • -

      continue - a new instance of span will be created whereas it will be a copy of the -one that it continues.

      -
    • -
    • -

      detach - the span doesn’t get stopped or closed. It only gets removed from the current thread.

      -
    • -
    • -

      create with explicit parent - you can create a new span and set an explicit parent to it

      -
    • -
    -
    -
    -

    Creating and closing spans

    -
    -

    You can manually create spans by using the Tracer interface.

    +}

    -
    // Start a span. If there was a span present in this thread it will become
    -// the `newSpan`'s parent.
    -Span newSpan = this.tracer.createSpan("calculateTax");
    +
    == Instrumentation
    +
    +Spring Cloud Sleuth instruments all your Spring application
    +automatically, so you shouldn't have to do anything to activate
    +it. The instrumentation is added using a variety of technologies
    +according to the stack that is available, e.g. for a servlet web
    +application we use a `Filter`, and for Spring Integration we use
    +`ChannelInterceptors`.
    +
    +You can customize the keys used in span tags. To limit the volume of
    +span data, by default an HTTP request will be tagged only with a
    +handful of metadata like the status code, host and URL. You can add
    +request headers by configuring `spring.sleuth.keys.http.headers` (a
    +list of header names).
    +
    +NOTE: Remember that tags are only collected and exported if there is a
    +`Sampler` that allows it (by default there is not, so there is no
    +danger of accidentally collecting too much data without configuring
    +something).
    +
    +NOTE: Currently the instrumentation in Spring Cloud Sleuth is eager - it means that
    +we're actively trying to pass the tracing context between threads. Also timing events
    +are captured even when sleuth isn't exporting data to a tracing system.
    +This approach may change in the future towards being lazy on this matter.
    +
    +== Span lifecycle
    +
    +You can do the following operations on the Span by means of *Tracer* interface:
    +
    +- <<creating-and-closing-spans, start>> - when you start a span its name is assigned and start timestamp is recorded.
    +- <<creating-and-closing-spans, close>> - the span gets finished (the end time of the span is recorded) and if
    +the span is *exportable* then it will be eligible for collection to Zipkin.
    +The span is also removed from the current thread.
    +- <<continuing-spans, continue>> - a new instance of span will be created whereas it will be a copy of the
    +one that it continues.
    +- <<continuing-spans, detach>> - the span doesn't get stopped or closed. It only gets removed from the current thread.
    +- <<creating-spans-with-explicit-parent, create with explicit parent>> - you can create a new span and set an explicit parent to it
    +
    +=== Creating and closing spans [[creating-and-closing-spans]]
    +
    +You can manually create spans by using the *Tracer* interface.
    +
    +[source,java]
    +
    +
    +
    +

    Span newSpan = this.tracer.createSpan("calculateTax"); try { - // ... + // …​ // You can tag a span this.tracer.addTag("taxValue", taxValue); - // ... + // …​ // You can log an event on a span newSpan.logEvent("taxCalculated"); } finally { // Once done remember to close the span. This will allow collecting // the span to send it to Zipkin this.tracer.close(newSpan); -} -

    -
    -
    -

    In this example we could see how to create a new instance of span. Assuming that there already -was a span present in this thread then it would become the parent of that span.

    -
    -
    - - - - - -
    -
    Important
    -
    -Always clean after you create a span! Don’t forget to close a span if you want to send it to Zipkin. -
    -
    -
    -
    -

    Continuing spans

    -
    -

    Sometimes you don’t want to create a new span but you want to continue one. Example of such a -situation might be (of course it all depends on the use-case):

    -
    -
    -
      -
    • -

      AOP - If there was already a span created before an aspect was reached then you might not want to create a new span.

      -
    • -
    • -

      Hystrix - executing a Hystrix command is most likely a logical part of the current processing. It’s in fact -only a technical implementation detail that you wouldn’t necessarily want to reflect in tracing as a separate being.

      -
    • -
    -
    -
    -

    The continued instance of span is equal to the one that it continues:

    +}

    -
    Span continuedSpan = this.tracer.continueSpan(spanToContinue);
    -assertThat(continuedSpan).isEqualTo(spanToContinue);
    +
    In this example we could see how to create a new instance of span. Assuming that there already
    +was a span present in this thread then it would become the parent of that span.
    +
    +IMPORTANT: Always clean after you create a span! Don't forget to close a span if you want to send it to Zipkin.
    +
    +=== Continuing spans [[continuing-spans]]
    +
    +Sometimes you don't want to create a new span but you want to continue one. Example of such a
    +situation might be (of course it all depends on the use-case):
    +
    +    - *AOP* - If there was already a span created before an aspect was reached then you might not want to create a new span.
    +    - *Hystrix* - executing a Hystrix command is most likely a logical part of the current processing. It's in fact
    +    only a technical implementation detail that you wouldn't necessarily want to reflect in tracing as a separate being.
    +
    +The continued instance of span is equal to the one that it continues:
    +[source,java]
    -

    To continue a span you can use the Tracer interface.

    +

    Span continuedSpan = this.tracer.continueSpan(spanToContinue); +assertThat(continuedSpan).isEqualTo(spanToContinue);

    -
    // let's assume that we're in a thread Y and we've received
    -// the `initialSpan` from thread X
    -Span continuedSpan = this.tracer.continueSpan(initialSpan);
    +
    To continue a span you can use the *Tracer* interface.
    +
    +[source,java]
    +
    +
    +
    +

    Span continuedSpan = this.tracer.continueSpan(initialSpan); try { - // ... + // …​ // You can tag a span this.tracer.addTag("taxValue", taxValue); - // ... + // …​ // You can log an event on a span continuedSpan.logEvent("taxCalculated"); } finally { - // Once done remember to detach the span. That way you'll + // Once done remember to detach the span. That way you’ll // safely remove it from the current thread without closing it this.tracer.detach(continuedSpan); -} -

    -
    -
    - - - - - -
    -
    Important
    -
    -Always clean after you create a span! Don’t forget to detach a span if some work was done started in one - thread (e.g. thread X) and it’s waiting for other threads (e.g. Y, Z) to finish. - Then the spans in the threads Y, Z should be detached at the end of their work. When the results are collected - the span in thread X should be closed. -
    -
    -
    -
    -

    Creating spans with an explicit parent

    -
    -

    There is a possibility that you want to start a new span and provide an explicit parent of that span. -Let’s assume that the parent of a span is in one thread and you want to start a new span in another thread. The -startSpan method of the Tracer interface is the method you are looking for.

    +}

    -
    // let's assume that we're in a thread Y and we've received
    -// the `initialSpan` from thread X. `initialSpan` will be the parent
    -// of the `newSpan`
    -Span newSpan = this.tracer.createSpan("calculateCommission", initialSpan);
    +
    IMPORTANT: Always clean after you create a span! Don't forget to detach a span if some work was done started in one
    + thread (e.g. thread X) and it's waiting for other threads (e.g. Y, Z) to finish.
    + Then the spans in the threads Y, Z should be detached at the end of their work. When the results are collected
    + the span in thread X should be closed.
    +
    +=== Creating spans with an explicit parent [[creating-spans-with-explicit-parent]]
    +
    +There is a possibility that you want to start a new span and provide an explicit parent of that span.
    +Let's assume that the parent of a span is in one thread and you want to start a new span in another thread. The
    +`startSpan` method of the `Tracer` interface is the method you are looking for.
    +
    +[source,java]
    +
    +
    +
    +

    Span newSpan = this.tracer.createSpan("calculateCommission", initialSpan); try { - // ... + // …​ // You can tag a span this.tracer.addTag("commissionValue", commissionValue); - // ... + // …​ // You can log an event on a span newSpan.logEvent("commissionCalculated"); } finally { @@ -7376,214 +7347,179 @@ try { // the span to send it to Zipkin. The tags and events set on the // newSpan will not be present on the parent this.tracer.close(newSpan); -} -

    -
    -
    - - - - - -
    -
    Important
    -
    -After having created such a span remember to close it. Otherwise you will see a lot of warnings in your logs - related to the fact that you have a span present in the current thread other than the one you’re trying to close. - What’s worse your spans won’t get closed properly thus will not get collected to Zipkin. -
    -
    -
    -
    -
    -
    -

    Naming spans

    -
    -
    -

    Picking a span name is not a trivial task. Span name should depict an operation name. The name should -be low cardinality (e.g. not include identifiers).

    -
    -
    -

    Since there is a lot of instrumentation going on some of the span names will be -artificial like:

    -
    -
    -
      -
    • -

      http:path when received an http request on a given path

      -
    • -
    • -

      async for asynchronous operations done via wrapped Callable and Runnable.

      -
    • -
    • -

      @Scheduled annotated methods will return the simple name of the class.

      -
    • -
    -
    -
    -

    Fortunately, for the asynchronous processing you can provide explicit naming.

    -
    -
    -

    @SpanName annotation

    -
    -

    You can do name the span explicitly via the @SpanName annotation.

    +}

    -
    @SpanName("calculateTax")
    -class TaxCountingRunnable implements Runnable {
    +
    IMPORTANT: After having created such a span remember to close it. Otherwise you will see a lot of warnings in your logs
    + related to the fact that you have a span present in the current thread other than the one you're trying to close.
    + What's worse your spans won't get closed properly thus will not get collected to Zipkin.
     
    -    @Override public void run() {
    +== Naming spans
    +
    +Picking a span name is not a trivial task. Span name should depict an operation name. The name should
    +be low cardinality (e.g. not include identifiers).
    +
    +Since there is a lot of instrumentation going on some of the span names will be
    +artificial like:
    +
    +- `http:path` when received an http request on a given path
    +- `async` for asynchronous operations done via wrapped `Callable` and `Runnable`.
    +- `@Scheduled` annotated methods will return the simple name of the class.
    +
    +Fortunately, for the asynchronous processing you can provide explicit naming.
    +
    +=== @SpanName annotation
    +
    +You can do name the span explicitly via the `@SpanName` annotation.
    +
    +[source,java]
    +
    +
    +
    +

    @SpanName("calculateTax") +class TaxCountingRunnable implements Runnable {

    +
    +
    +
    +
        @Override public void run() {
             // perform logic
         }
    -}
    +}
    -
    -

    In this case, when processed in the following manner:

    -
    -
    Runnable runnable = new TraceRunnable(tracer, spanNamer, new TaxCountingRunnable());
    +
    In this case, when processed in the following manner:
    +
    +[source,java]
    +
    +
    +
    +

    Runnable runnable = new TraceRunnable(tracer, spanNamer, new TaxCountingRunnable()); Future<?> future = executorService.submit(runnable); -// ... some additional logic ... -future.get(); -

    -
    -
    -

    The span will be named calculateTax.

    -
    -
    -
    -

    toString() method

    -
    -

    It’s pretty rare to create separate classes for Runnable or Callable. Typically one creates an anonymous -instance of those classes. You can’t annotate such classes thus to override that, if there is no @SpanName annotation present, -we’re checking if the class has a custom implementation of the toString() method.

    -
    -
    -

    So executing such code:

    +future.get();

    -
    Runnable runnable = new TraceRunnable(tracer, spanNamer, new Runnable() {
    +
    The span will be named `calculateTax`.
    +
    +=== toString() method
    +
    +It's pretty rare to create separate classes for `Runnable` or `Callable`. Typically one creates an anonymous
    +instance of those classes. You can't annotate such classes thus to override that, if there is no `@SpanName` annotation present,
    +we're checking if the class has a custom implementation of the `toString()` method.
    +
    +So executing such code:
    +
    +[source,java]
    +
    +
    +
    +

    Runnable runnable = new TraceRunnable(tracer, spanNamer, new Runnable() { @Override public void run() { // perform logic - } - - @Override public String toString() { + }

    +
    +
    +
    +
        @Override public String toString() {
             return "calculateTax";
         }
     });
     Future<?> future = executorService.submit(runnable);
     // ... some additional logic ...
    -future.get();
    +future.get();
    -
    -

    will lead in creating a span named calculateTax.

    -
    -
    -
    -
    -
    -

    Customizations

    -
    -
    -

    Thanks to the SpanInjector and SpanExtractor you can customize the way spans -are created and propagated.

    -
    -
    -

    There are currently two built-in ways to pass tracing information between processes:

    -
    -
    -
      -
    • -

      via Spring Integration

      -
    • -
    • -

      via HTTP

      -
    • -
    -
    -
    -

    Span ids are extracted from Zipkin-compatible (B3) headers (either Message +

    +
    +
    will lead in creating a span named `calculateTax`.
    +
    +== Customizations
    +
    +Thanks to the `SpanInjector` and `SpanExtractor` you can customize the way spans
    +are created and propagated.
    +
    +There are currently two built-in ways to pass tracing information between processes:
    +
    + * via Spring Integration
    + * via HTTP
    +
    +Span ids are extracted from Zipkin-compatible (B3) headers (either `Message`
     or HTTP headers), to start or join an existing trace. Trace information is
    -injected into any outbound requests so the next hop can extract them.

    +injected into any outbound requests so the next hop can extract them. + +=== Spring Integration + +For Spring Integration these are the beans responsible for creation of a Span from a `Message` + and filling in the `MessageBuilder` with tracing information. + +[source,java]
    +
    -
    -

    Spring Integration

    -

    For Spring Integration these are the beans responsible for creation of a Span from a Message - and filling in the MessageBuilder with tracing information.

    -
    -
    -
    -
    @Bean
    +

    @Bean public SpanExtractor<Message> messagingSpanExtractor() { - ... -} - -@Bean + …​ +}

    +
    +
    +

    @Bean public SpanInjector<MessageBuilder> messagingSpanInjector() { - ... -} -

    -
    -
    -

    You can override them by providing your own implementation and by adding a @Primary annotation -to your bean definition.

    -
    -
    -
    -

    HTTP

    -
    -

    For HTTP these are the beans responsible for creation of a Span from a HttpServletRequest - and filling in the HttpServletResponse with tracing information.

    + …​ +}

    -
    @Bean
    +
    You can override them by providing your own implementation and by adding a `@Primary` annotation
    +to your bean definition.
    +
    +=== HTTP
    +
    +For HTTP these are the beans responsible for creation of a Span from a `HttpServletRequest`
    +  and filling in the `HttpServletResponse` with tracing information.
    +
    +[source,java]
    +
    +
    +
    +

    @Bean public SpanExtractor<HttpServletRequest> httpServletRequestSpanExtractor() { - ... -} - -@Bean + …​ +}

    +
    +
    +

    @Bean public SpanInjector<HttpServletResponse> httpServletResponseSpanInjector() { - ... -} -

    -
    -
    -

    You can override them by providing your own implementation and by adding a @Primary annotation -to your bean definition.

    -
    -
    -
    -

    Example

    -
    -

    Let’s assume that instead of the standard Zipkin compatible tracing HTTP header names -you have

    -
    -
    -
      -
    • -

      for trace id - correlationId

      -
    • -
    • -

      for span id - mySpanId

      -
    • -
    -
    -
    -

    This is a an example of a SpanExtractor

    + …​ +}

    -
    static class CustomHttpServletRequestSpanExtractor
    -        implements SpanExtractor<HttpServletRequest> {
    +
    You can override them by providing your own implementation and by adding a `@Primary` annotation
    +to your bean definition.
     
    -    @Override
    +=== Example
    +
    +Let's assume that instead of the standard Zipkin compatible tracing HTTP header names
    +you have
    +
    +* for trace id - `correlationId`
    +* for span id - `mySpanId`
    +
    +This is a an example of a `SpanExtractor`
    +
    +[source,java]
    +
    +
    +
    +

    static class CustomHttpServletRequestSpanExtractor + implements SpanExtractor<HttpServletRequest> {

    +
    +
    +
    +
        @Override
         public Span joinTrace(HttpServletRequest carrier) {
             long traceId = Span.hexToId(carrier.getHeader("correlationId"));
             long spanId = Span.hexToId(carrier.getHeader("mySpanId"));
    @@ -7592,94 +7528,101 @@ you have

    // build rest of the Span return builder.build(); } -}
    +}
    -
    -

    The following SpanInjector could be created

    -
    -
    static class CustomHttpServletResponseSpanInjector
    -        implements SpanInjector<HttpServletResponse> {
    +
    The following `SpanInjector` could be created
     
    -    @Override
    +[source,java]
    +
    +
    +
    +

    static class CustomHttpServletResponseSpanInjector + implements SpanInjector<HttpServletResponse> {

    +
    +
    +
    +
        @Override
         public void inject(Span span, HttpServletResponse carrier) {
             carrier.addHeader("correlationId", Span.idToHex(span.getTraceId()));
             carrier.addHeader("mySpanId", Span.idToHex(span.getSpanId()));
             // inject the rest of Span values to the header
         }
    -}
    +}
    -
    -

    And you could register them like this:

    -
    -
    @Bean
    +
    And you could register them like this:
    +
    +[source,java]
    +
    +
    +
    +

    @Bean @Primary SpanExtractor<HttpServletRequest> customHttpServletRequestSpanExtractor() { return new CustomHttpServletRequestSpanExtractor(); -} - -@Bean +}

    +
    +
    +

    @Bean @Primary SpanInjector<HttpServletResponse> customHttpServletResponseSpanInjector() { return new CustomHttpServletResponseSpanInjector(); -} -

    -
    -
    -
    -
    -
    -

    Span Data as Messages

    -
    -
    -

    You can accumulate and send span data over -Spring Cloud Stream by -including the spring-cloud-sleuth-stream jar as a dependency, and -adding a Channel Binder implementation -(e.g. spring-cloud-starter-stream-rabbit for RabbitMQ or -spring-cloud-starter-stream-kafka for Kafka). This will -automatically turn your app into a producer of messages with payload -type Spans.

    -
    -
    -

    Zipkin Consumer

    -
    -

    There is a special convenience annotation for setting up a message consumer -for the Span data and pushing it into a Zipkin SpanStore. This application

    +}

    -
    @SpringBootApplication
    +
    == Span Data as Messages
    +
    +You can accumulate and send span data over
    +http://cloud.spring.io/spring-cloud-stream[Spring Cloud Stream] by
    +including the `spring-cloud-sleuth-stream` jar as a dependency, and
    +adding a Channel Binder implementation
    +(e.g. `spring-cloud-starter-stream-rabbit` for RabbitMQ or
    +`spring-cloud-starter-stream-kafka` for Kafka). This will
    +automatically turn your app into a producer of messages with payload
    +type `Spans`.
    +
    +=== Zipkin Consumer
    +
    +There is a special convenience annotation for setting up a message consumer
    +for the Span data and pushing it into a Zipkin `SpanStore`. This application
    +
    +[source,java]
    +
    +
    +
    +

    @SpringBootApplication @EnableZipkinStreamServer public class Consumer { public static void main(String[] args) { SpringApplication.run(Consumer.class, args); } -} -

    -
    -
    -

    will listen for the Span data on whatever transport you provide via a -Spring Cloud Stream Binder (e.g. include -spring-cloud-starter-stream-rabbit for RabbitMQ, and similar -starters exist for Redis and Kafka). The app will also be a -Zipkin server, which hosts -the UI and api on port 9411.

    -
    -
    -

    The default SpanStore is in-memory (good for demos and getting -started quickly). For a more robust solution you can add MySQL and -spring-boot-starter-jdbc to your classpath and enable the JDBC -SpanStore via configuration, e.g.:

    +}

    -
    spring:
    +
    will listen for the Span data on whatever transport you provide via a
    +Spring Cloud Stream `Binder` (e.g. include
    +`spring-cloud-starter-stream-rabbit` for RabbitMQ, and similar
    +starters exist for Redis and Kafka). The app will also be a
    +https://github.com/openzipkin/zipkin-java[Zipkin server], which hosts
    +the UI and api on port 9411.
    +
    +The default `SpanStore` is in-memory (good for demos and getting
    +started quickly). For a more robust solution you can add MySQL and
    +`spring-boot-starter-jdbc` to your classpath and enable the JDBC
    +`SpanStore` via configuration, e.g.:
    +
    +[source,yaml]
    +
    +
    +
    +

    spring: rabbitmq: host: ${RABBIT_HOST:localhost} datasource: @@ -7693,96 +7636,75 @@ started quickly). For a more robust solution you can add MySQL and sleuth: enabled: false zipkin: - store: - type: mysql -

    -
    -
    - - - - - -
    -
    Note
    -
    -The @EnableZipkinStreamServer is also annotated with -@EnableZipkinServer so the process will also expose the standard -Zipkin server endpoints for collecting spans over HTTP, and for -querying in the Zipkin Web UI. -
    -
    -
    -
    -

    Custom Consumer

    -
    -

    A custom consumer can also easily be implemented using -spring-cloud-sleuth-stream and binding to the SleuthSink. Example:

    + storage: + type: mysql

    -
    @EnableBinding(SleuthSink.class)
    +
    NOTE: The `@EnableZipkinStreamServer` is also annotated with
    +`@EnableZipkinServer` so the process will also expose the standard
    +Zipkin server endpoints for collecting spans over HTTP, and for
    +querying in the Zipkin Web UI.
    +
    +=== Custom Consumer
    +
    +A custom consumer can also easily be implemented using
    +`spring-cloud-sleuth-stream` and binding to the `SleuthSink`. Example:
    +
    +[source,java]
    +
    +
    +
    +

    @EnableBinding(SleuthSink.class) @SpringBootApplication(exclude = SleuthStreamAutoConfiguration.class) @MessageEndpoint -public class Consumer { - - @ServiceActivator(inputChannel = SleuthSink.INPUT) +public class Consumer {

    +
    +
    +
    +
        @ServiceActivator(inputChannel = SleuthSink.INPUT)
         public void sink(Spans input) throws Exception {
             // ... process spans
         }
    -}
    +}
    -
    - - - - - -
    -
    Note
    -
    -the sample consumer application above explicitly excludes -SleuthStreamAutoConfiguration so it doesn’t send messages to itself, -but this is optional (you might actually want to trace requests into -the consumer app). -
    -
    -
    -
    -
    -
    -

    Metrics

    -
    -
    -

    Currently Spring Cloud Sleuth registers very simple metrics related to spans. -It’s using the Spring Boot’s metrics support -to calculate the number of accepted and dropped spans. Each time a span gets -sent to Zipkin the number of accepted spans will increase. If there’s an error then -the number of dropped spans will get increased.

    -
    -
    -
    -
    -

    Integrations

    -
    -
    -

    Runnable and Callable

    -
    -

    If you’re wrapping your logic in Runnable or Callable it’s enough to wrap those classes in their Sleuth representative.

    -
    -
    -

    Example for Runnable:

    -
    -
    Runnable runnable = new Runnable() {
    +
    NOTE: the sample consumer application above explicitly excludes
    +`SleuthStreamAutoConfiguration` so it doesn't send messages to itself,
    +but this is optional (you might actually want to trace requests into
    +the consumer app).
    +
    +== Metrics
    +
    +Currently Spring Cloud Sleuth registers very simple metrics related to spans.
    +It's using the http://docs.spring.io/spring-boot/docs/current/reference/html/production-ready-metrics.html#production-ready-recording-metrics[Spring Boot's metrics support]
    +to calculate the number of accepted and dropped spans. Each time a span gets
    +sent to Zipkin the number of accepted spans will increase. If there's an error then
    +the number of dropped spans will get increased.
    +
    +== Integrations
    +
    +=== Runnable and Callable
    +
    +If you're wrapping your logic in `Runnable` or `Callable` it's enough to wrap those classes in their Sleuth representative.
    +
    +Example for `Runnable`:
    +
    +[source,java]
    +
    +
    +
    +

    Runnable runnable = new Runnable() { @Override public void run() { // do some work - } - - @Override + }

    +
    +
    +
    +
        @Override
         public String toString() {
             return "spanNameFromToStringMethod";
         }
    @@ -7791,21 +7713,26 @@ the number of dropped spans will get increased.

    Runnable traceRunnable = new TraceRunnable(tracer, spanNamer, runnable, "calculateTax"); // Wrapping `Runnable` with `Tracer`. The Span name will be taken either from the // `@SpanName` annotation or from `toString` method -Runnable traceRunnableFromTracer = tracer.wrap(runnable);
    +Runnable traceRunnableFromTracer = tracer.wrap(runnable);
    -
    -

    Example for Callable:

    -
    -
    Callable<String> callable = new Callable<String>() {
    +
    Example for `Callable`:
    +
    +[source,java]
    +
    +
    +
    +

    Callable<String> callable = new Callable<String>() { @Override public String call() throws Exception { return someLogic(); - } - - @Override + }

    +
    +
    +
    +
        @Override
         public String toString() {
             return "spanNameFromToStringMethod";
         }
    @@ -7814,180 +7741,168 @@ Runnable traceRunnableFromTracer = tracer.wrap(runnable);
    Callable<String> traceCallable = new TraceCallable<>(tracer, spanNamer, callable, "calculateTax"); // Wrapping `Callable` with `Tracer`. The Span name will be taken either from the // `@SpanName` annotation or from `toString` method -Callable<String> traceCallableFromTracer = tracer.wrap(callable); +Callable<String> traceCallableFromTracer = tracer.wrap(callable);
    -
    -

    That way you will ensure that a new Span is created and closed for each execution.

    -
    -
    -
    -

    Hystrix

    -
    -

    Custom Concurrency Strategy

    -
    -

    We’re registering a custom HystrixConcurrencyStrategy -that wraps all Callable instances into their Sleuth representative - -the TraceCallable. The strategy either starts or continues a span depending on the fact whether tracing was already going -on before the Hystrix command was called. To disable the custom Hystrix Concurrency Strategy set the spring.sleuth.hystrix.strategy.enabled to false.

    -
    -
    -
    -

    Manual Command setting

    -
    -

    Assuming that you have the following HystrixCommand:

    -
    -
    HystrixCommand<String> hystrixCommand = new HystrixCommand<String>(setter) {
    +
    That way you will ensure that a new Span is created and closed for each execution.
    +
    +=== Hystrix
    +
    +==== Custom Concurrency Strategy
    +
    +We're registering a custom https://github.com/Netflix/Hystrix/wiki/Plugins#concurrencystrategy[`HystrixConcurrencyStrategy`]
    +that wraps all `Callable` instances into their Sleuth representative -
    +the `TraceCallable`. The strategy either starts or continues a span depending on the fact whether tracing was already going
    +on before the Hystrix command was called. To disable the custom Hystrix Concurrency Strategy set the `spring.sleuth.hystrix.strategy.enabled` to `false`.
    +
    +==== Manual Command setting
    +
    +Assuming that you have the following `HystrixCommand`:
    +
    +[source,java]
    +
    +
    +
    +

    HystrixCommand<String> hystrixCommand = new HystrixCommand<String>(setter) { @Override protected String run() throws Exception { return someLogic(); } -}; -

    -
    -
    -

    In order to pass the tracing information you have to wrap the same logic in the Sleuth version of the HystrixCommand which is the -TraceCommand:

    +};

    -
    TraceCommand<String> traceCommand = new TraceCommand<String>(tracer, traceKeys, setter) {
    +
    In order to pass the tracing information you have to wrap the same logic in the Sleuth version of the `HystrixCommand` which is the
    +`TraceCommand`:
    +
    +[source,java]
    +
    +
    +
    +

    TraceCommand<String> traceCommand = new TraceCommand<String>(tracer, traceKeys, setter) { @Override public String doRun() throws Exception { return someLogic(); } -}; +};

    -
    -
    -
    -
    -

    HTTP integration

    -
    -

    Features from this section can be disabled by providing the spring.sleuth.web.enabled property with value equal to false.

    -
    -
    -

    HTTP Filter

    -
    -

    Via the TraceFilter all sampled incoming requests result in creation of a Span. That Span’s name is http: + the path to which - the request was sent. E.g. if the request was sent to /foo/bar then the name will be http:/foo/bar. You can configure which URIs you would - like to skip via the spring.sleuth.web.skipPattern property. If you have ManagementServerProperties on classpath then - its value of contextPath gets appended to the provided skip pattern.

    -
    -
    -
    -

    Async Servlet support

    -
    -

    If your controller returns a Callable or a WebAsyncTask Spring Cloud Sleuth will continue the existing span instead of creating a new one.

    -
    -
    -
    -
    -

    HTTP client integration

    -
    -

    Synchronous Rest Template

    -
    -

    We’re injecting a RestTemplate interceptor that ensures that all the tracing information is passed to the requests. Each time a -call is made a new Span is created. It gets closed upon receiving the response. In order to block the synchronous RestTemplate features -just set spring.sleuth.web.client.enabled to false.

    -
    -
    -
    -

    Asynchronous Rest Template

    -
    -

    Custom instrumentation is set to create and close Spans upon sending and receiving requests. To block the AsyncRestTemplate -features set spring.sleuth.web.async.client.enabled to false.

    -
    -
    -
    -
    -

    Feign

    -
    -

    By default Spring Cloud Sleuth provides integration with feign via the TraceFeignClientAutoConfiguration. You can disable it entirely -by setting spring.sleuth.feign.enabled to false. If you do so then no Feign related instrumentation will take place.

    -
    -
    -

    Part of Feign instrumentation is done via a FeignBeanPostProcessor. You can disable it by providing the spring.sleuth.feign.processor.enabled equal to false. -If you set it like this then Spring Cloud Sleuth will not instrument any of your custom Feign components. All the default instrumentation -however will be still there.

    -
    -
    -
    -

    Asynchronous communication

    -
    -

    @Async annotated methods

    -
    -

    In Spring Cloud Sleuth we’re instrumenting async related components so that the tracing information is passed between threads. You can disable this behaviour -by setting the value of spring.sleuth.async.enabled to false.

    -
    -
    -

    If you annotate your method with @Async then we’ll automatically create a new Span with the following characteristics:

    -
    -
    -
      -
    • -

      the Span name will be the annotated method name

      -
    • -
    • -

      the Span will be tagged with that method’s class name and the method name too

      -
    • -
    -
    -
    -
    -

    @Scheduled annotated methods

    -
    -

    In Spring Cloud Sleuth we’re instrumenting scheduled method execution so that the tracing information is passed between threads. You can disable this behaviour -by setting the value of spring.sleuth.scheduled.enabled to false.

    -
    -
    -

    If you annotate your method with @Scheduled then we’ll automatically create a new Span with the following characteristics:

    -
    -
    -
      -
    • -

      the Span name will be the annotated method name

      -
    • -
    • -

      the Span will be tagged with that method’s class name and the method name too

      -
    • -
    -
    -
    -

    If you want to skip Span creation for some @Scheduled annotated classes you can set the -spring.sleuth.scheduled.skipPattern with a regular expression that will match the fully qualified name of the -@Scheduled annotated class.

    -
    -
    -
    -

    Executor, ExecutorService and ScheduledExecutorService

    -
    -

    We’re providing LazyTraceExecutor, TraceableExecutorService and TraceableScheduledExecutorService. Those implementations -are creating Spans each time a new task is submitted, invoked or scheduled.

    -
    -
    -
    -
    -

    Messaging

    -
    -

    Spring Cloud Sleuth integrates with Spring Integration. It creates spans for publish and -subscribe events. To disable Spring Integration instrumentation, set spring.sleuth.integration.enabled to false.

    -
    -
    -
    -

    Zuul

    -
    -

    We’re registering Zuul filters to propagate the tracing information (the request header is enriched with tracing data). -To disable Zuul support set the spring.sleuth.zuul.enabled property to false.

    -
    -
    -
    -
    -

    Spring Cloud Consul

    -
    +
    +
    === RxJava
    +
    +We're registering a custom https://github.com/ReactiveX/RxJava/wiki/Plugins#rxjavaschedulershook[`RxJavaSchedulersHook`]
    +that wraps all `Action0` instances into their Sleuth representative -
    +the `TraceAction`. The hook either starts or continues a span depending on the fact whether tracing was already going
    +on before the Action was scheduled. To disable the custom RxJavaSchedulersHook set the `spring.sleuth.rxjava.schedulers.hook.enabled` to `false`.
    +
    +=== HTTP integration
    +
    +Features from this section can be disabled by providing the `spring.sleuth.web.enabled` property with value equal to `false`.
    +
    +==== HTTP Filter
    +
    +Via the `TraceFilter` all sampled incoming requests result in creation of a Span. That Span's name is `http:` + the path to which
    + the request was sent. E.g. if the request was sent to `/foo/bar` then the name will be `http:/foo/bar`. You can configure which URIs you would
    + like to skip via the `spring.sleuth.web.skipPattern` property. If you have `ManagementServerProperties` on classpath then
    + its value of `contextPath` gets appended to the provided skip pattern.
    +
    +==== Async Servlet support
    +
    +If your controller returns a `Callable` or a `WebAsyncTask` Spring Cloud Sleuth will continue the existing span instead of creating a new one.
    +
    +=== HTTP client integration
    +
    +==== Synchronous Rest Template
    +
    +We're injecting a `RestTemplate` interceptor that ensures that all the tracing information is passed to the requests. Each time a
    +call is made a new Span is created. It gets closed upon receiving the response. In order to block the synchronous `RestTemplate` features
    +just set `spring.sleuth.web.client.enabled` to `false`.
    +
    +==== Asynchronous Rest Template
    +
    +Custom instrumentation is set to create and close Spans upon sending and receiving requests. You can customize the `ClientHttpRequestFactory`
    +and the `AsyncClientHttpRequestFactory` by registering your beans. Remember to use tracing compatible implementations (e.g. don't forget to
    +wrap `ThreadPoolTaskScheduler` in a `TraceAsyncListenableTaskExecutor`).
    +
    +To block the `AsyncRestTemplate` features set `spring.sleuth.web.async.client.enabled` to `false`.
    +To disable creation of the default `TraceAsyncClientHttpRequestFactoryWrapper` set `spring.sleuth.web.async.client.factory.enabled`
    +to `false`. If you don't want to create `AsyncRestClient` at all set `spring.sleuth.web.async.client.template.enabled` to `false`.
    +
    +=== Feign
    +
    +By default Spring Cloud Sleuth provides integration with feign via the `TraceFeignClientAutoConfiguration`. You can disable it entirely
    +by setting `spring.sleuth.feign.enabled` to false. If you do so then no Feign related instrumentation will take place.
    +
    +Part of Feign instrumentation is done via a `FeignBeanPostProcessor`. You can disable it by providing the `spring.sleuth.feign.processor.enabled` equal to `false`.
    +If you set it like this then Spring Cloud Sleuth will not instrument any of your custom Feign components. All the default instrumentation
    +however will be still there.
    +
    +=== Asynchronous communication
    +
    +==== @Async annotated methods
    +
    +In Spring Cloud Sleuth we're instrumenting async related components so that the tracing information is passed between threads. You can disable this behaviour
    +by setting the value of `spring.sleuth.async.enabled` to `false`.
    +
    +If you annotate your method with `@Async` then we'll automatically create a new Span with the following characteristics:
    +
    +    - the Span name will be the annotated method name
    +    - the Span will be tagged with that method's class name and the method name too
    +
    +==== @Scheduled annotated methods
    +
    +In Spring Cloud Sleuth we're instrumenting scheduled method execution so that the tracing information is passed between threads. You can disable this behaviour
    +by setting the value of `spring.sleuth.scheduled.enabled` to `false`.
    +
    +If you annotate your method with `@Scheduled` then we'll automatically create a new Span with the following characteristics:
    +
    +    - the Span name will be the annotated method name
    +    - the Span will be tagged with that method's class name and the method name too
    +
    +If you want to skip Span creation for some `@Scheduled` annotated classes you can set the
    +`spring.sleuth.scheduled.skipPattern` with a regular expression that will match the fully qualified name of the
    +`@Scheduled` annotated class.
    +
    +==== Executor, ExecutorService and ScheduledExecutorService
    +
    +We're providing `LazyTraceExecutor`, `TraceableExecutorService` and `TraceableScheduledExecutorService`. Those implementations
    +are creating Spans each time a new task is submitted, invoked or scheduled.
    +
    +Here you can see an example of how to pass tracing information with `TraceableExecutorService` when working with `CompletableFuture`:
    +
    +[source,java]
    +
    +
    +
    +

    CompletableFuture<Long> completableFuture = CompletableFuture.supplyAsync) → { // perform some logic return 1_000_000L; }, new TraceableExecutorService(executorService, // 'calculateTax' explicitly names the span - this param is optional tracer, traceKeys, spanNamer, "calculateTax";

    +
    +
    +
    +
    === Messaging
    +
    +Spring Cloud Sleuth integrates with http://projects.spring.io/spring-integration/[Spring Integration]. It creates spans for publish and
    +subscribe events. To disable Spring Integration instrumentation, set `spring.sleuth.integration.enabled` to false.
    +
    +=== Zuul
    +
    +We're registering Zuul filters to propagate the tracing information (the request header is enriched with tracing data).
    +To disable Zuul support set the `spring.sleuth.zuul.enabled` property to `false`.
    +
    +== Running examples
    +
    +You can find the running examples deployed in the https://run.pivotal.io/[Pivotal Web Services]. Check them out in the following links:
    +
    +- http://docssleuth-zipkin-server.cfapps.io/[Zipkin for apps presented in the samples to the top], its https://github.com/spring-cloud-samples/sleuth-documentation-apps[Github Code] and its build status image:https://build.spring.io/plugins/servlet/buildStatusImage/SCE2E-SCSDAOCF[Build Status, link=https://build.spring.io/browse/SCE2E-SCSDAOCF]
    +- http://docsbrewing-zipkin-web.cfapps.io/[Zipkin for Brewery on PWS], its https://github.com/spring-cloud-samples/brewery[Github Code] and its build status image:https://build.spring.io/plugins/servlet/buildStatusImage/SCE2E-SCSSE2ECFT[Build Status, link=https://build.spring.io/browse/SCE2E-SCSBFDOCF]
    +
    +:github-tag: master
    +:github-repo: spring-cloud/spring-cloud-consul
    +:github-raw: http://raw.github.com/{github-repo}/{github-tag}
    +:github-code: http://github.com/{github-repo}/tree/{github-tag}
    += Spring Cloud Consul
    +
     This project provides Consul integrations for Spring Boot apps through autoconfiguration
     and binding to the Spring Environment and other Spring programming model idioms. With a few
     simple annotations you can quickly enable and configure the common patterns inside your
    @@ -7995,407 +7910,370 @@ application and build large distributed systems with Consul based components. Th
     patterns provided include Service Discovery, Control Bus and Configuration.
     Intelligent Routing (Zuul) and Client Side Load Balancing (Ribbon), Circuit Breaker
     (Hystrix) are provided by integration with Spring Cloud Netflix.
    +
    +
    +[[spring-cloud-consul-install]]
    +== Install Consul
    +Please see the https://www.consul.io/intro/getting-started/install.html[installation documentation] for instructions on how to install Consul.
    +
    +[[spring-cloud-consul-agent]]
    +== Consul Agent
    +
    +A Consul Agent client must be available to all Spring Cloud Consul applications.  By default, the Agent client is expected to be at `localhost:8500`.  See the https://consul.io/docs/agent/basics.html[Agent documentation] for specifics on how to start an Agent client and how to connect to a cluster of Consul Agent Servers.  For development, after you have installed consul, you may start a Consul Agent using the following command:
    -
    -

    Install Consul

    -
    -
    -

    Please see the installation documentation for instructions on how to install Consul.

    -
    -
    -
    -
    -

    Consul Agent

    -
    -
    -

    A Consul Agent client must be available to all Spring Cloud Consul applications. By default, the Agent client is expected to be at localhost:8500. See the Agent documentation for specifics on how to start an Agent client and how to connect to a cluster of Consul Agent Servers. For development, after you have installed consul, you may start a Consul Agent using the following command:

    -
    +
    /src/main/bash/local_run_consul.sh
    -
    ./src/main/bash/local_run_consul.sh
    +
    This will start an agent in server mode on port 8500, with the ui available at http://localhost:8500
    +
    +[[spring-cloud-consul-discovery]]
    +== Service Discovery with Consul
    +
    +Service Discovery is one of the key tenets of a microservice based architecture. Trying to hand configure each client or some form of convention can be very difficult to do and can be very brittle.  Consul provides Service Discovery services via an https://www.consul.io/docs/agent/http.html[HTTP API] and https://www.consul.io/docs/agent/dns.html[DNS].  Spring Cloud Consul leverages the HTTP API for service registration and discovery.  This does not prevent non-Spring Cloud applications from leveraging the DNS interface.  Consul Agents servers are run in a https://www.consul.io/docs/internals/architecture.html[cluster] that communicates via a https://www.consul.io/docs/internals/gossip.html[gossip protocol] and uses the https://www.consul.io/docs/internals/consensus.html[Raft consensus protocol].
    +
    +=== Registering with Consul
    +
    +When a client registers with Consul, it provides meta-data about itself such as host and port, id, name and tags.  An HTTP https://www.consul.io/docs/agent/checks.html[Check] is created by default that Consul hits the `/health` endpoint every 10 seconds.  If the health check fails, the service instance is marked as critical.
    +
    +Example Consul client:
    +
    +[source,java,indent=0]
    -

    This will start an agent in server mode on port 8500, with the ui available at http://localhost:8500

    -
    -
    -
    -
    -

    Service Discovery with Consul

    -
    -
    -

    Service Discovery is one of the key tenets of a microservice based architecture. Trying to hand configure each client or some form of convention can be very difficult to do and can be very brittle. Consul provides Service Discovery services via an HTTP API and DNS. Spring Cloud Consul leverages the HTTP API for service registration and discovery. This does not prevent non-Spring Cloud applications from leveraging the DNS interface. Consul Agents servers are run in a cluster that communicates via a gossip protocol and uses the Raft consensus protocol.

    -
    -
    -

    Registering with Consul

    -
    -

    When a client registers with Consul, it provides meta-data about itself such as host and port, id, name and tags. An HTTP Check is created by default that Consul hits the /health endpoint every 10 seconds. If the health check fails, the service instance is marked as critical.

    -
    -
    -

    Example Consul client:

    -
    -
    -
    -
    @SpringBootApplication
    +

    @SpringBootApplication @EnableDiscoveryClient @RestController -public class Application { - - @RequestMapping("/") - public String home() { - return "Hello world"; - } - - public static void main(String[] args) { - new SpringApplicationBuilder(Application.class).web(true).run(args); - } - -}

    +public class Application {

    +
    +
    +
    +
    @RequestMapping("/")
    +public String home() {
    +    return "Hello world";
    +}
    +
    +
    +
    +
    +
    public static void main(String[] args) {
    +    new SpringApplicationBuilder(Application.class).web(true).run(args);
    +}
    -

    (i.e. utterly normal Spring Boot app). If the Consul client is located somewhere other than localhost:8500, the configuration is required to locate the client. Example:

    +

    }

    -
    application.yml
    -
    spring:
    +
    (i.e. utterly normal Spring Boot app).  If the Consul client is located somewhere other than `localhost:8500`, the configuration is required to locate the client. Example:
    +
    +.application.yml
    +
    +
    +
    +

    spring: cloud: consul: host: localhost - port: 8500 -

    -
    -
    - - - - - -
    -
    Caution
    -
    -If you use Spring Cloud Consul Config, the above values will need to be placed in bootstrap.yml instead of application.yml. -
    -
    -
    -

    The default service name, instance id and port, taken from the Environment, are ${spring.application.name}, the Spring Context ID and ${server.port} respectively.

    -
    -
    -

    @EnableDiscoveryClient make the app into both a Consul "service" (i.e. it registers itself) and a "client" (i.e. it can query Consul to locate other services).

    -
    -
    -
    -

    HTTP Health Check

    -
    -

    The health check for a Consul instance defaults to "/health", which is the default locations of a useful endpoint in a Spring Boot Actuator application. You need to change these, even for an Actuator application if you use a non-default context path or servlet path (e.g. server.servletPath=/foo) or management endpoint path (e.g. management.contextPath=/admin). The interval that Consul uses to check the health endpoint may also be configured. "10s" and "1m" represent 10 seconds and 1 minute respectively. Example:

    + port: 8500

    -
    application.yml
    -
    spring:
    +
    CAUTION: If you use <<spring-cloud-consul-config,Spring Cloud Consul Config>>, the above values will need to be placed in `bootstrap.yml` instead of `application.yml`.
    +
    +The default service name, instance id and port, taken from the `Environment`, are `${spring.application.name}`, the Spring Context ID and `${server.port}` respectively.
    +
    +`@EnableDiscoveryClient` make the app into both a Consul "service" (i.e. it registers itself) and a "client" (i.e. it can query Consul to locate other services).
    +
    +=== HTTP Health Check
    +
    +The health check for a Consul instance defaults to "/health", which is the default locations of a useful endpoint in a Spring Boot Actuator application. You need to change these, even for an Actuator application if you use a non-default context path or servlet path (e.g. `server.servletPath=/foo`) or management endpoint path (e.g. `management.contextPath=/admin`). The interval that Consul uses to check the health endpoint may also be configured.  "10s" and "1m" represent 10 seconds and 1 minute respectively.  Example:
    +
    +.application.yml
    +
    +
    +
    +

    spring: cloud: consul: discovery: healthCheckPath: ${management.contextPath}/health - healthCheckInterval: 15s -

    -
    -
    -

    Making the Consul Instance ID Unique

    -
    -

    By default a consul instance is registered with an ID that is equal to its Spring Application Context ID. By default, the Spring Application Context ID is ${spring.application.name}:comma,separated,profiles:${server.port}. For most cases, this will allow multiple instances of one service to run on one machine. If further uniqueness is required, Using Spring Cloud you can override this by providing a unique identifier in spring.cloud.consul.discovery.instanceId. For example:

    + healthCheckInterval: 15s

    -
    application.yml
    -
    spring:
    +
    ==== Metadata and Consul tags
    +
    +Consul does not yet support metadata on services. Spring Cloud's `ServiceInstance` has a `Map<String, String> metadata` field. Spring Cloud Consul uses Consul tags to approximate metadata until Consul officially supports metadata. Tags with the form `key=value` will be split and used as a `Map` key and value respectively. Tags without the equal `=` sign, will be used as both the key and value.
    +
    +.application.yml
    +
    +
    +
    +

    spring: cloud: consul: discovery: - instanceId: ${spring.application.name}:${spring.application.instance_id:${random.value}} -

    -
    -
    -

    With this metadata, 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 random value will not be needed.

    -
    -
    -
    -
    -

    Using the DiscoveryClient

    -
    -

    Spring Cloud has support for Feign (a REST client builder) and also Spring RestTemplate using the logical service names instead of physical URLs.

    -
    -
    -

    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.

    + tags: foo=bar, baz

    -
    @Autowired
    -private DiscoveryClient discoveryClient;
    +
    The above configuration will result in a map with `foo->bar` and `baz->baz`.
     
    -public String serviceUrl() {
    +==== Making the Consul Instance ID Unique
    +
    +By default a consul instance is registered with an ID that is equal to its Spring Application Context ID. By default, the Spring Application Context ID is `${spring.application.name}:comma,separated,profiles:${server.port}`. For most cases, this will allow multiple instances of one service to run on one machine.  If further uniqueness is required, Using Spring Cloud you can override this by providing a unique identifier in `spring.cloud.consul.discovery.instanceId`. For example:
    +
    +.application.yml
    +
    +
    +
    +

    spring: + cloud: + consul: + discovery: + instanceId: ${spring.application.name}:${spring.application.instance_id:${random.value}}

    +
    +
    +
    +
    With this metadata, 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 random value will not be needed.
    +
    +=== Using the DiscoveryClient
    +Spring Cloud has support for https://github.com/spring-cloud/spring-cloud-netflix/blob/master/docs/src/main/asciidoc/spring-cloud-netflix.adoc#spring-cloud-feign[Feign] (a REST client builder) and also https://github.com/spring-cloud/spring-cloud-netflix/blob/master/docs/src/main/asciidoc/spring-cloud-netflix.adoc#spring-cloud-ribbon[Spring `RestTemplate`] using the logical service names instead of physical URLs.
    +
    +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; -} -

    -
    -
    -
    -
    -
    -

    Distributed Configuration with Consul

    -
    -
    -

    Consul provides a Key/Value Store for storing configuration and other metadata. Spring Cloud Consul Config is an alternative to the Config Server and Client. Configuration is loaded into the Spring Environment during the special "bootstrap" phase. Configuration is stored in the /config folder by default. Multiple PropertySource instances are created based on the application’s name and the active profiles that mimicks the Spring Cloud Config order of resolving properties. For example, an application with the name "testApp" and with the "dev" profile will have the following property sources created:

    +}

    -
    config/testApp,dev/
    +
    [[spring-cloud-consul-config]]
    +== Distributed Configuration with Consul
    +
    +Consul provides a https://consul.io/docs/agent/http/kv.html[Key/Value Store] for storing configuration and other metadata.  Spring Cloud Consul Config is an alternative to the https://github.com/spring-cloud/spring-cloud-config[Config Server and Client].  Configuration is loaded into the Spring Environment during the special "bootstrap" phase.  Configuration is stored in the `/config` folder by default.  Multiple `PropertySource` instances are created based on the application's name and the active profiles that mimicks the Spring Cloud Config order of resolving properties.  For example, an application with the name "testApp" and with the "dev" profile will have the following property sources created:
    +
    +
    +
    +

    config/testApp,dev/ config/testApp/ config/application,dev/ -config/application/ -

    -
    -
    -

    The most specific property source is at the top, with the least specific at the bottom. Properties is the config/application folder are applicable to all applications using consul for configuration. Properties in the config/testApp folder are only available to the instances of the service named "testApp".

    -
    -
    -

    Configuration is currently read on startup of the application. Sending a HTTP POST to /refresh will cause the configuration to be reloaded. Watching the key value store (which Consul supports) is not currently possible, but will be a future addition to this project.

    -
    -
    -

    How to activate

    -
    -

    Including a dependency on org.springframework.cloud:spring-cloud-consul-config will enable auto-configuration that will setup Spring Cloud Consul Config.

    -
    -
    -
    -

    Customizing

    -
    -

    Consul Config may be customized using the following properties:

    +config/application/

    -
    bootstrap.yml
    -
    spring:
    +
    The most specific property source is at the top, with the least specific at the bottom.  Properties is the `config/application` folder are applicable to all applications using consul for configuration.  Properties in the `config/testApp` folder are only available to the instances of the service named "testApp".
    +
    +Configuration is currently read on startup of the application.  Sending a HTTP POST to `/refresh` will cause the configuration to be reloaded.  Watching the key value store (which Consul supports) is not currently possible, but will be a future addition to this project.
    +
    +=== How to activate
    +
    +Including a dependency on `org.springframework.cloud:spring-cloud-consul-config` will enable auto-configuration that will setup Spring Cloud Consul Config.
    +
    +=== Customizing
    +
    +Consul Config may be customized using the following properties:
    +
    +.bootstrap.yml
    +
    +
    +
    +

    spring: cloud: consul: config: enabled: true prefix: configuration defaultContext: apps - profileSeparator: '::' -

    -
    -
    -
      -
    • -

      enabled setting this value to "false" disables Consul Config

      -
    • -
    • -

      prefix sets the base folder for configuration values

      -
    • -
    • -

      defaultContext sets the folder name used by all applications

      -
    • -
    • -

      profileSeparator sets the value of the separator used to separate the profile name in property sources with profiles

      -
    • -
    -
    -
    -
    -
    -
    -

    YAML or Properties with Config

    -
    -
    -

    It may be more convenient to store a blob of properties in YAML or Properties format as opposed to individual key/value pairs. Set the spring.cloud.consul.config.format property to YAML or PROPERTIES. For example to use YAML:

    + profileSeparator: '::'

    -
    bootstrap.yml
    -
    spring:
    +
    * `enabled` setting this value to "false" disables Consul Config
    +* `prefix` sets the base folder for configuration values
    +* `defaultContext` sets the folder name used by all applications
    +* `profileSeparator` sets the value of the separator used to separate the profile name in property sources with profiles
    +
    +
    +[[spring-cloud-consul-config-format]]
    +== YAML or Properties with Config
    +
    +It may be more convenient to store a blob of properties in YAML or Properties format as opposed to individual key/value pairs.  Set the `spring.cloud.consul.config.format` property to `YAML` or `PROPERTIES`. For example to use YAML:
    +
    +.bootstrap.yml
    +
    +
    +
    +

    spring: cloud: consul: config: - format: YAML -

    -
    -
    -

    YAML must be set in the appropriate data key in consul. Using the defaults above the keys would look like:

    + format: YAML

    -
    config/testApp,dev/data
    +
    YAML must be set in the appropriate `data` key in consul. Using the defaults above the keys would look like:
    +
    +
    +
    +

    config/testApp,dev/data config/testApp/data config/application,dev/data -config/application/data -

    -
    -
    -

    You could store a YAML document in any of the keys listed above.

    -
    -
    -

    You can change the data key using spring.cloud.consul.config.data-key.

    -
    -
    -
    -
    -

    git2consul with Config

    -
    -
    -

    git2consul is a Consul community project that loads files from a git repository to individual keys into Consul. By default the names of the keys are names of the files. YAML and Properties files are supported with file extensions of .yml and .properties respectively. Set the spring.cloud.consul.config.format property to FILES. For example:

    +config/application/data

    -
    bootstrap.yml
    -
    spring:
    +
    You could store a YAML document in any of the keys listed above.
    +
    +You can change the data key using `spring.cloud.consul.config.data-key`.
    +
    +[[spring-cloud-consul-config-git2consul]]
    +== git2consul with Config
    +git2consul is a Consul community project that loads files from a git repository to individual keys into Consul. By default the names of the keys are names of the files. YAML and Properties files are supported with file extensions of `.yml` and `.properties` respectively.  Set the `spring.cloud.consul.config.format` property to `FILES`. For example:
    +
    +.bootstrap.yml
    +
    +
    +
    +

    spring: cloud: consul: config: - format: FILES -

    -
    -
    -

    Given the following keys in /config, the development profile and an application name of foo:

    + format: FILES

    -
    .gitignore
    -application.yml
    +
    Given the following keys in `/config`, the `development` profile and an application name of `foo`:
    +
    +
    +
    +
    gitignore
    +

    application.yml bar.properties foo-development.properties foo-production.yml foo.properties -master.ref -

    -
    -
    -

    the following property sources would be created:

    +master.ref

    -
    config/foo-development.properties
    +
    the following property sources would be created:
    +
    +
    +
    +

    config/foo-development.properties config/foo.properties -config/application.yml +config/application.yml

    -
    -
    -

    The value of each key needs to be a properly formatted YAML or Properties file.

    -
    -
    -
    -
    -

    Fail Fast

    -
    -
    -

    It may be convenient in certain circumstances (like local development or certain test scenarios) to not fail if consul isn’t available for configuration. Setting spring.cloud.consul.config.failFast=false in bootstrap.yml will cause the configuration module to log a warning rather than throw an exception. This will allow the application to continue startup normally.

    -
    -
    -
    -
    -

    Consul Retry

    -
    -
    -

    If you expect that the consul agent may occasionally be unavailable when +

    +
    +
    The value of each key needs to be a properly formatted YAML or Properties file.
    +
    +
    +[[spring-cloud-consul-failfast]]
    +== Fail Fast
    +
    +It may be convenient in certain circumstances (like local development or certain test scenarios) to not fail if consul isn't available for configuration. Setting `spring.cloud.consul.config.failFast=false` in `bootstrap.yml` will cause the configuration module to log a warning rather than throw an exception. This will allow the application to continue startup normally.
    +
    +[[spring-cloud-consul-retry]]
    +== Consul Retry
    +
    +If you expect that the consul agent may occasionally be unavailable when
     your app starts, you can ask it to keep trying after a failure. You need to add
    -spring-retry and spring-boot-starter-aop to your classpath. The default
    +`spring-retry` and `spring-boot-starter-aop` to your classpath. The default
     behaviour is to retry 6 times with an initial backoff interval of 1000ms and an
     exponential multiplier of 1.1 for subsequent backoffs. You can configure these
    -properties (and others) using spring.cloud.consul.retry.* configuration properties.
    -This works with both Spring Cloud Consul Config and Discovery registration.

    -
    -
    - - - - - -
    -
    Tip
    -
    -To take full control of the retry add a @Bean of type -RetryOperationsInterceptor with id "consulRetryInterceptor". Spring -Retry has a RetryInterceptorBuilder that makes it easy to create one. -
    +properties (and others) using `spring.cloud.consul.retry.*` configuration properties. +This works with both Spring Cloud Consul Config and Discovery registration. + +TIP: To take full control of the retry add a `@Bean` of type +`RetryOperationsInterceptor` with id "consulRetryInterceptor". Spring +Retry has a `RetryInterceptorBuilder` that makes it easy to create one. + +[[spring-cloud-consul-bus]] +== Spring Cloud Bus with Consul + +Coming in a later release. + +[[spring-cloud-consul-hystrix]] +== Circuit Breaker with Hystrix + +Applications can use the Hystrix Circuit Breaker provided by the Spring Cloud Netflix project by including this starter in the projects pom.xml: `spring-cloud-starter-hystrix`. Hystrix doesn't depend on the Netflix Discovery Client. The `@EnableHystrix` annotation should be placed on a configuration class (usually the main class). Then methods can be annotated with `@HystrixCommand` to be protected by a circuit breaker. See http://projects.spring.io/spring-cloud/spring-cloud.html#_circuit_breaker_hystrix_clients[the documentation] for more details. + + +[[spring-cloud-consul-turbine]] +== Hystrix metrics aggregation with Turbine and Consul + +Turbine (provided by the Spring Cloud Netflix project), aggregates multiple instances Hystrix metrics streams, so the dashboard can display an aggregate view. Turbine uses the `DiscoveryClient` interface to lookup relevant instances. To use Turbine with Spring Cloud Consul, configure the Turbine application in a manner similar to the following examples: + +.pom.xml
    -
    -
    -

    Spring Cloud Bus with Consul

    -
    -

    Coming in a later release.

    -
    -
    -
    -
    -

    Circuit Breaker with Hystrix

    -
    -
    -

    Applications can use the Hystrix Circuit Breaker provided by the Spring Cloud Netflix project by including this starter in the projects pom.xml: spring-cloud-starter-hystrix. Hystrix doesn’t depend on the Netflix Discovery Client. The @EnableHystrix annotation should be placed on a configuration class (usually the main class). Then methods can be annotated with @HystrixCommand to be protected by a circuit breaker. See the documentation for more details.

    -
    -
    -
    -
    -

    Hystrix metrics aggregation with Turbine and Consul

    -
    -
    -

    Turbine (provided by the Spring Cloud Netflix project), aggregates multiple instances Hystrix metrics streams, so the dashboard can display an aggregate view. Turbine uses the DiscoveryClient interface to lookup relevant instances. To use Turbine with Spring Cloud Consul, configure the Turbine application in a manner similar to the following examples:

    -
    -
    -
    pom.xml
    -
    -
    <dependency>
    +

    <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-netflix-turbine</artifactId> </dependency> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-consul-discovery</artifactId> -</dependency>

    +</dependency>

    +
    +
    +
    +
    Notice that the Turbine dependency is not a starter. The turbine starter includes support for Netflix Eureka.
    +
    +.application.yml
    -

    Notice that the Turbine dependency is not a starter. The turbine starter includes support for Netflix Eureka.

    -
    -
    -
    application.yml
    -
    -
    spring.application.name: turbine
    +

    spring.application.name: turbine applications: consulhystrixclient turbine: aggregator: clusterConfig: ${applications} - appConfig: ${applications}

    + appConfig: ${applications}

    +
    +
    +
    +
    The `clusterConfig` and `appConfig` sections must match, so it's useful to put the comma-separated list of service ID's into a separate configuration property.
    +
    +.Turbine.java
    -

    The clusterConfig and appConfig sections must match, so it’s useful to put the comma-separated list of service ID’s into a separate configuration property.

    -
    -
    -
    Turbine.java
    -
    -
    @EnableTurbine
    +

    @EnableTurbine @EnableDiscoveryClient @SpringBootApplication public class Turbine { public static void main(String[] args) { SpringApplication.run(DemoturbinecommonsApplication.class, args); } -}

    +}

    -
    -
    -
    -

    Spring Cloud Zookeeper

    -
    +
    +
    :github-tag: master
    +:github-repo: spring-cloud/spring-cloud-zookeeper
    +:github-raw: http://raw.github.com/{github-repo}/{github-tag}
    +:github-code: http://github.com/{github-repo}/tree/{github-tag}
    +:toc: left
    +
    += Spring Cloud Zookeeper
    +
     This project provides Zookeeper 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
    @@ -8403,150 +8281,124 @@ application and build large distributed systems with Zookeeper based components.
     patterns provided include Service Discovery and Configuration.
     Intelligent Routing (Zuul) and Client Side Load Balancing (Ribbon), Circuit Breaker
     (Hystrix) are provided by integration with Spring Cloud Netflix.
    +
    +
    +[[spring-cloud-zookeeper-install]]
    +== Install Zookeeper
    +Please see the http://zookeeper.apache.org/doc/current/zookeeperStarted.html[installation documentation] for instructions on how to install Zookeeper.
    +
    +[[spring-cloud-zookeeper-discovery]]
    +== Service Discovery with Zookeeper
    +
    +Service Discovery is one of the key tenets of a microservice based architecture. Trying to hand configure each client or some form of convention can be very difficult to do and can be very brittle. http://curator.apache.org[Curator](A java library for Zookeeper) provides Service Discovery services via http://curator.apache.org/curator-x-discovery/[Service Discovery Extension]. Spring Cloud Zookeeper leverages this extension for service registration and discovery.
    +
    +=== How to activate
    +
    +Including a dependency on `org.springframework.cloud:spring-cloud-starter-zookeeper-discovery` will enable auto-configuration that will setup Spring Cloud Zookeeper Discovery.
    +
    +=== Registering with Zookeeper
    +
    +When a client registers with Zookeeper, it provides meta-data about itself such as host and port, id and name.
    +
    +Example Zookeeper client:
    +
    +[source,java,indent=0]
    -
    -

    Install Zookeeper

    -
    -
    -

    Please see the installation documentation for instructions on how to install Zookeeper.

    -
    -
    -
    -
    -

    Service Discovery with Zookeeper

    -
    -
    -

    Service Discovery is one of the key tenets of a microservice based architecture. Trying to hand configure each client or some form of convention can be very difficult to do and can be very brittle. Curator(A java library for Zookeeper) provides Service Discovery services via Service Discovery Extension. Spring Cloud Zookeeper leverages this extension for service registration and discovery.

    -
    -
    -

    How to activate

    -
    -

    Including a dependency on org.springframework.cloud:spring-cloud-starter-zookeeper-discovery will enable auto-configuration that will setup Spring Cloud Zookeeper Discovery.

    -
    -
    -
    -

    Registering with Zookeeper

    -
    -

    When a client registers with Zookeeper, it provides meta-data about itself such as host and port, id and name.

    -
    -

    Example Zookeeper client:

    -
    -
    -
    -
    @SpringBootApplication
    +

    @SpringBootApplication @EnableDiscoveryClient @RestController -public class Application { - - @RequestMapping("/") - public String home() { - return "Hello world"; - } - - public static void main(String[] args) { - new SpringApplicationBuilder(Application.class).web(true).run(args); - } - -}

    +public class Application {

    +
    +
    +
    +
    @RequestMapping("/")
    +public String home() {
    +    return "Hello world";
    +}
    +
    +
    +
    +
    +
    public static void main(String[] args) {
    +    new SpringApplicationBuilder(Application.class).web(true).run(args);
    +}
    -

    (i.e. utterly normal Spring Boot app). If Zookeeper is located somewhere other than localhost:2181, the configuration is required to locate the server. Example:

    +

    }

    -
    application.yml
    -
    spring:
    +
    (i.e. utterly normal Spring Boot app).  If Zookeeper is located somewhere other than `localhost:2181`, the configuration is required to locate the server. Example:
    +
    +.application.yml
    +
    +
    +
    +

    spring: cloud: zookeeper: - connect-string: localhost:2181 -

    -
    -
    - - - - - -
    -
    Caution
    -
    -If you use Spring Cloud Zookeeper Config, the above values will need to be placed in bootstrap.yml instead of application.yml. -
    -
    -
    -

    The default service name, instance id and port, taken from the Environment, are ${spring.application.name}, the Spring Context ID and ${server.port} respectively.

    -
    -
    -

    @EnableDiscoveryClient makes the app into both a Zookeeper "service" (i.e. it registers itself) and a "client" (i.e. it can query Zookeeper to locate other services).

    -
    -
    -
    -

    Using the DiscoveryClient

    -
    -

    Spring Cloud has support for Feign (a REST client builder) and also Spring RestTemplate using the logical service names instead of physical URLs.

    -
    -
    -

    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.

    + connect-string: localhost:2181

    -
    @Autowired
    -private DiscoveryClient discoveryClient;
    +
    CAUTION: If you use <<spring-cloud-zookeeper-config,Spring Cloud Zookeeper Config>>, the above values will need to be placed in `bootstrap.yml` instead of `application.yml`.
     
    -public String serviceUrl() {
    +The default service name, instance id and port, taken from the `Environment`, are `${spring.application.name}`, the Spring Context ID and `${server.port}` respectively.
    +
    +`@EnableDiscoveryClient` makes the app into both a Zookeeper "service" (i.e. it registers itself) and a "client" (i.e. it can query Zookeeper to locate other services).
    +
    +
    +=== Using the DiscoveryClient
    +Spring Cloud has support for https://github.com/spring-cloud/spring-cloud-netflix/blob/master/docs/src/main/asciidoc/spring-cloud-netflix.adoc#spring-cloud-feign[Feign] (a REST client builder) and also https://github.com/spring-cloud/spring-cloud-netflix/blob/master/docs/src/main/asciidoc/spring-cloud-netflix.adoc#spring-cloud-ribbon[Spring `RestTemplate`] using the logical service names instead of physical URLs.
    +
    +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 = discoveryClient.getInstances("STORES"); if (list != null && list.size() > 0 ) { return list.get(0).getUri().toString(); } return null; -} -

    -
    -
    -
    -
    -
    -

    Zookeeper Dependencies

    -
    -
    -

    Using the Zookeeper Dependencies

    -
    -

    Spring Cloud Zookeeper gives you a possibility to provide dependencies of your application as properties. As dependencies you can understand other applications that are registered -in Zookeeper and which you would like to call via Feign (a REST client builder) -and also Spring RestTemplate.

    -
    -
    -

    You can also benefit from the Zookeeper Dependency Watchers functionality that lets you control and monitor what is the state of your dependencies and decide what to do with that.

    -
    -
    -
    -

    How to activate Zookeeper Dependencies

    -
    -
      -
    • -

      Including a dependency on org.springframework.cloud:spring-cloud-starter-zookeeper-discovery will enable auto-configuration that will setup Spring Cloud Zookeeper Dependencies.

      -
    • -
    • -

      In addition to that you have to set the property spring.cloud.zookeeper.dependencies.enabled to true (defaults to true if not set explicitly).

      -
    • -
    • -

      You have to have the spring.cloud.zookeeper.dependencies section properly set up - check the subsequent section for more details.

      -
    • -
    -
    -
    -
    -

    Setting up Zookeeper Dependencies

    -
    -

    Let’s take a closer look at an example of dependencies representation:

    +}

    -
    application.yml
    -
    spring.application.name: yourServiceName
    +
    [[spring-cloud-zookeeper-dependencies]]
    +
    +== Zookeeper Dependencies
    +
    +=== Using the Zookeeper Dependencies
    +
    +Spring Cloud Zookeeper gives you a possibility to provide dependencies of your application as properties. As dependencies you can understand other applications that are registered
    +in Zookeeper and which you would like to call via https://github.com/spring-cloud/spring-cloud-netflix/blob/master/docs/src/main/asciidoc/spring-cloud-netflix.adoc#spring-cloud-feign[Feign] (a REST client builder)
    +and also https://github.com/spring-cloud/spring-cloud-netflix/blob/master/docs/src/main/asciidoc/spring-cloud-netflix.adoc#spring-cloud-ribbon[Spring `RestTemplate`].
    +
    +You can also benefit from the Zookeeper Dependency Watchers functionality that lets you control and monitor what is the state of your dependencies and decide what to do with that.
    +
    +=== How to activate Zookeeper Dependencies
    +
    +- Including a dependency on `org.springframework.cloud:spring-cloud-starter-zookeeper-discovery` will enable auto-configuration that will setup Spring Cloud Zookeeper Dependencies.
    +- If you have to have the `spring.cloud.zookeeper.dependencies` section properly set up - check the subsequent section for more details then the feature is active
    +- You can have the dependencies turned off even if you've provided the dependencies in your properties. Just set the property `spring.cloud.zookeeper.dependency.enabled` to false (defaults to `true`).
    +
    +=== Setting up Zookeeper Dependencies
    +
    +Let's take a closer look at an example of dependencies representation:
    +
    +.application.yml
    +
    +
    +
    +

    spring.application.name: yourServiceName spring.cloud.zookeeper: dependencies: newsletter: @@ -8566,463 +8418,355 @@ spring.cloud.zookeeper: loadBalancerType: ROUND_ROBIN contentTypeTemplate: application/vnd.mailing.$version+json version: v1 - required: true -

    -
    -
    -

    Let’s now go through each part of the dependency one by one. The root property name is spring.cloud.zookeeper.dependencies.

    -
    -
    -

    Aliases

    -
    -

    Below the root property you have to represent each dependency has by an alias due to the constraints of Ribbon (the application id has to be placed in the URL -thus you can’t pass any complex path like /foo/bar/name). The alias will be the name that you will use instead of serviceId for DiscoveryClient, Feign or RestTemplate.

    -
    -
    -

    In the aforementioned examples the aliases are newsletter and mailing. Example of Feign usage with newsletter would be:

    + required: true

    -
    @FeignClient("newsletter")
    +
    Let's now go through each part of the dependency one by one. The root property name is `spring.cloud.zookeeper.dependencies`.
    +
    +==== Aliases
    +
    +Below the root property you have to represent each dependency has by an alias due to the constraints of Ribbon (the application id has to be placed in the URL
    +thus you can't pass any complex path like /foo/bar/name). The alias will be the name that you will use instead of serviceId for `DiscoveryClient`, `Feign` or `RestTemplate`.
    +
    +In the aforementioned examples the aliases are `newsletter` and `mailing`. Example of Feign usage with `newsletter` would be:
    +
    +
    +
    +

    @FeignClient("newsletter") public interface NewsletterService { @RequestMapping(method = RequestMethod.GET, value = "/newsletter") String getNewsletters(); -} -

    -
    -
    -
    -

    Path

    -
    -

    Represented by path yaml property.

    -
    -
    -

    Path is the path under which the dependency is registered under Zookeeper. Like presented before Ribbon operates on URLs thus this path is not compliant with its requirement. -That is why Spring Cloud Zookeeper maps the alias to the proper path.

    -
    -
    -
    -

    Load balancer type

    -
    -

    Represented by loadBalancerType yaml property.

    -
    -
    -

    If you know what kind of load balancing strategy has to be applied when calling this particular dependency then you can provide it in the yaml file and it will be automatically applied. -You can choose one of the following load balancing strategies

    -
    -
    -
      -
    • -

      STICKY - once chosen the instance will always be called

      -
    • -
    • -

      RANDOM - picks an instance randomly

      -
    • -
    • -

      ROUND_ROBIN - iterates over instances over and over again

      -
    • -
    -
    -
    -
    -

    Content-Type template and version

    -
    -

    Represented by contentTypeTemplate and version yaml property.

    -
    -
    -

    If you version your api via the Content-Type header then you don’t want to add this header to each of your requests. Also if you want to call a new version of the API you don’t want to -roam around your code to bump up the API version. That’s why you can provide a contentTypeTemplate with a special $version placeholder. That placeholder will be filled by the value of the -version yaml property. Let’s take a look at an example.

    -
    -
    -

    Having the following contentTypeTemplate:

    +}

    -
    application/vnd.newsletter.$version+json
    +
    ==== Path
    +
    +Represented by `path` yaml property.
    +
    +Path is the path under which the dependency is registered under Zookeeper. Like presented before Ribbon operates on URLs thus this path is not compliant with its requirement.
    +That is why Spring Cloud Zookeeper maps the alias to the proper path.
    +
    +==== Load balancer type
    +
    +Represented by `loadBalancerType` yaml property.
    +
    +If you know what kind of load balancing strategy has to be applied when calling this particular dependency then you can provide it in the yaml file and it will be automatically applied.
    +You can choose one of the following load balancing strategies
    +
    +- STICKY - once chosen the instance will always be called
    +- RANDOM - picks an instance randomly
    +- ROUND_ROBIN - iterates over instances over and over again
    +
    +==== Content-Type template and version
    +
    +Represented by `contentTypeTemplate` and `version` yaml property.
    +
    +If you version your api via the `Content-Type` header then you don't want to add this header to each of your requests. Also if you want to call a new version of the API you don't want to
    +roam around your code to bump up the API version. That's why you can provide a `contentTypeTemplate` with a special `$version` placeholder. That placeholder will be filled by the value of the
    +`version` yaml property. Let's take a look at an example.
    +
    +Having the following `contentTypeTemplate`:
    -

    and the following version:

    +

    application/vnd.newsletter.$version+json

    -
    v1
    +
    and the following `version`:
    -

    Will result in setting up of a Content-Type header for each request:

    +

    v1

    -
    application/vnd.newsletter.v1+json
    +
    Will result in setting up of a `Content-Type` header for each request:
    -
    -
    -

    Default headers

    -
    -

    Represented by headers map in yaml

    -
    -

    Sometimes each call to a dependency requires setting up of some default headers. In order not to do that in code you can set them up in the yaml file. -Having the following headers section:

    +

    application/vnd.newsletter.v1+json

    -
    headers:
    +
    ==== Default headers
    +
    +Represented by `headers` map in yaml
    +
    +Sometimes each call to a dependency requires setting up of some default headers. In order not to do that in code you can set them up in the yaml file.
    +Having the following `headers` section:
    +
    +
    +
    +

    headers: Accept: - text/html - application/xhtml+xml Cache-Control: - - no-cache -

    -
    -
    -

    Results in adding the Accept and Cache-Control headers with appropriate list of values in your HTTP request.

    -
    -
    -
    -

    Obligatory dependencies

    -
    -

    Represented by required property in yaml

    -
    -
    -

    If one of your dependencies is required to be up and running when your application is booting then it’s enough to set up the required: true property in the yaml file.

    -
    -
    -

    If your application can’t localize the required dependency during boot time it will throw an exception and the Spring Context will fail to set up. -In other words your application won’t be able to start if the required dependency is not registered in Zookeeper.

    -
    -
    -

    You can read more about Spring Cloud Zookeeper Presence Checker in the following sections.

    -
    -
    -
    -

    Stubs

    -
    -

    You can provide a colon separated path to the JAR containing stubs of the dependency. Example

    + - no-cache

    -
    stubs: org.springframework:foo:stubs
    +
    Results in adding the `Accept` and `Cache-Control` headers with appropriate list of values in your HTTP request.
    +
    +==== Obligatory dependencies
    +
    +Represented by `required` property in yaml
    +
    +If one of your dependencies is required to be up and running when your application is booting then it's enough to set up the `required: true` property in the yaml file.
    +
    +If your application can't localize the required dependency during boot time it will throw an exception and the Spring Context will fail to set up.
    +In other words your application won't be able to start if the required dependency is not registered in Zookeeper.
    +
    +You can read more about Spring Cloud Zookeeper Presence Checker in the following sections.
    +
    +==== Stubs
    +
    +You can provide a colon separated path to the JAR containing stubs of the dependency. Example
    +
    +```
    +stubs: org.springframework:foo:stubs
    +```
    +
    +means that for a particular dependencies can be found under:
    +
    +* groupId: `org.springframework`
    +* artifactId: `foo`
    +* classifier: `stubs` - this is the default value
    +
    +This is actually equal to
    +
    +```
    +stubs: org.springframework:foo
    +```
    +
    +since `stubs` is the default classifier.
    +
    +=== Configuring Spring Cloud Zookeeper Dependencies
    +
    +There is a bunch of properties that you can set to enable / disable parts of Zookeeper Dependencies functionalities.
    +
    +- `spring.cloud.zookeeper.dependencies` - if you don't set this property you won't benefit from Zookeeper Dependencies
    +- `spring.cloud.zookeeper.dependency.ribbon.enabled` (enabled by default) - Ribbon requires explicit global configuration or a particular one for a dependency. By turning on this property
    + runtime load balancing strategy resolution is possible and you can profit from the `loadBalancerType` section of the Zookeeper Dependencies. The configuration that needs this property
    + has an implementation of `LoadBalancerClient` that delegates to the `ILoadBalancer` presented in the next bullet
    +- `spring.cloud.zookeeper.dependency.ribbon.loadbalancer` (enabled by default) - thanks to this property the custom `ILoadBalancer` knows that the part of the URI passed to Ribbon might
    +actually be the alias that has to be resolved to a proper path in Zookeeper. Without this property you won't be able to register applications under nested paths.
    +- `spring.cloud.zookeeper.dependency.headers.enabled` (enabled by default) - this property registers such a `RibbonClient` that automatically will append appropriate headers and content
    +types with version as presented in the Dependency configuration. Without this setting of those two parameters will not be operational.
    +- `spring.cloud.zookeeper.dependency.resttemplate.enabled` (enabled by default) - when enabled will modify the request headers of `@LoadBalanced` annotated `RestTemplate` so that it passes
    +headers and content type with version set in Dependency configuration. Wihtout this setting of those two parameters will not be operational.
    +
    +
    +[[spring-cloud-zookeeper-dependency-watcher]]
    +
    +== Spring Cloud Zookeeper Dependency Watcher
    +
    +The Dependency Watcher mechanism allows you to register listeners to your dependencies. The functionality is in fact an implementation of the `Observator` pattern. When a dependency changes
    +its state (UP or DOWN) then some custom logic can be applied.
    +
    +=== How to activate
    +
    +Spring Cloud Zookeeper Dependencies functionality needs to be enabled to profit from Dependency Watcher mechanism.
    +
    +=== Registering a listener
    +
    +In order to register a listener you have to implement an interface `org.springframework.cloud.zookeeper.discovery.watcher.DependencyWatcherListener` and register it as a bean.
    +The interface gives you one method:
    -
    -

    means that for a particular dependencies can be found under:

    +
    +
    +
    void stateChanged(String dependencyName, DependencyState newState);
    -
    -
      -
    • -

      groupId: org.springframework

      -
    • -
    • -

      artifactId: foo

      -
    • -
    • -

      classifier: stubs - this is the default value

      -
    • -
    -
    -
    -

    This is actually equal to

    -
    stubs: org.springframework:foo
    +
    If you want to register a listener for a particular dependency then the `dependencyName` would be the discriminator for your concrete implementation. `newState` will provide you with information
    + whether your dependency has changed to `CONNECTED` or `DISCONNECTED`.
    +
    +=== Presence Checker
    +
    +Bound with Dependency Watcher is the functionality called Presence Checker. It allows you to provide custom behaviour upon booting of your application to react accordingly to the state
    +of your dependencies.
    +
    +The default implementation of the abstract `org.springframework.cloud.zookeeper.discovery.watcher.presence.DependencyPresenceOnStartupVerifier` class is the
    +`org.springframework.cloud.zookeeper.discovery.watcher.presence.DefaultDependencyPresenceOnStartupVerifier` which works in the following way.
    +
    +- If the dependency is marked us `required` and it's not in Zookeeper then upon booting your application will throw an exception and shutdown
    +- If dependency is not `required` the `org.springframework.cloud.zookeeper.discovery.watcher.presence.LogMissingDependencyChecker` will log that application is missing at `WARN` level
    +
    +The functionality can be overriden since the `DefaultDependencyPresenceOnStartupVerifier` is registered only when there is no bean of `DependencyPresenceOnStartupVerifier`.
    +
    +
    +[[spring-cloud-zookeeper-config]]
    +
    +== Distributed Configuration with Zookeeper
    +
    +Zookeeper provides a http://zookeeper.apache.org/doc/current/zookeeperOver.html#sc_dataModelNameSpace[hierarchical namespace] that allows clients to store arbitrary data, such as configuration data.  Spring Cloud Zookeeper Config is an alternative to the https://github.com/spring-cloud/spring-cloud-config[Config Server and Client].  Configuration is loaded into the Spring Environment during the special "bootstrap" phase.  Configuration is stored in the `/config` namespace by default.  Multiple `PropertySource` instances are created based on the application's name and the active profiles that mimicks the Spring Cloud Config order of resolving properties.  For example, an application with the name "testApp" and with the "dev" profile will have the following property sources created:
    -

    since stubs is the default classifier.

    -
    -
    -
    -
    -

    Configuring Spring Cloud Zookeeper Dependencies

    -
    -

    There is a bunch of properties that you can set to enable / disable parts of Zookeeper Dependencies functionalities.

    -
    -
    -
      -
    • -

      spring.cloud.zookeeper.dependencies - if you don’t set this property you won’t benefit from Zookeeper Dependencies

      -
    • -
    • -

      spring.cloud.zookeeper.dependencies.ribbon.enabled (enabled by default) - Ribbon requires explicit global configuration or a particular one for a dependency. By turning on this property -runtime load balancing strategy resolution is possible and you can profit from the loadBalancerType section of the Zookeeper Dependencies. The configuration that needs this property -has an implementation of LoadBalancerClient that delegates to the ILoadBalancer presented in the next bullet

      -
    • -
    • -

      spring.cloud.zookeeper.dependencies.ribbon.loadbalancer (enabled by default) - thanks to this property the custom ILoadBalancer knows that the part of the URI passed to Ribbon might -actually be the alias that has to be resolved to a proper path in Zookeeper. Without this property you won’t be able to register applications under nested paths.

      -
    • -
    • -

      spring.cloud.zookeeper.dependencies.headers.enabled (enabled by default) - this property registers such a RibbonClient that automatically will append appropriate headers and content -types with version as presented in the Dependency configuration. Without this setting of those two parameters will not be operational.

      -
    • -
    • -

      spring.cloud.zookeeper.dependencies.resttemplate.enabled (enabled by default) - when enabled will modify the request headers of @LoadBalanced annotated RestTemplate so that it passes -headers and content type with version set in Dependency configuration. Wihtout this setting of those two parameters will not be operational.

      -
    • -
    -
    -
    -
    -
    -
    -

    Spring Cloud Zookeeper Dependency Watcher

    -
    -
    -

    The Dependency Watcher mechanism allows you to register listeners to your dependencies. The functionality is in fact an implementation of the Observator pattern. When a dependency changes -its state (UP or DOWN) then some custom logic can be applied.

    -
    -
    -

    How to activate

    -
    -

    Spring Cloud Zookeeper Dependencies functionality needs to be enabled to profit from Dependency Watcher mechanism.

    -
    -
    -
    -

    Registering a listener

    -
    -

    In order to register a listener you have to implement an interface org.springframework.cloud.zookeeper.discovery.watcher.DependencyWatcherListener and register it as a bean. -The interface gives you one method:

    -
    -
    -
    -
        void stateChanged(String dependencyName, DependencyState newState);
    -
    -
    -
    -

    If you want to register a listener for a particular dependency then the dependencyName would be the discriminator for your concrete implementation. newState will provide you with information - whether your dependency has changed to CONNECTED or DISCONNECTED.

    -
    -
    -
    -

    Presence Checker

    -
    -

    Bound with Dependency Watcher is the functionality called Presence Checker. It allows you to provide custom behaviour upon booting of your application to react accordingly to the state -of your dependencies.

    -
    -
    -

    The default implementation of the abstract org.springframework.cloud.zookeeper.discovery.watcher.presence.DependencyPresenceOnStartupVerifier class is the -org.springframework.cloud.zookeeper.discovery.watcher.presence.DefaultDependencyPresenceOnStartupVerifier which works in the following way.

    -
    -
    -
      -
    • -

      If the dependency is marked us required and it’s not in Zookeeper then upon booting your application will throw an exception and shutdown

      -
    • -
    • -

      If dependency is not required the org.springframework.cloud.zookeeper.discovery.watcher.presence.LogMissingDependencyChecker will log that application is missing at WARN level

      -
    • -
    -
    -
    -

    The functionality can be overriden since the DefaultDependencyPresenceOnStartupVerifier is registered only when there is no bean of DependencyPresenceOnStartupVerifier.

    -
    -
    -
    -
    -
    -

    Distributed Configuration with Zookeeper

    -
    -
    -

    Zookeeper provides a hierarchical namespace that allows clients to store arbitrary data, such as configuration data. Spring Cloud Zookeeper Config is an alternative to the Config Server and Client. Configuration is loaded into the Spring Environment during the special "bootstrap" phase. Configuration is stored in the /config namespace by default. Multiple PropertySource instances are created based on the application’s name and the active profiles that mimicks the Spring Cloud Config order of resolving properties. For example, an application with the name "testApp" and with the "dev" profile will have the following property sources created:

    -
    -
    -
    -
    config/testApp,dev
    +

    config/testApp,dev config/testApp config/application,dev -config/application

    -
    -
    -
    -

    The most specific property source is at the top, with the least specific at the bottom. Properties is the config/application namespace are applicable to all applications using zookeeper for configuration. Properties in the config/testApp namespace are only available to the instances of the service named "testApp".

    -
    -
    -

    Configuration is currently read on startup of the application. Sending a HTTP POST to /refresh will cause the configuration to be reloaded. Watching the configuration namespace (which Zookeeper supports) is not currently implemented, but will be a future addition to this project.

    -
    -
    -

    How to activate

    -
    -

    Including a dependency on org.springframework.cloud:spring-cloud-starter-zookeeper-config will enable auto-configuration that will setup Spring Cloud Zookeeper Config.

    -
    -
    -
    -

    Customizing

    -
    -

    Zookeeper Config may be customized using the following properties:

    +config/application

    -
    bootstrap.yml
    -
    spring:
    +
    The most specific property source is at the top, with the least specific at the bottom.  Properties is the `config/application` namespace are applicable to all applications using zookeeper for configuration.  Properties in the `config/testApp` namespace are only available to the instances of the service named "testApp".
    +
    +Configuration is currently read on startup of the application.  Sending a HTTP POST to `/refresh` will cause the configuration to be reloaded.  Watching the configuration namespace (which Zookeeper supports) is not currently implemented, but will be a future addition to this project.
    +
    +=== How to activate
    +
    +Including a dependency on `org.springframework.cloud:spring-cloud-starter-zookeeper-config` will enable auto-configuration that will setup Spring Cloud Zookeeper Config.
    +
    +=== Customizing
    +
    +Zookeeper Config may be customized using the following properties:
    +
    +.bootstrap.yml
    +
    +
    +
    +

    spring: cloud: zookeeper: config: enabled: true root: configuration defaultContext: apps - profileSeparator: '::' + profileSeparator: '::'

    -
    -
    -
      -
    • -

      enabled setting this value to "false" disables Zookeeper Config

      -
    • -
    • -

      root sets the base namespace for configuration values

      -
    • -
    • -

      defaultContext sets the name used by all applications

      -
    • -
    • -

      profileSeparator sets the value of the separator used to separate the profile name in property sources with profiles

      -
    • -
    -
    -
    -
    -
    -

    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 +
    * `enabled` setting this value to "false" disables Zookeeper Config
    +* `root` sets the base namespace for configuration values
    +* `defaultContext` sets the name used by all applications
    +* `profileSeparator` sets the value of the separator used to separate the profile name in property sources with profiles
    +
    +
    += Spring Boot Cloud CLI
    +:github: https://github.com/spring-cloud/spring-cloud-cli
    +:githubmaster: {github}/tree/master
    +:docslink: {githubmaster}/docs/src/main/asciidoc
    +
    +Spring Boot CLI provides http://projects.spring.io/spring-boot[Spring Boot] command line features for
    +https://github.com/spring-cloud[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.
    -
    -
    -
    -

    Installation

    -
    -
    -

    To install, make + + + +== Installation + +To install, make sure you have -Spring Boot CLI -(1.3.0 or better):

    -
    -
    -
    -
    $ spring version
    -Spring CLI v1.3.2.RELEASE
    -
    -
    -
    -

    E.g. for SDKMan users

    -
    -
    -
    -
    $ sdk install springboot 1.3.2.RELEASE
    -$ sdk use springboot 1.3.2.RELEASE
    -
    -
    -
    -

    and install the Spring Cloud plugin:

    -
    -
    -
    -
    $ mvn install
    -$ spring install org.springframework.cloud:spring-cloud-cli:1.1.0.RC1
    -
    -
    -
    - - - - - -
    -
    Important
    -
    -Prerequisites: to use the encryption and decryption features -you need the full-strength JCE installed in your JVM (it’s not there by default). +https://github.com/spring-projects/spring-boot[Spring Boot CLI] +(1.3.0 or better): + + $ spring version + Spring CLI v1.3.2.RELEASE + +E.g. for SDKMan users + +``` +$ sdk install springboot 1.3.2.RELEASE +$ sdk use springboot 1.3.2.RELEASE +``` + +and install the Spring Cloud plugin: + +``` +$ mvn install +$ spring install org.springframework.cloud:spring-cloud-cli:1.1.0.RC1 +``` + +IMPORTANT: **Prerequisites:** to use the encryption and decryption features +you need the full-strength JCE installed in your JVM (it's not there by default). You can download the "Java Cryptography Extension (JCE) Unlimited Strength Jurisdiction Policy Files" from Oracle, and follow instructions for installation (essentially replace the 2 policy files 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 {}
    + +== 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 +[source,groovy,indent=0]
    -

    which you can run from the command line like this

    +

    @EnableEurekaServer +class Eureka {}

    -
    $ spring run app.groovy
    +
    which you can run from the command line like this
    -

    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 +

    $ 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:

    +listen on AMQP for management events from the Spring CLoud Bus: + +.app.groovy +[source,groovy,indent=0]
    -
    -
    app.groovy
    -
    -
    @Grab('spring-cloud-starter-bus-amqp')
    +
    +
    +

    @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
    +
    == 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.

    +mysecret

    -
    $ spring encrypt mysecret --key @${HOME}/.ssh/id_rsa.pub
    -AQAjPgt3eFZQXwt8tsHAVv/QHiY5sI2dRcR+...
    +
    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
    +:github: https://github.com/spring-cloud/spring-cloud-security
    +:githubmaster: {github}/tree/master
    +:docslink: {githubmaster}/src/main/asciidoc
    +
     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
    @@ -9032,2310 +8776,1348 @@ 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.
    +
    +
    +== Quickstart
    +
    +=== OAuth2 Single Sign On
    +
    +Here's a Spring Cloud "Hello World" app with HTTP Basic
    +authentication and a single user account:
    +
    +.app.groovy
    +[source,java]
    -
    -

    Quickstart

    -
    -
    -

    OAuth2 Single Sign On

    -

    Here’s a Spring Cloud "Hello World" app with HTTP Basic -authentication and a single user account:

    -
    -
    -
    app.groovy
    -
    -
    @Grab('spring-boot-starter-security')
    +

    @Grab('spring-boot-starter-security') @Controller -class Application { - - @RequestMapping('/') - String home() { - 'Hello World' - } - -}

    +class Application {

    +
    +
    +
    +
    @RequestMapping('/')
    +String home() {
    +  'Hello World'
    +}
    -

    You can run it with spring run app.groovy and watch the logs for the password (username is "user"). So far this is just the default for a Spring Boot app.

    -
    -
    -

    Here’s a Spring Cloud app with OAuth2 SSO:

    +

    }

    -
    app.groovy
    -
    @Controller
    +
    You can run it with `spring run app.groovy` and watch the logs for the password (username is "user"). So far this is just the default for a Spring Boot app.
    +
    +Here's a Spring Cloud app with OAuth2 SSO:
    +
    +.app.groovy
    +[source,java]
    +
    +
    +
    +

    @Controller @EnableOAuth2Sso -class Application { - - @RequestMapping('/') - String home() { - 'Hello World' - } - -} +class Application {

    +
    +
    +
    +
    @RequestMapping('/')
    +String home() {
    +  'Hello World'
    +}
    -

    Spot the difference? This app will actually behave exactly the same as -the previous one, because it doesn’t know it’s OAuth2 credentals -yet.

    +

    }

    -
    -

    You can register an app in github quite easily, so try that if you +

    +
    +
    Spot the difference? This app will actually behave exactly the same as
    +the previous one, because it doesn't know it's OAuth2 credentals
    +yet.
    +
    +You can register an app in github quite easily, so try that if you
     want a production app on your own domain. If you are happy to test on
     localhost:8080, then set up these properties in your application
    -configuration:

    +configuration: + +.application.yml +[source,yaml]
    -
    -
    application.yml
    -
    -
    spring:
    +
    +
    +

    spring: oauth2: client: clientId: bd1c0a783ccdd1c9b9e4 clientSecret: 1a9030fbca47a5b2c28e92f19050bb77824b5ad1 - accessTokenUri: https://github.com/login/oauth/access_token - userAuthorizationUri: https://github.com/login/oauth/authorize + 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 + userInfoUri: https://api.github.com/user + preferTokenInfo: false

    -
    -
    -

    run the app above and it will redirect to github for authorization. If -you are already signed into github you won’t even notice that it has +

    +
    +
    run the app above and it will redirect to github for authorization. If
    +you are already signed into github you won't even notice that it has
     authenticated.  These credentials will only work if your app is
    -running on port 8080.

    -
    -
    -

    To limit the scope that the client asks for when it obtains an access token -you can set spring.oauth2.client.scope (comma separated or an array in YAML). By +running on port 8080. + +To limit the scope that the client asks for when it obtains an access token +you can set `spring.oauth2.client.scope` (comma separated or an array in YAML). By default the scope is empty and it is up to to Authorization Server to decide what the defaults should be, usually depending on the settings in -the client registration that it holds.

    -
    -
    - - - - - -
    -
    Note
    -
    -The examples above are all Groovy scripts. If you want to write the +the client registration that it holds. + +NOTE: The examples above are all Groovy scripts. If you want to write the same code in Java (or Groovy) you need to add Spring Security OAuth2 to the classpath (e.g. see the -sample here). -
    +https://github.com/spring-cloud-samples/sso[sample here]). + +=== OAuth2 Protected Resource + +You want to protect an API resource with an OAuth2 token? Here's a +simple example (paired with the client above): + +.app.groovy +[source,java]
    -
    -

    OAuth2 Protected Resource

    -

    You want to protect an API resource with an OAuth2 token? Here’s a -simple example (paired with the client above):

    -
    -
    -
    app.groovy
    -
    -
    @Grab('spring-cloud-starter-security')
    +

    @Grab('spring-cloud-starter-security') @RestController @EnableResourceServer -class Application { - - @RequestMapping('/') - def home() { - [message: 'Hello World'] - } - -}

    +class Application {

    +
    +
    +
    +
    @RequestMapping('/')
    +def home() {
    +  [message: 'Hello World']
    +}
    -

    and

    +

    }

    -
    application.yml
    -
    spring:
    +
    and
    +
    +.application.yml
    +[source,yaml]
    +
    +
    +
    +

    spring: oauth2: resource: - userInfoUri: https://api.github.com/user - preferTokenInfo: false + userInfoUri: https://api.github.com/user + preferTokenInfo: false

    -
    -
    -
    -
    -
    -

    More Detail

    -
    -
    -

    Single Sign On

    -
    - - - - - -
    -
    Note
    -
    -All of the OAuth2 SSO and resource server features moved to Spring Boot +
    +
    +
    == More Detail
    +
    +=== Single Sign On
    +
    +NOTE: All of the OAuth2 SSO and resource server features moved to Spring Boot
     in version 1.3. You can find documentation in the
    -Spring Boot user guide.
    -
    -
    -
    -
    -

    Token Relay

    -
    -

    A Token Relay is where an OAuth2 consumer acts as a Client and +http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/[Spring Boot user guide]. + +=== Token Relay + +A Token Relay is where an OAuth2 consumer acts as a Client and forwards the incoming token to outgoing resource requests. The consumer can be a pure Client (like an SSO application) or a Resource -Server.

    -
    -
    -

    Client Token Relay

    -
    -

    If your app has a -Spring -Cloud Zuul embedded reverse proxy (using @EnableZuulProxy) then you +Server. + +==== Client Token Relay + +If your app has a +http://cloud.spring.io/spring-cloud.html#netflix-zuul-reverse-proxy[Spring +Cloud Zuul] embedded reverse proxy (using `@EnableZuulProxy`) then you can ask it to forward OAuth2 access tokens downstream to the services -it is proxying. Thus the SSO app above can be enhanced simply like this:

    +it is proxying. Thus the SSO app above can be enhanced simply like this: + +.app.groovy +[source,java]
    -
    -
    app.groovy
    -
    -
    @Controller
    +
    +
    +

    @Controller @EnableOAuth2Sso @EnableZuulProxy -class Application { - -} -

    +class Application {

    -

    and it will (in addition to loggin the user in and grabbing a token) -pass the authentication token downstream to the /proxy/* -services. If those services are implemented with -@EnableOAuth2Resource then they will get a valid token in the -correct header.

    -
    -
    -

    How does it work? The @EnableOAuth2Sso annotation pulls in -spring-cloud-starter-security (which you could do manually in a -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 -filter -just extracts an access token from the currently authenticated user, -and puts it in a request header for the downstream requests.

    -
    -
    -
    -

    Resource Server Token Relay

    -
    -

    If your app has @EnableOAuth2Resource and also is a Client (i.e. it -has a spring.oauth2.client.clientId, even if it doesn’t use it), -then the OAuth2RestOperations that is provided for @Autowired -users by Spring Cloud (it is declared as @Primary) will also forward -tokens. If you don’t want to forward tokens (and that is a valid -choice, since you might want to act as yourself, rather than the -client that sent you the token), then you only need to create your own -OAuth2RestOperations instead of autowiring the default one. Here’s -a basic example showing the use of the autowired rest template ("foo.com" -is a Resource Server accepting the same tokens as the surrounding app):

    +

    }

    -
    MyController.java
    -
    @Autowired
    -private OAuth2RestOperations restTemplate;
    +
    and it will (in addition to loggin the user in and grabbing a token)
    +pass the authentication token downstream to the `/proxy/*`
    +services. If those services are implemented with
    +`@EnableOAuth2Resource` then they will get a valid token in the
    +correct header.
     
    -@RequestMapping("/relay")
    +How does it work? The `@EnableOAuth2Sso` annotation pulls in
    +`spring-cloud-starter-security` (which you could do manually in a
    +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
    +{githubmaster}/src/main/java/org/springframework/cloud/security/oauth2/proxy/OAuth2TokenRelayFilter.java[filter]
    +just extracts an access token from the currently authenticated user,
    +and puts it in a request header for the downstream requests.
    +
    +==== Resource Server Token Relay
    +
    +If your app has `@EnableOAuth2Resource` and also is a Client (i.e. it
    +has a `spring.oauth2.client.clientId`, even if it doesn't use it),
    +then the `OAuth2RestOperations` that is provided for `@Autowired`
    +users by Spring Cloud (it is declared as `@Primary`) will also forward
    +tokens. If you don't want to forward tokens (and that is a valid
    +choice, since you might want to act as yourself, rather than the
    +client that sent you the token), then you only need to create your own
    +`OAuth2RestOperations` instead of autowiring the default one. Here's
    +a basic example showing the use of the autowired rest template ("foo.com"
    +is a Resource Server accepting the same tokens as the surrounding app):
    +
    +.MyController.java
    +[source,java]
    +
    +
    +
    +

    @Autowired +private OAuth2RestOperations restTemplate;

    +
    +
    +

    @RequestMapping("/relay") public String relay() { ResponseEntity<String> response = restTemplate.getForEntity("https://foo.com/bar", String.class); return "Success! (" + response.getBody() + ")"; -} -

    -
    -
    -
    -
    -
    -
    -

    Configuring Authentication Downstream of a Zuul Proxy

    -
    -
    -

    You can control the authorization behaviour downstream of an -@EnableZuulProxy through the proxy.auth.* settings. Example:

    +}

    -
    application.yml
    -
    proxy:
    +
    == Configuring Authentication Downstream of a Zuul Proxy
    +
    +You can control the authorization behaviour downstream of an
    +`@EnableZuulProxy` through the `proxy.auth.*` settings. Example:
    +
    +.application.yml
    +[source,yaml]
    +
    +
    +
    +

    proxy: auth: routes: customers: oauth2 stores: passthru - recommendations: none + recommendations: none

    -
    -
    -

    In this example the "customers" service gets an OAuth2 token relay, +

    +
    +
    In this example the "customers" service gets an OAuth2 token relay,
     the "stores" service gets a passthrough (the authorization header is
     just passed downstream), and the "recommendations" service has its
     authorization header removed. The default behaviour is to do a token
    -relay if there is a token available, and passthru otherwise.

    -
    -
    -

    See - -ProxyAuthenticationProperties for full details.

    -
    -
    -
    -

    Spring Cloud for Cloud Foundry

    -
    -
    -
    -

    Spring Cloud for Cloudfoundry makes it easy to run -Spring Cloud apps in -Cloud Foundry (the Platform as a +relay if there is a token available, and passthru otherwise. + +See +{githubmaster}/src/main/java/org/springframework/cloud/security/oauth2/proxy/ProxyAuthenticationProperties[ +ProxyAuthenticationProperties] for full details. + += Spring Cloud for Cloud Foundry + +Spring Cloud for Cloudfoundry makes it easy to run +https://github.com/spring-cloud[Spring Cloud] apps in +https://github.com/cloudfoundry[Cloud Foundry] (the Platform as a Service). Cloud Foundry has the notion of a "service", which is middlware that you "bind" to an app, essentially providing it with an environment variable containing credentials (e.g. the location and -username to use for the service).

    -
    -
    -

    The spring-cloud-cloudfoundry-web project provides basic support for +username to use for the service). + +The `spring-cloud-cloudfoundry-web` project provides basic support for some enhanced features of webapps in Cloud Foundry: binding automatically to single-sign-on services and optionally enabling -sticky routing for discovery.

    +sticky routing for discovery. + +The `spring-cloud-cloudfoundry-discovery` project provides an +implementation of Spring Cloud Commons `DiscoveryClient` so you can +`@EnableDiscoveryClient` and provide your credentials as +`spring.cloud.cloudfoundry.discovery.[email,password]` and then you +can use the `DiscoveryClient` directly or via a `LoadBalancerClient` +(also `*.url` if you are not connecting to [Pivotal Web +Services](https://run.pivotal.io)). + +The first time you use it the discovery client might be slow owing to +the fact that it has to get an access token from Cloud Foundry. + +== Quickstart + +Here's a Spring Cloud app with Cloud Foundry discovery: + +.app.groovy +[source,java] +
    -

    The spring-cloud-cloudfoundry-discovery project provides an -implementation of Spring Cloud Commons DiscoveryClient so you can -@EnableDiscoveryClient and provide your credentials as -spring.cloud.cloudfoundry.discovery.[email,password] and then you -can use the DiscoveryClient directly or via a LoadBalancerClient -(also *.url if you are not connecting to [Pivotal Web -Services](https://run.pivotal.io)).

    -
    -
    -

    The first time you use it the discovery client might be slow owing to -the fact that it has to get an access token from Cloud Foundry.

    -
    -
    -
    -
    -

    Quickstart

    -
    -
    -

    Here’s a Spring Cloud app with Cloud Foundry discovery:

    -
    -
    -
    app.groovy
    -
    -
    @Grab('org.springframework.cloud:spring-cloud-cloudfoundry')
    +

    @Grab('org.springframework.cloud:spring-cloud-cloudfoundry') @RestController @EnableDiscoveryClient -class Application { - - @Autowired - DiscoveryClient client - - @RequestMapping('/') - String home() { - 'Hello from ' + client.getLocalServiceInstance() - } - -}

    +class Application {

    +
    +
    +
    +
    @Autowired
    +DiscoveryClient client
    +
    +
    +
    +
    +
    @RequestMapping('/')
    +String home() {
    +  'Hello from ' + client.getLocalServiceInstance()
    +}
    -

    If you run it without any service bindings:

    +

    }

    -
    $ spring jar app.jar app.groovy
    -$ cf push -p app.jar
    +
    If you run it without any service bindings:
    -

    It will show its app name in the home page.

    +

    $ spring jar app.jar app.groovy +$ cf push -p app.jar

    -
    -

    Single Sign On

    -
    - - - - - -
    -
    Note
    -
    -All of the OAuth2 SSO and resource server features moved to Spring Boot +
    +
    +
    It will show its app name in the home page.
    +
    +
    +=== Single Sign On
    +
    +NOTE: All of the OAuth2 SSO and resource server features moved to Spring Boot
     in version 1.3. You can find documentation in the
    -Spring Boot user guide.
    -
    -
    -
    -

    This project provides automatic binding from CloudFoundry service +http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/[Spring Boot user guide]. + +This project provides automatic binding from CloudFoundry service credentials to the Spring Boot features. If you have a CloudFoundry service called "sso", for instance, with credentials containing "client_id", "client_secret" and "auth_domain", it will bind automatically to the Spring OAuth2 client that you enable with -@EnableOAuth2Sso (from Spring Boot). The name of the service can be -parameterized using spring.oauth2.sso.serviceId.

    -
    -
    -
    -
    -

    Spring Cloud Cluster

    -
    -
    +`@EnableOAuth2Sso` (from Spring Boot). The name of the service can be +parameterized using `spring.oauth2.sso.serviceId`. + + += Spring Cloud Cluster + Spring Cloud Cluster offers a set of primitives for building "cluster" features into a distributed system. Example are leadership election, consistent storage of cluster state, global locks and one-time tokens. -
    -
    -
    -

    Leader Election

    -
    -
    -

    Leader election allows application to work together with other -applications to coordinate a cluster leadership via a third party system. -Currently we provide integrations with zookeeper, hazelcast and etcd.

    -
    -
    -

    From user perspective election is working via interfaces -org.springframework.cloud.cluster.leader.Candidate and -org.springframework.cloud.cluster.leader.Context. Candidate -contains access to leadership’s role and id and also have methods -onGranted and onRevoked. These callback methods are useful if -default Candidate implementation is changed.

    -
    -
    -

    Leader election is auto-configured if spring-cloud-cluster-autoconfigure -and either spring-cloud-cluster-hazelcast, spring-cloud-cluster-zookeeper -or spring-cloud-cluster-etcd jars are found from a classpath. In -case where both jars are found leader election is created using both -systems. See sections Zookeeper, -Hazelcast and -Etcd for more -information about a created beans.

    -
    -
    -

    Default Candidate created from auto-configuration is -org.springframework.cloud.cluster.leader.DefaultCandidate which -currently only logs granted and revoked events.

    -
    -
    -

    If there’s a need for disable all leader related auto-configuration, -a spring.cloud.cluster.leader.enabled can be set to false which -then allows to do manual configuration even if the jars an on a -classpath. Properties spring.cloud.cluster.leader.id and -spring.cloud.cluster.leader.role can be used to set default -identifier and role.

    -
    -
    -

    If you are interested to simple get notification of granted and -revoked events one option is to attach event listener into spring -application context. Events OnGrantedEvent and OnRevokedEvent are -sent as spring event objects.

    -
    -
    -

    Simply create your own event listener class:

    -
    -
    -
    -
    class MyEventListener implements ApplicationListener<AbstractLeaderEvent> {
     
    -  @Override
    +== Leader Election
    +
    +Leader election allows application to work together with other
    +applications to coordinate a cluster leadership via a third party system.
    +Currently we provide integrations with `zookeeper`, `hazelcast` and `etcd`.
    +
    +From user perspective election is working via interfaces
    +`org.springframework.cloud.cluster.leader.Candidate` and
    +`org.springframework.cloud.cluster.leader.Context`. `Candidate`
    +contains access to leadership's `role` and `id` and also have methods
    +`onGranted` and `onRevoked`. These callback methods are useful if
    +default `Candidate` implementation is changed.
    +
    +Leader election is auto-configured if `spring-cloud-cluster-autoconfigure`
    +and either `spring-cloud-cluster-hazelcast`, `spring-cloud-cluster-zookeeper`
    +or `spring-cloud-cluster-etcd` jars are found from a classpath. In
    +case where both jars are found leader election is created using both
    +systems. See sections <<spring-cloud-cluster-leaderelection-zookeeper>>,
    +<<spring-cloud-cluster-leaderelection-hazelcast>> and
    +<<spring-cloud-cluster-leaderelection-etcd>> for more
    +information about a created beans.
    +
    +Default `Candidate` created from auto-configuration is
    +`org.springframework.cloud.cluster.leader.DefaultCandidate` which
    +currently only logs granted and revoked events.
    +
    +If there's a need for disable all leader related auto-configuration,
    +a `spring.cloud.cluster.leader.enabled` can be set to false which
    +then allows to do manual configuration even if the jars an on a
    +classpath. Properties `spring.cloud.cluster.leader.id` and
    +`spring.cloud.cluster.leader.role` can be used to set default
    +identifier and role.
    +
    +If you are interested to simple get notification of granted and
    +revoked events one option is to attach event listener into spring
    +application context. Events `OnGrantedEvent` and `OnRevokedEvent` are
    +sent as spring event objects.
    +
    +Simply create your own event listener class:
    +[source,java]
    +
    +
    +
    +

    class MyEventListener implements ApplicationListener<AbstractLeaderEvent> {

    +
    +
    +
    +
      @Override
       public void onApplicationEvent(AbstractLeaderEvent event) {
         // do something with OnGrantedEvent or OnRevokedEvent
       }
    -}
    +}
    -
    -

    and then create it as a bean.

    -
    -
    @Configuration
    +
    and then create it as a bean.
    +
    +[source,java]
    +
    +
    +
    +

    @Configuration static class Config { @Bean public MyEventListener myEventListener() { return new MyEventListener(); } -} -

    -
    -
    -

    For simply log events you can also use a utility class -LoggingListener which allows easy configuration.

    +}

    -
    import org.springframework.cloud.cluster.leader.event.LoggingListener;
    +
    For simply log events you can also use a utility class
    +`LoggingListener` which allows easy configuration.
     
    -@Configuration
    +[source,java]
    +
    +
    +
    +

    import org.springframework.cloud.cluster.leader.event.LoggingListener;

    +
    +
    +

    @Configuration static class Config { @Bean public LoggingListener loggingListener() { return new LoggingListener("info"); } -} +}

    -
    -
    -

    Zookeeper

    -
    -

    Candidate implementation for zookeeper is created with a bean name -zookeeperLeaderCandidate which can be used to override the one -created during auto-configuration.

    -
    -
    -

    Zookeeper based election can be explicitly disabled using property -spring.cloud.cluster.zookeeper.leader.enabled.

    -
    -
    -

    Other properties spring.cloud.cluster.zookeeper.namespace and -spring.cloud.cluster.zookeeper.connect can be used to set the -zookeeper base namespace path and connect string.

    -
    -
    -
    -

    Hazelcast

    -
    -

    Candidate implementation for hazelcast is created with a bean name -hazelcastLeaderCandidate which can be used to override the one -created during auto-configuration.

    -
    -
    -

    Hazelcast based election can be explicitly disabled using property -spring.cloud.cluster.hazelcast.leader.enabled. If you want to provide xml -based configuration for Hazelcast instance use property -spring.cloud.cluster.hazelcast.config-location to tell location of a -Hazelcast xml configuration file. config-location is a normal spring -Resource.

    -
    -
    -
    -

    Etcd

    -
    -

    Candidate implementation for etcd is created with a bean name -etcdLeaderCandidate which can be used to override the one -created during auto-configuration.

    -
    -
    -

    Etcd based election can be explicitly disabled using property -spring.cloud.cluster.etcd.leader.enabled.

    -
    -
    -

    Multiple etcd cluster uris can be specified using property -spring.cloud.cluster.etcd.connect

    -
    -
    -
    -
    -

    Appendix: Compendium of Configuration Properties

    -
    +
    - ----- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameDefaultDescription

    encrypt.fail-on-error

    true

    Flag to say that a process should fail if there is an encryption or decryption - error.

    encrypt.key

    A symmetric key. As a stronger alternative consider using a keystore.

    encrypt.key-store.alias

    Alias for a key in the store.

    encrypt.key-store.location

    Location of the key store file, e.g. classpath:/keystore.jks.

    encrypt.key-store.password

    Password that locks the keystore.

    encrypt.key-store.secret

    Secret protecting the key (defaults to the same as the password).

    encrypt.rsa.algorithm

    The RSA algorithm to use (DEFAULT or OEAP). Once it is set do not change it (or - existing ciphers will not a decryptable).

    encrypt.rsa.salt

    deadbeef

    Salt for the random secret used to encrypt cipher text. Once it is set do not - change it (or existing ciphers will not a decryptable).

    encrypt.rsa.strong

    false

    Flag to indicate that "strong" AES encryption should be used internally. If +

    [[spring-cloud-cluster-leaderelection-zookeeper]]
    +=== Zookeeper
    +`Candidate` implementation for zookeeper is created with a bean name
    +`zookeeperLeaderCandidate` which can be used to override the one
    +created during auto-configuration.
    +
    +Zookeeper based election can be explicitly disabled using property
    +`spring.cloud.cluster.zookeeper.leader.enabled`.
    +
    +Other properties `spring.cloud.cluster.zookeeper.namespace` and
    +`spring.cloud.cluster.zookeeper.connect` can be used to set the
    +zookeeper base namespace path and connect string.
    +
    +[[spring-cloud-cluster-leaderelection-hazelcast]]
    +=== Hazelcast
    +`Candidate` implementation for hazelcast is created with a bean name
    +`hazelcastLeaderCandidate` which can be used to override the one
    +created during auto-configuration.
    +
    +Hazelcast based election can be explicitly disabled using property
    +`spring.cloud.cluster.hazelcast.leader.enabled`. If you want to provide xml
    +based configuration for Hazelcast instance use property
    +`spring.cloud.cluster.hazelcast.config-location` to tell location of a
    +Hazelcast xml configuration file. `config-location` is a normal spring
    +`Resource`.
    +
    +[[spring-cloud-cluster-leaderelection-etcd]]
    +=== Etcd
    +`Candidate` implementation for etcd is created with a bean name
    +`etcdLeaderCandidate` which can be used to override the one
    +created during auto-configuration.
    +
    +Etcd based election can be explicitly disabled using property
    +`spring.cloud.cluster.etcd.leader.enabled`.
    +
    +Multiple etcd cluster uris can be specified using property
    +`spring.cloud.cluster.etcd.connect`
    +
    += Appendix: Compendium of Configuration Properties
    +
    +|===
    +|Name | Default | Description
    +
    +|encrypt.fail-on-error | true | Flag to say that a process should fail if there is an encryption or decryption
    + error.
    +
    +|encrypt.key |  | A symmetric key. As a stronger alternative consider using a keystore.
    +
    +|encrypt.key-store.alias |  | Alias for a key in the store.
    +
    +|encrypt.key-store.location |  | Location of the key store file, e.g. classpath:/keystore.jks.
    +
    +|encrypt.key-store.password |  | Password that locks the keystore.
    +
    +|encrypt.key-store.secret |  | Secret protecting the key (defaults to the same as the password).
    +
    +|encrypt.rsa.algorithm |  | The RSA algorithm to use (DEFAULT or OEAP). Once it is set do not change it (or
    + existing ciphers will not a decryptable).
    +
    +|encrypt.rsa.salt | deadbeef | Salt for the random secret used to encrypt cipher text. Once it is set do not
    + change it (or existing ciphers will not a decryptable).
    +
    +|encrypt.rsa.strong | false | Flag to indicate that "strong" AES encryption should be used internally. If
      true then the GCM algorithm is applied to the AES encrypted bytes. Default is
      false (in which case "standard" CBC is used instead). Once it is set do not
    - change it (or existing ciphers will not a decryptable).

    endpoints.bus.enabled

    endpoints.bus.id

    endpoints.bus.sensitive

    endpoints.consul.enabled

    endpoints.consul.id

    endpoints.consul.sensitive

    endpoints.features.enabled

    endpoints.features.id

    endpoints.features.sensitive

    endpoints.pause.enabled

    endpoints.pause.id

    endpoints.pause.sensitive

    endpoints.refresh.enabled

    endpoints.refresh.id

    endpoints.refresh.sensitive

    endpoints.restart.enabled

    endpoints.restart.id

    endpoints.restart.pause-endpoint.enabled

    endpoints.restart.pause-endpoint.id

    endpoints.restart.pause-endpoint.sensitive

    endpoints.restart.resume-endpoint.enabled

    endpoints.restart.resume-endpoint.id

    endpoints.restart.resume-endpoint.sensitive

    endpoints.restart.sensitive

    endpoints.restart.timeout

    0

    endpoints.resume.enabled

    endpoints.resume.id

    endpoints.resume.sensitive

    eureka.client.allow-redirects

    false

    Indicates whether server can redirect a client request to a backup server/cluster. + change it (or existing ciphers will not a decryptable). + +|endpoints.bus.enabled | | + +|endpoints.bus.id | | + +|endpoints.bus.sensitive | | + +|endpoints.consul.enabled | | + +|endpoints.consul.id | | + +|endpoints.consul.sensitive | | + +|endpoints.features.enabled | | + +|endpoints.features.id | | + +|endpoints.features.sensitive | | + +|endpoints.pause.enabled | | + +|endpoints.pause.id | | + +|endpoints.pause.sensitive | | + +|endpoints.refresh.enabled | | + +|endpoints.refresh.id | | + +|endpoints.refresh.sensitive | | + +|endpoints.restart.enabled | | + +|endpoints.restart.id | | + +|endpoints.restart.pause-endpoint.enabled | | + +|endpoints.restart.pause-endpoint.id | | + +|endpoints.restart.pause-endpoint.sensitive | | + +|endpoints.restart.resume-endpoint.enabled | | + +|endpoints.restart.resume-endpoint.id | | + +|endpoints.restart.resume-endpoint.sensitive | | + +|endpoints.restart.sensitive | | + +|endpoints.restart.timeout | 0 | + +|endpoints.resume.enabled | | + +|endpoints.resume.id | | + +|endpoints.resume.sensitive | | + +|eureka.client.allow-redirects | false | Indicates whether server can redirect a client request to a backup server/cluster. If set to false, the server will handle the request directly, If set to true, it - may send HTTP redirect to the client, with a new server location.

    eureka.client.availability-zones

    Gets the list of availability zones (used in AWS data centers) for the region in + may send HTTP redirect to the client, with a new server location. + +|eureka.client.availability-zones | | Gets the list of availability zones (used in AWS data centers) for the region in which this instance resides. -

    The changes are effective at runtime at the next registry fetch cycle as specified - by registryFetchIntervalSeconds.

    eureka.client.backup-registry-impl

    Gets the name of the implementation which implements BackupRegistry to fetch the + + The changes are effective at runtime at the next registry fetch cycle as specified + by registryFetchIntervalSeconds. + +|eureka.client.backup-registry-impl | | Gets the name of the implementation which implements BackupRegistry to fetch the registry information as a fall back option for only the first time when the eureka client starts. -

    This may be needed for applications which needs additional resiliency for registry - information without which it cannot operate.

    eureka.client.cache-refresh-executor-exponential-back-off-bound

    10

    Cache refresh executor exponential back off related property. It is a maximum - multiplier value for retry delay, in case where a sequence of timeouts occurred.

    eureka.client.cache-refresh-executor-thread-pool-size

    2

    The thread pool size for the cacheRefreshExecutor to initialise with

    eureka.client.client-data-accept

    EurekaAccept name for client data accept

    eureka.client.decoder-name

    This is a transient config and once the latest codecs are stable, can be removed - (as there will only be one)

    eureka.client.disable-delta

    false

    Indicates whether the eureka client should disable fetching of delta and should + + This may be needed for applications which needs additional resiliency for registry + information without which it cannot operate. + +|eureka.client.cache-refresh-executor-exponential-back-off-bound | 10 | Cache refresh executor exponential back off related property. It is a maximum + multiplier value for retry delay, in case where a sequence of timeouts occurred. + +|eureka.client.cache-refresh-executor-thread-pool-size | 2 | The thread pool size for the cacheRefreshExecutor to initialise with + +|eureka.client.client-data-accept | | EurekaAccept name for client data accept + +|eureka.client.decoder-name | | This is a transient config and once the latest codecs are stable, can be removed + (as there will only be one) + +|eureka.client.disable-delta | false | Indicates whether the eureka client should disable fetching of delta and should rather resort to getting the full registry information. -

    Note that the delta fetches can reduce the traffic tremendously, because the rate + + Note that the delta fetches can reduce the traffic tremendously, because the rate of change with the eureka server is normally much lower than the rate of fetches. -

    The changes are effective at runtime at the next registry fetch cycle as specified - by registryFetchIntervalSeconds

    eureka.client.dollar-replacement

    _-

    Get a replacement string for Dollar sign <code>$</code> during - serializing/deserializing information in eureka server.

    eureka.client.enabled

    true

    Flag to indicate that the Eureka client is enabled.

    eureka.client.encoder-name

    This is a transient config and once the latest codecs are stable, can be removed - (as there will only be one)

    eureka.client.escape-char-replacement

    __

    Get a replacement string for underscore sign <code>_</code> during - serializing/deserializing information in eureka server.

    eureka.client.eureka-connection-idle-timeout-seconds

    30

    Indicates how much time (in seconds) that the HTTP connections to eureka server can + + The changes are effective at runtime at the next registry fetch cycle as specified + by registryFetchIntervalSeconds + +|eureka.client.dollar-replacement | _- | Get a replacement string for Dollar sign <code>$</code> during + serializing/deserializing information in eureka server. + +|eureka.client.enabled | true | Flag to indicate that the Eureka client is enabled. + +|eureka.client.encoder-name | | This is a transient config and once the latest codecs are stable, can be removed + (as there will only be one) + +|eureka.client.escape-char-replacement | __ | Get a replacement string for underscore sign <code>_</code> during + serializing/deserializing information in eureka server. + +|eureka.client.eureka-connection-idle-timeout-seconds | 30 | Indicates how much time (in seconds) that the HTTP connections to eureka server can stay idle before it can be closed. -

    In the AWS environment, it is recommended that the values is 30 seconds or less, + + In the AWS environment, it is recommended that the values is 30 seconds or less, since the firewall cleans up the connection information after a few mins leaving - the connection hanging in limbo

    eureka.client.eureka-server-connect-timeout-seconds

    5

    Indicates how long to wait (in seconds) before a connection to eureka server needs + the connection hanging in limbo + +|eureka.client.eureka-server-connect-timeout-seconds | 5 | Indicates how long to wait (in seconds) before a connection to eureka server needs to timeout. Note that the connections in the client are pooled by org.apache.http.client.HttpClient and this setting affects the actual connection - creation and also the wait time to get the connection from the pool.

    eureka.client.eureka-server-dnsname

    Gets the DNS name to be queried to get the list of eureka servers.This information + creation and also the wait time to get the connection from the pool. + +|eureka.client.eureka-server-dnsname | | Gets the DNS name to be queried to get the list of eureka servers.This information is not required if the contract returns the service urls by implementing serviceUrls. -

    The DNS mechanism is used when useDnsForFetchingServiceUrls is set to true and the + + The DNS mechanism is used when useDnsForFetchingServiceUrls is set to true and the eureka client expects the DNS to configured a certain way so that it can fetch changing eureka servers dynamically. -

    The changes are effective at runtime.

    eureka.client.eureka-server-port

    Gets the port to be used to construct the service url to contact eureka server when + + The changes are effective at runtime. + +|eureka.client.eureka-server-port | | Gets the port to be used to construct the service url to contact eureka server when the list of eureka servers come from the DNS.This information is not required if the contract returns the service urls eurekaServerServiceUrls(String). -

    The DNS mechanism is used when useDnsForFetchingServiceUrls is set to true and the + + The DNS mechanism is used when useDnsForFetchingServiceUrls is set to true and the eureka client expects the DNS to configured a certain way so that it can fetch changing eureka servers dynamically. -

    The changes are effective at runtime.

    eureka.client.eureka-server-read-timeout-seconds

    8

    Indicates how long to wait (in seconds) before a read from eureka server needs to - timeout.

    eureka.client.eureka-server-total-connections

    200

    Gets the total number of connections that is allowed from eureka client to all - eureka servers.

    eureka.client.eureka-server-total-connections-per-host

    50

    Gets the total number of connections that is allowed from eureka client to a eureka - server host.

    eureka.client.eureka-server-urlcontext

    Gets the URL context to be used to construct the service url to contact eureka + + The changes are effective at runtime. + +|eureka.client.eureka-server-read-timeout-seconds | 8 | Indicates how long to wait (in seconds) before a read from eureka server needs to + timeout. + +|eureka.client.eureka-server-total-connections | 200 | Gets the total number of connections that is allowed from eureka client to all + eureka servers. + +|eureka.client.eureka-server-total-connections-per-host | 50 | Gets the total number of connections that is allowed from eureka client to a eureka + server host. + +|eureka.client.eureka-server-urlcontext | | Gets the URL context to be used to construct the service url to contact eureka server when the list of eureka servers come from the DNS. This information is not required if the contract returns the service urls from eurekaServerServiceUrls. -

    The DNS mechanism is used when useDnsForFetchingServiceUrls is set to true and the + + The DNS mechanism is used when useDnsForFetchingServiceUrls is set to true and the eureka client expects the DNS to configured a certain way so that it can fetch - changing eureka servers dynamically. The changes are effective at runtime.

    eureka.client.eureka-service-url-poll-interval-seconds

    0

    Indicates how often(in seconds) to poll for changes to eureka server information. + changing eureka servers dynamically. The changes are effective at runtime. + +|eureka.client.eureka-service-url-poll-interval-seconds | 0 | Indicates how often(in seconds) to poll for changes to eureka server information. Eureka servers could be added or removed and this setting controls how soon the - eureka clients should know about it.

    eureka.client.fetch-registry

    true

    Indicates whether this client should fetch eureka registry information from eureka - server.

    eureka.client.fetch-remote-regions-registry

    Comma separated list of regions for which the eureka registry information will be + eureka clients should know about it. + +|eureka.client.fetch-registry | true | Indicates whether this client should fetch eureka registry information from eureka + server. + +|eureka.client.fetch-remote-regions-registry | | Comma separated list of regions for which the eureka registry information will be fetched. It is mandatory to define the availability zones for each of these regions as returned by availabilityZones. Failing to do so, will result in failure of - discovery client startup.

    eureka.client.filter-only-up-instances

    true

    Indicates whether to get the applications after filtering the applications for - instances with only InstanceStatus UP states.

    eureka.client.g-zip-content

    true

    Indicates whether the content fetched from eureka server has to be compressed + discovery client startup. + +|eureka.client.filter-only-up-instances | true | Indicates whether to get the applications after filtering the applications for + instances with only InstanceStatus UP states. + +|eureka.client.g-zip-content | true | Indicates whether the content fetched from eureka server has to be compressed whenever it is supported by the server. The registry information from the eureka - server is compressed for optimum network traffic.

    eureka.client.heartbeat-executor-exponential-back-off-bound

    10

    Heartbeat executor exponential back off related property. It is a maximum - multiplier value for retry delay, in case where a sequence of timeouts occurred.

    eureka.client.heartbeat-executor-thread-pool-size

    2

    The thread pool size for the heartbeatExecutor to initialise with

    eureka.client.initial-instance-info-replication-interval-seconds

    40

    Indicates how long initially (in seconds) to replicate instance info to the eureka - server

    eureka.client.instance-info-replication-interval-seconds

    30

    Indicates how often(in seconds) to replicate instance changes to be replicated to - the eureka server.

    eureka.client.log-delta-diff

    false

    Indicates whether to log differences between the eureka server and the eureka + server is compressed for optimum network traffic. + +|eureka.client.heartbeat-executor-exponential-back-off-bound | 10 | Heartbeat executor exponential back off related property. It is a maximum + multiplier value for retry delay, in case where a sequence of timeouts occurred. + +|eureka.client.heartbeat-executor-thread-pool-size | 2 | The thread pool size for the heartbeatExecutor to initialise with + +|eureka.client.initial-instance-info-replication-interval-seconds | 40 | Indicates how long initially (in seconds) to replicate instance info to the eureka + server + +|eureka.client.instance-info-replication-interval-seconds | 30 | Indicates how often(in seconds) to replicate instance changes to be replicated to + the eureka server. + +|eureka.client.log-delta-diff | false | Indicates whether to log differences between the eureka server and the eureka client in terms of registry information. -

    Eureka client tries to retrieve only delta changes from eureka server to minimize + + Eureka client tries to retrieve only delta changes from eureka server to minimize network traffic. After receiving the deltas, eureka client reconciles the information from the server to verify it has not missed out some information. Reconciliation failures could happen when the client has had network issues communicating to server.If the reconciliation fails, eureka client gets the full registry information. -

    While getting the full registry information, the eureka client can log the + + While getting the full registry information, the eureka client can log the differences between the client and the server and this setting controls that. -

    The changes are effective at runtime at the next registry fetch cycle as specified - by registryFetchIntervalSecondsr

    eureka.client.on-demand-update-status-change

    true

    If set to true, local status updates via ApplicationInfoManager will trigger - on-demand (but rate limited) register/updates to remote eureka servers

    eureka.client.prefer-same-zone-eureka

    true

    Indicates whether or not this instance should try to use the eureka server in the + + The changes are effective at runtime at the next registry fetch cycle as specified + by registryFetchIntervalSecondsr + +|eureka.client.on-demand-update-status-change | true | If set to true, local status updates via ApplicationInfoManager will trigger + on-demand (but rate limited) register/updates to remote eureka servers + +|eureka.client.prefer-same-zone-eureka | true | Indicates whether or not this instance should try to use the eureka server in the same zone for latency and/or other reason. -

    Ideally eureka clients are configured to talk to servers in the same zone -

    The changes are effective at runtime at the next registry fetch cycle as specified - by registryFetchIntervalSeconds

    eureka.client.property-resolver

    eureka.client.proxy-host

    Gets the proxy host to eureka server if any.

    eureka.client.proxy-password

    Gets the proxy password if any.

    eureka.client.proxy-port

    Gets the proxy port to eureka server if any.

    eureka.client.proxy-user-name

    Gets the proxy user name if any.

    eureka.client.region

    us-east-1

    Gets the region (used in AWS datacenters) where this instance resides.

    eureka.client.register-with-eureka

    true

    Indicates whether or not this instance should register its information with eureka + + Ideally eureka clients are configured to talk to servers in the same zone + + The changes are effective at runtime at the next registry fetch cycle as specified + by registryFetchIntervalSeconds + +|eureka.client.property-resolver | | + +|eureka.client.proxy-host | | Gets the proxy host to eureka server if any. + +|eureka.client.proxy-password | | Gets the proxy password if any. + +|eureka.client.proxy-port | | Gets the proxy port to eureka server if any. + +|eureka.client.proxy-user-name | | Gets the proxy user name if any. + +|eureka.client.region | us-east-1 | Gets the region (used in AWS datacenters) where this instance resides. + +|eureka.client.register-with-eureka | true | Indicates whether or not this instance should register its information with eureka server for discovery by others. -

    In some cases, you do not want your instances to be discovered whereas you just - want do discover other instances.

    eureka.client.registry-fetch-interval-seconds

    30

    Indicates how often(in seconds) to fetch the registry information from the eureka - server.

    eureka.client.registry-refresh-single-vip-address

    Indicates whether the client is only interested in the registry information for a - single VIP.

    eureka.client.service-url

    Map of availability zone to list of fully qualified URLs to communicate with eureka + + In some cases, you do not want your instances to be discovered whereas you just + want do discover other instances. + +|eureka.client.registry-fetch-interval-seconds | 30 | Indicates how often(in seconds) to fetch the registry information from the eureka + server. + +|eureka.client.registry-refresh-single-vip-address | | Indicates whether the client is only interested in the registry information for a + single VIP. + +|eureka.client.service-url | | Map of availability zone to list of fully qualified URLs to communicate with eureka server. Each value can be a single URL or a comma separated list of alternative locations. -

    Typically the eureka server URLs carry protocol,host,port,context and version + + Typically the eureka server URLs carry protocol,host,port,context and version information if any. Example: - http://ec2-256-156-243-129.compute-1.amazonaws.com:7001/eureka/ -

    The changes are effective at runtime at the next service url refresh cycle as - specified by eurekaServiceUrlPollIntervalSeconds.

    eureka.client.transport

    eureka.client.use-dns-for-fetching-service-urls

    false

    Indicates whether the eureka client should use the DNS mechanism to fetch a list of + http://ec2-256-156-243-129.compute-1.amazonaws.com:7001/eureka/ + + The changes are effective at runtime at the next service url refresh cycle as + specified by eurekaServiceUrlPollIntervalSeconds. + +|eureka.client.transport | | + +|eureka.client.use-dns-for-fetching-service-urls | false | Indicates whether the eureka client should use the DNS mechanism to fetch a list of eureka servers to talk to. When the DNS name is updated to have additional servers, that information is used immediately after the eureka client polls for that information as specified in eurekaServiceUrlPollIntervalSeconds. -

    Alternatively, the service urls can be returned serviceUrls, but the users should + + Alternatively, the service urls can be returned serviceUrls, but the users should implement their own mechanism to return the updated list in case of changes. -

    The changes are effective at runtime.

    eureka.dashboard.enabled

    true

    Flag to enable the Eureka dashboard. Default true.

    eureka.dashboard.path

    /

    The path to the Eureka dashboard (relative to the servlet path). Defaults to "/".

    eureka.instance.a-sgname

    Gets the AWS autoscaling group name associated with this instance. This information + + The changes are effective at runtime. + +|eureka.dashboard.enabled | true | Flag to enable the Eureka dashboard. Default true. + +|eureka.dashboard.path | / | The path to the Eureka dashboard (relative to the servlet path). Defaults to "/". + +|eureka.instance.a-sgname | | Gets the AWS autoscaling group name associated with this instance. This information is specifically used in an AWS environment to automatically put an instance out of - service after the instance is launched and it has been disabled for traffic..

    eureka.instance.app-group-name

    Get the name of the application group to be registered with eureka.

    eureka.instance.appname

    unknown

    Get the name of the application to be registered with eureka.

    eureka.instance.data-center-info

    Returns the data center this instance is deployed. This information is used to get - some AWS specific instance information if the instance is deployed in AWS.

    eureka.instance.default-address-resolution-order

    []

    eureka.instance.health-check-url

    Gets the absolute health check page URL for this instance. The users can provide + service after the instance is launched and it has been disabled for traffic.. + +|eureka.instance.app-group-name | | Get the name of the application group to be registered with eureka. + +|eureka.instance.appname | unknown | Get the name of the application to be registered with eureka. + +|eureka.instance.data-center-info | | Returns the data center this instance is deployed. This information is used to get + some AWS specific instance information if the instance is deployed in AWS. + +|eureka.instance.default-address-resolution-order | [] | + +|eureka.instance.health-check-url | | Gets the absolute health check page URL for this instance. The users can provide the healthCheckUrlPath if the health check page resides in the same instance talking to eureka, else in the cases where the instance is a proxy for some other server, users can provide the full URL. If the full URL is provided it takes precedence. -

    <p> + + <p> It is normally used for making educated decisions based on the health of the instance - for example, it can be used to determine whether to proceed deployments to an entire farm or stop the deployments without causing further damage. The full - URL should follow the format http://${eureka.hostname}:7001/ where the value - ${eureka.hostname} is replaced at runtime.

    eureka.instance.health-check-url-path

    /health

    Gets the relative health check URL path for this instance. The health check page + URL should follow the format http://${eureka.hostname}:7001/ where the value + ${eureka.hostname} is replaced at runtime. + +|eureka.instance.health-check-url-path | /health | Gets the relative health check URL path for this instance. The health check page URL is then constructed out of the hostname and the type of communication - secure or unsecure as specified in securePort and nonSecurePort. -

    It is normally used for making educated decisions based on the health of the + + It is normally used for making educated decisions based on the health of the instance - for example, it can be used to determine whether to proceed deployments - to an entire farm or stop the deployments without causing further damage.

    eureka.instance.home-page-url

    Gets the absolute home page URL for this instance. The users can provide the + to an entire farm or stop the deployments without causing further damage. + +|eureka.instance.home-page-url | | Gets the absolute home page URL for this instance. The users can provide the homePageUrlPath if the home page resides in the same instance talking to eureka, else in the cases where the instance is a proxy for some other server, users can provide the full URL. If the full URL is provided it takes precedence. -

    It is normally used for informational purposes for other services to use it as a - landing page. The full URL should follow the format http://${eureka.hostname}:7001/ - where the value ${eureka.hostname} is replaced at runtime.

    eureka.instance.home-page-url-path

    /

    Gets the relative home page URL Path for this instance. The home page URL is then + + It is normally used for informational purposes for other services to use it as a + landing page. The full URL should follow the format http://${eureka.hostname}:7001/ + where the value ${eureka.hostname} is replaced at runtime. + +|eureka.instance.home-page-url-path | / | Gets the relative home page URL Path for this instance. The home page URL is then constructed out of the hostName and the type of communication - secure or unsecure. -

    It is normally used for informational purposes for other services to use it as a - landing page.

    eureka.instance.host-info

    eureka.instance.hostname

    The hostname if it can be determined at configuration time (otherwise it will be - guessed from OS primitives).

    eureka.instance.inet-utils

    eureka.instance.initial-status

    Initial status to register with rmeote Eureka server.

    eureka.instance.instance-enabled-onit

    false

    Indicates whether the instance should be enabled for taking traffic as soon as it + + It is normally used for informational purposes for other services to use it as a + landing page. + +|eureka.instance.host-info | | + +|eureka.instance.hostname | | The hostname if it can be determined at configuration time (otherwise it will be + guessed from OS primitives). + +|eureka.instance.inet-utils | | + +|eureka.instance.initial-status | | Initial status to register with rmeote Eureka server. + +|eureka.instance.instance-enabled-onit | false | Indicates whether the instance should be enabled for taking traffic as soon as it is registered with eureka. Sometimes the application might need to do some - pre-processing before it is ready to take traffic.

    eureka.instance.instance-id

    Get the unique Id (within the scope of the appName) of this instance to be - registered with eureka.

    eureka.instance.ip-address

    Get the IPAdress of the instance. This information is for academic purposes only as + pre-processing before it is ready to take traffic. + +|eureka.instance.instance-id | | Get the unique Id (within the scope of the appName) of this instance to be + registered with eureka. + +|eureka.instance.ip-address | | Get the IPAdress of the instance. This information is for academic purposes only as the communication from other instances primarily happen using the information - supplied in {@link #getHostName(boolean)}.

    eureka.instance.lease-expiration-duration-in-seconds

    90

    Indicates the time in seconds that the eureka server waits since it received the + supplied in {@link #getHostName(boolean)}. + +|eureka.instance.lease-expiration-duration-in-seconds | 90 | Indicates the time in seconds that the eureka server waits since it received the last heartbeat before it can remove this instance from its view and there by disallowing traffic to this instance. -

    Setting this value too long could mean that the traffic could be routed to the + + Setting this value too long could mean that the traffic could be routed to the instance even though the instance is not alive. Setting this value too small could mean, the instance may be taken out of traffic because of temporary network glitches.This value to be set to atleast higher than the value specified in - leaseRenewalIntervalInSeconds.

    eureka.instance.lease-renewal-interval-in-seconds

    30

    Indicates how often (in seconds) the eureka client needs to send heartbeats to + leaseRenewalIntervalInSeconds. + +|eureka.instance.lease-renewal-interval-in-seconds | 30 | Indicates how often (in seconds) the eureka client needs to send heartbeats to eureka server to indicate that it is still alive. If the heartbeats are not received for the period specified in leaseExpirationDurationInSeconds, eureka server will remove the instance from its view, there by disallowing traffic to this instance. -

    Note that the instance could still not take traffic if it implements - HealthCheckCallback and then decides to make itself unavailable.

    eureka.instance.metadata-map

    Gets the metadata name/value pairs associated with this instance. This information - is sent to eureka server and can be used by other instances.

    eureka.instance.namespace

    eureka

    Get the namespace used to find properties. Ignored in Spring Cloud.

    eureka.instance.non-secure-port

    80

    Get the non-secure port on which the instance should receive traffic.

    eureka.instance.non-secure-port-enabled

    true

    Indicates whether the non-secure port should be enabled for traffic or not.

    eureka.instance.prefer-ip-address

    false

    Flag to say that, when guessing a hostname, the IP address of the server should be - used in prference to the hostname reported by the OS.

    eureka.instance.secure-health-check-url

    Gets the absolute secure health check page URL for this instance. The users can + + Note that the instance could still not take traffic if it implements + HealthCheckCallback and then decides to make itself unavailable. + +|eureka.instance.metadata-map | | Gets the metadata name/value pairs associated with this instance. This information + is sent to eureka server and can be used by other instances. + +|eureka.instance.namespace | eureka | Get the namespace used to find properties. Ignored in Spring Cloud. + +|eureka.instance.non-secure-port | 80 | Get the non-secure port on which the instance should receive traffic. + +|eureka.instance.non-secure-port-enabled | true | Indicates whether the non-secure port should be enabled for traffic or not. + +|eureka.instance.prefer-ip-address | false | Flag to say that, when guessing a hostname, the IP address of the server should be + used in prference to the hostname reported by the OS. + +|eureka.instance.secure-health-check-url | | Gets the absolute secure health check page URL for this instance. The users can provide the secureHealthCheckUrl if the health check page resides in the same instance talking to eureka, else in the cases where the instance is a proxy for some other server, users can provide the full URL. If the full URL is provided it takes precedence. -

    <p> + + <p> It is normally used for making educated decisions based on the health of the instance - for example, it can be used to determine whether to proceed deployments to an entire farm or stop the deployments without causing further damage. The full - URL should follow the format http://${eureka.hostname}:7001/ where the value - ${eureka.hostname} is replaced at runtime.

    eureka.instance.secure-port

    443

    Get the Secure port on which the instance should receive traffic.

    eureka.instance.secure-port-enabled

    false

    Indicates whether the secure port should be enabled for traffic or not.

    eureka.instance.secure-virtual-host-name

    Gets the secure virtual host name defined for this instance. -

    This is typically the way other instance would find this instance by using the + URL should follow the format http://${eureka.hostname}:7001/ where the value + ${eureka.hostname} is replaced at runtime. + +|eureka.instance.secure-port | 443 | Get the Secure port on which the instance should receive traffic. + +|eureka.instance.secure-port-enabled | false | Indicates whether the secure port should be enabled for traffic or not. + +|eureka.instance.secure-virtual-host-name | | Gets the secure virtual host name defined for this instance. + + This is typically the way other instance would find this instance by using the secure virtual host name.Think of this as similar to the fully qualified domain - name, that the users of your services will need to find this instance.

    eureka.instance.status-page-url

    Gets the absolute status page URL path for this instance. The users can provide the + name, that the users of your services will need to find this instance. + +|eureka.instance.status-page-url | | Gets the absolute status page URL path for this instance. The users can provide the statusPageUrlPath if the status page resides in the same instance talking to eureka, else in the cases where the instance is a proxy for some other server, users can provide the full URL. If the full URL is provided it takes precedence. -

    It is normally used for informational purposes for other services to find about the + + It is normally used for informational purposes for other services to find about the status of this instance. Users can provide a simple HTML indicating what is the - current status of the instance.

    eureka.instance.status-page-url-path

    /info

    Gets the relative status page URL path for this instance. The status page URL is + current status of the instance. + +|eureka.instance.status-page-url-path | /info | Gets the relative status page URL path for this instance. The status page URL is then constructed out of the hostName and the type of communication - secure or unsecure as specified in securePort and nonSecurePort. -

    It is normally used for informational purposes for other services to find about the + + It is normally used for informational purposes for other services to find about the status of this instance. Users can provide a simple HTML indicating what is the - current status of the instance.

    eureka.instance.virtual-host-name

    Gets the virtual host name defined for this instance. -

    This is typically the way other instance would find this instance by using the + current status of the instance. + +|eureka.instance.virtual-host-name | | Gets the virtual host name defined for this instance. + + This is typically the way other instance would find this instance by using the virtual host name.Think of this as similar to the fully qualified domain name, that - the users of your services will need to find this instance.

    eureka.server.a-sgcache-expiry-timeout-ms

    0

    eureka.server.a-sgquery-timeout-ms

    300

    eureka.server.a-sgupdate-interval-ms

    0

    eureka.server.a-wsaccess-id

    eureka.server.a-wssecret-key

    eureka.server.batch-replication

    false

    eureka.server.binding-strategy

    eureka.server.delta-retention-timer-interval-in-ms

    0

    eureka.server.disable-delta

    false

    eureka.server.disable-delta-for-remote-regions

    false

    eureka.server.disable-transparent-fallback-to-other-region

    false

    eureka.server.e-ipbind-rebind-retries

    3

    eureka.server.e-ipbinding-retry-interval-ms

    0

    eureka.server.e-ipbinding-retry-interval-ms-when-unbound

    0

    eureka.server.enable-replicated-request-compression

    false

    eureka.server.enable-self-preservation

    true

    eureka.server.eviction-interval-timer-in-ms

    0

    eureka.server.g-zip-content-from-remote-region

    true

    eureka.server.json-codec-name

    eureka.server.list-auto-scaling-groups-role-name

    ListAutoScalingGroups

    eureka.server.log-identity-headers

    true

    eureka.server.max-elements-in-peer-replication-pool

    10000

    eureka.server.max-elements-in-status-replication-pool

    10000

    eureka.server.max-idle-thread-age-in-minutes-for-peer-replication

    15

    eureka.server.max-idle-thread-in-minutes-age-for-status-replication

    10

    eureka.server.max-threads-for-peer-replication

    20

    eureka.server.max-threads-for-status-replication

    1

    eureka.server.max-time-for-replication

    30000

    eureka.server.min-threads-for-peer-replication

    5

    eureka.server.min-threads-for-status-replication

    1

    eureka.server.number-of-replication-retries

    5

    eureka.server.peer-eureka-nodes-update-interval-ms

    0

    eureka.server.peer-eureka-status-refresh-time-interval-ms

    0

    eureka.server.peer-node-connect-timeout-ms

    200

    eureka.server.peer-node-connection-idle-timeout-seconds

    30

    eureka.server.peer-node-read-timeout-ms

    200

    eureka.server.peer-node-total-connections

    1000

    eureka.server.peer-node-total-connections-per-host

    500

    eureka.server.prime-aws-replica-connections

    true

    eureka.server.property-resolver

    eureka.server.rate-limiter-burst-size

    10

    eureka.server.rate-limiter-enabled

    false

    eureka.server.rate-limiter-full-fetch-average-rate

    100

    eureka.server.rate-limiter-privileged-clients

    eureka.server.rate-limiter-registry-fetch-average-rate

    500

    eureka.server.rate-limiter-throttle-standard-clients

    false

    eureka.server.registry-sync-retries

    0

    eureka.server.registry-sync-retry-wait-ms

    0

    eureka.server.remote-region-app-whitelist

    eureka.server.remote-region-connect-timeout-ms

    1000

    eureka.server.remote-region-connection-idle-timeout-seconds

    30

    eureka.server.remote-region-fetch-thread-pool-size

    20

    eureka.server.remote-region-read-timeout-ms

    1000

    eureka.server.remote-region-registry-fetch-interval

    30

    eureka.server.remote-region-total-connections

    1000

    eureka.server.remote-region-total-connections-per-host

    500

    eureka.server.remote-region-trust-store

    eureka.server.remote-region-trust-store-password

    changeit

    eureka.server.remote-region-urls

    eureka.server.remote-region-urls-with-name

    eureka.server.renewal-percent-threshold

    0.85

    eureka.server.renewal-threshold-update-interval-ms

    0

    eureka.server.response-cache-auto-expiration-in-seconds

    180

    eureka.server.response-cache-update-interval-ms

    0

    eureka.server.retention-time-in-msin-delta-queue

    0

    eureka.server.route53-bind-rebind-retries

    3

    eureka.server.route53-binding-retry-interval-ms

    0

    eureka.server.route53-domain-ttl

    30

    eureka.server.sync-when-timestamp-differs

    true

    eureka.server.use-read-only-response-cache

    true

    eureka.server.wait-time-in-ms-when-sync-empty

    0

    eureka.server.xml-codec-name

    feign.compression.request.mime-types

    [text/xml, application/xml, application/json]

    The list of supported mime types.

    feign.compression.request.min-request-size

    2048

    The minimum threshold content size.

    health.config.enabled

    false

    Flag to indicate that the config server health indicator should be installed.

    health.hystrix.enabled

    false

    Flag to inidicate that the hystrix health indicator should be installed.

    netflix.atlas.batch-size

    10000

    netflix.atlas.enabled

    true

    netflix.atlas.uri

    proxy.auth.load-balanced

    false

    proxy.auth.routes

    Authentication strategy per route.

    spring.cloud.bus.ack.destination-service

    Service that wants to listen to acks. By default null (meaning all services).

    spring.cloud.bus.ack.enabled

    true

    Flag to switch off acks (default on).

    spring.cloud.bus.destination

    springCloudBus

    Name of Spring Cloud Stream destination for messages.

    spring.cloud.bus.enabled

    true

    Flag to indicate that the bus is enabled.

    spring.cloud.bus.env.enabled

    true

    Flag to switch off environment change events (default on).

    spring.cloud.bus.refresh.enabled

    true

    Flag to switch off refresh events (default on).

    spring.cloud.bus.trace.enabled

    false

    Flag to switch on tracing of acks (default off).

    spring.cloud.cloudfoundry.discovery.email

    Email address of user to authenticate.

    spring.cloud.cloudfoundry.discovery.enabled

    true

    Flag to indicate that discovery is enabled.

    spring.cloud.cloudfoundry.discovery.password

    Password for user to authenticate and obtain token.

    spring.cloud.cloudfoundry.discovery.url

    https://api.run.pivotal.io

    URL of Cloud Foundry API (Cloud Controller).

    spring.cloud.config.allow-override

    true

    Flag to indicate that {@link #isSystemPropertiesOverride() + the users of your services will need to find this instance. + +|eureka.server.a-sgcache-expiry-timeout-ms | 0 | + +|eureka.server.a-sgquery-timeout-ms | 300 | + +|eureka.server.a-sgupdate-interval-ms | 0 | + +|eureka.server.a-wsaccess-id | | + +|eureka.server.a-wssecret-key | | + +|eureka.server.batch-replication | false | + +|eureka.server.binding-strategy | | + +|eureka.server.delta-retention-timer-interval-in-ms | 0 | + +|eureka.server.disable-delta | false | + +|eureka.server.disable-delta-for-remote-regions | false | + +|eureka.server.disable-transparent-fallback-to-other-region | false | + +|eureka.server.e-ipbind-rebind-retries | 3 | + +|eureka.server.e-ipbinding-retry-interval-ms | 0 | + +|eureka.server.e-ipbinding-retry-interval-ms-when-unbound | 0 | + +|eureka.server.enable-replicated-request-compression | false | + +|eureka.server.enable-self-preservation | true | + +|eureka.server.eviction-interval-timer-in-ms | 0 | + +|eureka.server.g-zip-content-from-remote-region | true | + +|eureka.server.json-codec-name | | + +|eureka.server.list-auto-scaling-groups-role-name | ListAutoScalingGroups | + +|eureka.server.log-identity-headers | true | + +|eureka.server.max-elements-in-peer-replication-pool | 10000 | + +|eureka.server.max-elements-in-status-replication-pool | 10000 | + +|eureka.server.max-idle-thread-age-in-minutes-for-peer-replication | 15 | + +|eureka.server.max-idle-thread-in-minutes-age-for-status-replication | 10 | + +|eureka.server.max-threads-for-peer-replication | 20 | + +|eureka.server.max-threads-for-status-replication | 1 | + +|eureka.server.max-time-for-replication | 30000 | + +|eureka.server.min-threads-for-peer-replication | 5 | + +|eureka.server.min-threads-for-status-replication | 1 | + +|eureka.server.number-of-replication-retries | 5 | + +|eureka.server.peer-eureka-nodes-update-interval-ms | 0 | + +|eureka.server.peer-eureka-status-refresh-time-interval-ms | 0 | + +|eureka.server.peer-node-connect-timeout-ms | 200 | + +|eureka.server.peer-node-connection-idle-timeout-seconds | 30 | + +|eureka.server.peer-node-read-timeout-ms | 200 | + +|eureka.server.peer-node-total-connections | 1000 | + +|eureka.server.peer-node-total-connections-per-host | 500 | + +|eureka.server.prime-aws-replica-connections | true | + +|eureka.server.property-resolver | | + +|eureka.server.rate-limiter-burst-size | 10 | + +|eureka.server.rate-limiter-enabled | false | + +|eureka.server.rate-limiter-full-fetch-average-rate | 100 | + +|eureka.server.rate-limiter-privileged-clients | | + +|eureka.server.rate-limiter-registry-fetch-average-rate | 500 | + +|eureka.server.rate-limiter-throttle-standard-clients | false | + +|eureka.server.registry-sync-retries | 0 | + +|eureka.server.registry-sync-retry-wait-ms | 0 | + +|eureka.server.remote-region-app-whitelist | | + +|eureka.server.remote-region-connect-timeout-ms | 1000 | + +|eureka.server.remote-region-connection-idle-timeout-seconds | 30 | + +|eureka.server.remote-region-fetch-thread-pool-size | 20 | + +|eureka.server.remote-region-read-timeout-ms | 1000 | + +|eureka.server.remote-region-registry-fetch-interval | 30 | + +|eureka.server.remote-region-total-connections | 1000 | + +|eureka.server.remote-region-total-connections-per-host | 500 | + +|eureka.server.remote-region-trust-store | | + +|eureka.server.remote-region-trust-store-password | changeit | + +|eureka.server.remote-region-urls | | + +|eureka.server.remote-region-urls-with-name | | + +|eureka.server.renewal-percent-threshold | 0.85 | + +|eureka.server.renewal-threshold-update-interval-ms | 0 | + +|eureka.server.response-cache-auto-expiration-in-seconds | 180 | + +|eureka.server.response-cache-update-interval-ms | 0 | + +|eureka.server.retention-time-in-msin-delta-queue | 0 | + +|eureka.server.route53-bind-rebind-retries | 3 | + +|eureka.server.route53-binding-retry-interval-ms | 0 | + +|eureka.server.route53-domain-ttl | 30 | + +|eureka.server.sync-when-timestamp-differs | true | + +|eureka.server.use-read-only-response-cache | true | + +|eureka.server.wait-time-in-ms-when-sync-empty | 0 | + +|eureka.server.xml-codec-name | | + +|feign.compression.request.mime-types | [text/xml, application/xml, application/json] | The list of supported mime types. + +|feign.compression.request.min-request-size | 2048 | The minimum threshold content size. + +|health.config.enabled | false | Flag to indicate that the config server health indicator should be installed. + +|health.hystrix.enabled | false | Flag to inidicate that the hystrix health indicator should be installed. + +|netflix.atlas.batch-size | 10000 | + +|netflix.atlas.enabled | true | + +|netflix.atlas.uri | | + +|proxy.auth.load-balanced | false | + +|proxy.auth.routes | | Authentication strategy per route. + +|spring.cloud.bus.ack.destination-service | | Service that wants to listen to acks. By default null (meaning all services). + +|spring.cloud.bus.ack.enabled | true | Flag to switch off acks (default on). + +|spring.cloud.bus.destination | springCloudBus | Name of Spring Cloud Stream destination for messages. + +|spring.cloud.bus.enabled | true | Flag to indicate that the bus is enabled. + +|spring.cloud.bus.env.enabled | true | Flag to switch off environment change events (default on). + +|spring.cloud.bus.refresh.enabled | true | Flag to switch off refresh events (default on). + +|spring.cloud.bus.trace.enabled | false | Flag to switch on tracing of acks (default off). + +|spring.cloud.cloudfoundry.discovery.email | | Email address of user to authenticate. + +|spring.cloud.cloudfoundry.discovery.enabled | true | Flag to indicate that discovery is enabled. + +|spring.cloud.cloudfoundry.discovery.password | | Password for user to authenticate and obtain token. + +|spring.cloud.cloudfoundry.discovery.url | https://api.run.pivotal.io | URL of Cloud Foundry API (Cloud Controller). + +|spring.cloud.config.allow-override | true | Flag to indicate that {@link #isSystemPropertiesOverride() systemPropertiesOverride} can be used. Set to false to prevent users from changing - the default accidentally. Default true.

    spring.cloud.config.discovery.enabled

    false

    Flag to indicate that config server discovery is enabled (config server URL will be - looked up via discovery).

    spring.cloud.config.discovery.service-id

    CONFIGSERVER

    Service id to locate config server.

    spring.cloud.config.enabled

    true

    Flag to say that remote configuration is enabled. Default true;

    spring.cloud.config.fail-fast

    false

    Flag to indicate that failure to connect to the server is fatal (default false).

    spring.cloud.config.label

    The label name to use to pull remote configuration properties. The default is set - on the server (generally "master" for a git based server).

    spring.cloud.config.name

    Name of application used to fetch remote properties.

    spring.cloud.config.override-none

    false

    Flag to indicate that when {@link #setAllowOverride(boolean) allowOverride} is + the default accidentally. Default true. + +|spring.cloud.config.discovery.enabled | false | Flag to indicate that config server discovery is enabled (config server URL will be + looked up via discovery). + +|spring.cloud.config.discovery.service-id | CONFIGSERVER | Service id to locate config server. + +|spring.cloud.config.enabled | true | Flag to say that remote configuration is enabled. Default true; + +|spring.cloud.config.fail-fast | false | Flag to indicate that failure to connect to the server is fatal (default false). + +|spring.cloud.config.label | | The label name to use to pull remote configuration properties. The default is set + on the server (generally "master" for a git based server). + +|spring.cloud.config.name | | Name of application used to fetch remote properties. + +|spring.cloud.config.override-none | false | Flag to indicate that when {@link #setAllowOverride(boolean) allowOverride} is true, external properties should take lowest priority, and not override any - existing property sources (including local config files). Default false.

    spring.cloud.config.override-system-properties

    true

    Flag to indicate that the external properties should override system properties. - Default true.

    spring.cloud.config.password

    The password to use (HTTP Basic) when contacting the remote server.

    spring.cloud.config.profile

    default

    The default profile to use when fetching remote configuration (comma-separated). - Default is "default".

    spring.cloud.config.retry.initial-interval

    1000

    Initial retry interval in milliseconds.

    spring.cloud.config.retry.max-attempts

    6

    Maximum number of attempts.

    spring.cloud.config.retry.max-interval

    2000

    Maximum interval for backoff.

    spring.cloud.config.retry.multiplier

    1.1

    Multiplier for next interval.

    spring.cloud.config.uri

    http://localhost:8888

    The URI of the remote server (default http://localhost:8888).

    spring.cloud.config.username

    The username to use (HTTP Basic) when contacting the remote server.

    spring.cloud.consul.config.acl-token

    spring.cloud.consul.config.data-key

    data

    If format is Format.PROPERTIES or Format.YAML - then the following field is used as key to look up consul for configuration.

    spring.cloud.consul.config.default-context

    application

    spring.cloud.consul.config.enabled

    true

    spring.cloud.consul.config.fail-fast

    true

    Throw exceptions during config lookup if true, otherwise, log warnings.

    spring.cloud.consul.config.format

    spring.cloud.consul.config.prefix

    config

    spring.cloud.consul.config.profile-separator

    ,

    spring.cloud.consul.config.watch.delay

    10

    spring.cloud.consul.config.watch.enabled

    true

    spring.cloud.consul.config.watch.wait-time

    2

    spring.cloud.consul.discovery.acl-token

    spring.cloud.consul.discovery.catalog-services-watch-delay

    10

    spring.cloud.consul.discovery.catalog-services-watch-timeout

    2

    spring.cloud.consul.discovery.enabled

    true

    Is service discovery enabled?

    spring.cloud.consul.discovery.health-check-interval

    10s

    How often to perform the health check (e.g. 10s)

    spring.cloud.consul.discovery.health-check-path

    /health

    Alternate server path to invoke for health checking

    spring.cloud.consul.discovery.health-check-timeout

    Timeout for health check (e.g. 10s)

    spring.cloud.consul.discovery.health-check-url

    Custom health check url to override default

    spring.cloud.consul.discovery.heartbeat.enabled

    false

    spring.cloud.consul.discovery.heartbeat.heartbeat-interval

    spring.cloud.consul.discovery.heartbeat.interval-ratio

    spring.cloud.consul.discovery.heartbeat.ttl-unit

    s

    spring.cloud.consul.discovery.heartbeat.ttl-value

    30

    spring.cloud.consul.discovery.host-info

    spring.cloud.consul.discovery.hostname

    Hostname to use when accessing server

    spring.cloud.consul.discovery.instance-id

    Unique service instance id

    spring.cloud.consul.discovery.ip-address

    IP address to use when accessing service (must also set preferIpAddress - to use)

    spring.cloud.consul.discovery.lifecycle.enabled

    true

    spring.cloud.consul.discovery.management-suffix

    management

    Suffix to use when registering management service

    spring.cloud.consul.discovery.management-tags

    Tags to use when registering management service

    spring.cloud.consul.discovery.port

    Port to register the service under (defaults to listening port)

    spring.cloud.consul.discovery.prefer-agent-address

    false

    Source of how we will determine the address to use

    spring.cloud.consul.discovery.prefer-ip-address

    false

    Use ip address rather than hostname during registration

    spring.cloud.consul.discovery.query-passing

    false

    Add the 'passing` parameter to /v1/health/service/serviceName. - This pushes health check passing to the server.

    spring.cloud.consul.discovery.register

    true

    Register as a service in consul.

    spring.cloud.consul.discovery.register-health-check

    true

    Register health check in consul. Useful during development of a service.

    spring.cloud.consul.discovery.scheme

    http

    Whether to register an http or https service

    spring.cloud.consul.discovery.server-list-query-tags

    Map of serviceId’s → tag to query for in server list. - This allows filtering services by a single tag.

    spring.cloud.consul.discovery.service-name

    Service name

    spring.cloud.consul.discovery.tags

    Tags to use when registering service

    spring.cloud.consul.enabled

    true

    Is spring cloud consul enabled

    spring.cloud.consul.host

    localhost

    Consul agent hostname. Defaults to 'localhost'.

    spring.cloud.consul.port

    8500

    Consul agent port. Defaults to '8500'.

    spring.cloud.consul.retry.initial-interval

    1000

    Initial retry interval in milliseconds.

    spring.cloud.consul.retry.max-attempts

    6

    Maximum number of attempts.

    spring.cloud.consul.retry.max-interval

    2000

    Maximum interval for backoff.

    spring.cloud.consul.retry.multiplier

    1.1

    Multiplier for next interval.

    spring.cloud.hypermedia.refresh.fixed-delay

    5000

    spring.cloud.hypermedia.refresh.initial-delay

    10000

    spring.cloud.inetutils.default-hostname

    localhost

    The default hostname. Used in case of errors.

    spring.cloud.inetutils.default-ip-address

    127.0.0.1

    The default ipaddress. Used in case of errors.

    spring.cloud.inetutils.ignored-interfaces

    List of Java regex expressions for network interfaces that will be ignored.

    spring.cloud.inetutils.timeout-seconds

    1

    Timeout in seconds for calculating hostname.

    spring.cloud.stream.binders

    spring.cloud.stream.bindings

    spring.cloud.stream.consumer-defaults

    spring.cloud.stream.default-binder

    spring.cloud.stream.dynamic-destinations

    []

    spring.cloud.stream.ignore-unknown-properties

    true

    spring.cloud.stream.instance-count

    1

    spring.cloud.stream.instance-index

    0

    spring.cloud.stream.producer-defaults

    spring.cloud.stream.rabbit.binder.addresses

    []

    spring.cloud.stream.rabbit.binder.admin-adresses

    []

    spring.cloud.stream.rabbit.binder.compression-level

    0

    spring.cloud.stream.rabbit.binder.nodes

    []

    spring.cloud.stream.rabbit.binder.password

    spring.cloud.stream.rabbit.binder.ssl-properties-location

    spring.cloud.stream.rabbit.binder.use-ssl

    false

    spring.cloud.stream.rabbit.binder.username

    spring.cloud.stream.rabbit.binder.vhost

    spring.cloud.stream.rabbit.bindings

    spring.cloud.zookeeper.default-health-endpoint

    Default health endpoint that will be checked to verify that a dependency is alive

    spring.cloud.zookeeper.dependencies

    Mapping of alias to ZookeeperDependency. From Ribbon perspective the alias - is actually serviceID since Ribbon can’t accept nested structures in serviceID

    spring.cloud.zookeeper.dependency-configurations

    spring.cloud.zookeeper.dependency-names

    spring.cloud.zookeeper.discovery.enabled

    true

    spring.cloud.zookeeper.discovery.instance-host

    spring.cloud.zookeeper.discovery.metadata

    Gets the metadata name/value pairs associated with this instance. This information - is sent to zookeeper and can be used by other instances.

    spring.cloud.zookeeper.discovery.root

    /services

    spring.cloud.zookeeper.discovery.uri-spec

    {scheme}://{address}:{port}

    spring.cloud.zookeeper.prefix

    Common prefix that will be applied to all Zookeeper dependencies' paths

    spring.integration.poller.fixed-delay

    1000

    Fixed delay for default poller.

    spring.integration.poller.max-messages-per-poll

    1

    Maximum messages per poll for the default poller.

    spring.sleuth.keys.async.class-name-key

    class

    Simple name of the class with a method annotated with {@code @Async} + existing property sources (including local config files). Default false. + +|spring.cloud.config.override-system-properties | true | Flag to indicate that the external properties should override system properties. + Default true. + +|spring.cloud.config.password | | The password to use (HTTP Basic) when contacting the remote server. + +|spring.cloud.config.profile | default | The default profile to use when fetching remote configuration (comma-separated). + Default is "default". + +|spring.cloud.config.retry.initial-interval | 1000 | Initial retry interval in milliseconds. + +|spring.cloud.config.retry.max-attempts | 6 | Maximum number of attempts. + +|spring.cloud.config.retry.max-interval | 2000 | Maximum interval for backoff. + +|spring.cloud.config.retry.multiplier | 1.1 | Multiplier for next interval. + +|spring.cloud.config.uri | http://localhost:8888 | The URI of the remote server (default http://localhost:8888). + +|spring.cloud.config.username | | The username to use (HTTP Basic) when contacting the remote server. + +|spring.cloud.consul.config.acl-token | | + +|spring.cloud.consul.config.data-key | data | If format is Format.PROPERTIES or Format.YAML + then the following field is used as key to look up consul for configuration. + +|spring.cloud.consul.config.default-context | application | + +|spring.cloud.consul.config.enabled | true | + +|spring.cloud.consul.config.fail-fast | true | Throw exceptions during config lookup if true, otherwise, log warnings. + +|spring.cloud.consul.config.format | | + +|spring.cloud.consul.config.prefix | config | + +|spring.cloud.consul.config.profile-separator | , | + +|spring.cloud.consul.config.watch.delay | 10 | + +|spring.cloud.consul.config.watch.enabled | true | + +|spring.cloud.consul.config.watch.wait-time | 2 | + +|spring.cloud.consul.discovery.acl-token | | + +|spring.cloud.consul.discovery.catalog-services-watch-delay | 10 | + +|spring.cloud.consul.discovery.catalog-services-watch-timeout | 2 | + +|spring.cloud.consul.discovery.enabled | true | Is service discovery enabled? + +|spring.cloud.consul.discovery.health-check-interval | 10s | How often to perform the health check (e.g. 10s) + +|spring.cloud.consul.discovery.health-check-path | /health | Alternate server path to invoke for health checking + +|spring.cloud.consul.discovery.health-check-timeout | | Timeout for health check (e.g. 10s) + +|spring.cloud.consul.discovery.health-check-url | | Custom health check url to override default + +|spring.cloud.consul.discovery.heartbeat.enabled | false | + +|spring.cloud.consul.discovery.heartbeat.heartbeat-interval | | + +|spring.cloud.consul.discovery.heartbeat.interval-ratio | | + +|spring.cloud.consul.discovery.heartbeat.ttl-unit | s | + +|spring.cloud.consul.discovery.heartbeat.ttl-value | 30 | + +|spring.cloud.consul.discovery.host-info | | + +|spring.cloud.consul.discovery.hostname | | Hostname to use when accessing server + +|spring.cloud.consul.discovery.instance-id | | Unique service instance id + +|spring.cloud.consul.discovery.ip-address | | IP address to use when accessing service (must also set preferIpAddress + to use) + +|spring.cloud.consul.discovery.lifecycle.enabled | true | + +|spring.cloud.consul.discovery.management-suffix | management | Suffix to use when registering management service + +|spring.cloud.consul.discovery.management-tags | | Tags to use when registering management service + +|spring.cloud.consul.discovery.port | | Port to register the service under (defaults to listening port) + +|spring.cloud.consul.discovery.prefer-agent-address | false | Source of how we will determine the address to use + +|spring.cloud.consul.discovery.prefer-ip-address | false | Use ip address rather than hostname during registration + +|spring.cloud.consul.discovery.query-passing | false | Add the 'passing` parameter to /v1/health/service/serviceName. + This pushes health check passing to the server. + +|spring.cloud.consul.discovery.register | true | Register as a service in consul. + +|spring.cloud.consul.discovery.register-health-check | true | Register health check in consul. Useful during development of a service. + +|spring.cloud.consul.discovery.scheme | http | Whether to register an http or https service + +|spring.cloud.consul.discovery.server-list-query-tags | | Map of serviceId's -> tag to query for in server list. + This allows filtering services by a single tag. + +|spring.cloud.consul.discovery.service-name | | Service name + +|spring.cloud.consul.discovery.tags | | Tags to use when registering service + +|spring.cloud.consul.enabled | true | Is spring cloud consul enabled + +|spring.cloud.consul.host | localhost | Consul agent hostname. Defaults to 'localhost'. + +|spring.cloud.consul.port | 8500 | Consul agent port. Defaults to '8500'. + +|spring.cloud.consul.retry.initial-interval | 1000 | Initial retry interval in milliseconds. + +|spring.cloud.consul.retry.max-attempts | 6 | Maximum number of attempts. + +|spring.cloud.consul.retry.max-interval | 2000 | Maximum interval for backoff. + +|spring.cloud.consul.retry.multiplier | 1.1 | Multiplier for next interval. + +|spring.cloud.hypermedia.refresh.fixed-delay | 5000 | + +|spring.cloud.hypermedia.refresh.initial-delay | 10000 | + +|spring.cloud.inetutils.default-hostname | localhost | The default hostname. Used in case of errors. + +|spring.cloud.inetutils.default-ip-address | 127.0.0.1 | The default ipaddress. Used in case of errors. + +|spring.cloud.inetutils.ignored-interfaces | | List of Java regex expressions for network interfaces that will be ignored. + +|spring.cloud.inetutils.timeout-seconds | 1 | Timeout in seconds for calculating hostname. + +|spring.cloud.stream.binders | | + +|spring.cloud.stream.bindings | | + +|spring.cloud.stream.consumer-defaults | | + +|spring.cloud.stream.default-binder | | + +|spring.cloud.stream.dynamic-destinations | [] | + +|spring.cloud.stream.ignore-unknown-properties | true | + +|spring.cloud.stream.instance-count | 1 | + +|spring.cloud.stream.instance-index | 0 | + +|spring.cloud.stream.producer-defaults | | + +|spring.cloud.stream.rabbit.binder.addresses | [] | + +|spring.cloud.stream.rabbit.binder.admin-adresses | [] | + +|spring.cloud.stream.rabbit.binder.compression-level | 0 | + +|spring.cloud.stream.rabbit.binder.nodes | [] | + +|spring.cloud.stream.rabbit.binder.password | | + +|spring.cloud.stream.rabbit.binder.ssl-properties-location | | + +|spring.cloud.stream.rabbit.binder.use-ssl | false | + +|spring.cloud.stream.rabbit.binder.username | | + +|spring.cloud.stream.rabbit.binder.vhost | | + +|spring.cloud.stream.rabbit.bindings | | + +|spring.cloud.zookeeper.default-health-endpoint | | Default health endpoint that will be checked to verify that a dependency is alive + +|spring.cloud.zookeeper.dependencies | | Mapping of alias to ZookeeperDependency. From Ribbon perspective the alias + is actually serviceID since Ribbon can't accept nested structures in serviceID + +|spring.cloud.zookeeper.dependency-configurations | | + +|spring.cloud.zookeeper.dependency-names | | + +|spring.cloud.zookeeper.discovery.enabled | true | + +|spring.cloud.zookeeper.discovery.instance-host | | + +|spring.cloud.zookeeper.discovery.metadata | | Gets the metadata name/value pairs associated with this instance. This information + is sent to zookeeper and can be used by other instances. + +|spring.cloud.zookeeper.discovery.root | /services | + +|spring.cloud.zookeeper.discovery.uri-spec | {scheme}://{address}:{port} | + +|spring.cloud.zookeeper.prefix | | Common prefix that will be applied to all Zookeeper dependencies' paths + +|spring.integration.poller.fixed-delay | 1000 | Fixed delay for default poller. + +|spring.integration.poller.max-messages-per-poll | 1 | Maximum messages per poll for the default poller. + +|spring.sleuth.keys.async.class-name-key | class | Simple name of the class with a method annotated with {@code @Async} from which the asynchronous process started -

    @see org.springframework.scheduling.annotation.Async

    spring.sleuth.keys.async.method-name-key

    method

    Name of the method annotated with {@code @Async} -

    @see org.springframework.scheduling.annotation.Async

    spring.sleuth.keys.async.prefix

    Prefix for header names if they are added as tags.

    spring.sleuth.keys.async.thread-name-key

    thread

    Name of the thread that executed the async method -

    @see org.springframework.scheduling.annotation.Async

    spring.sleuth.keys.http.headers

    Additional headers that should be added as tags if they exist. If the header + + @see org.springframework.scheduling.annotation.Async + +|spring.sleuth.keys.async.method-name-key | method | Name of the method annotated with {@code @Async} + + @see org.springframework.scheduling.annotation.Async + +|spring.sleuth.keys.async.prefix | | Prefix for header names if they are added as tags. + +|spring.sleuth.keys.async.thread-name-key | thread | Name of the thread that executed the async method + + @see org.springframework.scheduling.annotation.Async + +|spring.sleuth.keys.http.headers | | Additional headers that should be added as tags if they exist. If the header value is multi-valued, the tag value will be a comma-separated, single-quoted - list.

    spring.sleuth.keys.http.host

    http.host

    The domain portion of the URL or host header. Example: - "mybucket.s3.amazonaws.com". Used to filter by host as opposed to ip address.

    spring.sleuth.keys.http.method

    http.method

    The HTTP method, or verb, such as "GET" or "POST". Used to filter against an - http route.

    spring.sleuth.keys.http.path

    http.path

    The absolute http path, without any query parameters. Example: + list. + +|spring.sleuth.keys.http.host | http.host | The domain portion of the URL or host header. Example: + "mybucket.s3.amazonaws.com". Used to filter by host as opposed to ip address. + +|spring.sleuth.keys.http.method | http.method | The HTTP method, or verb, such as "GET" or "POST". Used to filter against an + http route. + +|spring.sleuth.keys.http.path | http.path | The absolute http path, without any query parameters. Example: "/objects/abcd-ff". Used to filter against an http route, portably with zipkin v1. In zipkin v1, only equals filters are supported. Dropping query parameters makes the number of distinct URIs less. For example, one can query for the same @@ -11343,198 +10125,111 @@ created during auto-configuration.

    not reduce cardinality to a HTTP single route. For example, it is common to express a route as an http URI template like "/resource/{resource_id}". In systems where only equals queries are available, searching for - {@code http.uri=/resource} won’t match if the actual request was + {@code http.uri=/resource} won't match if the actual request was "/resource/abcd-ff". Historical note: This was commonly expressed as "http.uri" - in zipkin, eventhough it was most often just a path.

    spring.sleuth.keys.http.prefix

    http.

    Prefix for header names if they are added as tags.

    spring.sleuth.keys.http.request-size

    http.request.size

    The size of the non-empty HTTP request body, in bytes. Ex. "16384" -

    <p>Large uploads can exceed limits or contribute directly to latency.

    spring.sleuth.keys.http.response-size

    http.response.size

    The size of the non-empty HTTP response body, in bytes. Ex. "16384" -

    <p>Large downloads can exceed limits or contribute directly to latency.

    spring.sleuth.keys.http.status-code

    http.status_code

    The HTTP response code, when not in 2xx range. Ex. "503" Used to filter for + in zipkin, eventhough it was most often just a path. + +|spring.sleuth.keys.http.prefix | http. | Prefix for header names if they are added as tags. + +|spring.sleuth.keys.http.request-size | http.request.size | The size of the non-empty HTTP request body, in bytes. Ex. "16384" + + <p>Large uploads can exceed limits or contribute directly to latency. + +|spring.sleuth.keys.http.response-size | http.response.size | The size of the non-empty HTTP response body, in bytes. Ex. "16384" + + <p>Large downloads can exceed limits or contribute directly to latency. + +|spring.sleuth.keys.http.status-code | http.status_code | The HTTP response code, when not in 2xx range. Ex. "503" Used to filter for error status. 2xx range are not logged as success codes are less interesting - for latency troubleshooting. Omitting saves at least 20 bytes per span.

    spring.sleuth.keys.http.url

    http.url

    The entire URL, including the scheme, host and query parameters if available. + for latency troubleshooting. Omitting saves at least 20 bytes per span. + +|spring.sleuth.keys.http.url | http.url | The entire URL, including the scheme, host and query parameters if available. Ex. - "https://mybucket.s3.amazonaws.com/objects/abcd-ff?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Algorithm=AWS4-HMAC-SHA256…​" + "https://mybucket.s3.amazonaws.com/objects/abcd-ff?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Algorithm=AWS4-HMAC-SHA256..." Combined with {@link #method}, you can understand the fully-qualified request line. This is optional as it may include private data or be of - considerable length.

    spring.sleuth.keys.hystrix.command-group

    commandGroup

    Name of the command group. Hystrix uses the command group key to group + considerable length. + +|spring.sleuth.keys.hystrix.command-group | commandGroup | Name of the command group. Hystrix uses the command group key to group together commands such as for reporting, alerting, dashboards, or team/library ownership. -

    @see com.netflix.hystrix.HystrixCommandGroupKey

    spring.sleuth.keys.hystrix.command-key

    commandKey

    Name of the command key. Describes the name for the given command. + + @see com.netflix.hystrix.HystrixCommandGroupKey + +|spring.sleuth.keys.hystrix.command-key | commandKey | Name of the command key. Describes the name for the given command. A key to represent a {@link com.netflix.hystrix.HystrixCommand} for monitoring, circuit-breakers, metrics publishing, caching and other such uses. -

    @see com.netflix.hystrix.HystrixCommandKey

    spring.sleuth.keys.hystrix.prefix

    Prefix for header names if they are added as tags.

    spring.sleuth.keys.hystrix.thread-pool-key

    threadPoolKey

    Name of the thread pool key. The thread-pool key represents a {@link com.netflix.hystrix.HystrixThreadPool} + + @see com.netflix.hystrix.HystrixCommandKey + +|spring.sleuth.keys.hystrix.prefix | | Prefix for header names if they are added as tags. + +|spring.sleuth.keys.hystrix.thread-pool-key | threadPoolKey | Name of the thread pool key. The thread-pool key represents a {@link com.netflix.hystrix.HystrixThreadPool} for monitoring, metrics publishing, caching, and other such uses. A {@link com.netflix.hystrix.HystrixCommand} is associated with a single {@link com.netflix.hystrix.HystrixThreadPool} as retrieved by the {@link com.netflix.hystrix.HystrixThreadPoolKey} injected into it, or it defaults to one created using the {@link com.netflix.hystrix.HystrixCommandGroupKey} it is created with. -

    @see com.netflix.hystrix.HystrixThreadPoolKey

    spring.sleuth.keys.message.headers

    Additional headers that should be added as tags if they exist. If the header + + @see com.netflix.hystrix.HystrixThreadPoolKey + +|spring.sleuth.keys.message.headers | | Additional headers that should be added as tags if they exist. If the header value is not a String it will be converted to a String using its toString() - method.

    spring.sleuth.keys.message.payload.size

    message/payload-size

    An estimate of the size of the payload if available.

    spring.sleuth.keys.message.payload.type

    message/payload-type

    The type of the payload.

    spring.sleuth.keys.message.prefix

    message/

    Prefix for header names if they are added as tags.

    spring.sleuth.metric.span.accepted-name

    counter.span.accepted

    spring.sleuth.metric.span.dropped-name

    counter.span.dropped

    spring.sleuth.sampler.percentage

    0.1

    Percentage of requests that should be sampled. E.g. 1.0 - 100% requests should be - sampled. The precision is whole-numbers only (i.e. there’s no support for 0.1% of - the traces).

    zuul.add-proxy-headers

    true

    zuul.host.max-per-route-connections

    20

    zuul.host.max-total-connections

    200

    zuul.ignore-local-service

    true

    zuul.ignored-headers

    zuul.ignored-patterns

    zuul.ignored-services

    zuul.prefix

    zuul.remove-semicolon-content

    true

    zuul.retryable

    zuul.routes

    zuul.security_headers

    zuul.servlet-path

    /zuul

    zuul.strip-prefix

    true

    zuul.trace-request-body

    true

    + method. + +|spring.sleuth.keys.message.payload.size | message/payload-size | An estimate of the size of the payload if available. + +|spring.sleuth.keys.message.payload.type | message/payload-type | The type of the payload. + +|spring.sleuth.keys.message.prefix | message/ | Prefix for header names if they are added as tags. + +|spring.sleuth.metric.span.accepted-name | counter.span.accepted | + +|spring.sleuth.metric.span.dropped-name | counter.span.dropped | + +|spring.sleuth.sampler.percentage | 0.1 | Percentage of requests that should be sampled. E.g. 1.0 - 100% requests should be + sampled. The precision is whole-numbers only (i.e. there's no support for 0.1% of + the traces). + +|zuul.add-proxy-headers | true | + +|zuul.host.max-per-route-connections | 20 | + +|zuul.host.max-total-connections | 200 | + +|zuul.ignore-local-service | true | + +|zuul.ignored-headers | | + +|zuul.ignored-patterns | | + +|zuul.ignored-services | | + +|zuul.prefix | | + +|zuul.remove-semicolon-content | true | + +|zuul.retryable | | + +|zuul.routes | | + +|zuul.security_headers | | + +|zuul.servlet-path | /zuul | + +|zuul.strip-prefix | true | + +|zuul.trace-request-body | true | + +|=== +
    +