From 2ba367b22edd20e84d4915e8253996958f1ca405 Mon Sep 17 00:00:00 2001 From: Ryan Baxter Date: Tue, 27 Feb 2018 12:03:35 -0500 Subject: [PATCH] Sync docs from vFinchley.M7 to gh-pages --- Finchley.M7/multi/multi__actuator_api.html | 3 + .../multi/multi__additional_resources.html | 2 +- ...addressing_all_instances_of_a_service.html | 2 +- .../multi/multi__addressing_an_instance.html | 2 +- .../multi/multi__apache_kafka_binder.html | 38 +- ...ompendium_of_configuration_properties.html | 4 +- .../multi/multi__binder_implementations.html | 2 +- Finchley.M7/multi/multi__binders.html | 18 +- .../multi__broadcasting_your_own_events.html | 6 +- ...ing_a_simple_gateway_using_spring_mvc.html | 19 + .../multi/multi__client_side_usage_2.html | 10 +- Finchley.M7/multi/multi__configuration_2.html | 45 + .../multi/multi__configuration_options.html | 26 +- ...entication_downstream_of_a_zuul_proxy.html | 4 +- Finchley.M7/multi/multi__contract_dsl.html | 62 +- Finchley.M7/multi/multi__current_span.html | 6 +- .../multi__current_tracing_component.html | 4 +- Finchley.M7/multi/multi__customization.html | 16 +- Finchley.M7/multi/multi__customizations.html | 10 +- ...multi__customizing_the_message_broker.html | 4 +- Finchley.M7/multi/multi__developer_guide.html | 3 + Finchley.M7/multi/multi__discovery.html | 4 +- Finchley.M7/multi/multi__features_2.html | 18 +- Finchley.M7/multi/multi__getting_started.html | 4 +- Finchley.M7/multi/multi__global_filters.html | 3 + Finchley.M7/multi/multi__glossary.html | 3 + .../multi/multi__health_indicator_5.html | 4 +- Finchley.M7/multi/multi__http_clients.html | 4 +- Finchley.M7/multi/multi__instrumentation.html | 4 +- Finchley.M7/multi/multi__integrations.html | 38 +- ...ulti__inter_application_communication.html | 8 +- ...ulti__introducing_spring_cloud_stream.html | 4 +- Finchley.M7/multi/multi__introduction.html | 22 +- Finchley.M7/multi/multi__links.html | 4 +- Finchley.M7/multi/multi__main_concepts.html | 26 +- ...ulti__managing_spans_with_annotations.html | 16 +- Finchley.M7/multi/multi__metrics_emitter.html | 4 +- Finchley.M7/multi/multi__migrations.html | 16 +- Finchley.M7/multi/multi__more_detail.html | 12 +- Finchley.M7/multi/multi__naming_spans.html | 8 +- .../multi/multi__programming_model.html | 16 +- Finchley.M7/multi/multi__propagation.html | 14 +- Finchley.M7/multi/multi__quick_start_2.html | 4 +- Finchley.M7/multi/multi__quick_start_3.html | 4 +- Finchley.M7/multi/multi__quickstart.html | 6 +- Finchley.M7/multi/multi__rabbitmq_binder.html | 32 +- .../multi/multi__running_examples.html | 2 +- Finchley.M7/multi/multi__samples.html | 2 +- Finchley.M7/multi/multi__sampling.html | 10 +- .../multi/multi__sending_spans_to_zipkin.html | 4 +- ...lti__service_discovery_eureka_clients.html | 2 +- .../multi__service_id_must_be_unique.html | 2 +- ...multi__service_registry_configuration.html | 4 +- .../multi/multi__single_sign_on_2.html | 4 +- Finchley.M7/multi/multi__span_lifecycle.html | 14 +- .../multi/multi__spring_cloud_bus.html | 2 +- .../multi/multi__spring_cloud_consul.html | 4 +- .../multi/multi__spring_cloud_contract.html | 4 +- .../multi/multi__spring_cloud_contract_2.html | 4 +- .../multi__spring_cloud_contract_faq.html | 34 +- ...ti__spring_cloud_contract_stub_runner.html | 48 +- ..._cloud_contract_verifier_introduction.html | 30 +- ...ing_cloud_contract_verifier_messaging.html | 18 +- ..._spring_cloud_contract_verifier_setup.html | 68 +- ...multi__spring_cloud_contract_wiremock.html | 20 +- ...multi__spring_cloud_for_cloud_foundry.html | 4 +- .../multi/multi__spring_cloud_gateway.html | 3 + .../multi/multi__spring_cloud_openfeign.html | 4 + .../multi/multi__spring_cloud_security.html | 4 +- .../multi/multi__spring_cloud_sleuth.html | 2 +- .../multi/multi__spring_cloud_stream.html | 4 +- .../multi/multi__spring_cloud_vault.html | 2 +- .../multi/multi__spring_cloud_zookeeper.html | 4 +- .../multi__stub_runner_for_messaging.html | 22 +- Finchley.M7/multi/multi__testing.html | 6 +- .../multi/multi__tracing_bus_events.html | 4 +- ...lti__using_the_pluggable_architecture.html | 22 +- .../multi__zipkin_stream_span_consumer.html | 4 +- .../multi/multi_contenttypemanagement.html | 16 +- .../multi/multi_gateway-how-it-works.html | 3 + ..._gateway-request-predicates-factories.html | 102 ++ .../multi/multi_gateway-route-filters.html | 183 +++ Finchley.M7/multi/multi_gateway-starter.html | 5 + Finchley.M7/multi/multi_schema-evolution.html | 28 +- .../multi_spring-cloud-consul-agent.html | 2 +- .../multi/multi_spring-cloud-consul-bus.html | 2 +- .../multi_spring-cloud-consul-config.html | 10 +- .../multi_spring-cloud-consul-discovery.html | 14 +- .../multi_spring-cloud-consul-hystrix.html | 2 +- .../multi_spring-cloud-consul-install.html | 2 +- .../multi_spring-cloud-consul-retry.html | 4 +- .../multi_spring-cloud-consul-turbine.html | 4 +- .../multi/multi_spring-cloud-feign.html | 199 +++ .../multi_spring-cloud-zookeeper-config.html | 8 +- ...i_spring-cloud-zookeeper-dependencies.html | 20 +- ...ng-cloud-zookeeper-dependency-watcher.html | 8 +- ...ulti_spring-cloud-zookeeper-discovery.html | 6 +- .../multi_spring-cloud-zookeeper-install.html | 2 +- .../multi_spring-cloud-zookeeper-netflix.html | 2 +- ...ring-cloud-zookeeper-service-registry.html | 4 +- Finchley.M7/multi/multi_spring-cloud.html | 2 +- .../multi/multi_vault-lease-renewal.html | 4 +- .../multi_vault.config.authentication.html | 58 +- ...ulti_vault.config.backends.configurer.html | 4 +- ...ult.config.backends.database-backends.html | 18 +- .../multi/multi_vault.config.backends.html | 16 +- .../multi/multi_vault.config.fail-fast.html | 4 +- Finchley.M7/multi/multi_vault.config.ssl.html | 4 +- Finchley.M7/single/spring-cloud.html | 1434 +++++++++++------ Finchley.M7/spring-cloud.xml | 1224 ++++++++++++++ 110 files changed, 3327 insertions(+), 992 deletions(-) create mode 100644 Finchley.M7/multi/multi__actuator_api.html create mode 100644 Finchley.M7/multi/multi__building_a_simple_gateway_using_spring_mvc.html create mode 100644 Finchley.M7/multi/multi__configuration_2.html create mode 100644 Finchley.M7/multi/multi__developer_guide.html create mode 100644 Finchley.M7/multi/multi__global_filters.html create mode 100644 Finchley.M7/multi/multi__glossary.html create mode 100644 Finchley.M7/multi/multi__spring_cloud_gateway.html create mode 100644 Finchley.M7/multi/multi__spring_cloud_openfeign.html create mode 100644 Finchley.M7/multi/multi_gateway-how-it-works.html create mode 100644 Finchley.M7/multi/multi_gateway-request-predicates-factories.html create mode 100644 Finchley.M7/multi/multi_gateway-route-filters.html create mode 100644 Finchley.M7/multi/multi_gateway-starter.html create mode 100644 Finchley.M7/multi/multi_spring-cloud-feign.html diff --git a/Finchley.M7/multi/multi__actuator_api.html b/Finchley.M7/multi/multi__actuator_api.html new file mode 100644 index 00000000..3169335d --- /dev/null +++ b/Finchley.M7/multi/multi__actuator_api.html @@ -0,0 +1,3 @@ + + + 112. Actuator API

112. Actuator API

TODO: document the /gateway actuator endpoint

\ No newline at end of file diff --git a/Finchley.M7/multi/multi__additional_resources.html b/Finchley.M7/multi/multi__additional_resources.html index 2c67845d..c49370a9 100644 --- a/Finchley.M7/multi/multi__additional_resources.html +++ b/Finchley.M7/multi/multi__additional_resources.html @@ -1,3 +1,3 @@ - 46. Additional resources

46. Additional resources

Marcin Grzejszczak talking about Spring Cloud Sleuth and Zipkin

click here to see the video

\ No newline at end of file + 47. Additional resources

47. Additional resources

Marcin Grzejszczak talking about Spring Cloud Sleuth and Zipkin

click here to see the video

\ No newline at end of file diff --git a/Finchley.M7/multi/multi__addressing_all_instances_of_a_service.html b/Finchley.M7/multi/multi__addressing_all_instances_of_a_service.html index 918b3a16..e5baa06a 100644 --- a/Finchley.M7/multi/multi__addressing_all_instances_of_a_service.html +++ b/Finchley.M7/multi/multi__addressing_all_instances_of_a_service.html @@ -1,3 +1,3 @@ - 40. Addressing all instances of a service

40. 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 rest of the service ID.

\ No newline at end of file + 41. Addressing all instances of a service

41. 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 rest of the service ID.

\ No newline at end of file diff --git a/Finchley.M7/multi/multi__addressing_an_instance.html b/Finchley.M7/multi/multi__addressing_an_instance.html index 09a08156..406e5ebc 100644 --- a/Finchley.M7/multi/multi__addressing_an_instance.html +++ b/Finchley.M7/multi/multi__addressing_an_instance.html @@ -1,3 +1,3 @@ - 39. Addressing an Instance

39. Addressing an Instance

Each instance of the application has a service ID, whose value can be set using spring.cloud.bus.id, and whose value is expected to be a colon-separated list of identifiers, in order of least specific to most specific. The default value is constructed from the environment as a combination of the spring.application.name and server.port (or spring.application.index if set). The default value of the ID is constructed in the form app:index:id where:

  • app is the vcap.application.name if it exists, or spring.application.name
  • index is the vcap.application.instance_index if it exists, or else spring.application.index, or else local.server.port (or server.port or 0).
  • id is the vcap.application.instance_id if it exists, or else a random value.

The HTTP endpoints accept a "destination" parameter, e.g. "/bus/refresh?destination=customers:9000", where the destination is a service 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.

\ No newline at end of file + 40. Addressing an Instance

40. Addressing an Instance

Each instance of the application has a service ID, whose value can be set using spring.cloud.bus.id, and whose value is expected to be a colon-separated list of identifiers, in order of least specific to most specific. The default value is constructed from the environment as a combination of the spring.application.name and server.port (or spring.application.index if set). The default value of the ID is constructed in the form app:index:id where:

  • app is the vcap.application.name if it exists, or spring.application.name
  • index is the vcap.application.instance_index if it exists, or else spring.application.index, or else local.server.port (or server.port or 0).
  • id is the vcap.application.instance_id if it exists, or else a random value.

The HTTP endpoints accept a "destination" parameter, e.g. "/bus/refresh?destination=customers:9000", where the destination is a service 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.

\ No newline at end of file diff --git a/Finchley.M7/multi/multi__apache_kafka_binder.html b/Finchley.M7/multi/multi__apache_kafka_binder.html index 0995c930..05fb1ee3 100644 --- a/Finchley.M7/multi/multi__apache_kafka_binder.html +++ b/Finchley.M7/multi/multi__apache_kafka_binder.html @@ -1,14 +1,14 @@ - 36. Apache Kafka Binder

36. Apache Kafka Binder

36.1 Usage

For using the Apache Kafka binder, you just need to add it to your Spring Cloud Stream application, using the following Maven coordinates:

<dependency>
+   37. Apache Kafka Binder

37. Apache Kafka Binder

37.1 Usage

For using the Apache Kafka binder, you just need to add it to your Spring Cloud Stream application, using the following Maven coordinates:

<dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-stream-binder-kafka</artifactId>
 </dependency>

Alternatively, you can also use the Spring Cloud Stream Kafka Starter.

<dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-starter-stream-kafka</artifactId>
-</dependency>

36.2 Apache Kafka Binder Overview

A simplified diagram of how the Apache Kafka binder operates can be seen below.

Figure 36.1. Kafka Binder

kafka binder

The Apache Kafka Binder implementation maps each destination to an Apache Kafka topic. +</dependency>

37.2 Apache Kafka Binder Overview

A simplified diagram of how the Apache Kafka binder operates can be seen below.

Figure 37.1. Kafka Binder

kafka binder

The Apache Kafka Binder implementation maps each destination to an Apache Kafka topic. The consumer group maps directly to the same Apache Kafka concept. -Partitioning also maps directly to Apache Kafka partitions as well.

36.3 Configuration Options

This section contains the configuration options used by the Apache Kafka binder.

For common configuration options and properties pertaining to binder, refer to the core documentation.

36.3.1 Kafka Binder Properties

spring.cloud.stream.kafka.binder.brokers

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

Default: localhost.

spring.cloud.stream.kafka.binder.defaultBrokerPort

brokers allows hosts specified with or without port information (e.g., host1,host2:port2). +Partitioning also maps directly to Apache Kafka partitions as well.

37.3 Configuration Options

This section contains the configuration options used by the Apache Kafka binder.

For common configuration options and properties pertaining to binder, refer to the core documentation.

37.3.1 Kafka Binder Properties

spring.cloud.stream.kafka.binder.brokers

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

Default: localhost.

spring.cloud.stream.kafka.binder.defaultBrokerPort

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 to which the Kafka binder can connect.

Default: localhost.

spring.cloud.stream.kafka.binder.defaultZkPort

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.configuration

Key/Value map of client properties (both producers and consumer) passed to all clients created by the binder. Due to the fact that these properties will be used by both producers and consumers, usage should be restricted to common properties, especially security settings.

Default: Empty map.

spring.cloud.stream.kafka.binder.headers

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

Default: empty.

spring.cloud.stream.kafka.binder.healthTimeout

The time to wait to get partition information in seconds; default 60. @@ -24,7 +24,7 @@ Of note, this setting is independent of the auto.topic.cre If set to false, the binder will rely on the partition size of the topic being already configured. If the partition count of the target topic is smaller than the expected value, the binder will fail to start.

Default: false.

spring.cloud.stream.kafka.binder.socketBufferSize

Size (in bytes) of the socket buffer to be used by the Kafka consumers.

Default: 2097152.

spring.cloud.stream.kafka.binder.transaction.transactionIdPrefix

Enable transactions in the binder; see transaction.id in the Kafka documentation and Transactions in the spring-kafka documentation. When transactions are enabled, individual producer properties are ignored and all producers use the spring.cloud.stream.kafka.binder.transaction.producer.* properties.

Default null (no transactions)

spring.cloud.stream.kafka.binder.transaction.producer.*

Global producer properties for producers in a transactional binder. -See spring.cloud.stream.kafka.binder.transaction.transactionIdPrefix and Section 36.3.3, “Kafka Producer Properties” and the general producer properties supported by all binders.

Default: See individual producer properties.

36.3.2 Kafka Consumer Properties

The following properties are available for Kafka consumers only and +See spring.cloud.stream.kafka.binder.transaction.transactionIdPrefix and Section 37.3.3, “Kafka Producer Properties” and the general producer properties supported by all binders.

Default: See individual producer properties.

37.3.2 Kafka Consumer Properties

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

autoRebalanceEnabled

When true, topic partitions will be automatically rebalanced between the members of a consumer group. When false, each consumer will be assigned a fixed set of partitions based on spring.cloud.stream.instanceCount and spring.cloud.stream.instanceIndex. This requires both spring.cloud.stream.instanceCount and spring.cloud.stream.instanceIndex properties to be set appropriately on each launched instance. @@ -41,13 +41,13 @@ If the consumer group is set explicitly for the consumer 'binding' (via error.<destination>.<group>. The DLQ topic name can be configurable via the property dlqName. This provides an alternative option to the more common Kafka replay scenario for the case when the number of errors is relatively small and replaying the entire original topic may be too cumbersome. -See Section 36.6, “Dead-Letter Topic Processing” processing for more information. +See Section 37.6, “Dead-Letter Topic Processing” processing for more information. Starting with version 2.0, messages sent to the DLQ topic are enhanced with the following headers: x-original-topic, x-exception-message and x-exception-stacktrace as byte[].

Default: false.

configuration

Map with a key/value pair containing generic Kafka consumer properties.

Default: Empty map.

dlqName

The name of the DLQ topic to receive the error messages.

Default: null (If not specified, messages that result in errors will be forwarded to a topic named error.<destination>.<group>).

dlqProducerProperties

Using this, dlq specific producer properties can be set. All the properties available through kafka producer properties can be set through this property.

Default: Default Kafka producer properties.

standardHeaders

Indicates which standard headers are populated by the inbound channel adapter. none, id, timestamp or both. Useful if using native deserialization and the first component to receive a message needs an id (such as an aggregator that is configured to use a JDBC message store).

Default: none

converterBeanName

The name of a bean that implements RecordMessageConverter; used in the inbound channel adapter to replace the default MessagingMessageConverter.

Default: null

idleEventInterval

The interval, in milliseconds between events indicating that no messages have recently been received. Use an ApplicationListener<ListenerContainerIdleEvent> to receive these events. -See the section called “Example: Pausing and Resuming the Consumer” for a usage example.

Default: 30000

36.3.3 Kafka Producer Properties

The following properties are available for Kafka producers only and +See the section called “Example: Pausing and Resuming the Consumer” for a usage example.

Default: 30000

37.3.3 Kafka Producer Properties

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

bufferSize

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.

Default: false.

batchTimeout

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.

messageKeyExpression

A SpEL expression evaluated against the outgoing message used to populate the key of the produced Kafka message. For example headers.key or payload.myKey.

Default: none.

headerPatterns

A comma-delimited list of simple patterns to match spring-messaging headers to be mapped to the kafka Headers in the ProducerRecord. @@ -58,7 +58,7 @@ For example !foo,fo* will pass minPartitionCount for a binder and partitionCount for an application, as the larger value will be used. If a topic already exists with a smaller partition count and autoAddPartitions is disabled (the default), then the binder will fail to start. If a topic already exists with a smaller partition count and autoAddPartitions is enabled, new partitions will be added. -If a topic already exists with a larger number of partitions than the maximum of (minPartitionCount and partitionCount), the existing partition count will be used.

36.3.4 Usage examples

In this section, we illustrate the use of the above properties for specific scenarios.

Example: Setting autoCommitOffset false and relying on manual acking.

This example illustrates how one may manually acknowledge offsets in a consumer application.

This example requires that spring.cloud.stream.kafka.bindings.input.consumer.autoCommitOffset is set to false. +If a topic already exists with a larger number of partitions than the maximum of (minPartitionCount and partitionCount), the existing partition count will be used.

37.3.4 Usage examples

In this section, we illustrate the use of the above properties for specific scenarios.

Example: Setting autoCommitOffset false and relying on manual acking.

This example illustrates how one may manually acknowledge offsets in a consumer application.

This example requires that spring.cloud.stream.kafka.bindings.input.consumer.autoCommitOffset is set to false. Use the corresponding input channel name for your example.

@SpringBootApplication
 @EnableBinding(Sink.class)
 public class ManuallyAcknowdledgingConsumer {
@@ -182,10 +182,10 @@ If you use the default Kafka version, then ensure that you exclude the kafka bro
   </exclusions>
 </dependency>

If you exclude the Apache Kafka server dependency and the topic is not present on the server, then the Apache Kafka broker will create the topic if auto topic creation is enabled on the server. Please keep in mind that if you are relying on this, then the Kafka server will use the default number of partitions and replication factors. -On the other hand, if auto topic creation is disabled on the server, then care must be taken before running the application to create the topic with the desired number of partitions.

If you want to have full control over how partitions are allocated, then leave the default settings as they are, i.e. do not exclude the kafka broker jar and ensure that spring.cloud.stream.kafka.binder.autoCreateTopics is set to true, which is the default.

36.4 Error Channels

Starting with version 1.3, the binder unconditionally sends exceptions to an error channel for each consumer destination, and can be configured to send async producer send failures to an error channel too. -See the section called “Message Channel Binders and Error Channels” for more information.

The payload of the ErrorMessage for a send failure is a KafkaSendFailureException with properties:

  • failedMessage - the spring-messaging Message<?> that failed to be sent.
  • record - the raw ProducerRecord that was created from the failedMessage

There is no automatic handling of producer exceptions (such as sending to a Dead-Letter queue); you can consume these exceptions with your own Spring Integration flow.

36.5 Kafka Metrics

Kafka binder module exposes the following metrics:

spring.cloud.stream.binder.kafka.someGroup.someTopic.lag - this metric indicates how many messages have not been yet consumed from given binder’s topic by given consumer group. +On the other hand, if auto topic creation is disabled on the server, then care must be taken before running the application to create the topic with the desired number of partitions.

If you want to have full control over how partitions are allocated, then leave the default settings as they are, i.e. do not exclude the kafka broker jar and ensure that spring.cloud.stream.kafka.binder.autoCreateTopics is set to true, which is the default.

37.4 Error Channels

Starting with version 1.3, the binder unconditionally sends exceptions to an error channel for each consumer destination, and can be configured to send async producer send failures to an error channel too. +See the section called “Message Channel Binders and Error Channels” for more information.

The payload of the ErrorMessage for a send failure is a KafkaSendFailureException with properties:

  • failedMessage - the spring-messaging Message<?> that failed to be sent.
  • record - the raw ProducerRecord that was created from the failedMessage

There is no automatic handling of producer exceptions (such as sending to a Dead-Letter queue); you can consume these exceptions with your own Spring Integration flow.

37.5 Kafka Metrics

Kafka binder module exposes the following metrics:

spring.cloud.stream.binder.kafka.someGroup.someTopic.lag - this metric indicates how many messages have not been yet consumed from given binder’s topic by given consumer group. For example if the value of the metric spring.cloud.stream.binder.kafka.myGroup.myTopic.lag is 1000, then consumer group myGroup has 1000 messages to waiting to be consumed from topic myTopic. -This metric is particularly useful to provide auto-scaling feedback to PaaS platform of your choice.

36.6 Dead-Letter Topic Processing

Because it can’t be anticipated how users would want to dispose of dead-lettered messages, the framework does not provide any standard mechanism to handle them. +This metric is particularly useful to provide auto-scaling feedback to PaaS platform of your choice.

37.6 Dead-Letter Topic Processing

Because it can’t be anticipated how users would want to dispose of dead-lettered messages, the framework does not provide any standard mechanism to handle them. If the reason for the dead-lettering is transient, you may wish to route the messages back to the original topic. However, if the problem is a permanent issue, that could cause an infinite loop. The following spring-boot application is an example of how to route those messages back to the original topic, but moves them to a third "parking lot" topic after three attempts. @@ -272,7 +272,7 @@ spring.cloud.stream.kafka.binder.headers=x-retries

} }

-

36.7 Partitioning with the Kafka Binder

Apache Kafka supports topic partitioning natively.

Sometimes it is advantageous to send data to specific partitions, for example when you want to strictly order message processing - all messages for a particular customer should go to the same partition.

The following illustrates how to configure the producer and consumer side:

@SpringBootApplication
+

37.7 Partitioning with the Kafka Binder

Apache Kafka supports topic partitioning natively.

Sometimes it is advantageous to send data to specific partitions, for example when you want to strictly order message processing - all messages for a particular customer should go to the same partition.

The following illustrates how to configure the producer and consumer side:

@SpringBootApplication
 @EnableBinding(Source.class)
 public class KafkaPartitionProducerApplication {
 
@@ -339,7 +339,7 @@ Kafka will allocate partitions across the instances.

          destination: partitioned.topic
           group: myGroup

You can add instances as needed; Kafka will rebalance the partition allocations. -If the instance count (or instance count * concurrency) exceeds the number of partitions, some consumers will be idle.

36.8 Kafka Streams Binding Capabilities of Spring Cloud Stream

Spring Cloud Stream Kafka support also includes a binder specifically designed for Apache Kafka Streams binding. +If the instance count (or instance count * concurrency) exceeds the number of partitions, some consumers will be idle.

37.8 Kafka Streams Binding Capabilities of Spring Cloud Stream

Spring Cloud Stream Kafka support also includes a binder specifically designed for Apache Kafka Streams binding. Using this binder, applications can be written that leverage the Apache Kafka Streams API. For more information on Kafka Streams, see Kafka Streams API Developer Manual

Kafka Streams support in Spring Cloud Stream is based on the foundations provided by the Spring Kafka project. For details on that support, see Kafaka Streams Support in Spring Kafka.

Here are the maven coordinates for the Spring Cloud Stream Kafka Streams binder artifact.

<dependency>
@@ -347,7 +347,7 @@ For details on that support, see <artifactId>spring-cloud-stream-binder-kafka-streams</artifactId>
 </dependency>

High level streams DSL provided through the Kafka Streams API can be used through Spring Cloud Stream support. Some minimal support for writing applications using the processor API is also available through the binder. -Kafka Streams applications using the Spring Cloud Stream support can be written using the processor model, i.e. messages read from an inbound topic and messages written to an outbound topic or using the sink style where it does not have an output binding.

36.8.1 Usage example of high level streams DSL

This application will listen from a Kafka topic and write the word count for each unique word that it sees in a 5 seconds time window.

@SpringBootApplication
+Kafka Streams applications using the Spring Cloud Stream support can be written using the processor model, i.e. messages read from an inbound topic and messages written to an outbound topic or using the sink style where it does not have an output binding.

37.8.1 Usage example of high level streams DSL

This application will listen from a Kafka topic and write the word count for each unique word that it sees in a 5 seconds time window.

@SpringBootApplication
 @EnableBinding(KStreamProcessor.class)
 public class WordCountProcessorApplication {
 
@@ -367,7 +367,7 @@ public class WordCountProcessorApplication {
 		SpringApplication.run(WordCountProcessorApplication.class, args);
 	}

If you build it as a Spring Boot uber jar, you can run the above example in the following way:

java -jar uber.jar  --spring.cloud.stream.bindings.input.destination=words --spring.cloud.stream.bindings.output.destination=counts

This means that the application will listen from the incoming Kafka topic words and write to the output topic counts.

Spring Cloud Stream will ensure that the messages from both the incoming and outgoing topics are bound as KStream objects. Applications can exclusively focus on the business aspects of the code, i.e. writing the logic required in the processor rather than setting up the streams specific configuration required by the Kafka Streams infrastructure. -All such infrastructure details are handled by the framework.

36.8.2 Multiple Input bindings on the inbound

Spring Cloud Stream Kafka Streams binder allows the users to write applications with multiple bindings. +All such infrastructure details are handled by the framework.

37.8.2 Multiple Input bindings on the inbound

Spring Cloud Stream Kafka Streams binder allows the users to write applications with multiple bindings. There are use cases in which you may want to have multiple incoming KStream objects or a combination of KStream and KTable objects. Both of these flavors are supported. Here are some examples.

@EnableBinding(KStreamKTableBinding.class)
@@ -404,7 +404,7 @@ interface KStreamKTableBinding extends KafkaStreamsProcessor {
 
     @Input("inputX")
     KTable<?, ?> inputTable();
-}

36.8.3 Support for branching in Kafka Streams API

Kafka Streams allow outbound data to be split into multiple topics based on some predicates. +}

37.8.3 Support for branching in Kafka Streams API

Kafka Streams allow outbound data to be split into multiple topics based on some predicates. Spring Cloud Stream Kafka Streams binder provides support for this feature without losing the overall programming model exposed through StreamListener in the end user application. You write the application in the usual way as demonstrated above in the word count example. When using the branching feature, you are required to do a few things. @@ -471,7 +471,7 @@ spring.cloud.stream.bindings.output3: spring.cloud.stream.bindings.input: destination: words consumer: - headerMode: raw

36.8.4 Message conversion in Spring Cloud Stream Kafka Streams applications

Spring Cloud Stream Kafka Streams binder allows the usage of usual patterns for content type conversions as in other message channel based binder applications. + headerMode: raw

37.8.4 Message conversion in Spring Cloud Stream Kafka Streams applications

Spring Cloud Stream Kafka Streams binder allows the usage of usual patterns for content type conversions as in other message channel based binder applications. Many Kafka Streams operations - that are part of the actual application and not at the inbound and outbound - need to know the type of SerDe’s used to correctly transform key and value data. Therefore, it may be more natural to rely on the SerDe facilities provided by the Apache Kafka Streams library itself for inbound and outbound conversions rather than using the content type conversions offered by the framework. On the other hand, you might be already familiar with the content type conversion patterns in spring cloud stream and want to keep using them for inbound and outbound conversions. @@ -548,12 +548,12 @@ public KStream<?, WordCount> process(KStream<Object, String> input) ..... ..... }); -}

36.8.5 Support for interactive queries

As part of the public API of the binder, it now exposes a class called QueryableStoreRegistry. +}

37.8.5 Support for interactive queries

As part of the public API of the binder, it now exposes a class called QueryableStoreRegistry. You can access this as a Spring bean in your application. One easy way to get access to this bean from your application is to autowire the bean as below.

@Autowired
 private QueryableStoreRegistry queryableStoreRegistry;

Once you gain access to this bean, then you can find out the particular state store that you are interested in. Here is an example:

ReadOnlyKeyValueStore<Object, Object> keyValueStore =
-						queryableStoreRegistry.getQueryableStoreType("my-store", QueryableStoreTypes.keyValueStore());

Then you can retrieve the data that you stored in this store during the execution of your application.

36.8.6 Kafka Streams properties

We covered all the relevant properties that you need when writing Kafka Streams applications using Spring Cloud Stream, scattered in the above sections, but here they are again.

The following properties are available at the binder level and must be prefixed with spring.cloud.stream.kafka.binder..

configuration
Map with a key/value pair containing properties pertaining to Apache Kafka Streams API. + queryableStoreRegistry.getQueryableStoreType("my-store", QueryableStoreTypes.keyValueStore());

Then you can retrieve the data that you stored in this store during the execution of your application.

37.8.6 Kafka Streams properties

We covered all the relevant properties that you need when writing Kafka Streams applications using Spring Cloud Stream, scattered in the above sections, but here they are again.

The following properties are available at the binder level and must be prefixed with spring.cloud.stream.kafka.binder..

configuration
Map with a key/value pair containing properties pertaining to Apache Kafka Streams API. This property must be prefixed with spring.cloud.stream.kafka.streams.binder.. Following are some examples of using this property.
spring.cloud.stream.kafka.streams.binder.configuration.default.key.serde=org.apache.kafka.common.serialization.Serdes$StringSerde
 spring.cloud.stream.kafka.streams.binder.configuration.default.value.serde=org.apache.kafka.common.serialization.Serdes$StringSerde
@@ -563,4 +563,4 @@ You can override the application id for an individual Stre
 You have to ensure that you are using the same group name for all input bindings in the case of multiple inputs on the same methods.

Default: default

The following properties are available for Kafka Streams producers only and must be prefixed with spring.cloud.stream.kafka.streams.bindings.<binding name>.producer..

keySerde

key serde to use

Default: none.

valueSerde

value serde to use

Default: none.

useNativeEncoding

flag to enable native encoding

Default: false.

The following properties are available for Kafka Streams consumers only and must be prefixed with spring.cloud.stream.kafka.streams.bindings.<binding name>.consumer..

keySerde

key serde to use

Default: none.

valueSerde

value serde to use

Default: none.

materializedAs

state store to materialize when using incoming KTable types

Default: none.

useNativeDecoding

flag to enable native decoding

Default: false.

dlqName

DLQ topic name.

Default: none.

Other common properties used from core Spring Cloud Stream.

spring.cloud.stream.bindings.<binding name>.destination
 spring.cloud.stream.bindings.<binding name>.group

TimeWindow properties:

Windowing is an important concept in stream processing applications. Following properties are available for configuring time windows.

spring.cloud.stream.kafka.streams.timeWindow.length

When this property is given, you can autowire a TimeWindows bean into the application. -The value is expressed in milliseconds.

Default: none.

spring.cloud.stream.kstream.timeWindow.advanceBy

Value is given in milliseconds.

Default: none.

\ No newline at end of file +The value is expressed in milliseconds.

Default: none.

spring.cloud.stream.kstream.timeWindow.advanceBy

Value is given in milliseconds.

Default: none.

\ No newline at end of file diff --git a/Finchley.M7/multi/multi__appendix_compendium_of_configuration_properties.html b/Finchley.M7/multi/multi__appendix_compendium_of_configuration_properties.html index dd7e9446..5b4a3062 100644 --- a/Finchley.M7/multi/multi__appendix_compendium_of_configuration_properties.html +++ b/Finchley.M7/multi/multi__appendix_compendium_of_configuration_properties.html @@ -1,6 +1,6 @@ - Part XIV. Appendix: Compendium of Configuration Properties

Part XIV. 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 + Part XVI. Appendix: Compendium of Configuration Properties

Part XVI. 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 @@ -264,4 +264,4 @@ proxy, so they are sharing authentication data. If using a physical URL outside your own domain, then generally it would be a bad idea to leak user credentials.

zuul.servlet-path

/zuul

Path to install Zuul as a servlet (not part of Spring MVC). The servlet is more memory efficient for requests with large bodies, e.g. file uploads.

zuul.ssl-hostname-validation-enabled

true

Flag to say whether the hostname for ssl connections should be verified or not. Default is true. - This should only be used in test setups!

zuul.strip-prefix

true

Flag saying whether to strip the prefix from the path before forwarding.

zuul.trace-request-body

true

Flag to say that request bodies can be traced.

\ No newline at end of file + This should only be used in test setups!

zuul.strip-prefix

true

Flag saying whether to strip the prefix from the path before forwarding.

zuul.trace-request-body

true

Flag to say that request bodies can be traced.

\ No newline at end of file diff --git a/Finchley.M7/multi/multi__binder_implementations.html b/Finchley.M7/multi/multi__binder_implementations.html index 8fc51a7b..7cbd3046 100644 --- a/Finchley.M7/multi/multi__binder_implementations.html +++ b/Finchley.M7/multi/multi__binder_implementations.html @@ -1,3 +1,3 @@ - Part V. Binder Implementations

Part V. Binder Implementations

\ No newline at end of file + Part VI. Binder Implementations

Part VI. Binder Implementations

\ No newline at end of file diff --git a/Finchley.M7/multi/multi__binders.html b/Finchley.M7/multi/multi__binders.html index a266ad12..bca434cd 100644 --- a/Finchley.M7/multi/multi__binders.html +++ b/Finchley.M7/multi/multi__binders.html @@ -1,29 +1,29 @@ - 26. Binders

26. Binders

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

26.1 Producers and Consumers

Figure 26.1. Producers and Consumers

producers consumers

A producer is any component that sends messages to a channel. + 27. Binders

27. Binders

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

27.1 Producers and Consumers

Figure 27.1. Producers and Consumers

producers consumers

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 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).

26.2 Binder SPI

The Binder SPI consists of a number of interfaces, out-of-the box utility classes and discovery strategies that provide a pluggable mechanism for connecting to external middleware.

The key point of the SPI is the Binder interface which is a strategy for connecting inputs and outputs to external middleware.

public interface Binder<T, C extends ConsumerProperties, P extends ProducerProperties> {
+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).

27.2 Binder SPI

The Binder SPI consists of a number of interfaces, out-of-the box utility classes and discovery strategies that provide a pluggable mechanism for connecting to external middleware.

The key point of the SPI is the Binder interface which is a strategy for connecting inputs and outputs to external middleware.

public interface Binder<T, C extends ConsumerProperties, P extends ProducerProperties> {
     Binding<T> bindConsumer(String name, String group, T inboundBindTarget, C consumerProperties);
 
     Binding<T> bindProducer(String name, T outboundBindTarget, P producerProperties);
 }

The interface is parameterized, offering a number of extension points:

  • input and output bind targets - as of version 1.0, only MessageChannel is supported, but this is intended to be used as an extension point in the future;
  • extended consumer and producer properties - allowing specific Binder implementations to add supplemental properties which can be supported in a type-safe manner.

A typical binder implementation consists of the following

  • a class that implements the Binder interface;
  • a Spring @Configuration class that creates a bean of the type above along with the middleware connection infrastructure;
  • a META-INF/spring.binders file found on the classpath containing one or more binder definitions, e.g.
kafka:\
-org.springframework.cloud.stream.binder.kafka.config.KafkaBinderConfiguration

26.3 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.

26.3.1 Classpath Detection

By default, Spring Cloud Stream relies on Spring Boot’s auto-configuration to configure the binding process. +org.springframework.cloud.stream.binder.kafka.config.KafkaBinderConfiguration

27.3 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.

27.3.1 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. For example, a Spring Cloud Stream project that aims to bind only to RabbitMQ can simply add the following dependency:

<dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-stream-binder-rabbit</artifactId>
-</dependency>

For the specific maven coordinates of other binder dependencies, please refer to the documentation of that binder implementation.

26.4 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. +</dependency>

For the specific maven coordinates of other binder dependencies, please refer to the documentation of that binder implementation.

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

rabbit:\
 org.springframework.cloud.stream.binder.rabbit.config.RabbitServiceAutoConfiguration

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.

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 (that has channels with the names input and output for read/write respectively) 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

26.5 Connecting to Multiple Systems

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. +spring.cloud.stream.bindings.output.binder=rabbit

27.5 Connecting to Multiple Systems

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]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. Frameworks that intend to use Spring Cloud Stream transparently may create binder configurations that can be referenced by name, but will not affect the default binder configuration. @@ -50,9 +50,9 @@ This denotes a configuration that will exist independently of the default binder environment: spring: rabbitmq: - host: <host2>

26.6 Binder configuration properties

The following properties are available when creating custom binder configurations. + host: <host2>

27.6 Binder configuration properties

The following properties are available when creating custom binder configurations. They must be prefixed with spring.cloud.stream.binders.<configurationName>.

type

The binder type. It typically references one of the binders found on the classpath, in particular a key in a META-INF/spring.binders file.

By default, it has the same value as the configuration name.

inheritEnvironment

Whether the configuration will inherit the environment of the application itself.

Default true.

environment

Root for a set of properties that can be used to customize the environment of the binder. When this is configured, the context in which the binder is being created is not a child of the application context. This allows for complete separation between the binder components and the application components.

Default empty.

defaultCandidate

Whether the binder configuration is a candidate for being considered a default binder, or can be used only when explicitly referenced. -This allows adding binder configurations without interfering with the default processing.

Default true.

\ No newline at end of file +This allows adding binder configurations without interfering with the default processing.

Default true.

\ No newline at end of file diff --git a/Finchley.M7/multi/multi__broadcasting_your_own_events.html b/Finchley.M7/multi/multi__broadcasting_your_own_events.html index 4c81378e..717b3063 100644 --- a/Finchley.M7/multi/multi__broadcasting_your_own_events.html +++ b/Finchley.M7/multi/multi__broadcasting_your_own_events.html @@ -1,12 +1,12 @@ - 44. Broadcasting Your Own Events

44. Broadcasting Your Own Events

The Bus can carry any event of type RemoteApplicationEvent, but the + 45. Broadcasting Your Own Events

45. 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 it needs to be in a subpackage of org.springframework.cloud.bus.event.

To customise the event name you can use @JsonTypeName on your custom class or rely on the default strategy which is to use the simple name of the class. Note that both the producer and the consumer will need access to the class -definition.

44.1 Registering events in custom packages

If you cannot or don’t want to use a subpackage of org.springframework.cloud.bus.event +definition.

45.1 Registering events in custom packages

If you cannot or don’t want to use a subpackage of org.springframework.cloud.bus.event for your custom events, you must specify which packages to scan for events of type RemoteApplicationEvent using @RemoteApplicationEventScan. Packages specified with @RemoteApplicationEventScan include subpackages.

For example, if you have a custom event called FooEvent:

package com.acme;
@@ -33,4 +33,4 @@ package of BusConfiguration.

You can also exp }

All examples of @RemoteApplicationEventScan above are equivalent, in that the com.acme package will be registered by explicitly specifying the packages on @RemoteApplicationEventScan. Note, you can specify multiple base -packages to scan.

\ No newline at end of file +packages to scan.

\ No newline at end of file diff --git a/Finchley.M7/multi/multi__building_a_simple_gateway_using_spring_mvc.html b/Finchley.M7/multi/multi__building_a_simple_gateway_using_spring_mvc.html new file mode 100644 index 00000000..0ed4f990 --- /dev/null +++ b/Finchley.M7/multi/multi__building_a_simple_gateway_using_spring_mvc.html @@ -0,0 +1,19 @@ + + + 114. Building a Simple Gateway Using Spring MVC

114. Building a Simple Gateway Using Spring MVC

Spring Cloud Gateway provides a utility object called ProxyExchange which you can use inside a regular Spring MVC handler as a method parameter. It supports basic downstream HTTP exchanges via methods that mirror the HTTP verbs, or forwarding to a local handler via the forward() method.

Example (proxying a request to "/test" downstream to a remote server):

@RestController
+@SpringBootApplication
+public class GatewaySampleApplication {
+
+	@Value("${remote.home}")
+	private URI home;
+
+	@GetMapping("/test")
+	public ResponseEntity<?> proxy(ProxyExchange<Object> proxy) throws Exception {
+		return proxy.uri(home.toString() + "/image/png").get();
+	}
+
+}

There are convenience methods on the ProxyExchange to enable the handler method to discover and enhance the URI path of the incoming request. For example you might want to extract the trailing elements of a path to pass them downstream:

@GetMapping("/proxy/path/**")
+public ResponseEntity<?> proxyPath(ProxyExchange<?> proxy) throws Exception {
+  String path = proxy.path("/proxy/path/");
+  return proxy.uri(home.toString() + "/foos/" + path).get();
+}

All the features of Spring MVC are available to Gateway handler methods. So you can inject request headers and query parameters, for instance, and you can constrain the incoming requests with declarations in the mapping annotation. See the documentation for @RequestMapping in Spring MVC for more details of those features.

Headers can be added to the downstream response using the header() methods on ProxyExchange.

You can also manipulate response headers (and anything else you like in the response) by adding a mapper to the get() etc. method. The mapper is a Function that takes the incoming ResponseEntity and converts it to an outgoing one.

First class support is provided for "sensitive" headers ("cookie" and "authorization" by default) which are not passed downstream, and for "proxy" headers (x-forwarded-*).

\ No newline at end of file diff --git a/Finchley.M7/multi/multi__client_side_usage_2.html b/Finchley.M7/multi/multi__client_side_usage_2.html index 4d506416..cde834db 100644 --- a/Finchley.M7/multi/multi__client_side_usage_2.html +++ b/Finchley.M7/multi/multi__client_side_usage_2.html @@ -1,8 +1,8 @@ - 95. Client Side Usage

95. Client Side Usage

To use these features in an application, just build it as a Spring + 96. Client Side Usage

96. Client Side Usage

To use these features in an application, just build it as a Spring Boot application that depends on spring-cloud-vault-config (e.g. see -the test cases). Example Maven configuration:

Example 95.1. pom.xml

<parent>
+the test cases). Example Maven configuration:

Example 96.1. pom.xml

<parent>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-parent</artifactId>
     <version>1.5.4.RELEASE</version>
@@ -47,7 +47,7 @@ the test cases). Example Maven configuration:

8200 if it is running. To modify the startup behavior you can change the location of the Vault server using bootstrap.properties (like application.properties but for -the bootstrap phase of an application context), e.g.

Example 95.2. bootstrap.yml

spring.cloud.vault:
+the bootstrap phase of an application context), e.g.

Example 96.2. bootstrap.yml

spring.cloud.vault:
     host: localhost
     port: 8200
     scheme: https
@@ -63,5 +63,5 @@ additional configuration like
 SSL and
 authentication.

If the application imports the spring-boot-starter-actuator project, the status of the vault server will be available via the /health endpoint.

The vault health indicator can be enabled or disabled through the -property health.vault.enabled (default true).

95.1 Authentication

Vault requires an authentication mechanism to authorize client requests.

Spring Cloud Vault supports multiple authentication mechanisms to authenticate applications with Vault.

For a quickstart, use the root token printed by the Vault initialization.

Example 95.3. bootstrap.yml

spring.cloud.vault:
-    token: 19aefa97-cccc-bbbb-aaaa-225940e63d76

[Warning]Warning

Consider carefully your security requirements. Static token authentication is fine if you want quickly get started with Vault, but a static token is not protected any further. Any disclosure to unintended parties allows Vault use with the associated token roles.

\ No newline at end of file +property health.vault.enabled (default true).

96.1 Authentication

Vault requires an authentication mechanism to authorize client requests.

Spring Cloud Vault supports multiple authentication mechanisms to authenticate applications with Vault.

For a quickstart, use the root token printed by the Vault initialization.

Example 96.3. bootstrap.yml

spring.cloud.vault:
+    token: 19aefa97-cccc-bbbb-aaaa-225940e63d76

[Warning]Warning

Consider carefully your security requirements. Static token authentication is fine if you want quickly get started with Vault, but a static token is not protected any further. Any disclosure to unintended parties allows Vault use with the associated token roles.

\ No newline at end of file diff --git a/Finchley.M7/multi/multi__configuration_2.html b/Finchley.M7/multi/multi__configuration_2.html new file mode 100644 index 00000000..aca875c7 --- /dev/null +++ b/Finchley.M7/multi/multi__configuration_2.html @@ -0,0 +1,45 @@ + + + 111. Configuration

111. Configuration

Configuration for Spring Cloud Gateway is driven by a collection of `RouteDefinitionLocator`s.

RouteDefinitionLocator.java.  +

public interface RouteDefinitionLocator {
+	Flux<RouteDefinition> getRouteDefinitions();
+}

+

By default, a PropertiesRouteDefinitionLocator loads properties using Spring Boot’s @ConfigurationProperties mechanism.

The configuration examples above all use a shortcut notation that uses positional arguments rather than named ones. The two examples below are equivalent:

application.yml.  +

spring:
+  cloud:
+    gateway:
+      routes:
+      - id: setstatus_route
+        uri: http://example.org
+        filters:
+        - name: SetStatus
+          args:
+            status: 401
+      - id: setstatusshortcut_route
+        uri: http://example.org
+        filters:
+        - SetStatus=401

+

For some usages of the gateway, properties will be adequate, but some production use cases will benefit from loading configuration from an external source, such as a database. Future milestone versions will have RouteDefinitionLocator implementations based off of Spring Data Repositories such as: Redis, MongoDB and Cassandra.

111.1 Fluent Java Routes API

To allow for simple configuration in Java, there is a fluent API defined in the Routes class.

GatewaySampleApplication.java.  +

// static imports from GatewayFilters and RoutePredicates
+@Bean
+public RouteLocator customRouteLocator(ThrottleGatewayFilterFactory throttle) {
+    return Routes.locator()
+            .route("test")
+                .predicate(host("**.abc.org").and(path("/image/png")))
+                .addResponseHeader("X-TestHeader", "foobar")
+                .uri("http://httpbin.org:80")
+            .route("test2")
+                .predicate(path("/image/webp"))
+                .add(addResponseHeader("X-AnotherHeader", "baz"))
+                .uri("http://httpbin.org:80")
+            .route("test3")
+                .order(-1)
+                .predicate(host("**.throttle.org").and(path("/get")))
+                .add(throttle.apply(tuple().of("capacity", 1,
+                     "refillTokens", 1,
+                     "refillPeriod", 10,
+                     "refillUnit", "SECONDS")))
+                .uri("http://httpbin.org:80")
+            .build();
+}

+

This style also allows for more custom predicate assertions. The predicates defined by RouteDefinitionLocator beans are combined using logical and. By using the fluent Java API, you can use the and(), or() and negate() operators on the Predicate class.

111.2 DiscoveryClient Route Definition Locator

The Gateway can be configured to create routes based on services registered with a DiscoveryClient compatible service registry.

To enable this, set spring.cloud.gateway.discovery.locator.enabled=true and make sure a DiscoveryClient implementation is on the classpath and enabled (such as Netflix Eureka, Consul or Zookeeper).

\ No newline at end of file diff --git a/Finchley.M7/multi/multi__configuration_options.html b/Finchley.M7/multi/multi__configuration_options.html index 823c88a9..e64cf7a6 100644 --- a/Finchley.M7/multi/multi__configuration_options.html +++ b/Finchley.M7/multi/multi__configuration_options.html @@ -1,24 +1,24 @@ - 27. Configuration Options

27. Configuration Options

Spring Cloud Stream supports general configuration options as well as configuration for bindings and binders. + 28. Configuration Options

28. Configuration Options

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.

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.

27.1 Spring Cloud Stream Properties

spring.cloud.stream.instanceCount

The number of deployed instances of an application. +This includes application arguments, environment variables, and YAML or .properties files.

28.1 Spring Cloud Stream Properties

spring.cloud.stream.instanceCount

The number of deployed instances of an application. Must be set for partitioning on the producer side, and on the consumer side if using RabbitMQ and with Kafka if autoRebalanceEnabled=false.

Default: 1.

spring.cloud.stream.instanceIndex
The instance index of the application: a number from 0 to instanceCount-1. Used for partitioning with RabbitMQ and with Kafka if autoRebalanceEnabled=false. 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). 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 multiple binders are configured. -See Multiple Binders on the Classpath.

Default: empty.

spring.cloud.stream.overrideCloudConnectors

This property is only applicable when the cloud profile is active and Spring Cloud Connectors are provided with the application. +See Multiple Binders on the Classpath.

Default: empty.

spring.cloud.stream.overrideCloudConnectors

This property is only applicable when the cloud profile is active and Spring Cloud Connectors are provided with the application. If the property is false (the default), the binder will detect a suitable bound service (e.g. a RabbitMQ service bound in Cloud Foundry for the RabbitMQ binder) and will use it for creating connections (usually via Spring Cloud Connectors). When set to true, this property instructs binders to completely ignore the bound services and rely on Spring Boot properties (e.g. relying on the spring.rabbitmq.* properties provided in the environment for the RabbitMQ binder). -The typical usage of this property is to be nested in a customized environment when connecting to multiple systems.

Default: false.

spring.cloud.stream.bindingRetryInterval

The interval (seconds) between retrying binding creation when, for example, the binder doesn’t support late binding and the broker is down (e.g. Apache Kafka). -Set to zero to treat such conditions as fatal, preventing the application from starting.

Default: 30

27.2 Binding Properties

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).

To avoid repetition, Spring Cloud Stream supports setting values for all channels, in the format spring.cloud.stream.default.<property>=<value>.

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.

27.2.1 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>., e.g. spring.cloud.stream.bindings.input.destination=ticktock.

Default values can be set by using the prefix spring.cloud.stream.default, e.g. spring.cloud.stream.default.contentType=application/json.

destination
The target destination of a channel on the bound middleware (e.g., the RabbitMQ exchange or Kafka topic). +The typical usage of this property is to be nested in a customized environment when connecting to multiple systems.

Default: false.

spring.cloud.stream.bindingRetryInterval

The interval (seconds) between retrying binding creation when, for example, the binder doesn’t support late binding and the broker is down (e.g. Apache Kafka). +Set to zero to treat such conditions as fatal, preventing the application from starting.

Default: 30

28.2 Binding Properties

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).

To avoid repetition, Spring Cloud Stream supports setting values for all channels, in the format spring.cloud.stream.default.<property>=<value>.

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.

28.2.1 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>., e.g. spring.cloud.stream.bindings.input.destination=ticktock.

Default values can be set by using the prefix spring.cloud.stream.default, e.g. spring.cloud.stream.default.contentType=application/json.

destination
The target destination of a channel on the bound middleware (e.g., the RabbitMQ exchange or Kafka topic). If the channel is bound as a consumer, it could be bound to multiple destinations and the destination names can be specified as comma separated String values. If not set, the channel name is used instead. The default value of this property cannot be overridden.
group

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.

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

binder

The binder used by this binding. -See Section 26.4, “Multiple Binders on the Classpath” for details.

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

27.2.2 Consumer properties

The following binding properties are available for input bindings only and must be prefixed with spring.cloud.stream.bindings.<channelName>.consumer., e.g. spring.cloud.stream.bindings.input.consumer.concurrency=3.

Default values can be set by using the prefix spring.cloud.stream.default.consumer, e.g. spring.cloud.stream.default.consumer.headerMode=none.

concurrency

The concurrency of the inbound consumer.

Default: 1.

partitioned

Whether the consumer receives data from a partitioned producer.

Default: false.

headerMode

When set to none, disables header parsing on input. +See Consumer Groups.

Default: null (indicating an anonymous consumer).

contentType

The content type of the channel.

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

binder

The binder used by this binding. +See Section 27.4, “Multiple Binders on the Classpath” for details.

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

28.2.2 Consumer properties

The following binding properties are available for input bindings only and must be prefixed with spring.cloud.stream.bindings.<channelName>.consumer., e.g. spring.cloud.stream.bindings.input.consumer.concurrency=3.

Default values can be set by using the prefix spring.cloud.stream.default.consumer, e.g. spring.cloud.stream.default.consumer.headerMode=none.

concurrency

The concurrency of the inbound consumer.

Default: 1.

partitioned

Whether the consumer receives data from a partitioned producer.

Default: false.

headerMode

When set to none, disables header parsing on input. Effective only for messaging middleware that does not support message headers natively and requires header embedding. This option is useful when consuming data from non-Spring Cloud Stream applications when native headers are not supported. When set to headers, uses the middleware’s native header mechanism. @@ -27,13 +27,13 @@ Set to 1 to disable retry.

Default: When set to a negative value, it will default to spring.cloud.stream.instanceIndex. See that property for more information.

Default: -1.

instanceCount

When set to a value greater than equal to zero, allows customizing the instance count of this consumer (if different from spring.cloud.stream.instanceCount). When set to a negative value, it will default to spring.cloud.stream.instanceCount. -See that property for more information.

Default: -1.

27.2.3 Producer Properties

The following binding properties are available for output bindings only and must be prefixed with spring.cloud.stream.bindings.<channelName>.producer., e.g. spring.cloud.stream.bindings.input.producer.partitionKeyExpression=payload.id.

Default values can be set by using the prefix spring.cloud.stream.default.producer, e.g. spring.cloud.stream.default.producer.partitionKeyExpression=payload.id.

partitionKeyExpression

A SpEL expression that determines how to partition outbound data. +See that property for more information.

Default: -1.

28.2.3 Producer Properties

The following binding properties are available for output bindings only and must be prefixed with spring.cloud.stream.bindings.<channelName>.producer., e.g. spring.cloud.stream.bindings.input.producer.partitionKeyExpression=payload.id.

Default values can be set by using the prefix spring.cloud.stream.default.producer, e.g. spring.cloud.stream.default.producer.partitionKeyExpression=payload.id.

partitionKeyExpression

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 Section 24.6, “Partitioning Support”.

Default: null.

partitionKeyExtractorClass

A PartitionKeyExtractorStrategy implementation. +See Section 25.6, “Partitioning Support”.

Default: null.

partitionKeyExtractorClass

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 Section 24.6, “Partitioning Support”.

Default: null.

partitionSelectorClass

A PartitionSelectorStrategy implementation. +See Section 25.6, “Partitioning Support”.

Default: null.

partitionSelectorClass

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. Mutually exclusive with partitionSelectorClass. @@ -49,7 +49,7 @@ When set to embeddedHeaders, embeds headers into th When this configuration is being used, the outbound message marshalling is not based on the contentType of the binding. When native encoding is used, it is the responsibility of the consumer to use appropriate decoder (ex: Kafka consumer value de-serializer) to deserialize the inbound message. Also, when native encoding/decoding is used the headerMode=embeddedHeaders property is ignored and headers will not be embedded into the message.

Default: false.

errorChannelEnabled

When set to true, if the binder supports async send results; send failures will be sent to an error channel for the destination. -See the section called “Message Channel Binders and Error Channels” for more information.

Default: false.

27.3 Using dynamically bound destinations

Besides the channels defined via @EnableBinding, Spring Cloud Stream allows applications to send messages to dynamically bound destinations. +See the section called “Message Channel Binders and Error Channels” for more information.

Default: false.

28.3 Using dynamically bound destinations

Besides the channels defined via @EnableBinding, Spring Cloud Stream allows applications to send messages to dynamically bound destinations. This is useful, for example, when the target destination needs to be determined at runtime. Applications can do so by using the BinderAwareChannelResolver bean, registered automatically by the @EnableBinding annotation.

The property 'spring.cloud.stream.dynamicDestinations' can be used for restricting the dynamic destination names to a set known beforehand (whitelisting). If the property is not set, any destination can be bound dynamically.

The BinderAwareChannelResolver can be used directly as in the following example, in which a REST controller uses a path variable to decide the target channel.

@EnableBinding
@@ -117,4 +117,4 @@ public NewBindingCallback
[Note]Note

If you need to support dynamic destinations with multiple binder types, use Object for the generic type and cast the extended argument as needed.

\ No newline at end of file +}
[Note]Note

If you need to support dynamic destinations with multiple binder types, use Object for the generic type and cast the extended argument as needed.

\ No newline at end of file diff --git a/Finchley.M7/multi/multi__configuring_authentication_downstream_of_a_zuul_proxy.html b/Finchley.M7/multi/multi__configuring_authentication_downstream_of_a_zuul_proxy.html index 3c3afc88..684c308f 100644 --- a/Finchley.M7/multi/multi__configuring_authentication_downstream_of_a_zuul_proxy.html +++ b/Finchley.M7/multi/multi__configuring_authentication_downstream_of_a_zuul_proxy.html @@ -1,6 +1,6 @@ - 78. Configuring Authentication Downstream of a Zuul Proxy

78. Configuring Authentication Downstream of a Zuul Proxy

You can control the authorization behaviour downstream of an + 79. Configuring Authentication Downstream of a Zuul Proxy

79. 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:
   auth:
@@ -14,4 +14,4 @@ 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.

\ No newline at end of file +ProxyAuthenticationProperties for full details.

\ No newline at end of file diff --git a/Finchley.M7/multi/multi__contract_dsl.html b/Finchley.M7/multi/multi__contract_dsl.html index 3fd40bb1..4b8c2292 100644 --- a/Finchley.M7/multi/multi__contract_dsl.html +++ b/Finchley.M7/multi/multi__contract_dsl.html @@ -1,6 +1,6 @@ - 88. Contract DSL

88. Contract DSL

Spring Cloud Contract supports out of the box 2 types of DSL. One written in + 89. Contract DSL

89. Contract DSL

Spring Cloud Contract supports out of the box 2 types of DSL. One written in Groovy and one written in YAML.

If you decide to write the contract in Groovy, do not be alarmed if you have not used Groovy before. Knowledge of the language is not really needed, as the Contract DSL uses only a tiny subset of it (only literals, method calls and closures). Also, the DSL is statically @@ -94,13 +94,13 @@ response: regex: bar - key: foo3 command: andMeToo($it)

[Tip]Tip

You can compile contracts to stubs mapping using standalone maven command: -mvn org.springframework.cloud:spring-cloud-contract-maven-plugin:convert

88.1 Limitations

[Warning]Warning

Spring Cloud Contract Verifier does not properly support XML. Please use JSON or +mvn org.springframework.cloud:spring-cloud-contract-maven-plugin:convert

89.1 Limitations

[Warning]Warning

Spring Cloud Contract Verifier does not properly support XML. Please use JSON or help us implement this feature.

[Warning]Warning

The support for verifying the size of JSON arrays is experimental. If you want to turn it on, please set the value of the following system property to true: spring.cloud.contract.verifier.assert.size. By default, this feature is set to false. You can also provide the assertJsonSize property in the plugin configuration.

[Warning]Warning

Because JSON structure can have any form, it can be impossible to parse it properly when using the Groovy DSL and the value(consumer(…​), producer(…​)) notation in GString. That -is why you should use the Groovy Map notation.

88.2 Common Top-Level elements

The following sections describe the most common top-level elements:

88.2.1 Description

You can add a description to your contract. The description is arbitrary text. The +is why you should use the Groovy Map notation.

89.2 Common Top-Level elements

The following sections describe the most common top-level elements:

89.2.1 Description

You can add a description to your contract. The description is arbitrary text. The following code shows an example:

Groovy DSL. 

		org.springframework.cloud.contract.spec.Contract.make {
 			description('''
@@ -158,7 +158,7 @@ response:
         regex: bar
       - key: foo3
         command: andMeToo($it)

-

88.2.2 Name

You can provide a name for your contract. Assume that you provided the following name: +

89.2.2 Name

You can provide a name for your contract. Assume that you provided the following name: should register a user. If you do so, the name of the autogenerated test is validate_should_register_a_user. Also, the name of the stub in a WireMock stub is should_register_a_user.json.

[Important]Important

You must ensure that the name does not contain any characters that make the @@ -170,14 +170,14 @@ override each other.

Groovy DSL.  }

YAML. 

name: some name

-

88.2.3 Ignoring Contracts

If you want to ignore a contract, you can either set a value of ignored contracts in the +

89.2.3 Ignoring Contracts

If you want to ignore a contract, you can either set a value of ignored contracts in the plugin configuration or set the ignored property on the contract itself:

Groovy DSL. 

org.springframework.cloud.contract.spec.Contract.make {
 	ignored()
 }

YAML. 

ignored: true

-

88.2.4 Passing Values from Files

Starting with version 1.2.0, you can pass values from files. Assume that you have the +

89.2.4 Passing Values from Files

Starting with version 1.2.0, you can pass values from files. Assume that you have the following resources in our project.

└── src
     └── test
         └── resources
@@ -214,7 +214,7 @@ response:
   bodyFromFile: response.json

Further assume that the JSON files is as follows:

request.json

{ "status" : "REQUEST" }

response.json

{ "status" : "RESPONSE" }

When test or stub generation takes place, the contents of the file is passed to the body of a request or a response. The name of the file needs to be a file with location -relative to the folder in which the contract lays.

88.2.5 HTTP Top-Level Elements

The following methods can be called in the top-level closure of a contract definition. +relative to the folder in which the contract lays.

89.2.5 HTTP Top-Level Elements

The following methods can be called in the top-level closure of a contract definition. request and response are mandatory. priority is optional.

Groovy DSL. 

org.springframework.cloud.contract.spec.Contract.make {
 	// Definition of HTTP request part of the contract
@@ -244,7 +244,7 @@ response:
 ...

[Important]Important

If you want to make your contract have a higher value of priority you need to pass a lower number to the priority tag / method. E.g. priority with -value 5 has higher priority than priority with value 10.

88.3 Request

The HTTP protocol requires only method and url to be specified in a request. The +value 5 has higher priority than priority with value 10.

89.3 Request

The HTTP protocol requires only method and url to be specified in a request. The same information is mandatory in request definition of the Contract.

Groovy DSL. 

org.springframework.cloud.contract.spec.Contract.make {
 	request {
@@ -509,7 +509,7 @@ parametrization of either fileName or "transformers" : [ "response-template", "foo-transformer" ]
   }
 }
-	'''

88.4 Response

The response must contain an HTTP status code and may contain other information. The + '''

89.4 Response

The response must contain an HTTP status code and may contain other information. The following code shows an example:

Groovy DSL. 

org.springframework.cloud.contract.spec.Contract.make {
 	request {
@@ -526,12 +526,12 @@ following code shows an example:

Groovy DSL.  ... status: 200

Besides status, the response may contain headers and a body, both of which are -specified the same way as in the request (see the previous paragraph).

88.5 Dynamic properties

The contract can contain some dynamic properties: timestamps, IDs, and so on. You do not +specified the same way as in the request (see the previous paragraph).

89.5 Dynamic properties

The contract can contain some dynamic properties: timestamps, IDs, and so on. You do not want to force the consumers to stub their clocks to always return the same value of time so that it gets matched by the stub.

For Groovy DSL you can provide the dynamic parts in your contracts in two ways: pass them directly in the body or set them in separate sections called -testMatchers and stubMatchers.

For YAML you can only use the matchers section.

88.5.1 Dynamic properties inside the body

[Important]Important

This section is valid only for Groovy DSL. Check out the -Section 88.5.7, “Dynamic Properties in the Matchers Sections” section for YAML examples of a similar feature.

You can set the properties inside the body either with the value method or, if you use +testMatchers and stubMatchers.

For YAML you can only use the matchers section.

89.5.1 Dynamic properties inside the body

[Important]Important

This section is valid only for Groovy DSL. Check out the +Section 89.5.7, “Dynamic Properties in the Matchers Sections” section for YAML examples of a similar feature.

You can set the properties inside the body either with the value method or, if you use the Groovy map notation, with $(). The following example shows how to set dynamic properties with the value method:

value(consumer(...), producer(...))
 value(c(...), p(...))
@@ -540,8 +540,8 @@ value(client(...), server(...))

The following example shows how to set d $(c(...), p(...)) $(stub(...), test(...)) $(client(...), server(...))

Both approaches work equally well. stub and client methods are aliases over the consumer -method. Subsequent sections take a closer look at what you can do with those values.

88.5.2 Regular expressions

[Important]Important

This section is valid only for Groovy DSL. Check out the -Section 88.5.7, “Dynamic Properties in the Matchers Sections” section for YAML examples of a similar feature.

You can use regular expressions to write your requests in Contract DSL. Doing so is +method. Subsequent sections take a closer look at what you can do with those values.

89.5.2 Regular expressions

[Important]Important

This section is valid only for Groovy DSL. Check out the +Section 89.5.7, “Dynamic Properties in the Matchers Sections” section for YAML examples of a similar feature.

You can use regular expressions to write your requests in Contract DSL. Doing so is particularly useful when you want to indicate that a given response should be provided for requests that follow a given pattern. Also, you can use regular expressions when you need to use patterns and not exact values both for your test and your server side tests.

The following example shows how to use regular expressions to write a request:

org.springframework.cloud.contract.spec.Contract.make {
@@ -687,8 +687,8 @@ Pattern nonBlank() {
 				message: "User not found by email = [${value(producer(regex(email())), consumer('not.existing@user.com'))}]"
 		)
 	}
-}

88.5.3 Passing Optional Parameters

[Important]Important

This section is valid only for Groovy DSL. Check out the -Section 88.5.7, “Dynamic Properties in the Matchers Sections” section for YAML examples of a similar feature.

It is possible to provide optional parameters in your contract. However, you can provide +}

89.5.3 Passing Optional Parameters

[Important]Important

This section is valid only for Groovy DSL. Check out the +Section 89.5.7, “Dynamic Properties in the Matchers Sections” section for YAML examples of a similar feature.

It is possible to provide optional parameters in your contract. However, you can provide optional parameters only for the following:

  • STUB side of the Request
  • TEST side of the Response

The following example shows how to provide optional parameters:

org.springframework.cloud.contract.spec.Contract.make {
 	priority 1
 	request {
@@ -753,8 +753,8 @@ expression that must be present 0 or more times.

If you use Spock for, the }, "priority" : 1 } -'''

88.5.4 Executing Custom Methods on the Server Side

[Important]Important

This section is valid only for Groovy DSL. Check out the -Section 88.5.7, “Dynamic Properties in the Matchers Sections” section for YAML examples of a similar feature.

You can define a method call that executes on the server side during the test. Such a +'''

89.5.4 Executing Custom Methods on the Server Side

[Important]Important

This section is valid only for Groovy DSL. Check out the +Section 89.5.7, “Dynamic Properties in the Matchers Sections” section for YAML examples of a similar feature.

You can define a method call that executes on the server side during the test. Such a method can be added to the class defined as "baseClassForTests" in the configuration. The following code shows an example of the contract portion of the test case:

org.springframework.cloud.contract.spec.Contract.make {
 	request {
@@ -817,7 +817,7 @@ It should resemble the following code:

"/something");
 
 // then:
- assertThat(response.statusCode()).isEqualTo(200);

88.5.5 Referencing the Request from the Response

The best situation is to provide fixed values, but sometimes you need to reference a + assertThat(response.statusCode()).isEqualTo(200);

89.5.5 Referencing the Request from the Response

The best situation is to provide fixed values, but sometimes you need to reference a request in your response.

If you’re writing contracts using Groovy DSL, you can use the fromRequest() method, which lets you reference a bunch of elements from the HTTP request. You can use the following options:

  • fromRequest().url(): Returns the request URL and query parameters.
  • fromRequest().query(String key): Returns the first query parameter with a given name.
  • fromRequest().query(String key, int index): Returns the nth query parameter with a @@ -965,7 +965,7 @@ in sending the following response body:

    }
    [Important]Important

    This feature works only with WireMock having a version greater than or equal to 2.5.1. The Spring Cloud Contract Verifier uses WireMock’s response-template response transformer. It uses Handlebars to convert the Mustache {{{ }}} templates into -proper values. Additionally, it registers two helper functions:

    • escapejsonbody: Escapes the request body in a format that can be embedded in a JSON.
    • jsonpath: For a given parameter, find an object in the request body.

88.5.6 Registering Your Own WireMock Extension

WireMock lets you register custom extensions. By default, Spring Cloud Contract registers +proper values. Additionally, it registers two helper functions:

  • escapejsonbody: Escapes the request body in a format that can be embedded in a JSON.
  • jsonpath: For a given parameter, find an object in the request body.

89.5.6 Registering Your Own WireMock Extension

WireMock lets you register custom extensions. By default, Spring Cloud Contract registers the transformer, which lets you reference a request from a response. If you want to provide your own extensions, you can register an implementation of the org.springframework.cloud.contract.verifier.dsl.wiremock.WireMockExtensions interface. @@ -997,7 +997,7 @@ org.springframework.cloud.contract.stubrunner.provider.wiremock.TestWireMockExte } }

[Important]Important

Remember to override the applyGlobally() method and set it to false if you -want the transformation to be applied only for a mapping that explicitly requires it.

88.5.7 Dynamic Properties in the Matchers Sections

If you work with Pact, the following discussion may seem familiar. +want the transformation to be applied only for a mapping that explicitly requires it.

89.5.7 Dynamic Properties in the Matchers Sections

If you work with Pact, the following discussion may seem familiar. Quite a few users are used to having a separation between the body and setting the dynamic parts of a contract.

You can use two separate sections:

  • stubMatchers, which lets you define the dynamic values that should end up in a stub. You can set it in the request or inputMessage part of your contract.
  • testMatchers, which is present in the response or outputMessage side of the @@ -1402,7 +1402,7 @@ and: assertThat(parsedJson.read("\$.events[0].eventId", String.class)).matches("^([a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12})\$") assertThat(parsedJson.read("\$.events[0].status", String.class)).matches(".+")

    As you can see, the assertion is malformed. Only the first element of the array got asserted. In order to fix this, you should apply the assertion to the whole $.events -collection and assert it with the byCommand(…​) method.

88.6 JAX-RS Support

The Spring Cloud Contract Verifier supports the JAX-RS 2 Client API. The base class needs +collection and assert it with the byCommand(…​) method.

89.6 JAX-RS Support

The Spring Cloud Contract Verifier supports the JAX-RS 2 Client API. The base class needs to define protected WebTarget webTarget and server initialization. The only option for testing JAX-RS API is to start a web server. Also, a request with a body needs to have a content type set. Otherwise, the default of application/octet-stream gets used.

In order to use JAX-RS mode, use the following settings:

testMode == 'JAXRSCLIENT'

The following example shows a generated test API:

'''
@@ -1427,7 +1427,7 @@ content type set. Otherwise, the default of application/oc
  // and:
   DocumentContext parsedJson = JsonPath.parse(responseAsString);
   assertThatJson(parsedJson).field("['property1']").isEqualTo("a");
-'''

88.7 Async Support

If you’re using asynchronous communication on the server side (your controllers are +'''

89.7 Async Support

If you’re using asynchronous communication on the server side (your controllers are returning Callable, DeferredResult, and so on), then, inside your contract, you must provide a sync() method in the response section. The following code shows an example:

Groovy DSL. 

org.springframework.cloud.contract.spec.Contract.make {
@@ -1444,7 +1444,7 @@ provide a sync() method in the response:
     async: true

-

88.8 Working with Context Paths

Spring Cloud Contract supports context paths.

[Important]Important

The only change needed to fully support context paths is the switch on the +

89.8 Working with Context Paths

Spring Cloud Contract supports context paths.

[Important]Important

The only change needed to fully support context paths is the switch on the PRODUCER side. Also, the autogenerated tests must use EXPLICIT mode. The consumer side remains untouched. In order for the generated test to pass, you must use EXPLICIT mode.

Maven.  @@ -1488,8 +1488,8 @@ socket.

Consider the following contract:

or
 	}
 }

If you do it this way:

  • All of your requests in the autogenerated tests are sent to the real endpoint with your context path included (for example, /my-context-path/url).
  • Your contracts reflect that you have a context path. Your generated stubs also have -that information (for example, in the stubs, you have to call /my-context-path/url).

88.9 Messaging Top-Level Elements

The DSL for messaging looks a little bit different than the one that focuses on HTTP. The -following sections explain the differences:

88.9.1 Output Triggered by a Method

The output message can be triggered by calling a method (such as a Scheduler when a was +that information (for example, in the stubs, you have to call /my-context-path/url).

89.9 Messaging Top-Level Elements

The DSL for messaging looks a little bit different than the one that focuses on HTTP. The +following sections explain the differences:

89.9.1 Output Triggered by a Method

The output message can be triggered by calling a method (such as a Scheduler when a was started and a message was sent), as shown in the following example:

Groovy DSL. 

def dsl = Contract.make {
 	// Human readable description
@@ -1534,7 +1534,7 @@ outputMessage:
 

In the previous example case, the output message is sent to output if a method called bookReturnedTriggered is executed. On the message publisher’s side, we generate a test that calls that method to trigger the message. On the consumer side, you can use -the some_label to trigger the message.

88.9.2 Output Triggered by a Message

The output message can be triggered by receiving a message, as shown in the following +the some_label to trigger the message.

89.9.2 Output Triggered by a Message

The output message can be triggered by receiving a message, as shown in the following example:

Groovy DSL. 

def dsl = Contract.make {
 	description 'Some Description'
@@ -1590,7 +1590,7 @@ outputMessage:
 received on the input destination. On the message publisher’s side, the engine
 generates a test that sends the input message to the defined destination. On the
 consumer side, you can either send a message to the input destination or use a label
-(some_label in the example) to trigger the message.

88.9.3 Consumer/Producer

[Important]Important

This section is valid only for Groovy DSL.

In HTTP, you have a notion of client/stub and `server/test notation. You can also +(some_label in the example) to trigger the message.

89.9.3 Consumer/Producer

[Important]Important

This section is valid only for Groovy DSL.

In HTTP, you have a notion of client/stub and `server/test notation. You can also use those paradigms in messaging. In addition, Spring Cloud Contract Verifier also provides the consumer and producer methods, as presented in the following example (note that you can use either $ or value methods to provide consumer and producer @@ -1611,10 +1611,10 @@ parts):

Contract.make {
 				bookName: 'foo'
 		])
 	}
-}

88.9.4 Common

In the input or outputMessage section you can call assertThat with the name +}

89.9.4 Common

In the input or outputMessage section you can call assertThat with the name of a method (e.g. assertThatMessageIsOnTheQueue()) that you have defined in the base class or in a static import. Spring Cloud Contract will execute that method -in the generated test.

88.10 Multiple Contracts in One File

You can define multiple contracts in one file. Such a contract might resemble the +in the generated test.

89.10 Multiple Contracts in One File

You can define multiple contracts in one file. Such a contract might resemble the following example:

Groovy DSL. 

import org.springframework.cloud.contract.spec.Contract
 
@@ -1703,4 +1703,4 @@ index of the contract in the list.

The generated stubs is shown in the fol 1_WithList.json

As you can see, the first file got the name parameter from the contract. The second got the name of the contract file (WithList.groovy) prefixed with the index (in this case, the contract had an index of 1 in the list of contracts in the file).

[Tip]Tip

As you can see, it iss much better if you name your contracts because doing so makes -your tests far more meaningful.

\ No newline at end of file +your tests far more meaningful.

\ No newline at end of file diff --git a/Finchley.M7/multi/multi__current_span.html b/Finchley.M7/multi/multi__current_span.html index 6c7511a4..a62455d9 100644 --- a/Finchley.M7/multi/multi__current_span.html +++ b/Finchley.M7/multi/multi__current_span.html @@ -1,9 +1,9 @@ - 51. Current Span

51. Current Span

Brave supports a "current span" concept which represents the in-flight + 52. Current Span

52. Current Span

Brave supports a "current span" concept which represents the in-flight operation. Tracer.currentSpan() can be used to add custom tags to a span and Tracer.nextSpan() can be used to create a child of whatever -is in-flight.

51.1 Setting a span in scope manually

When writing new instrumentation, it is important to place a span you +is in-flight.

52.1 Setting a span in scope manually

When writing new instrumentation, it is important to place a span you created in scope as the current span. Not only does this allow users to access it with Tracer.currentSpan(), but it also allows customizations like SLF4J MDC to see the current trace IDs.

Tracer.withSpanInScope(Span) facilitates this and is most conveniently @@ -17,4 +17,4 @@ span in scope like this.

withSpanInScope.

try (SpanInScope cleared = tracer.withSpanInScope(null)) {
   startBackgroundThread();
-}
\ No newline at end of file +}
\ No newline at end of file diff --git a/Finchley.M7/multi/multi__current_tracing_component.html b/Finchley.M7/multi/multi__current_tracing_component.html index ec5ee21a..6057af13 100644 --- a/Finchley.M7/multi/multi__current_tracing_component.html +++ b/Finchley.M7/multi/multi__current_tracing_component.html @@ -1,9 +1,9 @@ - 50. Current Tracing Component

50. Current Tracing Component

Brave supports a "current tracing component" concept which should only + 51. Current Tracing Component

51. Current Tracing Component

Brave supports a "current tracing component" concept which should only be used when you have no other means to get a reference. This was made for JDBC connections, as they often initialize prior to the tracing component.

The most recent tracing component instantiated is available via Tracing.current(). You there’s also a shortcut to get only the tracer via Tracing.currentTracer(). If you use either of these methods, do -noot cache the result. Instead, look them up each time you need them.

\ No newline at end of file +noot cache the result. Instead, look them up each time you need them.

\ No newline at end of file diff --git a/Finchley.M7/multi/multi__customization.html b/Finchley.M7/multi/multi__customization.html index c8611685..c06a9290 100644 --- a/Finchley.M7/multi/multi__customization.html +++ b/Finchley.M7/multi/multi__customization.html @@ -1,9 +1,9 @@ - 89. Customization

89. Customization

[Important]Important

This section is valid only for Groovy DSL

You can customize the Spring Cloud Contract Verifier by extending the DSL, as shown in -the remainder of this section.

89.1 Extending the DSL

You can provide your own functions to the DSL. The key requirement for this feature is to + 90. Customization

90. Customization

[Important]Important

This section is valid only for Groovy DSL

You can customize the Spring Cloud Contract Verifier by extending the DSL, as shown in +the remainder of this section.

90.1 Extending the DSL

You can provide your own functions to the DSL. The key requirement for this feature is to maintain the static compatibility. Later in this document, you can see examples of:

  • Creating a JAR with reusable classes.
  • Referencing of these classes in the DSLs.

You can find the full example -here.

89.1.1 Common JAR

The following examples show three classes that can be reused in the DSLs.

PatternUtils contains functions used by both the consumer and the producer.

package com.example;
+here.

90.1.1 Common JAR

The following examples show three classes that can be reused in the DSLs.

PatternUtils contains functions used by both the consumer and the producer.

package com.example;
 
 import java.util.regex.Pattern;
 
@@ -134,8 +134,8 @@ maintain the static compatibility. Later in this document, you can see examples
 		return new ServerDslProperty( PatternUtils.ok(), "OK");
 	}
 }
-//end::impl[]

89.1.2 Adding the Dependency to the Project

In order for the plugins and IDE to be able to reference the common JAR classes, you need -to pass the dependency to your project.

89.1.3 Test the Dependency in the Project’s Dependencies

First, add the common jar dependency as a test dependency. Because your contracts files +//end::impl[]

90.1.2 Adding the Dependency to the Project

In order for the plugins and IDE to be able to reference the common JAR classes, you need +to pass the dependency to your project.

90.1.3 Test the Dependency in the Project’s Dependencies

First, add the common jar dependency as a test dependency. Because your contracts files are available on the test resources path, the common jar classes automatically become visible in your Groovy files. The following examples show how to test the dependency:

Maven. 

<dependency>
@@ -146,7 +146,7 @@ visible in your Groovy files. The following examples show how to test the depend
 </dependency>

Gradle. 

testCompile("com.example:beer-common:0.0.1-SNAPSHOT")

-

89.1.4 Test a Dependency in the Plugin’s Dependencies

Now, you must add the dependency for the plugin to reuse at runtime, as shown in the +

90.1.4 Test a Dependency in the Plugin’s Dependencies

Now, you must add the dependency for the plugin to reuse at runtime, as shown in the following example:

Maven. 

<plugin>
 	<groupId>org.springframework.cloud</groupId>
@@ -173,7 +173,7 @@ following example:

Maven.  </plugin>

Gradle. 

classpath "com.example:beer-common:0.0.1-SNAPSHOT"

-

89.1.5 Referencing classes in DSLs

You can now reference your classes in your DSL, as shown in the following example:

package contracts.beer.rest
+

90.1.5 Referencing classes in DSLs

You can now reference your classes in your DSL, as shown in the following example:

package contracts.beer.rest
 
 import com.example.ConsumerUtils
 import com.example.ProducerUtils
@@ -214,4 +214,4 @@ then:
 			contentType(applicationJson())
 		}
 	}
-}
\ No newline at end of file +}
\ No newline at end of file diff --git a/Finchley.M7/multi/multi__customizations.html b/Finchley.M7/multi/multi__customizations.html index 7340007d..2b5ac26c 100644 --- a/Finchley.M7/multi/multi__customizations.html +++ b/Finchley.M7/multi/multi__customizations.html @@ -1,6 +1,6 @@ - 56. Customizations

56. Customizations

56.1 Spring Integration

56.2 HTTP

56.3 TraceFilter

You can also modify the behaviour of the TraceFilter - the component that is responsible + 57. Customizations

57. Customizations

57.1 Spring Integration

57.2 HTTP

57.3 TraceFilter

You can also modify the behaviour of the TraceFilter - the component that is responsible for processing the input HTTP request and adding tags basing on the HTTP response. You can customize the tags, or modify the response headers by registering your own instance of the TraceFilter bean.

In the following example we will register the TraceFilter bean and we will add the ZIPKIN-TRACE-ID response header containing the current Span’s trace id. Also we will @@ -26,11 +26,11 @@ add to the Span a tag with key custom and a value < currentSpan.tag("custom", "tag"); chain.doFilter(request, response); } -}

56.4 Custom service name

By default Sleuth assumes that when you send a span to Zipkin, you want the span’s service name +}

57.4 Custom service name

By default Sleuth assumes that when you send a span to Zipkin, you want the span’s service name to be equal to spring.application.name value. That’s not always the case though. There are situations in which you want to explicitly provide a different service name for all spans coming from your application. To achieve that it’s enough to just pass the following property - to your application to override that value (example for foo service name):

spring.zipkin.service.name: foo

56.5 Customization of reported spans

Before reporting spans to e.g. Zipkin you can be interested in modifying that span in some way. + to your application to override that value (example for foo service name):

spring.zipkin.service.name: foo

57.5 Customization of reported spans

Before reporting spans to e.g. Zipkin you can be interested in modifying that span in some way. You can achieve that by using the SpanAdjuster interface.

In Sleuth we’re generating spans with a fixed name. Some users want to modify the name depending on values of tags. Implementation of the SpanAdjuster interface can be used to alter that name. Example:

Example. If you register two beans of SpanAdjuster type:

@Bean SpanAdjuster adjusterOne() {
 	return span -> span.toBuilder().name("foo").build();
@@ -38,9 +38,9 @@ of tags. Implementation of the SpanAdjuster interfa
 
 @Bean SpanAdjuster adjusterTwo() {
 	return span -> span.toBuilder().name(span.name() + " bar").build();
-}

This will lead in changing the name of the reported span to foo bar, just before it gets reported (e.g. to Zipkin).

56.6 Host locator

[Important]Important

This section is about defining host from service discovery. It’s NOT +}

This will lead in changing the name of the reported span to foo bar, just before it gets reported (e.g. to Zipkin).

57.6 Host locator

[Important]Important

This section is about defining host from service discovery. It’s NOT about finding Zipkin in service discovery.

In order to define the host that is corresponding to a particular span we need to resolve the host name and port. The default approach is to take it from server properties. If those for some reason are not set then we’re trying to retrieve the host name from the network interfaces.

If you have the discovery client enabled and prefer to retrieve the host address from the registered instance in a service registry then you have to set the property (it’s applicable for both HTTP and -Stream based span reporting).

spring.zipkin.locator.discovery.enabled: true
\ No newline at end of file +Stream based span reporting).

spring.zipkin.locator.discovery.enabled: true
\ No newline at end of file diff --git a/Finchley.M7/multi/multi__customizing_the_message_broker.html b/Finchley.M7/multi/multi__customizing_the_message_broker.html index 64a6c88c..f6b3f477 100644 --- a/Finchley.M7/multi/multi__customizing_the_message_broker.html +++ b/Finchley.M7/multi/multi__customizing_the_message_broker.html @@ -1,6 +1,6 @@ - 42. Customizing the Message Broker

42. Customizing the Message Broker

Spring Cloud Bus uses + 43. Customizing the Message Broker

43. Customizing the Message Broker

Spring Cloud Bus uses 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 @@ -14,4 +14,4 @@ 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.

\ No newline at end of file +consult the Spring Cloud Stream documentation.

\ No newline at end of file diff --git a/Finchley.M7/multi/multi__developer_guide.html b/Finchley.M7/multi/multi__developer_guide.html new file mode 100644 index 00000000..560b6e71 --- /dev/null +++ b/Finchley.M7/multi/multi__developer_guide.html @@ -0,0 +1,3 @@ + + + 113. Developer Guide

113. Developer Guide

TODO: overview of writing custom integrations

113.1 Writing Custom Route Predicate Factories

TODO: document writing Custom Route Predicate Factories

113.2 Writing Custom GatewayFilter Factories

TODO: document writing Custom GatewayFilter Factories

113.3 Writing Custom Global Filters

TODO: document writing Custom Global Filters

113.4 Writing Custom Route Locators and Writers

TODO: document writing Custom Route Locators and Writers

\ No newline at end of file diff --git a/Finchley.M7/multi/multi__discovery.html b/Finchley.M7/multi/multi__discovery.html index dc66cc8b..f40b8cf2 100644 --- a/Finchley.M7/multi/multi__discovery.html +++ b/Finchley.M7/multi/multi__discovery.html @@ -1,6 +1,6 @@ - 79. Discovery

79. Discovery

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

app.groovy.  + 80. Discovery

80. Discovery

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

app.groovy. 

@Grab('org.springframework.cloud:spring-cloud-cloudfoundry')
 @RestController
 @EnableDiscoveryClient
@@ -19,4 +19,4 @@
 $ cf push -p app.jar

It will show its app name in the home page.

The DiscoveryClient can lists all the apps in a space, according to the credentials it is authenticated with, where the space defaults to the one the client is running in (if any). If neither org nor space -are configured, they default per the user’s profile in Cloud Foundry.

\ No newline at end of file +are configured, they default per the user’s profile in Cloud Foundry.

\ No newline at end of file diff --git a/Finchley.M7/multi/multi__features_2.html b/Finchley.M7/multi/multi__features_2.html index ff3763d3..5b48daf0 100644 --- a/Finchley.M7/multi/multi__features_2.html +++ b/Finchley.M7/multi/multi__features_2.html @@ -1,6 +1,6 @@ - 47. Features

47. 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] ...
    +   48. Features

    48. 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 @@ -17,14 +17,14 @@ Configure the location of the service using spring.zipkin. above. Other logging systems have to configure their own formatter to get the same result. The default is logging.pattern.level set to %5p [${spring.zipkin.service.name:${spring.application.name:-}},%X{X-B3-TraceId:-},%X{X-B3-SpanId:-},%X{X-Span-Export:-}] (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.

47.1 Introduction to Brave

[Important]Important

Starting with version 2.0.0 Spring Cloud Sleuth uses + This means that if you’re not using SLF4J this pattern WILL NOT be automatically applied.

48.1 Introduction to Brave

[Important]Important

Starting with version 2.0.0 Spring Cloud Sleuth uses Brave as the tracing library. For your convenience we’re embedding part of the Brave’s docs here.

Brave is a library used to capture and report latency information about distributed operations to Zipkin. Most users won’t use Brave directly, rather libraries or frameworks than employ Brave on their behalf.

This module includes tracer creates and joins spans that model the latency of potentially distributed work. It also includes libraries to propagate the trace context over network boundaries, for example, via -http headers.

47.1.1 Tracing

Most importantly, you need a brave.Tracer, configured to [report to Zipkin] +http headers.

48.1.1 Tracing

Most importantly, you need a brave.Tracer, configured to [report to Zipkin] (https://github.com/openzipkin/zipkin-reporter-java).

Here’s an example setup that sends trace data (spans) to Zipkin over http (as opposed to Kafka).

class MyClass {
 
@@ -41,12 +41,12 @@ http (as opposed to Kafka).

[Important]Important

If your span contains a name greater than 50 chars, then that name will be truncated to 50 chars. Your names have to be explicit and concrete. Big names lead to -latency issues and sometimes even thrown exceptions.

47.1.2 Tracing

The tracer creates and joins spans that model the latency of potentially +latency issues and sometimes even thrown exceptions.

48.1.2 Tracing

The tracer creates and joins spans that model the latency of potentially distributed work. It can employ sampling to reduce overhead in process or to reduce the amount of data sent to Zipkin.

Spans returned by a tracer report data to Zipkin when finished, or do nothing if unsampled. After starting a span, you can annotate events of interest or add tags containing details or lookup keys.

Spans have a context which includes trace identifiers that place it at -the correct spot in the tree representing the distributed operation.

47.1.3 Local Tracing

When tracing local code, just run it inside a span.

Span span = tracer.newTrace().name("encode").start();
+the correct spot in the tree representing the distributed operation.

48.1.3 Local Tracing

When tracing local code, just run it inside a span.

Span span = tracer.newTrace().name("encode").start();
 try {
   doSomethingExpensive();
 } finally {
@@ -58,7 +58,7 @@ you will be a part of an existing trace. When this is the case, call
   doSomethingExpensive();
 } finally {
   span.finish();
-}

47.1.4 Customizing spans

Once you have a span, you can add tags to it, which can be used as lookup +}

48.1.4 Customizing spans

Once you have a span, you can add tags to it, which can be used as lookup keys or details. For example, you might add a tag with your runtime version.

span.tag("clnt/finagle.version", "6.36.0");

When exposing the ability to customize spans to third parties, prefer brave.SpanCustomizer as opposed to brave.Span. The former is simpler to @@ -67,7 +67,7 @@ understand and test, and doesn’t tempt users with span lifecycle hooks.

Since brave.Span implements brave.SpanCustomizer, it is just as easy for you to pass to users.

Ex.

for (MyTraceCallback callback : userCallbacks) {
   callback.request(request, span);
-}

47.1.5 Implicitly looking up the current span

Sometimes you won’t know if a trace is in progress or not, and you don’t +}

48.1.5 Implicitly looking up the current span

Sometimes you won’t know if a trace is in progress or not, and you don’t want users to do null checks. brave.CurrentSpanCustomizer adds to any span that’s in progress or drops data accordingly.

Ex.

// user code can then inject this without a chance of it being null.
 @Autowire SpanCustomizer span;
@@ -75,7 +75,7 @@ span that’s in progress or drops data accordingly.

Ex.

void userCode() {
   span.annotate("tx.started");
   ...
-}

47.1.6 RPC tracing

Check for instrumentation written here +}

48.1.6 RPC tracing

Check for instrumentation written here and Zipkin’s list before rolling your own RPC instrumentation!

RPC tracing is often done automatically by interceptors. Under the scenes, they add tags and events that relate to their role in an RPC operation.

Here’s an example of a client span:

// before you send a request, add metadata that describes the operation
@@ -123,4 +123,4 @@ oneWayReceive.start().flush();
 
 // you should not modify this span anymore as it is complete. However,
 // you can create children to represent follow-up work.
-next = tracer.newSpan(oneWayReceive.context()).name("step2").start();

Note The above propagation logic is a simplified version of our [http handlers](https://github.com/openzipkin/sleuth/tree/master/instrumentation/http#http-server).

There’s a working example of a one-way span [here](src/test/java/sleuth/features/async/OneWaySpanTest.java).

\ No newline at end of file +next = tracer.newSpan(oneWayReceive.context()).name("step2").start();

Note The above propagation logic is a simplified version of our [http handlers](https://github.com/openzipkin/sleuth/tree/master/instrumentation/http#http-server).

There’s a working example of a one-way span [here](src/test/java/sleuth/features/async/OneWaySpanTest.java).

\ No newline at end of file diff --git a/Finchley.M7/multi/multi__getting_started.html b/Finchley.M7/multi/multi__getting_started.html index d62ad35b..a4ecbc3c 100644 --- a/Finchley.M7/multi/multi__getting_started.html +++ b/Finchley.M7/multi/multi__getting_started.html @@ -1,6 +1,6 @@ - 35. Getting Started

35. Getting Started

To get started with creating Spring Cloud Stream applications, visit the Spring Initializr and create a new Maven project named "GreetingSource". + 36. Getting Started

36. Getting Started

To get started with creating Spring Cloud Stream applications, visit the Spring Initializr and create a new Maven project named "GreetingSource". Select Spring Boot {supported-spring-boot-version} in the dropdown. In the Search for dependencies text box type Stream Rabbit or Stream Kafka depending on what binder you want to use.

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

import org.springframework.cloud.stream.annotation.EnableBinding;
@@ -52,4 +52,4 @@ hello world 1458595076731
 hello world 1458595077732
 hello world 1458595078733
 hello world 1458595079734
-hello world 1458595080735

35.1 Deploying Stream applications on CloudFoundry

On CloudFoundry services are usually exposed via a special environment variable called VCAP_SERVICES.

When configuring your binder connections, you can use the values from an environment variable as explained on the dataflow cloudfoundry server docs.

\ No newline at end of file +hello world 1458595080735

36.1 Deploying Stream applications on CloudFoundry

On CloudFoundry services are usually exposed via a special environment variable called VCAP_SERVICES.

When configuring your binder connections, you can use the values from an environment variable as explained on the dataflow cloudfoundry server docs.

\ No newline at end of file diff --git a/Finchley.M7/multi/multi__global_filters.html b/Finchley.M7/multi/multi__global_filters.html new file mode 100644 index 00000000..26669f6f --- /dev/null +++ b/Finchley.M7/multi/multi__global_filters.html @@ -0,0 +1,3 @@ + + + 110. Global Filters

110. Global Filters

The GlobalFilter interface has the same signature as GatewayFilter. These are special filters that are conditionally applied to all routes. (This interface and usage are subject to change in future milestones).

110.1 Combined Global Filter and GatewayFilter Ordering

TODO: document ordering

110.2 Forward Routing Filter

The ForwardRoutingFilter looks for a URI in the exchange attribute ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR. If the url has a forward scheme (ie forward:///localendpoint), it will use the Spring DispatcherHandler to handler the request. The unmodified original url is appended to the list in the ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR attribute.

110.3 LoadBalancerClient Filter

The LoadBalancerClientFilter looks for a URI in the exchange attribute ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR. If the url has a lb scheme (ie lb://myservice), it will use the Spring Cloud LoadBalancerClient to resolve the name (myservice in the previous example) to an actual host and port and replace the URI in the same attribute. The unmodified original url is appended to the list in the ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR attribute. The filter will also look in the ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR attribute to see if it equals lb and then the same rules apply.

110.4 Netty Routing Filter

The Netty Routing Filter runs if the url located in the ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR exchange attribute has a http or https scheme. It uses the Netty HttpClient to make the downstream proxy request. The response is put in the ServerWebExchangeUtils.CLIENT_RESPONSE_ATTR exchange attribute for use in a later filter. (There is an experimental WebClientHttpRoutingFilter that performs the same function, but does not require netty)

110.5 Netty Write Response Filter

The NettyWriteResponseFilter runs if there is a Netty HttpClientResponse in the ServerWebExchangeUtils.CLIENT_RESPONSE_ATTR exchange attribute. It is run after all other filters have completed and writes the proxy response back to the gateway client response. (There is an experimental WebClientWriteResponseFilter that performs the same function, but does not require netty)

110.6 RouteToRequestUrl Filter

The RouteToRequestUrlFilter runs if there is a Route object in the ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR exchange attribute. It creates a new URI, based off of the request URI, but updated with the URI attribute of the Route object. The new URI is placed in the ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR exchange attribute`.

If the URI has a scheme prefix, such as lb:ws://serviceid, the lb scheme is stripped from the URI and placed in the ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR for use later in the filter chain.

110.7 Websocket Routing Filter

The Websocket Routing Filter runs if the url located in the ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR exchange attribute has a ws or wss scheme. It uses the Spring Web Socket infrastructure to forward the Websocket request downstream.

Websockets may be load-balanced by prefixing the URI with lb, such as lb:ws://serviceid.

\ No newline at end of file diff --git a/Finchley.M7/multi/multi__glossary.html b/Finchley.M7/multi/multi__glossary.html new file mode 100644 index 00000000..f7eecef9 --- /dev/null +++ b/Finchley.M7/multi/multi__glossary.html @@ -0,0 +1,3 @@ + + + 106. Glossary

106. Glossary

  • Route: Route the basic building block of the gateway. It is defined by an ID, a destination URI, a collection of predicates and a collection of filters. A route is matched if aggregate predicate is true.
  • Predicate: This is a Java 8 Function Predicate. The input type is a Spring Framework ServerWebExchange. This allows developers to match on anything from the HTTP request, such as headers or parameters.
  • Filter: These are instances Spring Framework GatewayFilter constructed in with a specific factory. Here, requests and responses can be modified before or after sending the downstream request.
\ No newline at end of file diff --git a/Finchley.M7/multi/multi__health_indicator_5.html b/Finchley.M7/multi/multi__health_indicator_5.html index c5ff48c8..bc15c30b 100644 --- a/Finchley.M7/multi/multi__health_indicator_5.html +++ b/Finchley.M7/multi/multi__health_indicator_5.html @@ -1,4 +1,4 @@ - 32. Health Indicator

32. Health Indicator

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.

\ No newline at end of file + 33. Health Indicator

33. Health Indicator

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.

\ No newline at end of file diff --git a/Finchley.M7/multi/multi__http_clients.html b/Finchley.M7/multi/multi__http_clients.html index e7281df1..023f7a0b 100644 --- a/Finchley.M7/multi/multi__http_clients.html +++ b/Finchley.M7/multi/multi__http_clients.html @@ -1,8 +1,8 @@ - 22. HTTP Clients

22. HTTP Clients

Spring Cloud Netflix will automatically create the HTTP client used by Ribbon, Feign, and + 22. HTTP Clients

22. HTTP Clients

Spring Cloud Netflix will automatically create the HTTP client used by Ribbon, Feign, and Zuul for you. However you can also provide your own HTTP clients customized how you please yourself. To do this you can either create a bean of type ClosableHttpClient if you are using the Apache Http Cient, or OkHttpClient if you are using OK HTTP.

[Note]Note

When you create your own HTTP client you are also responsible for implementing the correct connection management strategies for these clients. Doing this improperly -can result in resource management issues.

\ No newline at end of file +can result in resource management issues.

\ No newline at end of file diff --git a/Finchley.M7/multi/multi__instrumentation.html b/Finchley.M7/multi/multi__instrumentation.html index d1e99009..25f8db15 100644 --- a/Finchley.M7/multi/multi__instrumentation.html +++ b/Finchley.M7/multi/multi__instrumentation.html @@ -1,6 +1,6 @@ - 52. Instrumentation

52. Instrumentation

Spring Cloud Sleuth instruments all your Spring application + 53. Instrumentation

53. 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 @@ -12,4 +12,4 @@ request headers by configuring spring.sleuth.keys.http.hea list of header names).

[Note]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).

\ No newline at end of file +something).

\ No newline at end of file diff --git a/Finchley.M7/multi/multi__integrations.html b/Finchley.M7/multi/multi__integrations.html index d3d02125..c9c0cc6d 100644 --- a/Finchley.M7/multi/multi__integrations.html +++ b/Finchley.M7/multi/multi__integrations.html @@ -1,8 +1,8 @@ - 59. Integrations

59. Integrations

59.1 OpenTracing

Spring Cloud Sleuth is OpenTracing compatible. If you have + 60. Integrations

60. Integrations

60.1 OpenTracing

Spring Cloud Sleuth is OpenTracing compatible. If you have OpenTracing on the classpath we will automatically register the OpenTracing -Tracer bean. If you wish to disable this just set spring.sleuth.opentracing.enabled to false

59.2 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() {
+Tracer bean. If you wish to disable this just set spring.sleuth.opentracing.enabled to false

60.2 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() {
 	@Override
 	public void run() {
 		// do some work
@@ -34,10 +34,10 @@ Callable<String> traceCallable = "calculateTax");
 // Wrapping `Callable` with `Tracing`. That way the current span will be available
 // in the thread of `Callable`
-Callable<String> traceCallableFromTracer = tracing.currentTraceContext().wrap(callable);

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

59.3 Hystrix

59.3.1 Custom Concurrency Strategy

We’re registering a custom HystrixConcurrencyStrategy +Callable<String> traceCallableFromTracer = tracing.currentTraceContext().wrap(callable);

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

60.3 Hystrix

60.3.1 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.

59.3.2 Manual Command setting

Assuming that you have the following HystrixCommand:

HystrixCommand<String> hystrixCommand = new HystrixCommand<String>(setter) {
+on before the Hystrix command was called. To disable the custom Hystrix Concurrency Strategy set the spring.sleuth.hystrix.strategy.enabled to false.

60.3.2 Manual Command setting

Assuming that you have the following HystrixCommand:

HystrixCommand<String> hystrixCommand = new HystrixCommand<String>(setter) {
 	@Override
 	protected String run() throws Exception {
 		return someLogic();
@@ -48,29 +48,29 @@ on before the Hystrix command was called. To disable the custom Hystrix Concurre
 	public String doRun() throws Exception {
 		return someLogic();
 	}
-};

59.4 RxJava

We’re registering a custom RxJavaSchedulersHook +};

60.4 RxJava

We’re registering a custom 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.

You can define a list of regular expressions for thread names, for which you don’t want a Span to be created. Just provide a comma separated list -of regular expressions in the spring.sleuth.rxjava.schedulers.ignoredthreads property.

59.5 HTTP integration

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

59.5.1 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 +of regular expressions in the spring.sleuth.rxjava.schedulers.ignoredthreads property.

60.5 HTTP integration

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

60.5.1 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. If you want to reuse the Sleuth’s default skip patterns and just append your own, pass those patterns via - the spring.sleuth.web.additionalSkipPattern.

59.5.2 HandlerInterceptor

Since we want the span names to be precise we’re using a TraceHandlerInterceptor that either wraps an + the spring.sleuth.web.additionalSkipPattern.

60.5.2 HandlerInterceptor

Since we want the span names to be precise we’re using a TraceHandlerInterceptor that either wraps an existing HandlerInterceptor or is added directly to the list of existing HandlerInterceptors. The TraceHandlerInterceptor adds a special request attribute to the given HttpServletRequest. If the the TraceFilter doesn’t see this attribute set it will create a "fallback" span which is an additional span created on the server side so that the trace is presented properly in the UI. Seeing that most likely - signifies that there is a missing instrumentation. In that case please file an issue in Spring Cloud Sleuth.

59.5.3 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.

59.5.4 WebFlux support

Via the TraceWebFilter all sampled incoming requests result in creation of a Span. That Span’s name is http: + the path to which + signifies that there is a missing instrumentation. In that case please file an issue in Spring Cloud Sleuth.

60.5.3 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.

60.5.4 WebFlux support

Via the TraceWebFilter 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. If you want to reuse the Sleuth’s default skip patterns and just append your own, pass those patterns via - the spring.sleuth.web.additionalSkipPattern.

59.6 HTTP client integration

59.6.1 Synchronous Rest Template

We’re injecting a RestTemplate interceptor that ensures that all the tracing information is passed to the requests. Each time a + the spring.sleuth.web.additionalSkipPattern.

60.6 HTTP client integration

60.6.1 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.

[Important]Important

You have to register RestTemplate as a bean so that the interceptors will get injected. -If you create a RestTemplate instance with a new keyword then the instrumentation WILL NOT work.

59.6.2 Asynchronous Rest Template

[Important]Important

Starting with Sleuth 2.0.0 we no longer register +If you create a RestTemplate instance with a new keyword then the instrumentation WILL NOT work.

60.6.2 Asynchronous Rest Template

[Important]Important

Starting with Sleuth 2.0.0 we no longer register a bean of AsyncRestTemplate type. It’s up to you to create such a bean. Then we will instrument it.

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 @@ -95,25 +95,25 @@ can see an example of how to set up such a custom AsyncRes //CUSTOMIZE HERE return factory; } -}

59.6.3 WebClient

We inject a ExchangeFilterFunction implementation that creates a span and via on success and on +}

60.6.3 WebClient

We inject a ExchangeFilterFunction implementation that creates a span and via on success and on error callbacks takes care of closing client side spans.

[Important]Important

You have to register WebClient as a bean so that the tracing instrumention gets applied. -If you create a WebClient instance with a new keyword then the instrumentation WILL NOT work.

59.6.4 Traverson

If you’re using the Traverson library +If you create a WebClient instance with a new keyword then the instrumentation WILL NOT work.

60.6.4 Traverson

If you’re using the Traverson library it’s enough for you to inject a RestTemplate as a bean into your Traverson object. Since RestTemplate is already intercepted, you will get full support of tracing in your client. Below you can find a pseudo code of how to do that:

@Autowired RestTemplate restTemplate;
 
 Traverson traverson = new Traverson(URI.create("http://some/address"),
     MediaType.APPLICATION_JSON, MediaType.APPLICATION_JSON_UTF8).setRestOperations(restTemplate);
-// use Traverson

59.7 Feign

By default Spring Cloud Sleuth provides integration with feign via the TraceFeignClientAutoConfiguration. You can disable it entirely +// use Traverson

60.7 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.

59.8 Asynchronous communication

59.8.1 @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:

  • if the method is annotated with @SpanName then the value of the annotation will be the Span’s name
  • if the method is not annotated with @SpanName 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

59.8.2 @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 +however will be still there.

60.8 Asynchronous communication

60.8.1 @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:

  • if the method is annotated with @SpanName then the value of the annotation will be the Span’s name
  • if the method is not annotated with @SpanName 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

60.8.2 @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.

[Tip]Tip

If you are using spring-cloud-sleuth-stream and spring-cloud-netflix-hystrix-stream together, Span will be created for each Hystrix metrics and sent to Zipkin. This may be annoying. You can prevent this by setting -spring.sleuth.scheduled.skipPattern=org.springframework.cloud.netflix.hystrix.stream.HystrixStreamTask

59.8.3 Executor, ExecutorService and ScheduledExecutorService

We’re providing LazyTraceExecutor, TraceableExecutorService and TraceableScheduledExecutorService. Those implementations +spring.sleuth.scheduled.skipPattern=org.springframework.cloud.netflix.hystrix.stream.HystrixStreamTask

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

CompletableFuture<Long> completableFuture = CompletableFuture.supplyAsync(() -> {
 	// perform some logic
 	return 1_000_000L;
@@ -140,9 +140,9 @@ can see an example of how to set up such a custom Executor
 		executor.initialize();
 		return new LazyTraceExecutor(this.beanFactory, executor);
 	}
-}

59.9 Messaging

Spring Cloud Sleuth integrates with Spring Integration. It creates spans for publish and +}

60.9 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.

You can provide the spring.sleuth.integration.patterns pattern to explicitly provide the names of channels that you want to include for tracing. By default all channels are included.

[Important]Important

When using the Executor to build a Spring Integration IntegrationFlow remember to use the untraced version of the Executor. -Decorating Spring Integration Executor Channel with TraceableExecutorService will cause the spans to be improperly closed.

59.10 Zuul

We’re instrumenting the Zuul Ribbon integration by enriching the Ribbon requests with tracing information. -To disable Zuul support set the spring.sleuth.zuul.enabled property to false.

\ No newline at end of file +Decorating Spring Integration Executor Channel with TraceableExecutorService will cause the spans to be improperly closed.

60.10 Zuul

We’re instrumenting the Zuul Ribbon integration by enriching the Ribbon requests with tracing information. +To disable Zuul support set the spring.sleuth.zuul.enabled property to false.

\ No newline at end of file diff --git a/Finchley.M7/multi/multi__inter_application_communication.html b/Finchley.M7/multi/multi__inter_application_communication.html index 56398cd6..77952e3d 100644 --- a/Finchley.M7/multi/multi__inter_application_communication.html +++ b/Finchley.M7/multi/multi__inter_application_communication.html @@ -1,10 +1,10 @@ - 30. Inter-Application Communication

30. Inter-Application Communication

30.1 Connecting Multiple Application Instances

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 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 (that has the channel name output) will set the following property:

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

Log Sink (that has the channel name input) will set the following property:

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

30.2 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. + 31. Inter-Application Communication

31. Inter-Application Communication

31.1 Connecting Multiple Application Instances

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 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 (that has the channel name output) will set the following property:

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

Log Sink (that has the channel name input) will set the following property:

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

31.2 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. 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.

When Spring Cloud Stream applications are deployed via Spring Cloud Data Flow, 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.

30.3 Partitioning

30.3.1 Configuring Output Bindings for Partitioning

An output binding is configured to send partitioned data by setting one and only one of its partitionKeyExpression or partitionKeyExtractorName (see next paragraph) properties, as well as its partitionCount property.

For example, the following is a valid and typical configuration:

spring.cloud.stream.bindings.output.producer.partitionKeyExpression=payload.id
+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.

31.3 Partitioning

31.3.1 Configuring Output Bindings for Partitioning

An output binding is configured to send partitioned data by setting one and only one of its partitionKeyExpression or partitionKeyExtractorName (see next paragraph) properties, as well as its partitionCount property.

For example, the following is a valid and typical configuration:

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

Based on the above example configuration, 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 which 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 providing implementation of org.springframework.cloud.stream.binder.PartitionKeyExtractorStrategy and configuring it as a bean (i.e., @Bean). In the event you have more then one bean of type org.springframework.cloud.stream.binder.PartitionKeyExtractorStrategy available in the Application Context you can further filter it by specifying its name via partitionKeyExtractorName property:

--spring.cloud.stream.bindings.output.producer.partitionKeyExtractorName=customPartitionKeyExtractor
 --spring.cloud.stream.bindings.output.producer.partitionCount=5
@@ -28,4 +28,4 @@ With Kafka, if autoRebalanceEnabled is autoRebalanceEnabled is set to false, the instanceCount and instanceIndex are used by the binder to determine which partition(s) the instance will subscribe to (you must have at least as many partitions as there are instances).
 The binder will allocate the partitions instead of Kafka.
 This might be useful if you want messages for a particular partition to always go to the same instance.
-When a binder configuration that requires them, 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.

\ No newline at end of file +When a binder configuration that requires them, 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.

\ No newline at end of file diff --git a/Finchley.M7/multi/multi__introducing_spring_cloud_stream.html b/Finchley.M7/multi/multi__introducing_spring_cloud_stream.html index 9cdd204b..c84d35d0 100644 --- a/Finchley.M7/multi/multi__introducing_spring_cloud_stream.html +++ b/Finchley.M7/multi/multi__introducing_spring_cloud_stream.html @@ -1,6 +1,6 @@ - 23. Introducing Spring Cloud Stream

23. Introducing Spring Cloud Stream

Spring Cloud Stream is a framework for building message-driven microservice applications. + 24. Introducing Spring Cloud Stream

24. Introducing Spring Cloud Stream

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.

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.

@SpringBootApplication
@@ -37,4 +37,4 @@ You can use this in the application by autowiring it, as in the following exampl
   public void contextLoads() {
     assertNotNull(this.sink.input());
   }
-}
\ No newline at end of file +}
\ No newline at end of file diff --git a/Finchley.M7/multi/multi__introduction.html b/Finchley.M7/multi/multi__introduction.html index e5c3c60b..cc64da0c 100644 --- a/Finchley.M7/multi/multi__introduction.html +++ b/Finchley.M7/multi/multi__introduction.html @@ -1,6 +1,6 @@ - 45. Introduction

45. Introduction

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

45.1 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 + 46. Introduction

46. Introduction

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

46.1 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 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 @@ -19,7 +19,7 @@ response from the server side. If one subtracts the cs timestamp from this times 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
 Span Id = D
 Client Sent

That means that the current span has Trace-Id set to X, Span-Id set to D. Also, the - Client Sent event took place.

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

Parent child relationship

45.2 Purpose

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

45.2.1 Distributed tracing with Zipkin

Altogether there are 7 spans . If you go to traces in Zipkin you will see this number in the second trace:

Traces

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

Traces Info propagation
[Note]Note

When picking a particular trace you will see merged spans. That means that if there were 2 spans sent to + Client Sent event took place.

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

Parent child relationship

46.2 Purpose

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

46.2.1 Distributed tracing with Zipkin

Altogether there are 7 spans . If you go to traces in Zipkin you will see this number in the second trace:

Traces

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

Traces Info propagation
[Note]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.

Why is there a difference between the 7 and 4 spans in this case?

  • 2 spans come from http:/start span. It has the Server Received (SR) and Server Sent (SS) annotations.
  • 2 spans come from the RPC call from service1 to service2 to the http:/foo endpoint. The Client Sent (CS) and Client Received (CR) events took place on service1 side. Server Received (SR) and Server Sent (SS) events took place @@ -29,16 +29,16 @@ on the service3 side. Physically there are 2 spans and Client Received (CR) events took place on service2 side. Server Received (SR) and Server Sent (SS) events took place on the service4 side. Physically there are 2 spans but they form 1 logical span related to an RPC call.

So if we count the physical spans we have 1 from http:/start, 2 from service1 calling service2, 2 form service2 calling service3 and 2 from service2 calling service4. Altogether 7 spans.

Logically we see the information of Total Spans: 4 because we have 1 span related to the incoming request -to service1 and 3 spans related to RPC calls.

45.2.2 Visualizing errors

Zipkin allows you to visualize errors in your trace. When an exception was thrown and wasn’t caught then we’re +to service1 and 3 spans related to RPC calls.

46.2.2 Visualizing errors

Zipkin allows you to visualize errors in your trace. When an exception was thrown and wasn’t caught then we’re setting proper tags on the span which Zipkin can properly colorize. You could see in the list of traces one - trace that was in red color. That’s because there was an exception thrown.

If you click that trace then you’ll see a similar picture

Error Traces

Then if you click on one of the spans you’ll see the following

Error Traces Info propagation

As you can see you can easily see the reason for an error and the whole stacktrace related to it.

45.2.3 Distributed tracing with Brave

Starting with version 2.0.0, Spring Cloud Sleuth uses + trace that was in red color. That’s because there was an exception thrown.

If you click that trace then you’ll see a similar picture

Error Traces

Then if you click on one of the spans you’ll see the following

Error Traces Info propagation

As you can see you can easily see the reason for an error and the whole stacktrace related to it.

46.2.3 Distributed tracing with Brave

Starting with version 2.0.0, Spring Cloud Sleuth uses Brave as the tracing library. That means that Sleuth no longer takes care of storing the context but it delegates that work to Brave.

Due to the fact that Sleuth had different naming / tagging conventions than Brave, we’ve decided to follow the Brave’s conventions from now on. However, if you want to use the legacy Sleuth approaches, it’s enough to set the spring.sleuth.http.legacy.enabled property -to true.

45.2.4 Live examples

Figure 45.1. Click Pivotal Web Services icon to see it live!

Zipkin deployed on Pivotal Web Services

Click here to see it live!

The dependency graph in Zipkin would look like this:

Dependencies

Figure 45.2. Click Pivotal Web Services icon to see it live!

Zipkin deployed on Pivotal Web Services

Click here to see it live!

45.2.5 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
+to true.

46.2.4 Live examples

Figure 46.1. Click Pivotal Web Services icon to see it live!

Zipkin deployed on Pivotal Web Services

Click here to see it live!

The dependency graph in Zipkin would look like this:

Dependencies

Figure 46.2. Click Pivotal Web Services icon to see it live!

Zipkin deployed on Pivotal Web Services

Click here to see it live!

46.2.5 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
 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]
@@ -133,7 +133,7 @@ we’re passing the dependencies in the groupId:artifa
 		<!--<appender-ref ref="flatfile"/>-->
 	</root>
 </configuration>
[Note]Note

If you’re using a custom logback-spring.xml then you have to pass the spring.application.name in -bootstrap instead of application property file. Otherwise your custom logback file won’t read the property properly.

45.2.6 Propagating Span Context

The span context is the state that must get propagated to any child Spans across process boundaries. +bootstrap instead of application property file. Otherwise your custom logback file won’t read the property properly.

46.2.6 Propagating Span Context

The span context is the state that must get propagated to any child Spans across process boundaries. Part of the Span Context is the Baggage. The trace and span IDs are a required part of the span context. Baggage is an optional part.

Baggage is a set of key:value pairs stored in the span context. Baggage travels together with the trace and is attached to every span. Spring Cloud Sleuth will understand that a header is baggage related if the HTTP @@ -148,8 +148,8 @@ baggage and will not even receive that information.

Tags are attached to a can search by tag to find the trace, where there exists a span having the searched tag value.

If you want to be able to lookup a span based on baggage, you should add corresponding entry as a tag in the root span.

[Important]Important

Remember that the span needs to be in scope!

initialSpan.tag("foo",
 		ExtraFieldPropagation.get(initialSpan.context(), "foo"));
 initialSpan.tag("UPPER_CASE",
-		ExtraFieldPropagation.get(initialSpan.context(), "UPPER_CASE"));

45.3 Adding to the project

[Important]Important

To ensure that your application name is properly displayed in Zipkin - set the spring.application.name property in bootstrap.yml.

45.3.1 Only Sleuth (log correlation)

If you want to profit only from Spring Cloud Sleuth without the Zipkin integration just add + ExtraFieldPropagation.get(initialSpan.context(), "UPPER_CASE"));

46.3 Adding to the project

[Important]Important

To ensure that your application name is properly displayed in Zipkin + set the spring.application.name property in bootstrap.yml.

46.3.1 Only Sleuth (log correlation)

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.

Maven. 

<dependencyManagement> 1
       <dependencies>
@@ -179,7 +179,7 @@ dependencies { "org.springframework.cloud:spring-cloud-starter-sleuth"
 }

1

In order not to pick versions by yourself it’s much better if you add the dependency management via -the Spring BOM

2

Add the dependency to spring-cloud-starter-sleuth

45.3.2 Sleuth with Zipkin via HTTP

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

Maven.  +the Spring BOM

2

Add the dependency to spring-cloud-starter-sleuth

46.3.2 Sleuth with Zipkin via HTTP

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

Maven. 

<dependencyManagement> 1
       <dependencies>
           <dependency>
@@ -208,7 +208,7 @@ dependencies { "org.springframework.cloud:spring-cloud-starter-zipkin"
 }

1

In order not to pick versions by yourself it’s much better if you add the dependency management via -the Spring BOM

2

Add the dependency to spring-cloud-starter-zipkin

45.3.3 Sleuth with Zipkin via RabbitMQ or Kafka

If you want to use RabbitMQ or Kafka instead of http, add the spring-rabbit or spring-kafka +the Spring BOM

2

Add the dependency to spring-cloud-starter-zipkin

46.3.3 Sleuth with Zipkin via RabbitMQ or Kafka

If you want to use RabbitMQ or Kafka instead of http, add the spring-rabbit or spring-kafka dependencies. The default destination name is zipkin.

Note: spring-cloud-sleuth-stream is deprecated and incompatible with these destinations

If you want Sleuth over RabbitMQ add the spring-cloud-starter-zipkin and spring-rabbit dependencies.

Maven. 

<dependencyManagement> 1
@@ -244,4 +244,4 @@ dependencies {
     compile "org.springframework.amqp:spring-rabbit" 3
 }

1

In order not to pick versions by yourself it’s much better if you add the dependency management via -the Spring BOM

2

Add the dependency to spring-cloud-starter-zipkin - that way all dependent dependencies will be downloaded

3

To automatically configure rabbit, simply add the spring-rabbit dependency

\ No newline at end of file +the Spring BOM

2

Add the dependency to spring-cloud-starter-zipkin - that way all dependent dependencies will be downloaded

3

To automatically configure rabbit, simply add the spring-rabbit dependency

\ No newline at end of file diff --git a/Finchley.M7/multi/multi__links.html b/Finchley.M7/multi/multi__links.html index b9085d1b..9919af53 100644 --- a/Finchley.M7/multi/multi__links.html +++ b/Finchley.M7/multi/multi__links.html @@ -1,6 +1,6 @@ - 93. Links \ No newline at end of file diff --git a/Finchley.M7/multi/multi__main_concepts.html b/Finchley.M7/multi/multi__main_concepts.html index 30cd74dd..8d618dc7 100644 --- a/Finchley.M7/multi/multi__main_concepts.html +++ b/Finchley.M7/multi/multi__main_concepts.html @@ -1,34 +1,34 @@ - 24. Main Concepts

24. Main Concepts

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’s application model
  • The Binder abstraction
  • Persistent publish-subscribe support
  • Consumer group support
  • Partitioning support
  • A pluggable Binder API

24.1 Application Model

A Spring Cloud Stream application consists of a middleware-neutral core. + 25. Main Concepts

25. Main Concepts

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’s application model
  • The Binder abstraction
  • Persistent publish-subscribe support
  • Consumer group support
  • Partitioning support
  • A pluggable Binder API

25.1 Application Model

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.

Figure 24.1. Spring Cloud Stream Application

SCSt with binder

24.1.1 Fat JAR

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.

24.2 The Binder Abstraction

Spring Cloud Stream provides Binder implementations for Kafka and Rabbit MQ. +Channels are connected to external brokers through middleware-specific Binder implementations.

Figure 25.1. Spring Cloud Stream Application

SCSt with binder

25.1.1 Fat JAR

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.

25.2 The Binder Abstraction

Spring Cloud Stream provides Binder implementations for Kafka and Rabbit MQ. 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 Chapter 23, 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. +In the sink example from the Chapter 24, 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.

24.3 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.

Figure 24.2. Spring Cloud Stream Publish-Subscribe

SCSt sensors

Data reported by sensors to an HTTP endpoint is sent to a common destination named raw-sensor-data. +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.

25.3 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.

Figure 25.2. Spring Cloud Stream Publish-Subscribe

SCSt sensors

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. -By using native middleware support, Spring Cloud Stream also simplifies use of the publish-subscribe model across different platforms.

24.4 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. +By using native middleware support, Spring Cloud Stream also simplifies use of the publish-subscribe model across different platforms.

25.4 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.<channelName>.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.<channelName>.group=hdfsWrite or spring.cloud.stream.bindings.<channelName>.group=average.

Figure 24.3. Spring Cloud Stream Consumer Groups

SCSt 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.

24.5 Consumer Types

Two types of consumer are supported:

  • Message-driven (sometimes referred to as Asynchronous)
  • Polled (sometimes referred to as Synchronous)

Prior to version 2.0, only asynchronous consumers were supported, where a message is delivered as soon as it is available (and there is a thread available to process it).

You might want to use a synchronous consumer when you wish to control the rate at which messages are processed.

24.5.1 Durability

Consistent with the opinionated application model of Spring Cloud Stream, consumer group subscriptions are durable. +For the consumers shown in the following figure, this property would be set as spring.cloud.stream.bindings.<channelName>.group=hdfsWrite or spring.cloud.stream.bindings.<channelName>.group=average.

Figure 25.3. Spring Cloud Stream Consumer Groups

SCSt 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.

25.5 Consumer Types

Two types of consumer are supported:

  • Message-driven (sometimes referred to as Asynchronous)
  • Polled (sometimes referred to as Synchronous)

Prior to version 2.0, only asynchronous consumers were supported, where a message is delivered as soon as it is available (and there is a thread available to process it).

You might want to use a synchronous consumer when you wish to control the rate at which messages are processed.

25.5.1 Durability

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]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, 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).

24.6 Partitioning Support

Spring Cloud Stream provides support for partitioning data between multiple instances of a given application. +This prevents the application’s instances from receiving duplicate messages (unless that behavior is desired, which is unusual).

25.6 Partitioning Support

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).

Figure 24.4. Spring Cloud Stream Partitioning

SCSt partitioning

Partitioning is a critical concept in stateful processing, where it is critical, 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]Note

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

\ No newline at end of file +Partitioning can thus be used whether the broker itself is naturally partitioned (e.g., Kafka) or not (e.g., RabbitMQ).

Figure 25.4. Spring Cloud Stream Partitioning

SCSt partitioning

Partitioning is a critical concept in stateful processing, where it is critical, 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]Note

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

\ No newline at end of file diff --git a/Finchley.M7/multi/multi__managing_spans_with_annotations.html b/Finchley.M7/multi/multi__managing_spans_with_annotations.html index b76dcb99..ee098c8a 100644 --- a/Finchley.M7/multi/multi__managing_spans_with_annotations.html +++ b/Finchley.M7/multi/multi__managing_spans_with_annotations.html @@ -1,11 +1,11 @@ - 55. Managing spans with annotations

55. Managing spans with annotations

55.1 Rationale

The main arguments for this features are

  • api-agnostic means to collaborate with a span

    • use of annotations allows users to add to a span with no library dependency on a span api. + 56. Managing spans with annotations

      56. Managing spans with annotations

      56.1 Rationale

      The main arguments for this features are

      • api-agnostic means to collaborate with a span

        • use of annotations allows users to add to a span with no library dependency on a span api. This allows Sleuth to change its core api less impact to user code.
      • reduced surface area for basic span operations.

        • without this feature one has to use the span api, which has lifecycle commands that could be used incorrectly. By only exposing scope, tag and log functionality, users can collaborate without accidentally breaking span lifecycle.
      • collaboration with runtime generated code

        • with libraries such as Spring Data / Feign the implementations of interfaces are generated at runtime thus span wrapping of objects was tedious. Now you can provide annotations - over interfaces and arguments of those interfaces

      55.2 Creating new spans

      If you really don’t want to take care of creating local spans manually you can profit from the + over interfaces and arguments of those interfaces

56.2 Creating new spans

If you really don’t want to take care of creating local spans manually you can profit from the @NewSpan annotation. Also we give you the @SpanTag annotation to add tags in an automated fashion.

Let’s look at some examples of usage.

@NewSpan
 void testMethod();

Annotating the method without any parameter will lead to a creation of a new span whose name @@ -23,7 +23,7 @@ the tag key will be testTag and the tag value will public void testMethod3() { }

You can place the @NewSpan annotation on both the class and an interface. If you override the interface’s method and provide a different value of the @NewSpan annotation then the most -concrete one wins (in this case customNameOnTestMethod3 will be set).

55.3 Continuing spans

If you want to just add tags and annotations to an existing span it’s enough +concrete one wins (in this case customNameOnTestMethod3 will be set).

56.3 Continuing spans

If you want to just add tags and annotations to an existing span it’s enough to use the @ContinueSpan annotation as presented below. Note that in contrast with the @NewSpan annotation you can also add logs via the log parameter:

// method declaration
 @ContinueSpan(log = "testMethod11")
@@ -31,18 +31,18 @@ with the @NewSpan annotation you can also add logs
 
 // method execution
 this.testBean.testMethod11("test");
-this.testBean.testMethod13();

That way the span will get continued and:

  • logs with name testMethod11.before and testMethod11.after will be created
  • if an exception will be thrown a log testMethod11.afterFailure will also be created
  • tag with key testTag11 and value test will be created

55.4 More advanced tag setting

There are 3 different ways to add tags to a span. All of them are controlled by the SpanTag annotation. +this.testBean.testMethod13();

That way the span will get continued and:

  • logs with name testMethod11.before and testMethod11.after will be created
  • if an exception will be thrown a log testMethod11.afterFailure will also be created
  • tag with key testTag11 and value test will be created

56.4 More advanced tag setting

There are 3 different ways to add tags to a span. All of them are controlled by the SpanTag annotation. Precedence is:

  • try with the bean of TagValueResolver type and provided name
  • if one hasn’t provided the bean name, try to evaluate an expression. We’re searching for a TagValueExpressionResolver bean. -The default implementation uses SPEL expression resolution.
  • if one hasn’t provided any expression to evaluate just return a toString() value of the parameter

55.4.1 Custom extractor

The value of the tag for following method will be computed by an implementation of TagValueResolver interface. +The default implementation uses SPEL expression resolution.

  • if one hasn’t provided any expression to evaluate just return a toString() value of the parameter
  • 56.4.1 Custom extractor

    The value of the tag for following method will be computed by an implementation of TagValueResolver interface. Its class name has to be passed as the value of the resolver attribute.

    Having such an annotated method:

    @NewSpan
     public void getAnnotationForTagValueResolver(@SpanTag(key = "test", resolver = TagValueResolver.class) String test) {
     }

    and such a TagValueResolver bean implementation

    @Bean(name = "myCustomTagValueResolver")
     public TagValueResolver tagValueResolver() {
     	return parameter -> "Value from myCustomTagValueResolver";
    -}

    Will lead to setting of a tag value equal to Value from myCustomTagValueResolver.

    55.4.2 Resolving expressions for value

    Having such an annotated method:

    @NewSpan
    +}

    Will lead to setting of a tag value equal to Value from myCustomTagValueResolver.

    56.4.2 Resolving expressions for value

    Having such an annotated method:

    @NewSpan
     public void getAnnotationForTagValueExpression(@SpanTag(key = "test", expression = "length() + ' characters'") String test) {
     }

    and no custom implementation of a TagValueExpressionResolver will lead to evaluation of the SPEL expression and a tag with value 4 characters will be set on the span. If you want to use some other expression resolution mechanism you can create your own implementation -of the bean.

    55.4.3 Using toString method

    Having such an annotated method:

    @NewSpan
    +of the bean.

    56.4.3 Using toString method

    Having such an annotated method:

    @NewSpan
     public void getAnnotationForArgumentToString(@SpanTag("test") Long param) {
    -}

    if executed with a value of 15 will lead to setting of a tag with a String value of "15".

    \ No newline at end of file +}

    if executed with a value of 15 will lead to setting of a tag with a String value of "15".

    \ No newline at end of file diff --git a/Finchley.M7/multi/multi__metrics_emitter.html b/Finchley.M7/multi/multi__metrics_emitter.html index 2c4cd545..6079afa1 100644 --- a/Finchley.M7/multi/multi__metrics_emitter.html +++ b/Finchley.M7/multi/multi__metrics_emitter.html @@ -1,6 +1,6 @@ - 33. Metrics Emitter

    33. Metrics Emitter

    Spring Cloud Stream provides a module called spring-cloud-stream-metrics that can be used to emit any available metric from Spring Boot metrics endpoint to a named channel. + 34. Metrics Emitter

    34. Metrics Emitter

    Spring Cloud Stream provides a module called spring-cloud-stream-metrics that can be used to emit any available metric from Spring Boot metrics endpoint to a named channel. This module allow operators to collect metrics from stream applications without relying on polling their endpoints.

    The module is activated when you set the destination name for metrics binding, e.g. spring.cloud.stream.bindings.applicationMetrics.destination=<DESTINATION_NAME>. applicationMetrics can be configured in a similar fashion to any other producer binding. The default contentType setting of applicationMetrics is application/json.

    The following properties can be used for customizing the emission of metrics:

    spring.cloud.stream.metrics.key
    The name of the metric being emitted. Should be an unique value per application.
    Default
    ${spring.application.name:${vcap.application.name:${spring.config.name:application}}}
    spring.cloud.stream.metrics.prefix

    Prefix string to be prepended to the metrics key.

    Default: ``

    spring.cloud.stream.metrics.properties

    Just like the includes option, it allows white listing application properties that will be added to the metrics payload

    Default: null.

    A detailed overview of the metrics export process can be found in the Spring Boot reference documentation. @@ -74,4 +74,4 @@ Alternatively, if it is intended to use configuration settings that are differen "spring.application.name":"time-source", "spring.application.index":"0" } -}

    \ No newline at end of file +}
    \ No newline at end of file diff --git a/Finchley.M7/multi/multi__migrations.html b/Finchley.M7/multi/multi__migrations.html index 01c9ef60..b2f483a3 100644 --- a/Finchley.M7/multi/multi__migrations.html +++ b/Finchley.M7/multi/multi__migrations.html @@ -1,7 +1,7 @@ - 92. Migrations

    92. Migrations

    This section covers migrating from one version of Spring Cloud Contract Verifier to the -next version. It covers the following versions upgrade paths:

    92.1 1.0.x → 1.1.x

    This section covers upgrading from version 1.0 to version 1.1.

    92.1.1 New structure of generated stubs

    In 1.1.x we have introduced a change to the structure of generated stubs. If you have + 93. Migrations

    93. Migrations

    This section covers migrating from one version of Spring Cloud Contract Verifier to the +next version. It covers the following versions upgrade paths:

    93.1 1.0.x → 1.1.x

    This section covers upgrading from version 1.0 to version 1.1.

    93.1.1 New structure of generated stubs

    In 1.1.x we have introduced a change to the structure of generated stubs. If you have been using the @AutoConfigureWireMock notation to use the stubs from the classpath, it no longer works. The following example shows how the @AutoConfigureWireMock notation used to work:

    @AutoConfigureWireMock(stubs = "classpath:/customer-stubs/mappings", port = 8084)

    You must either change the location of the stubs to: @@ -79,18 +79,18 @@ structure presented in the previous snippet.

    Maven.&nbs from "${project.buildDir}/resources/main/customer-stubs/META-INF/${project.group}/${project.name}/${project.version}" into "${project.buildDir}/resources/main/customer-stubs" }

    -

    92.2 1.1.x → 1.2.x

    This section covers upgrading from version 1.1 to version 1.2.

    92.2.1 Custom HttpServerStub

    HttpServerStub includes a method that was not in version 1.1. The method is +

    93.2 1.1.x → 1.2.x

    This section covers upgrading from version 1.1 to version 1.2.

    93.2.1 Custom HttpServerStub

    HttpServerStub includes a method that was not in version 1.1. The method is String registeredMappings() If you have classes that implement HttpServerStub, you now have to implement the registeredMappings() method. It should return a String representing all mappings available in a single HttpServerStub.

    See issue 355 for more -detail.

    92.2.2 New packages for generated tests

    The flow for setting the generated tests package name will look like this:

    • Set basePackageForTests
    • If basePackageForTests was not set, pick the package from baseClassForTests
    • If baseClassForTests was not set, pick packageWithBaseClasses
    • If nothing got set, pick the default value: +detail.

    93.2.2 New packages for generated tests

    The flow for setting the generated tests package name will look like this:

    • Set basePackageForTests
    • If basePackageForTests was not set, pick the package from baseClassForTests
    • If baseClassForTests was not set, pick packageWithBaseClasses
    • If nothing got set, pick the default value: org.springframework.cloud.contract.verifier.tests

    See issue 260 for more -detail.

    92.2.3 New Methods in TemplateProcessor

    In order to add support for fromRequest.path, the following methods had to be added to the +detail.

    93.2.3 New Methods in TemplateProcessor

    In order to add support for fromRequest.path, the following methods had to be added to the TemplateProcessor interface:

    • path()
    • path(int index)

    See issue 388 for more -detail.

    92.2.4 RestAssured 3.0

    Rest Assured, used in the generated test classes, got bumped to 3.0. If +detail.

    93.2.4 RestAssured 3.0

    Rest Assured, used in the generated test classes, got bumped to 3.0. If you manually set versions of Spring Cloud Contract and the release train you might see the following exception:

    Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.1:testCompile (default-testCompile) on project some-project: Compilation failure: Compilation failure:
     [ERROR] /some/path/SomeClass.java:[4,39] package com.jayway.restassured.response does not exist

    This exception will occur due to the fact that the tests got generated with an old version of plugin and at test execution time you have an incompatible -version of the release train (and vice versa).

    Done via issue 267

    92.3 1.2.x → 2.0.x

    92.3.1 No Camel support

    We will add back Apache Camel support only after this issue -gets fixed

    \ No newline at end of file +version of the release train (and vice versa).

    Done via issue 267

    93.3 1.2.x → 2.0.x

    93.3.1 No Camel support

    We will add back Apache Camel support only after this issue +gets fixed

    \ No newline at end of file diff --git a/Finchley.M7/multi/multi__more_detail.html b/Finchley.M7/multi/multi__more_detail.html index 0e38c217..009fb858 100644 --- a/Finchley.M7/multi/multi__more_detail.html +++ b/Finchley.M7/multi/multi__more_detail.html @@ -1,11 +1,11 @@ - 77. More Detail

    77. More Detail

    77.1 Single Sign On

    [Note]Note

    All of the OAuth2 SSO and resource server features moved to Spring Boot + 78. More Detail

    78. More Detail

    78.1 Single Sign On

    [Note]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.

    77.2 Token Relay

    A Token Relay is where an OAuth2 consumer acts as a Client and +Spring Boot user guide.

    78.2 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.

    77.2.1 Client Token Relay

    If your app is a user facing OAuth2 client (i.e. has declared +Server.

    78.2.1 Client Token Relay

    If your app is a user facing OAuth2 client (i.e. has declared @EnableOAuth2Sso or @EnableOAuth2Client) then it has an OAuth2ClientContext in request scope from Spring Boot. You can create your own OAuth2RestTemplate from this context and an @@ -16,7 +16,7 @@ Security and Spring Boot.)

    OAuth2ProtectedResourceDetails automatically if you are using client_credentials tokens. In that case you need to create your own ClientCredentialsResourceDetails and configure it with -@ConfigurationProperties("security.oauth2.client").

    77.2.2 Client Token Relay in Zuul Proxy

    If your app also has a +@ConfigurationProperties("security.oauth2.client").

    78.2.2 Client Token Relay in Zuul Proxy

    If your app also has a Spring Cloud Zuul embedded reverse proxy (using @EnableZuulProxy) then you can ask it to forward OAuth2 access tokens downstream to the services @@ -39,7 +39,7 @@ a ZuulFilter, which itself is activated because Zuu 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.

    77.2.3 Resource Server Token Relay

    If your app has @EnableResourceServer you might want to relay the +and puts it in a request header for the downstream requests.

    78.2.3 Resource Server Token Relay

    If your app has @EnableResourceServer you might want to relay the incoming token downstream to other services. If you use a RestTemplate to contact the downstream services then this is just a matter of how to create the template with the right context.

    If your service uses UserInfoTokenServices to authenticate incoming @@ -81,4 +81,4 @@ 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 OAuth2Context instead of autowiring the default one.

    Feign clients will also pick up an interceptor that uses the OAuth2ClientContext if it is available, so they should also do a -token relay anywhere where a RestTemplate would.

    \ No newline at end of file +token relay anywhere where a RestTemplate would.

    \ No newline at end of file diff --git a/Finchley.M7/multi/multi__naming_spans.html b/Finchley.M7/multi/multi__naming_spans.html index c8237be2..a6ff9c3a 100644 --- a/Finchley.M7/multi/multi__naming_spans.html +++ b/Finchley.M7/multi/multi__naming_spans.html @@ -1,8 +1,8 @@ - 54. Naming spans

    54. Naming spans

    Picking a span name is not a trivial task. Span name should depict an operation name. The name should + 55. Naming spans

    55. 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:

    • controller-method-name when received by a Controller with a method name conrollerMethodName
    • 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.

    54.1 @SpanName annotation

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

    @SpanName("calculateTax")
    +artificial like:

    • controller-method-name when received by a Controller with a method name conrollerMethodName
    • 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.

    55.1 @SpanName annotation

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

    @SpanName("calculateTax")
     class TaxCountingRunnable implements Runnable {
     
     	@Override public void run() {
    @@ -12,7 +12,7 @@ artificial like:

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

    The span will be named calculateTax.

    54.2 toString() method

    It’s pretty rare to create separate classes for Runnable or Callable. Typically one creates an anonymous +future.get();

    The span will be named calculateTax.

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

    Runnable runnable = new TraceRunnable(tracer, spanNamer, errorParser, new Runnable() {
     	@Override public void run() {
    @@ -25,4 +25,4 @@ we’re checking if the class has a custom implementation of the // ... some additional logic ...
    -future.get();

    will lead in creating a span named calculateTax.

    \ No newline at end of file +future.get();

    will lead in creating a span named calculateTax.

    \ No newline at end of file diff --git a/Finchley.M7/multi/multi__programming_model.html b/Finchley.M7/multi/multi__programming_model.html index 71f40c6e..ea886015 100644 --- a/Finchley.M7/multi/multi__programming_model.html +++ b/Finchley.M7/multi/multi__programming_model.html @@ -1,7 +1,7 @@ - 25. Programming Model

    25. Programming Model

    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.

    25.1 Declaring and Binding Producers and Consumers

    25.1.1 Triggering Binding Via @EnableBinding

    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. + 26. Programming Model

    26. Programming Model

    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.

    26.1 Declaring and Binding Producers and Consumers

    26.1.1 Triggering Binding Via @EnableBinding

    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:

    ...
     @Import(...)
     @Configuration
    @@ -10,7 +10,7 @@ The @EnableBinding annotation itself is meta-annota
         ...
         Class<?>[] value() default {};
     }

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

    [Note]Note

    The @EnableBinding annotation is only required on your Configuration classes, you can provide as many binding interfaces as you need, for instance: @EnableBinding(value={Orders.class, Payment.class}. -Where both Order and Payment interfaces would declare @Input and @Output channels.

    25.1.2 @Input and @Output

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

    public interface Barista {
    +Where both Order and Payment interfaces would declare @Input and @Output channels.

    26.1.2 @Input and @Output

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

    public interface Barista {
     
         @Input
         SubscribableChannel orders();
    @@ -57,7 +57,7 @@ In this documentation, we will continue to refer to MessageChannels as the 

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

    public interface Processor extends Source, Sink {
    -}

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

    25.1.3 Accessing Bound Channels

    Injecting the Bound Interfaces

    For each bound interface, Spring Cloud Stream will generate a bean that implements the interface. +}

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

    26.1.3 Accessing Bound Channels

    Injecting the Bound Interfaces

    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.

    @Component
     public class SendingBean {
    @@ -103,7 +103,7 @@ Given the following declaration:

    public void sayHello(String name) {
              this.output.send(MessageBuilder.withPayload(name).build());
         }
    -}

    25.1.4 Producing and Consuming Messages

    You can write a Spring Cloud Stream application using either Spring Integration annotations or Spring Cloud Stream’s @StreamListener annotation. +}

    26.1.4 Producing and Consuming Messages

    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

    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:

    @EnableBinding(Source.class)
     public class TimerSource {
    @@ -220,7 +220,7 @@ You can override that behavior, by taking responsibility for the acknowledgment,
     			Map<String, Foo> payload = (Map<String, Foo>) received.getPayload();
                 ...
     
    -		}, new ParameterizedTypeReference<Map<String, Foo>>() {});

    25.1.5 Reactive Programming Support

    Spring Cloud Stream also supports the use of reactive APIs where incoming and outgoing data is handled as continuous data flows. + }, new ParameterizedTypeReference<Map<String, Foo>>() {});

    26.1.5 Reactive Programming Support

    Spring Cloud Stream also supports the use of reactive APIs where incoming and outgoing data is handled as continuous data flows. Support for reactive APIs is available via the spring-cloud-stream-reactive, which needs to be added explicitly to your project.

    The programming model with reactive APIs is declarative, where instead of specifying how each individual message should be handled, you can use operators that describe functional transformations from inbound to outbound data flows.

    Spring Cloud Stream supports the following reactive APIs:

    • Reactor

    In the future, it is intended to support a more generic model based on Reactive Streams.

    The reactive programming model is also using the @StreamListener annotation for setting up reactive handlers. The differences are that:

    • the @StreamListener annotation must not specify an input or output, as they are provided as arguments and return values from the method;
    • the arguments of the method must be annotated with @Input and @Output indicating which input or output will the incoming and respectively outgoing data flows connect to;
    • the return value of the method, if any, will be annotated with @Output, indicating the input where data shall be sent.
    [Note]Note

    Reactive programming support requires Java 1.8.

    [Note]Note

    As of Spring Cloud Stream 1.1.1 and later (starting with release train Brooklyn.SR2), reactive programming support requires the use of Reactor 3.0.4.RELEASE and higher. Earlier Reactor versions (including 3.0.1.RELEASE, 3.0.2.RELEASE and 3.0.3.RELEASE) are not supported. spring-cloud-stream-reactive will transitively retrieve the proper version, but it is possible for the project structure to manage the version of the io.projectreactor:reactor-core to an earlier release, especially when using Maven. @@ -295,7 +295,7 @@ The Publisher is still using Reactor Flux under the hood, but from an applicatio e -> e.poller(p -> p.fixedDelay(1))) .toReactivePublisher(); } -}

    25.1.6 Aggregation

    Spring Cloud Stream provides support for aggregating multiple applications together, connecting their input and output channels directly and avoiding the additional cost of exchanging messages via a broker. +}

    26.1.6 Aggregation

    Spring Cloud Stream provides support for aggregating multiple applications together, connecting their input and output channels directly and avoiding the additional cost of exchanging messages via a broker. As of version 1.0 of Spring Cloud Stream, aggregation is supported only for the following types of applications:

    • sources - applications with a single output channel named output, typically having a single binding of the type org.springframework.cloud.stream.messaging.Source
    • sinks - applications with a single input channel named input, typically having a single binding of the type org.springframework.cloud.stream.messaging.Sink
    • processors - applications with a single input channel named input and a single output channel named output, typically having a single binding of the type org.springframework.cloud.stream.messaging.Processor.

    They can be aggregated together by creating a sequence of interconnected applications, in which the output channel of an element in the sequence is connected to the input channel of the next element, if it exists. A sequence can start with either a source or a processor, it can contain an arbitrary number of processors and must end with either a processor or a sink.

    Depending on the nature of the starting and ending element, the sequence may have one or more bindable channels, as follows:

    • if the sequence starts with a source and ends with a sink, all communication between the applications is direct and no channels will be bound
    • if the sequence starts with a processor, then its input channel will become the input channel of the aggregate and will be bound accordingly
    • if the sequence ends with a processor, then its output channel will become the output channel of the aggregate and will be bound accordingly

    Aggregation is performed using the AggregateApplicationBuilder utility class, as in the following example. Let’s consider a project in which we have source, processor and a sink, which may be defined in the project, or may be contained in one of the project’s dependencies.

    [Note]Note

    Each component (source, sink or processor) in an aggregate application must be provided in a separate package if the configuration classes use @SpringBootApplication. @@ -376,4 +376,4 @@ For instance,

    class).namespace("source").args("--fixedDelay=5000")
                 .via(ProcessorApplication.class).namespace("processor1").args("--debug=true").run(args);
         }
    -}

    The binding properties like --spring.cloud.stream.bindings.output.destination=processor-output need to be specified as one of the external configuration properties (cmdline arg etc.).

    \ No newline at end of file +}

    The binding properties like --spring.cloud.stream.bindings.output.destination=processor-output need to be specified as one of the external configuration properties (cmdline arg etc.).

    \ No newline at end of file diff --git a/Finchley.M7/multi/multi__propagation.html b/Finchley.M7/multi/multi__propagation.html index e31b5f08..a7b5d431 100644 --- a/Finchley.M7/multi/multi__propagation.html +++ b/Finchley.M7/multi/multi__propagation.html @@ -1,6 +1,6 @@ - 49. Propagation

    49. Propagation

    Propagation is needed to ensure activity originating from the same root + 50. Propagation

    50. Propagation

    Propagation is needed to ensure activity originating from the same root are collected together in the same trace. The most common propagation approach is to copy a trace context from a client sending an RPC request to a server receiving it.

    For example, when an downstream Http call is made, its trace context is @@ -29,7 +29,7 @@ injector.inject(span.context(), request);

    Here’s what server-side extracted = tracing.propagation().extractor(Request::getHeader); // when a server receives a request, it joins or starts a new trace -span = tracer.nextSpan(extracted, request);

    49.1 Propagating extra fields

    Sometimes you need to propagate extra fields, such as a request ID or an alternate trace context. +span = tracer.nextSpan(extracted, request);

    50.1 Propagating extra fields

    Sometimes you need to propagate extra fields, such as a request ID or an alternate trace context. For example, if you are in a Cloud Foundry environment, you might want to pass the request ID:

    // when you initialize the builder, define the extra field you want to propagate
     tracingBuilder.propagationFactory(
       ExtraFieldPropagation.newFactory(B3Propagation.FACTORY, "x-vcap-request-id")
    @@ -40,7 +40,7 @@ requestId = ExtraFieldPropagation.get(tracingBuilder.propagationFactory(
       ExtraFieldPropagation.newFactory(B3Propagation.FACTORY, "x-amzn-trace-id")
    -);

    49.1.1 Prefixed fields

    You can also prefix fields, if they follow a common pattern. For example, the following will +);

    50.1.1 Prefixed fields

    You can also prefix fields, if they follow a common pattern. For example, the following will propagate the field "x-vcap-request-id" as-is, but send the fields "country-code" and "user-id" on the wire as "x-baggage-country-code" and "x-baggage-user-id" respectively.

    Setup your tracing instance with allowed fields:

    tracingBuilder.propagationFactory(
       ExtraFieldPropagation.newFactoryBuilder(B3Propagation.FACTORY)
    @@ -54,11 +54,11 @@ Brave it’s required to pass the list of baggage keys.
     There are two properties to achieve this. Via the spring.sleuth.baggage-keys you set keys
     that will get prefixed with baggage- for http calls and baggage_ for messaging. You can also pass
     a list of prefixed keys that will be whitelisted without any prefix via
    -spring.sleuth.propagation-keys property.

    49.1.2 Extracting a propagated context

    The TraceContext.Extractor<C> reads trace identifiers and sampling status +spring.sleuth.propagation-keys property.

    50.1.2 Extracting a propagated context

    The TraceContext.Extractor<C> reads trace identifiers and sampling status from an incoming request or message. The carrier is usually a request object or headers.

    This utility is used in standard instrumentation like [HttpServerHandler](../instrumentation/http/src/main/java/sleuth/http/HttpServerHandler.java), but can also be used for custom RPC or messaging code.

    TraceContextOrSamplingFlags is usually only used with Tracer.nextSpan(extracted), unless you are -sharing span IDs between a client and a server.

    49.1.3 Sharing span IDs between client and server

    A normal instrumentation pattern is creating a span representing the server +sharing span IDs between a client and a server.

    50.1.3 Sharing span IDs between client and server

    A normal instrumentation pattern is creating a span representing the server side of an RPC. Extractor.extract might return a complete trace context when applied to an incoming client request. Tracer.joinSpan attempts to continue the this trace, using the same span ID if supported, or creating a child span @@ -87,7 +87,7 @@ always provisioned and the incoming context determines the parent ID.

    Here └───────────────────┘

    Note: Some span reporters do not support sharing span IDs. For example, if you set Tracing.Builder.spanReporter(amazonXrayOrGoogleStackdrive), disable join via Tracing.Builder.supportsJoin(false). This will force a new child span on -Tracer.joinSpan().

    49.1.4 Implementing Propagation

    TraceContext.Extractor<C> is implemented by a Propagation.Factory plugin. Internally, this code +Tracer.joinSpan().

    50.1.4 Implementing Propagation

    TraceContext.Extractor<C> is implemented by a Propagation.Factory plugin. Internally, this code will create the union type TraceContextOrSamplingFlags with one of the following: * TraceContext if trace and span IDs were present. * TraceIdContext if a trace ID was present, but not span IDs. @@ -95,4 +95,4 @@ will create the union type TraceContextOrSamplingFlagsTraceContext was extracted, add the extra data as TraceContext.extra() -* Otherwise, add it as TraceContextOrSamplingFlags.extra(), which Tracer.nextSpan handles.

    \ No newline at end of file +* Otherwise, add it as TraceContextOrSamplingFlags.extra(), which Tracer.nextSpan handles.

    \ No newline at end of file diff --git a/Finchley.M7/multi/multi__quick_start_2.html b/Finchley.M7/multi/multi__quick_start_2.html index cfcb7543..e9737764 100644 --- a/Finchley.M7/multi/multi__quick_start_2.html +++ b/Finchley.M7/multi/multi__quick_start_2.html @@ -1,10 +1,10 @@ - 38. Quick Start

    38. 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 or spring-cloud-starter-bus-kafka to your dependency management and Spring Cloud takes care of the rest. Make sure the broker (RabbitMQ or Kafka) is available and configured: 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. for Rabbit

    application.yml.  + 39. Quick Start

    39. 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 or spring-cloud-starter-bus-kafka to your dependency management and Spring Cloud takes care of the rest. Make sure the broker (RabbitMQ or Kafka) is available and configured: 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. for Rabbit

    application.yml. 

    spring:
       rabbitmq:
         host: mybroker.com
         port: 5672
         username: user
         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 may be added in the future (ie. only service X nodes in data center Y, etc…​). There are also some http endpoints under the /bus/* actuator namespace. There are currently two implemented. The first, /bus/env, sends key/value pairs to update each node’s Spring Environment. The second, /bus/refresh, will reload each application’s configuration, just as if they had all been pinged on their /refresh endpoint.

    [Note]Note

    The Bus starters cover Rabbit and Kafka, because those are the two most common implementations, but Spring Cloud Stream is quite flexible and binder will work combined with spring-cloud-bus.

    \ No newline at end of file +

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

    [Note]Note

    The Bus starters cover Rabbit and Kafka, because those are the two most common implementations, but Spring Cloud Stream is quite flexible and binder will work combined with spring-cloud-bus.

    \ No newline at end of file diff --git a/Finchley.M7/multi/multi__quick_start_3.html b/Finchley.M7/multi/multi__quick_start_3.html index 541419ea..b1067cc5 100644 --- a/Finchley.M7/multi/multi__quick_start_3.html +++ b/Finchley.M7/multi/multi__quick_start_3.html @@ -1,6 +1,6 @@ - 94. Quick Start

    94. Quick Start

    Prerequisites

    To get started with Vault and this guide you need a + 95. Quick Start

    95. Quick Start

    Prerequisites

    To get started with Vault and this guide you need a *NIX-like operating systems that provides:

    • wget, openssl and unzip
    • at least Java 7 and a properly configured JAVA_HOME environment variable

    Install Vault

    $ src/test/bash/install_vault.sh

    Create SSL certificates for Vault

    $ src/test/bash/create_certificates.sh
    [Note]Note

    create_certificates.sh creates certificates in work/ca and a JKS truststore work/keystore.jks. If you want to run Spring Cloud Vault using this quickstart guide you need to configure the truststore the spring.cloud.vault.ssl.trust-store property to file:work/keystore.jks.

    Start Vault server

    $ src/test/bash/local_run_vault.sh

    Vault is started listening on 0.0.0.0:8200 using the inmem storage and https. Vault is sealed and not initialized when starting up.

    [Note]Note

    If you want to run tests, leave Vault uninitialized. The tests will @@ -34,4 +34,4 @@ backend is enabled which accesses secret config settings via JSON endpoints.

    SpringApplication (i.e. what is normally "application" in a regular Spring Boot app), "profile" is an active profile (or comma-separated list of properties). Properties retrieved from Vault will be used "as-is" -without further prefixing of the property names.

    \ No newline at end of file +without further prefixing of the property names.

    \ No newline at end of file diff --git a/Finchley.M7/multi/multi__quickstart.html b/Finchley.M7/multi/multi__quickstart.html index 6c0c426f..b680ae60 100644 --- a/Finchley.M7/multi/multi__quickstart.html +++ b/Finchley.M7/multi/multi__quickstart.html @@ -1,6 +1,6 @@ - 76. Quickstart

    76. Quickstart

    76.1 OAuth2 Single Sign On

    Here’s a Spring Cloud "Hello World" app with HTTP Basic + 77. Quickstart

    77. Quickstart

    77.1 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')
     @Controller
    @@ -50,7 +50,7 @@ decide what the defaults should be, usually depending on the settings in
     the client registration that it holds.

    [Note]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).

    76.2 OAuth2 Protected Resource

    You want to protect an API resource with an OAuth2 token? Here’s a +sample here).

    77.2 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')
     @RestController
    @@ -69,4 +69,4 @@ simple example (paired with the client above):

    app.groovy.  resource: userInfoUri: https://api.github.com/user preferTokenInfo: false

    -

    \ No newline at end of file +

    \ No newline at end of file diff --git a/Finchley.M7/multi/multi__rabbitmq_binder.html b/Finchley.M7/multi/multi__rabbitmq_binder.html index 23476067..5d513f03 100644 --- a/Finchley.M7/multi/multi__rabbitmq_binder.html +++ b/Finchley.M7/multi/multi__rabbitmq_binder.html @@ -1,12 +1,12 @@ - 37. RabbitMQ Binder

    37. RabbitMQ Binder

    37.1 Usage

    For using the RabbitMQ binder, you just need to add it to your Spring Cloud Stream application, using the following Maven coordinates:

    <dependency>
    +   38. RabbitMQ Binder

    38. RabbitMQ Binder

    38.1 Usage

    For using the RabbitMQ binder, you just need to add it to your Spring Cloud Stream application, using the following Maven coordinates:

    <dependency>
       <groupId>org.springframework.cloud</groupId>
       <artifactId>spring-cloud-stream-binder-rabbit</artifactId>
     </dependency>

    Alternatively, you can also use the Spring Cloud Stream RabbitMQ Starter.

    <dependency>
       <groupId>org.springframework.cloud</groupId>
       <artifactId>spring-cloud-starter-stream-rabbit</artifactId>
    -</dependency>

    37.2 RabbitMQ Binder Overview

    A simplified diagram of how the RabbitMQ binder operates can be seen below.

    Figure 37.1. RabbitMQ Binder

    rabbit binder

    The RabbitMQ Binder implementation maps each destination to a TopicExchange. +</dependency>

    38.2 RabbitMQ Binder Overview

    A simplified diagram of how the RabbitMQ binder operates can be seen below.

    Figure 38.1. RabbitMQ Binder

    rabbit binder

    The RabbitMQ Binder implementation maps each destination to a TopicExchange. For each consumer group, a Queue will be bound to that TopicExchange. Each consumer instance have a corresponding RabbitMQ Consumer instance for its group’s Queue. For partitioned producers/consumers the queues are suffixed with the partition index and use the partition index as routing key.

    Using the autoBindDlq option, you can optionally configure the binder to create and configure dead-letter queues (DLQs) (and a dead-letter exchange DLX). @@ -16,9 +16,9 @@ If retry is disabled (maxAttempts = 1), you should In addition, republishToDlq causes the binder to publish a failed message to the DLQ (instead of rejecting it); this enables additional information to be added to the message in headers, such as the stack trace in the x-exception-stacktrace header. This option does not need retry enabled; you can republish a failed message after just one attempt. Starting with version 1.2, you can configure the delivery mode of republished messages; see property republishDeliveryMode.

    [Important]Important

    Setting requeueRejected to true will cause the message to be requeued and redelivered continually, which is likely not what you want unless the failure issue is transient. -In general, it’s better to enable retry within the binder by setting maxAttempts to greater than one, or set republishToDlq to true.

    See Section 37.3.1, “RabbitMQ Binder Properties” for more information about these properties.

    The framework does not provide any standard mechanism to consume dead-letter messages (or to re-route them back to the primary queue). -Some options are described in Section 37.6, “Dead-Letter Queue Processing”.

    [Note]Note

    When multiple RabbitMQ binders are used in a Spring Cloud Stream application, it is important to disable 'RabbitAutoConfiguration' to avoid the same configuration from RabbitAutoConfiguration being applied to the two binders.

    Starting with version 1.3, the RabbitMessageChannelBinder creates an internal ConnectionFactory copy for the non-transactional producers to avoid dead locks on consumers when shared, cached connections are blocked because of Memory Alarm on Broker.

    37.3 Configuration Options

    This section contains settings specific to the RabbitMQ Binder and bound channels.

    For general binding configuration options and properties, -please refer to the Spring Cloud Stream core documentation.

    37.3.1 RabbitMQ Binder Properties

    By default, the RabbitMQ binder uses Spring Boot’s ConnectionFactory, and it therefore supports all Spring Boot configuration options for RabbitMQ. +In general, it’s better to enable retry within the binder by setting maxAttempts to greater than one, or set republishToDlq to true.

    See Section 38.3.1, “RabbitMQ Binder Properties” for more information about these properties.

    The framework does not provide any standard mechanism to consume dead-letter messages (or to re-route them back to the primary queue). +Some options are described in Section 38.6, “Dead-Letter Queue Processing”.

    [Note]Note

    When multiple RabbitMQ binders are used in a Spring Cloud Stream application, it is important to disable 'RabbitAutoConfiguration' to avoid the same configuration from RabbitAutoConfiguration being applied to the two binders.

    Starting with version 1.3, the RabbitMessageChannelBinder creates an internal ConnectionFactory copy for the non-transactional producers to avoid dead locks on consumers when shared, cached connections are blocked because of Memory Alarm on Broker.

    38.3 Configuration Options

    This section contains settings specific to the RabbitMQ Binder and bound channels.

    For general binding configuration options and properties, +please refer to the Spring Cloud Stream core documentation.

    38.3.1 RabbitMQ Binder Properties

    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 Spring Boot options, the RabbitMQ binder supports the following properties:

    spring.cloud.stream.rabbit.binder.adminAddresses

    A comma-separated list of RabbitMQ management plugin URLs. Only used when nodes contains more than one entry. @@ -29,7 +29,7 @@ When more than one entry, used to locate the server address where a queue is loc Each entry in this list must have a corresponding entry in spring.rabbitmq.addresses. Only needed if you are using a RabbitMQ cluster and wish to consume from the node that hosts the queue. See Queue Affinity and the LocalizedQueueConnectionFactory for more information.

    Default: empty.

    spring.cloud.stream.rabbit.binder.compressionLevel

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

    Default: 1 (BEST_LEVEL).

    37.3.2 RabbitMQ Consumer Properties

    The following properties are available for Rabbit consumers only and +See java.util.zip.Deflater.

    Default: 1 (BEST_LEVEL).

    38.3.2 RabbitMQ Consumer Properties

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

    acknowledgeMode

    The acknowledge mode.

    Default: AUTO.

    autoBindDlq

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

    Default: false.

    bindingRoutingKey

    The routing key with which to bind the queue to the exchange (if bindQueue is true). for partitioned destinations -<instanceIndex> will be appended.

    Default: #.

    bindQueue

    Whether to bind the queue to the destination exchange; set to false if you have set up your own infrastructure and have previously created/bound the queue.

    Default: true.

    deadLetterQueueName

    name of the DLQ

    Default: prefix+destination.dlq

    deadLetterExchange

    a DLX to assign to the queue; if autoBindDlq is true

    Default: 'prefix+DLX'

    deadLetterRoutingKey

    a dead letter routing key to assign to the queue; if autoBindDlq is true

    Default: destination

    declareExchange

    Whether to declare the exchange for the destination.

    Default: true.

    delayedExchange

    Whether to declare the exchange as a Delayed Message Exchange - requires the delayed message exchange plugin on the broker. The x-delayed-type argument is set to the exchangeType.

    Default: false.

    dlqDeadLetterExchange

    if a DLQ is declared, a DLX to assign to that queue

    Default: none

    dlqDeadLetterRoutingKey

    if a DLQ is declared, a dead letter routing key to assign to that queue; default none

    Default: none

    dlqExpires

    how long before an unused dead letter queue is deleted (ms)

    Default: no expiration

    dlqLazy

    Declare the dead letter queue with the x-queue-mode=lazy argument. @@ -43,7 +43,7 @@ Defaults to false so that the container keeps tryin Only relevant if missingQueuesFatal is true; otherwise the container keeps retrying indefinitely.

    Default
    3
    queueNameGroupOnly

    When true, consume from a queue with a name equal to the group; otherwise the queue name is destination.group. This is useful, for example, when using Spring Cloud Stream to consume from an existing RabbitMQ queue.

    Default: false.

    recoveryInterval

    The interval between connection recovery attempts, in milliseconds.

    Default: 5000.

    requeueRejected

    Whether delivery failures should be requeued when retry is disabled or republishToDlq is false.

    Default: false.

    republishDeliveryMode

    When republishToDlq is true, specify the delivery mode of the republished message.

    Default: DeliveryMode.PERSISTENT

    republishToDlq

    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 binder will republish failed messages to the DLQ with additional headers, including the exception message and stack trace from the cause of the final failure.

    Default: false

    transacted

    Whether to use transacted channels.

    Default: false.

    ttl

    default time to live to apply to the queue when declared (ms)

    Default: no limit

    txSize

    The number of deliveries between acks.

    Default: 1.

    37.3.3 Rabbit Producer Properties

    The following properties are available for Rabbit producers only and +If set to true, the binder will republish failed messages to the DLQ with additional headers, including the exception message and stack trace from the cause of the final failure.

    Default: false

    transacted

    Whether to use transacted channels.

    Default: false.

    ttl

    default time to live to apply to the queue when declared (ms)

    Default: no limit

    txSize

    The number of deliveries between acks.

    Default: 1.

    38.3.3 Rabbit Producer Properties

    The following properties are available for Rabbit producers only and 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.

    batchingEnabled

    Whether to enable message batching by producers.

    Default: false.

    batchSize

    The number of messages to buffer when batching is enabled.

    Default: 100.

    batchBufferLimit
    Default: 10000.
    batchTimeout
    Default: 5000.
    bindingRoutingKey

    The routing key with which to bind the queue to the exchange (if bindQueue is true). Only applies to non-partitioned destinations. Only applies if requiredGroups are provided and then only to those groups.

    Default: #.

    bindQueue

    Whether to bind the queue to the destination exchange; set to false if you have set up your own infrastructure and have previously created/bound the queue. @@ -73,12 +73,12 @@ This is useful, for example, when using Spring Cloud Stream to consume from an e Only applies if requiredGroups are provided and then only to those groups.

    Default: false.

    routingKeyExpression

    A SpEL expression to determine the routing key to use when publishing messages. For a fixed routing key, use a literal expression, e.g. routingKeyExpression='my.routingKey' in a properties file, or routingKeyExpression: '''my.routingKey''' in a YAML file.

    Default: destination or destination-<partition> for partitioned destinations.

    transacted

    Whether to use transacted channels.

    Default: false.

    ttl

    default time to live to apply to the queue when declared (ms) Only applies if requiredGroups are provided and then only to those groups.

    Default: no limit

    [Note]Note

    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 (prior to 0.11), that do not natively support headers).

    37.4 Retry With the RabbitMQ Binder

    37.4.1 Overview

    When retry is enabled within the binder, the listener container thread is suspended for any back off periods that are configured. +Spring Cloud Stream supports them as part of an extended internal protocol used for any type of transport (including transports, such as Kafka (prior to 0.11), that do not natively support headers).

    38.4 Retry With the RabbitMQ Binder

    38.4.1 Overview

    When retry is enabled within the binder, the listener container thread is suspended for any back off periods that are configured. This might be important when strict ordering is required with a single consumer but for other use cases it prevents other messages from being processed on that thread. An alternative to using binder retry is to set up dead lettering with time to live on the dead-letter queue (DLQ), as well as dead-letter configuration on the DLQ itself. -See Section 37.3.1, “RabbitMQ Binder Properties” for more information about the properties discussed here. +See Section 38.3.1, “RabbitMQ Binder Properties” for more information about the properties discussed here. Example configuration to enable this feature:

    • Set autoBindDlq to true - the binder will create a DLQ; you can optionally specify a name in deadLetterQueueName
    • Set dlqTtl to the back off time you want to wait between redeliveries
    • Set the dlqDeadLetterExchange to the default exchange - expired messages from the DLQ will be routed to the original queue since the default deadLetterRoutingKey is the queue name (destination.group)

    To force a message to be dead-lettered, either throw an AmqpRejectAndDontRequeueException, or set requeueRejected to true and throw any exception.

    The loop will continue without end, which is fine for transient problems but you may want to give up after some number of attempts. -Fortunately, RabbitMQ provides the x-death header which allows you to determine how many cycles have occurred.

    To acknowledge a message after giving up, throw an ImmediateAcknowledgeAmqpException.

    37.4.2 Putting it All Together

    ---
    +Fortunately, RabbitMQ provides the x-death header which allows you to determine how many cycles have occurred.

    To acknowledge a message after giving up, throw an ImmediateAcknowledgeAmqpException.

    38.4.2 Putting it All Together

    ---
     spring.cloud.stream.bindings.input.destination=myDestination
     spring.cloud.stream.bindings.input.group=consumerGroup
     #disable binder retries
    @@ -109,14 +109,14 @@ After 5 seconds, the message expires and is routed to the original queue using t
         }
     
     }

    -

    Notice that the count property in the x-death header is a Long.

    37.5 Error Channels

    Starting with version 1.3, the binder unconditionally sends exceptions to an error channel for each consumer destination, and can be configured to send async producer send failures to an error channel too. -See the section called “Message Channel Binders and Error Channels” for more information.

    With rabbitmq, there are two types of send failures:

    The latter is rare; quoting the RabbitMQ documentation "[A nack] will only be delivered if an internal error occurs in the Erlang process responsible for a queue.".

    As well as enabling producer error channels as described in the section called “Message Channel Binders and Error Channels”, the RabbitMQ binder will only send messages to the channels if the connection factory is appropriately configured:

    • ccf.setPublisherConfirms(true);
    • ccf.setPublisherReturns(true);

    When using spring boot configuration for the connection factory, set properties:

    • spring.rabbitmq.publisher-confirms
    • spring.rabbitmq.publisher-returns

    The payload of the ErrorMessage for a returned message is a ReturnedAmqpMessageException with properties:

    • failedMessage - the spring-messaging Message<?> that failed to be sent.
    • amqpMessage - the raw spring-amqp Message
    • replyCode - an integer value indicating the reason for the failure (e.g. 312 - No route)
    • replyText - a text value indicating the reason for the failure e.g. NO_ROUTE.
    • exchange - the exchange to which the message was published.
    • routingKey - the routing key used when the message was published.

    For negatively acknowledged confirms, the payload is a NackedAmqpMessageException with properties:

    • failedMessage - the spring-messaging Message<?> that failed to be sent.
    • nackReason - a reason (if available; you may need to examine the broker logs for more information).

    There is no automatic handling of these exceptions (such as sending to a Dead-Letter queue); you can consume these exceptions with your own Spring Integration flow.

    37.6 Dead-Letter Queue Processing

    Because it can’t be anticipated how users would want to dispose of dead-lettered messages, the framework does not provide any standard mechanism to handle them. +

    Notice that the count property in the x-death header is a Long.

    38.5 Error Channels

    Starting with version 1.3, the binder unconditionally sends exceptions to an error channel for each consumer destination, and can be configured to send async producer send failures to an error channel too. +See the section called “Message Channel Binders and Error Channels” for more information.

    With rabbitmq, there are two types of send failures:

    The latter is rare; quoting the RabbitMQ documentation "[A nack] will only be delivered if an internal error occurs in the Erlang process responsible for a queue.".

    As well as enabling producer error channels as described in the section called “Message Channel Binders and Error Channels”, the RabbitMQ binder will only send messages to the channels if the connection factory is appropriately configured:

    • ccf.setPublisherConfirms(true);
    • ccf.setPublisherReturns(true);

    When using spring boot configuration for the connection factory, set properties:

    • spring.rabbitmq.publisher-confirms
    • spring.rabbitmq.publisher-returns

    The payload of the ErrorMessage for a returned message is a ReturnedAmqpMessageException with properties:

    • failedMessage - the spring-messaging Message<?> that failed to be sent.
    • amqpMessage - the raw spring-amqp Message
    • replyCode - an integer value indicating the reason for the failure (e.g. 312 - No route)
    • replyText - a text value indicating the reason for the failure e.g. NO_ROUTE.
    • exchange - the exchange to which the message was published.
    • routingKey - the routing key used when the message was published.

    For negatively acknowledged confirms, the payload is a NackedAmqpMessageException with properties:

    • failedMessage - the spring-messaging Message<?> that failed to be sent.
    • nackReason - a reason (if available; you may need to examine the broker logs for more information).

    There is no automatic handling of these exceptions (such as sending to a Dead-Letter queue); you can consume these exceptions with your own Spring Integration flow.

    38.6 Dead-Letter Queue Processing

    Because it can’t be anticipated how users would want to dispose of dead-lettered messages, the framework does not provide any standard mechanism to handle them. If the reason for the dead-lettering is transient, you may wish to route the messages back to the original queue. However, if the problem is a permanent issue, that could cause an infinite loop. The following spring-boot application is an example of how to route those messages back to the original queue, but moves them to a third "parking lot" queue after three attempts. The second example utilizes the RabbitMQ Delayed Message Exchange to introduce a delay to the requeued message. In this example, the delay increases for each attempt. -These examples use a @RabbitListener to receive messages from the DLQ, you could also use RabbitTemplate.receive() in a batch process.

    The examples assume the original destination is so8400in and the consumer group is so8400.

    37.6.1 Non-Partitioned Destinations

    The first two examples are when the destination is not partitioned.

    @SpringBootApplication
    +These examples use a @RabbitListener to receive messages from the DLQ, you could also use RabbitTemplate.receive() in a batch process.

    The examples assume the original destination is so8400in and the consumer group is so8400.

    38.6.1 Non-Partitioned Destinations

    The first two examples are when the destination is not partitioned.

    @SpringBootApplication
     public class ReRouteDlqApplication {
     
         private static final String ORIGINAL_QUEUE = "so8400in.so8400";
    @@ -214,7 +214,7 @@ These examples use a @RabbitListener to receive mes
             return new Queue(PARKING_LOT);
         }
     
    -}

    37.6.2 Partitioned Destinations

    With partitioned destinations, there is one DLQ for all partitions and we determine the original queue from the headers.

    republishToDlq=false

    When republishToDlq is false, RabbitMQ publishes the message to the DLX/DLQ with an x-death header containing information about the original destination.

    @SpringBootApplication
    +}

    38.6.2 Partitioned Destinations

    With partitioned destinations, there is one DLQ for all partitions and we determine the original queue from the headers.

    republishToDlq=false

    When republishToDlq is false, RabbitMQ publishes the message to the DLX/DLQ with an x-death header containing information about the original destination.

    @SpringBootApplication
     public class ReRouteDlqApplication {
     
     	private static final String ORIGINAL_QUEUE = "so8400in.so8400";
    @@ -310,7 +310,7 @@ These examples use a @RabbitListener to receive mes
     		return new Queue(PARKING_LOT);
     	}
     
    -}

    37.7 Partitioning with the RabbitMQ Binder

    RabbitMQ does not support partitioning natively.

    Sometimes it is advantageous to send data to specific partitions, for example when you want to strictly order message processing - all messages for a particular customer should go to the same partition.

    The RabbitMessageChannelBinder provides partitioning by binding a queue for each partition to the destination exchange.

    The following illustrates how to configure the producer and consumer side:

    Producer.  +}

    38.7 Partitioning with the RabbitMQ Binder

    RabbitMQ does not support partitioning natively.

    Sometimes it is advantageous to send data to specific partitions, for example when you want to strictly order message processing - all messages for a particular customer should go to the same partition.

    The RabbitMessageChannelBinder provides partitioning by binding a queue for each partition to the destination exchange.

    The following illustrates how to configure the producer and consumer side:

    Producer. 

    @SpringBootApplication
     @EnableBinding(Source.class)
     public class RabbitPartitionProducerApplication {
    @@ -385,4 +385,4 @@ Otherwise, any messages sent to a partition will be lost until the corresponding
                     instance-index: 0

    [Important]Important

    The RabbitMessageChannelBinder does not support dynamic scaling; there must be at least one consumer per partition. The consumer’s instanceIndex is used to indicate which partition will be consumed. -On platforms such as Cloud Foundry there can only be one instance with an instanceIndex.

    \ No newline at end of file +On platforms such as Cloud Foundry there can only be one instance with an instanceIndex.

    \ No newline at end of file diff --git a/Finchley.M7/multi/multi__running_examples.html b/Finchley.M7/multi/multi__running_examples.html index 1ae8e1a0..a42dbacc 100644 --- a/Finchley.M7/multi/multi__running_examples.html +++ b/Finchley.M7/multi/multi__running_examples.html @@ -1,3 +1,3 @@ - 60. Running examples

    60. Running examples

    You can find the running examples deployed in the Pivotal Web Services. Check them out in the following links:

    \ No newline at end of file + 61. Running examples

    61. Running examples

    You can find the running examples deployed in the Pivotal Web Services. Check them out in the following links:

    \ No newline at end of file diff --git a/Finchley.M7/multi/multi__samples.html b/Finchley.M7/multi/multi__samples.html index 4ee74922..9e1bcc34 100644 --- a/Finchley.M7/multi/multi__samples.html +++ b/Finchley.M7/multi/multi__samples.html @@ -1,3 +1,3 @@ - 34. Samples

    34. Samples

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

    \ No newline at end of file + 35. Samples

    35. Samples

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

    \ No newline at end of file diff --git a/Finchley.M7/multi/multi__sampling.html b/Finchley.M7/multi/multi__sampling.html index 56ed9bd8..0550b6cb 100644 --- a/Finchley.M7/multi/multi__sampling.html +++ b/Finchley.M7/multi/multi__sampling.html @@ -1,11 +1,11 @@ - 48. Sampling

    48. Sampling

    Sampling may be employed to reduce the data collected and reported out + 49. Sampling

    49. Sampling

    Sampling may be employed to reduce the data collected and reported out of process. When a span isn’t sampled, it adds no overhead (noop).

    Sampling is an up-front decision, meaning that the decision to report data is made at the first operation in a trace, and that decision is propagated downstream.

    By default, there’s a global sampler that applies a single rate to all traced operations. Tracer.Builder.sampler is how you indicate this, -and it defaults to trace every request.

    48.1 Declarative sampling

    Some need to sample based on the type or annotations of a java method.

    Most users will use a framework interceptor which automates this sort of +and it defaults to trace every request.

    49.1 Declarative sampling

    Some need to sample based on the type or annotations of a java method.

    Most users will use a framework interceptor which automates this sort of policy. Here’s how they might work internally.

    // derives a sample rate from an annotation on a java method
     DeclarativeSampler<Traced> sampler = DeclarativeSampler.create(Traced::sampleRate);
     
    @@ -17,7 +17,7 @@ DeclarativeSampler<Traced> sampler = DeclarativeSampler.create(Traced::sam
       } finally {
         span.finish();
       }
    -}

    48.2 Custom sampling

    You may want to apply different policies depending on what the operation +}

    49.2 Custom sampling

    You may want to apply different policies depending on what the operation is. For example, you might not want to trace requests to static resources such as images, or you might want to trace all requests to a new api.

    Most users will use a framework interceptor which automates this sort of policy. Here’s how they might work internally.

    Span newTrace(Request input) {
    @@ -28,7 +28,7 @@ policy. Here’s how they might work internally.

    return tracer.newTrace(flags);
    -}

    Note: the above is the basis for the built-in http sampler

    48.3 Sampling in Spring Cloud Sleuth

    Spring Cloud Sleuth by default sets all spans to non-exportable. +}

    Note: the above is the basis for the built-in http sampler

    49.3 Sampling in Spring Cloud Sleuth

    Spring Cloud Sleuth by default sets all spans to non-exportable. That means that 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 @@ -42,4 +42,4 @@ value needs to be a double from 0.0 to return Sampler.ALWAYS_SAMPLE; }

    [Tip]Tip

    You can set the HTTP header X-B3-Flags to 1 or when doing messaging you can set spanFlags header to 1. Then the current span will be forced to be exportable -regardless of the sampling decision.

    \ No newline at end of file +regardless of the sampling decision.

    \ No newline at end of file diff --git a/Finchley.M7/multi/multi__sending_spans_to_zipkin.html b/Finchley.M7/multi/multi__sending_spans_to_zipkin.html index d62e3387..9015e329 100644 --- a/Finchley.M7/multi/multi__sending_spans_to_zipkin.html +++ b/Finchley.M7/multi/multi__sending_spans_to_zipkin.html @@ -1,10 +1,10 @@ - 57. Sending spans to Zipkin

    57. Sending spans to Zipkin

    By default if you add spring-cloud-starter-zipkin as a dependency to your project, + 58. Sending spans to Zipkin

    58. Sending spans to Zipkin

    By default if you add spring-cloud-starter-zipkin as a dependency to your project, when the span is closed, it will be sent to Zipkin over HTTP. The communication is asynchronous. You can configure the URL by setting the spring.zipkin.baseUrl property as follows:

    spring.zipkin.baseUrl: http://192.168.99.100:9411/

    If you want to find Zipkin via service discovery it’s enough to pass the Zipkin’s service id inside the URL (example for zipkinserver service id)

    spring.zipkin.baseUrl: http://zipkinserver/

    If you have web, rabbit or kafka together on the classpath, you might need to pick the means by which you would like to send spans to zipkin. To do that just set either web, rabbit or kafka to the spring.zipkin.sender.type property. -Example for web:

    spring.zipkin.sender.type: web
    \ No newline at end of file +Example for web:

    spring.zipkin.sender.type: web
    \ No newline at end of file diff --git a/Finchley.M7/multi/multi__service_discovery_eureka_clients.html b/Finchley.M7/multi/multi__service_discovery_eureka_clients.html index bc7a2452..39e5c270 100644 --- a/Finchley.M7/multi/multi__service_discovery_eureka_clients.html +++ b/Finchley.M7/multi/multi__service_discovery_eureka_clients.html @@ -152,7 +152,7 @@ Spring Cloud will auto configure a transport client based on Spring </exclusions> </dependency>

    11.9 Alternatives to the native Netflix EurekaClient

    You don’t have to use the raw Netflix EurekaClient and usually it is more convenient to use it behind a wrapper of some sort. Spring -Cloud has support for Feign (a REST client +Cloud has support for Feign (a REST client builder) and also Spring RestTemplate using the logical Eureka service identifiers (VIPs) instead of physical URLs. To configure Ribbon with a fixed list of physical servers you diff --git a/Finchley.M7/multi/multi__service_id_must_be_unique.html b/Finchley.M7/multi/multi__service_id_must_be_unique.html index ddea4cfa..e859c7c1 100644 --- a/Finchley.M7/multi/multi__service_id_must_be_unique.html +++ b/Finchley.M7/multi/multi__service_id_must_be_unique.html @@ -1,3 +1,3 @@ - 41. Service ID must be unique

    41. Service 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 service ID againts the current service ID. If multiple instances of a service have the same 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 ID. Cloud Foundry supplies an index to differentiate. To ensure that the ID is unique outside Cloud Foundry, set spring.application.index to something unique for each instance of a service.

    \ No newline at end of file + 42. Service ID must be unique

    42. Service 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 service ID againts the current service ID. If multiple instances of a service have the same 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 ID. Cloud Foundry supplies an index to differentiate. To ensure that the ID is unique outside Cloud Foundry, set spring.application.index to something unique for each instance of a service.

    \ No newline at end of file diff --git a/Finchley.M7/multi/multi__service_registry_configuration.html b/Finchley.M7/multi/multi__service_registry_configuration.html index 19b7e6ef..e3ba4871 100644 --- a/Finchley.M7/multi/multi__service_registry_configuration.html +++ b/Finchley.M7/multi/multi__service_registry_configuration.html @@ -1,6 +1,6 @@ - 100. Service Registry Configuration

    100. Service Registry Configuration

    You can use a DiscoveryClient (such as from Spring Cloud Consul) to locate + 101. Service Registry Configuration

    101. Service Registry Configuration

    You can use a DiscoveryClient (such as from Spring Cloud Consul) to locate a Vault server by setting spring.cloud.vault.discovery.enabled=true (default false). The net result of that is that your apps need a bootstrap.yml (or an environment variable) with the appropriate discovery configuration. @@ -14,4 +14,4 @@ need to provide a scheme metadata entry to be set e If no scheme is configured and the service is not exposed as secure service, then configuration defaults to spring.cloud.vault.scheme which is https when it’s not set.

    spring.cloud.vault.discovery:
         enabled: true
    -    service-id: my-vault-service
    \ No newline at end of file + service-id: my-vault-service
    \ No newline at end of file diff --git a/Finchley.M7/multi/multi__single_sign_on_2.html b/Finchley.M7/multi/multi__single_sign_on_2.html index e329fc63..8dbfb797 100644 --- a/Finchley.M7/multi/multi__single_sign_on_2.html +++ b/Finchley.M7/multi/multi__single_sign_on_2.html @@ -1,6 +1,6 @@ - 80. Single Sign On

    80. Single Sign On

    [Note]Note

    All of the OAuth2 SSO and resource server features moved to Spring Boot + 81. Single Sign On

    81. Single Sign On

    [Note]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 credentials to the Spring Boot features. If you have a CloudFoundry @@ -8,4 +8,4 @@ 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.

    \ No newline at end of file +parameterized using spring.oauth2.sso.serviceId.

    \ No newline at end of file diff --git a/Finchley.M7/multi/multi__span_lifecycle.html b/Finchley.M7/multi/multi__span_lifecycle.html index c1e103e0..fe076d6e 100644 --- a/Finchley.M7/multi/multi__span_lifecycle.html +++ b/Finchley.M7/multi/multi__span_lifecycle.html @@ -1,9 +1,9 @@ - 53. Span lifecycle

    53. Span lifecycle

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

    • 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 sampled then it will be eligible for collection to e.g. Zipkin.
    • 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
    [Tip]Tip

    Spring Cloud Sleuth creates the instance of Tracer for you. In order to use it, -all you need is to just autowire it.

    53.1 Creating and finishing spans

    You can manually create spans by using the Tracer.

    // Start a span. If there was a span present in this thread it will become
    +   54. Span lifecycle

    54. Span lifecycle

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

    • 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 sampled then it will be eligible for collection to e.g. Zipkin.
    • 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
    [Tip]Tip

    Spring Cloud Sleuth creates the instance of Tracer for you. In order to use it, +all you need is to just autowire it.

    54.1 Creating and finishing spans

    You can manually create spans by using the Tracer.

    // Start a span. If there was a span present in this thread it will become
     // the `newSpan`'s parent.
     Span newSpan = this.tracer.nextSpan().name("calculateTax");
     try (Tracer.SpanInScope ws = this.tracer.withSpanInScope(newSpan.start())) {
    @@ -20,7 +20,7 @@ Span 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]Important

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

    [Important]Important

    If your span contains a name greater than 50 chars, then that name will be truncated to 50 chars. Your names have to be explicit and concrete. Big names lead to -latency issues and sometimes even thrown exceptions.

    53.2 Continuing spans

    Sometimes you don’t want to create a new span but you want to continue one. Example of such a +latency issues and sometimes even thrown exceptions.

    54.2 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.

    To continue a span you can use brave.Tracer.

    // let's assume that we're in a thread Y and we've received
     // the `initialSpan` from thread X
    @@ -36,7 +36,7 @@ Span continuedSpan = // Once done remember to flush the span. That means that
     	// it will get reported but the span itself is not yet finished
     	continuedSpan.flush();
    -}

    53.3 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. +}

    54.3 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. In Brave, whenever you call nextSpan(), it’s creating one in reference to the span being currently in scope. It’s enough to just put @@ -60,4 +60,4 @@ Span newSpan = null; newSpan.finish(); } }

    [Important]Important

    After having created such a span remember to finish it, otherwise it will not get -reported to e.g. Zipkin

    \ No newline at end of file +reported to e.g. Zipkin

    \ No newline at end of file diff --git a/Finchley.M7/multi/multi__spring_cloud_bus.html b/Finchley.M7/multi/multi__spring_cloud_bus.html index 192ccf5a..caef88f5 100644 --- a/Finchley.M7/multi/multi__spring_cloud_bus.html +++ b/Finchley.M7/multi/multi__spring_cloud_bus.html @@ -1,3 +1,3 @@ - Part VI. Spring Cloud Bus

    Part VI. Spring Cloud Bus

    Spring Cloud Bus links nodes of a distributed system with a lightweight message broker. This can then be used to broadcast state changes (e.g. configuration changes) or other management instructions. A key idea is that the Bus is like a distributed Actuator for a Spring Boot application that is scaled out, but it can also be used as a communication channel between apps. Starters are provided for an AMQP broker as the transport or for Kafka, but the same basic feature set (and some more depending on the transport) is on the roadmap for other transports.

    [Note]Note

    Spring Cloud is released under the non-restrictive Apache 2.0 license. If you would like to contribute to this section of the documentation or if you find an error, please find the source code and issue trackers in the project at github.

    \ No newline at end of file + Part VII. Spring Cloud Bus

    Part VII. Spring Cloud Bus

    Spring Cloud Bus links nodes of a distributed system with a lightweight message broker. This can then be used to broadcast state changes (e.g. configuration changes) or other management instructions. A key idea is that the Bus is like a distributed Actuator for a Spring Boot application that is scaled out, but it can also be used as a communication channel between apps. Starters are provided for an AMQP broker as the transport or for Kafka, but the same basic feature set (and some more depending on the transport) is on the roadmap for other transports.

    [Note]Note

    Spring Cloud is released under the non-restrictive Apache 2.0 license. If you would like to contribute to this section of the documentation or if you find an error, please find the source code and issue trackers in the project at github.

    \ No newline at end of file diff --git a/Finchley.M7/multi/multi__spring_cloud_consul.html b/Finchley.M7/multi/multi__spring_cloud_consul.html index 086de519..0e72cd16 100644 --- a/Finchley.M7/multi/multi__spring_cloud_consul.html +++ b/Finchley.M7/multi/multi__spring_cloud_consul.html @@ -1,9 +1,9 @@ - Part VIII. Spring Cloud Consul

    Part VIII. Spring Cloud Consul

    1.3.5.BUILD-SNAPSHOT

    This project provides Consul integrations for Spring Boot apps through autoconfiguration + Part IX. Spring Cloud Consul

    Part IX. Spring Cloud Consul

    1.3.5.BUILD-SNAPSHOT

    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 application and build large distributed systems with Consul based components. The 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.

    \ No newline at end of file +(Hystrix) are provided by integration with Spring Cloud Netflix.

    \ No newline at end of file diff --git a/Finchley.M7/multi/multi__spring_cloud_contract.html b/Finchley.M7/multi/multi__spring_cloud_contract.html index cb1caea2..3e80a04e 100644 --- a/Finchley.M7/multi/multi__spring_cloud_contract.html +++ b/Finchley.M7/multi/multi__spring_cloud_contract.html @@ -1,4 +1,4 @@ - Part XII. Spring Cloud Contract

    Part XII. Spring Cloud Contract

    _Documentation Authors: Adam Dudczak, Mathias Düsterhöft, Marcin Grzejszczak, Dennis Kieselhorst, Jakub Kubryński, Karol Lassak, -Olga Maciaszek-Sharma, Mariusz Smykuła, Dave Syer, Jay Bryant

    1.3.5.BUILD-SNAPSHOT

    \ No newline at end of file + Part XIII. Spring Cloud Contract

    Part XIII. Spring Cloud Contract

    _Documentation Authors: Adam Dudczak, Mathias Düsterhöft, Marcin Grzejszczak, Dennis Kieselhorst, Jakub Kubryński, Karol Lassak, +Olga Maciaszek-Sharma, Mariusz Smykuła, Dave Syer, Jay Bryant

    1.3.5.BUILD-SNAPSHOT

    \ No newline at end of file diff --git a/Finchley.M7/multi/multi__spring_cloud_contract_2.html b/Finchley.M7/multi/multi__spring_cloud_contract_2.html index 839f542b..a82da4c0 100644 --- a/Finchley.M7/multi/multi__spring_cloud_contract_2.html +++ b/Finchley.M7/multi/multi__spring_cloud_contract_2.html @@ -1,7 +1,7 @@ - 81. Spring Cloud Contract

    81. Spring Cloud Contract

    You need confidence when pushing new features to a new application or service in a + 82. Spring Cloud Contract

    82. Spring Cloud Contract

    You need confidence when pushing new features to a new application or service in a distributed system. This project provides support for Consumer Driven Contracts and service schemas in Spring applications (for both HTTP and message-based interactions), covering a range of options for writing tests, publishing them as assets, and asserting -that a contract is kept by producers and consumers.

    \ No newline at end of file +that a contract is kept by producers and consumers.

    \ No newline at end of file diff --git a/Finchley.M7/multi/multi__spring_cloud_contract_faq.html b/Finchley.M7/multi/multi__spring_cloud_contract_faq.html index f64149d7..7a01f472 100644 --- a/Finchley.M7/multi/multi__spring_cloud_contract_faq.html +++ b/Finchley.M7/multi/multi__spring_cloud_contract_faq.html @@ -1,8 +1,8 @@ - 83. Spring Cloud Contract FAQ

    83. Spring Cloud Contract FAQ

    83.1 Why use Spring Cloud Contract Verifier and not X ?

    For the time being Spring Cloud Contract Verifier is a JVM based tool. So it could be your first pick when you’re already creating + 84. Spring Cloud Contract FAQ

    84. Spring Cloud Contract FAQ

    84.1 Why use Spring Cloud Contract Verifier and not X ?

    For the time being Spring Cloud Contract Verifier is a JVM based tool. So it could be your first pick when you’re already creating software for the JVM. This project has a lot of really interesting features but especially quite a few of them definitely make -Spring Cloud Contract Verifier stand out on the "market" of Consumer Driven Contract (CDC) tooling. Out of many the most interesting are:

    • Possibility to do CDC with messaging
    • Clear and easy to use, statically typed DSL
    • Possibility to copy paste your current JSON file to the contract and only edit its elements
    • Automatic generation of tests from the defined Contract
    • Stub Runner functionality - the stubs are automatically downloaded at runtime from Nexus / Artifactory
    • Spring Cloud integration - no discovery service is needed for integration tests

    83.2 I don’t want to write a contract in Groovy!

    No problem. You can write a contract in YAML!

    83.3 What is this value(consumer(), producer()) ?

    One of the biggest challenges related to stubs is their reusability. Only if they can be vastly used, will they serve their purpose. +Spring Cloud Contract Verifier stand out on the "market" of Consumer Driven Contract (CDC) tooling. Out of many the most interesting are:

    • Possibility to do CDC with messaging
    • Clear and easy to use, statically typed DSL
    • Possibility to copy paste your current JSON file to the contract and only edit its elements
    • Automatic generation of tests from the defined Contract
    • Stub Runner functionality - the stubs are automatically downloaded at runtime from Nexus / Artifactory
    • Spring Cloud integration - no discovery service is needed for integration tests

    84.2 I don’t want to write a contract in Groovy!

    No problem. You can write a contract in YAML!

    84.3 What is this value(consumer(), producer()) ?

    One of the biggest challenges related to stubs is their reusability. Only if they can be vastly used, will they serve their purpose. What typically makes that difficult are the hard-coded values of request / response elements. For example dates or ids. Imagine the following JSON request

    {
         "time" : "2016-10-10 20:10:15",
    @@ -68,19 +68,19 @@ for time and UUID are simplified and most likely invalid but we want to keep thi
     					])
     			}
     }
    [Important]Important

    Please read the Groovy docs related to JSON to understand how to -properly structure the request / response bodies.

    83.4 How to do Stubs versioning?

    83.4.1 API Versioning

    Let’s try to answer a question what versioning really means. If you’re referring to the API version then there are +properly structure the request / response bodies.

    84.4 How to do Stubs versioning?

    84.4.1 API Versioning

    Let’s try to answer a question what versioning really means. If you’re referring to the API version then there are different approaches.

    • use Hypermedia, links and do not version your API by any means
    • pass versions through headers / urls

    I will not try to answer a question which approach is better. Whatever suit your needs and allows you to generate business value should be picked.

    Let’s assume that you do version your API. In that case you should provide as many contracts as many versions you support. -You can create a subfolder for every version or append it to th contract name - whatever suits you more.

    83.4.2 JAR versioning

    If by versioning you mean the version of the JAR that contains the stubs then there are essentially two main approaches.

    Let’s assume that you’re doing Continuous Delivery / Deployment which means that you’re generating a new version of +You can create a subfolder for every version or append it to th contract name - whatever suits you more.

    84.4.2 JAR versioning

    If by versioning you mean the version of the JAR that contains the stubs then there are essentially two main approaches.

    Let’s assume that you’re doing Continuous Delivery / Deployment which means that you’re generating a new version of the jar each time you go through the pipeline and that jar can go to production at any time. For example your jar version looks like this (it got built on the 20.10.2016 at 20:15:21) :

    1.0.0.20161020-201521-RELEASE

    In that case your generated stub jar will look like this.

    1.0.0.20161020-201521-RELEASE-stubs.jar

    In this case you should inside your application.yml or @AutoConfigureStubRunner when referencing stubs provide the latest version of the stubs. You can do that by passing the + sign. Example

    @AutoConfigureStubRunner(ids = {"com.example:http-server-dsl:+:stubs:8080"})

    If the versioning however is fixed (e.g. 1.0.4.RELEASE or 2.1.1) then you have to set the concrete value of the jar -version. Example for 2.1.1.

    @AutoConfigureStubRunner(ids = {"com.example:http-server-dsl:2.1.1:stubs:8080"})

    83.4.3 Dev or prod stubs

    You can manipulate the classifier to run the tests against current development version of the stubs of other services +version. Example for 2.1.1.

    @AutoConfigureStubRunner(ids = {"com.example:http-server-dsl:2.1.1:stubs:8080"})

    84.4.3 Dev or prod stubs

    You can manipulate the classifier to run the tests against current development version of the stubs of other services or the ones that were deployed to production. If you alter your build to deploy the stubs with the prod-stubs classifier - once you reach production deployment then you can run tests in one case with dev stubs and one with prod stubs.

    Example of tests using development version of stubs

    @AutoConfigureStubRunner(ids = {"com.example:http-server-dsl:+:stubs:8080"})

    Example of tests using production version of stubs

    @AutoConfigureStubRunner(ids = {"com.example:http-server-dsl:+:prod-stubs:8080"})

    You can pass those values also via properties from your deployment pipeline.

    83.5 Common repo with contracts

    Another way of storing contracts other than having them with the producer is keeping them in a common place. + once you reach production deployment then you can run tests in one case with dev stubs and one with prod stubs.

    Example of tests using development version of stubs

    @AutoConfigureStubRunner(ids = {"com.example:http-server-dsl:+:stubs:8080"})

    Example of tests using production version of stubs

    @AutoConfigureStubRunner(ids = {"com.example:http-server-dsl:+:prod-stubs:8080"})

    You can pass those values also via properties from your deployment pipeline.

    84.5 Common repo with contracts

    Another way of storing contracts other than having them with the producer is keeping them in a common place. It can be related to security issues where the consumers can’t clone the producer’s code. Also if you keep contracts in a single place then you, as a producer, will know how many consumers you have and which -consumer will you break with your local changes.

    83.5.1 Repo structure

    Let’s assume that we have a producer with coordinates com.example:server and 3 consumers: client1, +consumer will you break with your local changes.

    84.5.1 Repo structure

    Let’s assume that we have a producer with coordinates com.example:server and 3 consumers: client1, client2, client3. Then in the repository with common contracts you would have the following setup (which you can checkout here:

    ├── com
     │   └── example
    @@ -271,11 +271,11 @@ Those poms are necessary for the consumer side to run mvn
     			</excludes>
     		</fileSet>
     	</fileSets>
    -</assembly>

    83.5.2 Workflow

    The workflow would look similar to the one presented in the Step by step guide to CDC. The only difference +</assembly>

    84.5.2 Workflow

    The workflow would look similar to the one presented in the Step by step guide to CDC. The only difference is that the producer doesn’t own the contracts anymore. So the consumer and the producer have to work on - common contracts in a common repository.

    83.5.3 Consumer

    When the consumer wants to work on the contracts offline, instead of cloning the producer code, the + common contracts in a common repository.

    84.5.3 Consumer

    When the consumer wants to work on the contracts offline, instead of cloning the producer code, the consumer team clones the common repository, goes to the required producer’s folder (e.g. com/example/server) -and runs mvn clean install -DskipTests to install locally the stubs converted from the contracts.

    [Tip]Tip

    You need to have Maven installed locally

    83.5.4 Producer

    As a producer it’s enough to alter the Spring Cloud Contract Verifier to provide the URL and the dependency +and runs mvn clean install -DskipTests to install locally the stubs converted from the contracts.

    [Tip]Tip

    You need to have Maven installed locally

    84.5.4 Producer

    As a producer it’s enough to alter the Spring Cloud Contract Verifier to provide the URL and the dependency of the JAR containing the contracts:

    <plugin>
     	<groupId>org.springframework.cloud</groupId>
     	<artifactId>spring-cloud-contract-maven-plugin</artifactId>
    @@ -291,7 +291,7 @@ of the JAR containing the contracts:

    http://link/to/your/nexus/or/artifactory/or/sth. It will be then unpacked in a local temporary folder
     and contracts present under the com/example/server will be picked as the ones used to generate the
     tests and the stubs. Due to this convention the producer team will know which consumer teams will be broken
    -when some incompatible changes are done.

    The rest of the flow looks the same.

    83.5.5 How can I define messaging contracts per topic not per producer?

    To avoid messaging contracts duplication in the common repo, when few producers writing messages to one topic, +when some incompatible changes are done.

    The rest of the flow looks the same.

    84.5.5 How can I define messaging contracts per topic not per producer?

    To avoid messaging contracts duplication in the common repo, when few producers writing messages to one topic, we could create the structure when the rest contracts would be placed in a folder per producer and messaging contracts in the folder per topic.

    For Maven Project

    To make it possible to work on the producer side we could do the following things (all via Maven plugins):

    • Add common repo dependency to your classpath:
    <dependency>
        <groupId>com.example</groupId>
    @@ -396,13 +396,13 @@ deleteUnwantedContracts.dependsOn("deleteUnwantedContracts")
    • Configure plugin by specifying the directory containing contracts using contractsDslDir property
    contracts {
     
         contractsDslDir = new File("${buildDir}/unpackedContracts")
    -}

    83.6 Can I have multiple base classes for tests?

    Yes! Check out the Different base classes for contracts sections -of either Gradle or Maven plugins.

    83.7 How can I debug the request/response being sent by the generated tests client?

    The generated tests all boil down to RestAssured in some form or fashion which relies on Apache HttpClient. HttpClient has a facility called wire logging which logs the entire request and response to HttpClient. Spring Boot has a logging common application property for doing this sort of thing, just add this to your application properties

    logging.level.org.apache.http.wire=DEBUG

    83.7.1 How can I debug the mapping/request/response being sent by WireMock?

    Starting from version 1.2.0 we turn on WireMock logging to +}

    84.6 Can I have multiple base classes for tests?

    Yes! Check out the Different base classes for contracts sections +of either Gradle or Maven plugins.

    84.7 How can I debug the request/response being sent by the generated tests client?

    The generated tests all boil down to RestAssured in some form or fashion which relies on Apache HttpClient. HttpClient has a facility called wire logging which logs the entire request and response to HttpClient. Spring Boot has a logging common application property for doing this sort of thing, just add this to your application properties

    logging.level.org.apache.http.wire=DEBUG

    84.7.1 How can I debug the mapping/request/response being sent by WireMock?

    Starting from version 1.2.0 we turn on WireMock logging to info and the WireMock notifier to being verbose. Now you will exactly know what request was received by WireMock server and which -matching response definition was picked.

    To turn off this feature just bump WireMock logging to ERROR

    logging.level.com.github.tomakehurst.wiremock=ERROR

    83.7.2 How can I see what got registered in the HTTP server stub?

    You can use the mappingsOutputFolder property on @AutoConfigureStubRunner or StubRunnerRule +matching response definition was picked.

    To turn off this feature just bump WireMock logging to ERROR

    logging.level.com.github.tomakehurst.wiremock=ERROR

    84.7.2 How can I see what got registered in the HTTP server stub?

    You can use the mappingsOutputFolder property on @AutoConfigureStubRunner or StubRunnerRule to dump all mappings per artifact id. Also the port at which the given stub server was -started will be attached.

    83.7.3 Can I reference the request from the response?

    Yes! With version 1.1.0 we’ve added such a possibility. On the HTTP stub server side we’re providing support -for this for WireMock. In case of other HTTP server stubs you’ll have to implement the approach yourself.

    83.7.4 Can I reference text from file?

    Yes! With version 1.2.0 we’ve added such a possibility. It’s enough to call file(…​) method in the +started will be attached.

    84.7.3 Can I reference the request from the response?

    Yes! With version 1.1.0 we’ve added such a possibility. On the HTTP stub server side we’re providing support +for this for WireMock. In case of other HTTP server stubs you’ll have to implement the approach yourself.

    84.7.4 Can I reference text from file?

    Yes! With version 1.2.0 we’ve added such a possibility. It’s enough to call file(…​) method in the DSL and provide a path relative to where the contract lays. -If you’re using YAML just use the bodyFromFile property.

    \ No newline at end of file +If you’re using YAML just use the bodyFromFile property.

    \ No newline at end of file diff --git a/Finchley.M7/multi/multi__spring_cloud_contract_stub_runner.html b/Finchley.M7/multi/multi__spring_cloud_contract_stub_runner.html index 45c03091..8bc00184 100644 --- a/Finchley.M7/multi/multi__spring_cloud_contract_stub_runner.html +++ b/Finchley.M7/multi/multi__spring_cloud_contract_stub_runner.html @@ -1,10 +1,10 @@ - 86. Spring Cloud Contract Stub Runner

    86. Spring Cloud Contract Stub Runner

    One of the issues that you might encounter while using Spring Cloud Contract Verifier is + 87. Spring Cloud Contract Stub Runner

    87. Spring Cloud Contract Stub Runner

    One of the issues that you might encounter while using Spring Cloud Contract Verifier is passing the generated WireMock JSON stubs from the server side to the client side (or to various clients). The same takes place in terms of client-side generation for messaging.

    Copying the JSON files and setting the client side for messaging manually is out of the question. That is why we introduced Spring Cloud Contract Stub Runner. It can -automatically download and run the stubs for you.

    86.1 Snapshot versions

    Add the additional snapshot repository to your build.gradle file to use snapshot +automatically download and run the stubs for you.

    87.1 Snapshot versions

    Add the additional snapshot repository to your build.gradle file to use snapshot versions, which are automatically uploaded after every successful build:

    Maven. 

    <repositories>
     	<repository>
    @@ -67,7 +67,7 @@ versions, which are automatically uploaded after every successful build:

    "http://repo.spring.io/milestone" } maven { url "http://repo.spring.io/release" } }

    -

    86.2 Publishing Stubs as JARs

    The easiest approach would be to centralize the way stubs are kept. For example, you can +

    87.2 Publishing Stubs as JARs

    The easiest approach would be to centralize the way stubs are kept. For example, you can keep them as jars in a Maven repository.

    [Tip]Tip

    For both Maven and Gradle, the setup comes ready to work. However, you can customize it if you want to.

    Maven. 

    <!-- First disable the default jar setup in the properties section -->
    @@ -155,9 +155,9 @@ publishing {
     		}
     	}
     }

    -

    86.3 Stub Runner Core

    Runs stubs for service collaborators. Treating stubs as contracts of services allows to use stub-runner as an implementation of +

    87.3 Stub Runner Core

    Runs stubs for service collaborators. Treating stubs as contracts of services allows to use stub-runner as an implementation of Consumer Driven Contracts.

    Stub Runner allows you to automatically download the stubs of the provided dependencies (or pick those from the classpath), start WireMock servers for them and feed them with proper stub definitions. -For messaging, special stub routes are defined.

    86.3.1 Retrieving stubs

    You can pick the following options of acquiring stubs

    • Aether based solution that downloads JARs with stubs from Artifactory / Nexus
    • Classpath scanning solution that searches classpath via pattern to retrieve stubs
    • Write your own implementation of the org.springframework.cloud.contract.stubrunner.StubDownloaderBuilder for full customization

    The latter example is described in the Custom Stub Runner section.

    Stub downloading

    You can control the stub downloading via the stubsMode switch. It picks value from the +For messaging, special stub routes are defined.

    87.3.1 Retrieving stubs

    You can pick the following options of acquiring stubs

    • Aether based solution that downloads JARs with stubs from Artifactory / Nexus
    • Classpath scanning solution that searches classpath via pattern to retrieve stubs
    • Write your own implementation of the org.springframework.cloud.contract.stubrunner.StubDownloaderBuilder for full customization

    The latter example is described in the Custom Stub Runner section.

    Stub downloading

    You can control the stub downloading via the stubsMode switch. It picks value from the StubRunnerProperties.StubsMode enum. You can use the following options

    • StubRunnerProperties.StubsMode.CLASSPATH (default value) - will pick stubs from the classpath
    • StubRunnerProperties.StubsMode.LOCAL - will pick stubs from a local storage (e.g. .m2)
    • StubRunnerProperties.StubsMode.REMOTE - will pick stubs from a remote location

    Example:

    @AutoConfigureStubRunner(repositoryRoot="http://foo.bar", ids = "com.example:beer-api-producer:+:stubs:8095", stubsMode = StubRunnerProperties.StubsMode.LOCAL)

    Classpath scanning

    If you set the stubsMode property to StubRunnerProperties.StubsMode.CLASSPATH (or set nothing since CLASSPATH is the default value) then classpath will get scanned. Let’s look at the following example:

    @AutoConfigureStubRunner(ids = {
    @@ -216,7 +216,7 @@ structure in your stubs jar.

    └──
                     │       └── contract2.groovy
                     └── mappings
                         └── mapping.json

    By maintaining this structure classpath gets scanned and you can profit from the messaging / -HTTP stubs without the need to download artifacts.

    86.3.2 Running stubs

    Limitations

    [Important]Important

    There might be a problem with StubRunner shutting down ports between tests. You might +HTTP stubs without the need to download artifacts.

    87.3.2 Running stubs

    Limitations

    [Important]Important

    There might be a problem with StubRunner shutting down ports between tests. You might have a situation in which you get port conflicts. As long as you use the same context across tests everything works fine. But when the context are different (e.g. different stubs or different profiles) then you have to either use @DirtiesContext to shut down the stub servers, or else run them on @@ -283,7 +283,7 @@ mappings available for the given server:

    ["uuid" : "f9152eb9-bf77-4c38-8289-90be7d10d0d7"
     },
     ...
    -]

    Messaging Stubs

    Depending on the provided Stub Runner dependency and the DSL the messaging routes are automatically set up.

    86.4 Stub Runner JUnit Rule

    Stub Runner comes with a JUnit rule thanks to which you can very easily download and run stubs for given group and artifact id:

    @ClassRule public static StubRunnerRule rule = new StubRunnerRule()
    +]

    Messaging Stubs

    Depending on the provided Stub Runner dependency and the DSL the messaging routes are automatically set up.

    87.4 Stub Runner JUnit Rule

    Stub Runner comes with a JUnit rule thanks to which you can very easily download and run stubs for given group and artifact id:

    @ClassRule public static StubRunnerRule rule = new StubRunnerRule()
     		.repoRoot(repoRoot())
     		.downloadStub("org.springframework.cloud.contract.verifier.stubs", "loanIssuance")
     		.downloadStub("org.springframework.cloud.contract.verifier.stubs:fraudDetectionServer");

    After that rule gets executed Stub Runner connects to your Maven repository and for the given list of dependencies tries to:

    • download them
    • cache them locally
    • unzip them to a temporary folder
    • start a WireMock server for each Maven dependency on a random port from the provided range of ports / provided port
    • feed the WireMock server with all JSON files that are valid WireMock definitions
    • can also send messages (remember to pass an implementation of MessageVerifier interface)

    Stub Runner uses Eclipse Aether mechanism to download the Maven dependencies. @@ -367,14 +367,14 @@ def 'should outp then(httpGet(rule.findStubUrl("fraudDetectionServer").toString() + "/name")).isEqualTo("fraudDetectionServer"); }

    Check the Common properties for JUnit and Spring for more information on how to apply global configuration of Stub Runner.

    [Important]Important

    To use the JUnit rule together with messaging you have to provide an implementation of the MessageVerifier interface to the rule builder (e.g. rule.messageVerifier(new MyMessageVerifier())). -If you don’t do this then whenever you try to send a message an exception will be thrown.

    86.4.1 Maven settings

    The stub downloader honors Maven settings for a different local repository folder. -Authentication details for repositories and profiles are currently not taken into account, so you need to specify it using the properties mentioned above.

    86.4.2 Providing fixed ports

    You can also run your stubs on fixed ports. You can do it in two different ways. One is to pass it in the properties, and the other via fluent API of -JUnit rule.

    86.4.3 Fluent API

    When using the StubRunnerRule you can add a stub to download and then pass the port for the last downloaded stub.

    @ClassRule public static StubRunnerRule rule = new StubRunnerRule()
    +If you don’t do this then whenever you try to send a message an exception will be thrown.

    87.4.1 Maven settings

    The stub downloader honors Maven settings for a different local repository folder. +Authentication details for repositories and profiles are currently not taken into account, so you need to specify it using the properties mentioned above.

    87.4.2 Providing fixed ports

    You can also run your stubs on fixed ports. You can do it in two different ways. One is to pass it in the properties, and the other via fluent API of +JUnit rule.

    87.4.3 Fluent API

    When using the StubRunnerRule you can add a stub to download and then pass the port for the last downloaded stub.

    @ClassRule public static StubRunnerRule rule = new StubRunnerRule()
     		.repoRoot(repoRoot())
     		.downloadStub("org.springframework.cloud.contract.verifier.stubs", "loanIssuance")
     		.withPort(12345)
     		.downloadStub("org.springframework.cloud.contract.verifier.stubs:fraudDetectionServer:12346");

    You can see that for this example the following test is valid:

    then(rule.findStubUrl("loanIssuance")).isEqualTo(URI.create("http://localhost:12345").toURL());
    -then(rule.findStubUrl("fraudDetectionServer")).isEqualTo(URI.create("http://localhost:12346").toURL());

    86.4.4 Stub Runner with Spring

    Sets up Spring configuration of the Stub Runner project.

    By providing a list of stubs inside your configuration file the Stub Runner automatically downloads +then(rule.findStubUrl("fraudDetectionServer")).isEqualTo(URI.create("http://localhost:12346").toURL());

    87.4.4 Stub Runner with Spring

    Sets up Spring configuration of the Stub Runner project.

    By providing a list of stubs inside your configuration file the Stub Runner automatically downloads and registers in WireMock the selected stubs.

    If you want to find the URL of your stubbed dependency you can autowire the StubFinder interface and use its methods as presented below:

    @ContextConfiguration(classes = Config, loader = SpringBootContextLoader)
     @SpringBootTest(properties = [" stubrunner.cloud.enabled=false",
    @@ -465,7 +465,7 @@ Below you can find an example of achieving the same result by setting values on
     		stubsMode = StubRunnerProperties.StubsMode.REMOTE,
     		repositoryRoot = "classpath:m2repo/repository/")

    Stub Runner Spring registers environment variables in the following manner for every registered WireMock server. Example for Stub Runner ids - com.example:foo, com.example:bar.

    • stubrunner.runningstubs.foo.port
    • stubrunner.runningstubs.bar.port

    Which you can reference in your code.

    86.5 Stub Runner Spring Cloud

    Stub Runner can integrate with Spring Cloud.

    For real life examples you can check the

    86.5.1 Stubbing Service Discovery

    The most important feature of Stub Runner Spring Cloud is the fact that it’s stubbing

    • DiscoveryClient
    • Ribbon ServerList

    that means that regardless of the fact whether you’re using Zookeeper, Consul, Eureka or anything else, you don’t need that in your tests. + com.example:foo, com.example:bar.

    • stubrunner.runningstubs.foo.port
    • stubrunner.runningstubs.bar.port

    Which you can reference in your code.

    87.5 Stub Runner Spring Cloud

    Stub Runner can integrate with Spring Cloud.

    For real life examples you can check the

    87.5.1 Stubbing Service Discovery

    The most important feature of Stub Runner Spring Cloud is the fact that it’s stubbing

    • DiscoveryClient
    • Ribbon ServerList

    that means that regardless of the fact whether you’re using Zookeeper, Consul, Eureka or anything else, you don’t need that in your tests. We’re starting WireMock instances of your dependencies and we’re telling your application whenever you’re using Feign, load balanced RestTemplate or DiscoveryClient directly, to call those stubbed servers instead of calling the real Service Discovery tool.

    For example this test will pass

    def 'should make service discovery work'() {
     	expect: 'WireMocks are running'
    @@ -484,15 +484,15 @@ via a static block like presented below (example for Eureka)

    static {
             System.setProperty("eureka.client.enabled", "false");
             System.setProperty("spring.cloud.config.failFast", "false");
    -    }

    86.5.2 Additional Configuration

    You can match the artifactId of the stub with the name of your app by using the stubrunner.idsToServiceIds: map. + }

    87.5.2 Additional Configuration

    You can match the artifactId of the stub with the name of your app by using the stubrunner.idsToServiceIds: map. You can disable Stub Runner Ribbon support by providing: stubrunner.cloud.ribbon.enabled equal to false You can disable Stub Runner support by providing: stubrunner.cloud.enabled equal to false

    [Tip]Tip

    By default all service discovery will be stubbed. That means that regardless of the fact if you have an existing DiscoveryClient its results will be ignored. However, if you want to reuse it, just set stubrunner.cloud.delegate.enabled to true and then your existing DiscoveryClient results will be - merged with the stubbed ones.

    86.6 Stub Runner Boot Application

    Spring Cloud Contract Stub Runner Boot is a Spring Boot application that exposes REST endpoints to + merged with the stubbed ones.

    87.6 Stub Runner Boot Application

    Spring Cloud Contract Stub Runner Boot is a Spring Boot application that exposes REST endpoints to trigger the messaging labels and to access started WireMock servers.

    One of the use-cases is to run some smoke (end to end) tests on a deployed application. You can check out the Spring Cloud Pipelines -project for more information.

    86.6.1 How to use it?

    Stub Runner Server

    Just add the

    compile "org.springframework.cloud:spring-cloud-starter-stub-runner"

    Annotate a class with @EnableStubRunnerServer, build a fat-jar and you’re ready to go!

    For the properties check the Stub Runner Spring section.

    Stub Runner Server Fat Jar

    You can download a standalone JAR from Maven (for example, for version 1.2.3.RELEASE), as follows:

    $ wget -O stub-runner.jar 'https://search.maven.org/remote_content?g=org.springframework.cloud&a=spring-cloud-contract-stub-runner-boot&v=1.2.3.RELEASE'
    +project for more information.

    87.6.1 How to use it?

    Stub Runner Server

    Just add the

    compile "org.springframework.cloud:spring-cloud-starter-stub-runner"

    Annotate a class with @EnableStubRunnerServer, build a fat-jar and you’re ready to go!

    For the properties check the Stub Runner Spring section.

    Stub Runner Server Fat Jar

    You can download a standalone JAR from Maven (for example, for version 1.2.3.RELEASE), as follows:

    $ wget -O stub-runner.jar 'https://search.maven.org/remote_content?g=org.springframework.cloud&a=spring-cloud-contract-stub-runner-boot&v=1.2.3.RELEASE'
     $ java -jar stub-runner.jar --stubrunner.ids=... --stubrunner.repositoryRoot=...

    Spring Cloud CLI

    Starting from 1.4.0.RELEASE version of the Spring Cloud CLI project you can start Stub Runner Boot by executing spring cloud stubrunner.

    In order to pass the configuration just create a stubrunner.yml file in the current working directory or a subdirectory called config or in ~/.spring-cloud. The file could look like this @@ -502,7 +502,7 @@ or a subdirectory called config or in spring cloud stubrunner from your terminal window to start -the Stub Runner server. It will be available at port 8750.

    86.6.2 Endpoints

    HTTP

    • GET /stubs - returns a list of all running stubs in ivy:integer notation
    • GET /stubs/{ivy} - returns a port for the given ivy notation (when calling the endpoint ivy can also be artifactId only)

    Messaging

    For Messaging

    • GET /triggers - returns a list of all running labels in ivy : [ label1, label2 …​] notation
    • POST /triggers/{label} - executes a trigger with label
    • POST /triggers/{ivy}/{label} - executes a trigger with label for the given ivy notation (when calling the endpoint ivy can also be artifactId only)

    86.6.3 Example

    @ContextConfiguration(classes = StubRunnerBoot, loader = SpringBootContextLoader)
    +the Stub Runner server. It will be available at port 8750.

    87.6.2 Endpoints

    HTTP

    • GET /stubs - returns a list of all running stubs in ivy:integer notation
    • GET /stubs/{ivy} - returns a port for the given ivy notation (when calling the endpoint ivy can also be artifactId only)

    Messaging

    For Messaging

    • GET /triggers - returns a list of all running labels in ivy : [ label1, label2 …​] notation
    • POST /triggers/{label} - executes a trigger with label
    • POST /triggers/{ivy}/{label} - executes a trigger with label for the given ivy notation (when calling the endpoint ivy can also be artifactId only)

    87.6.3 Example

    @ContextConfiguration(classes = StubRunnerBoot, loader = SpringBootContextLoader)
     @SpringBootTest(properties = "spring.cloud.zookeeper.enabled=false")
     @ActiveProfiles("test")
     class StubRunnerBootSpec extends Specification {
    @@ -588,7 +588,7 @@ the Stub Runner server. It will be available at port 8750<
     			e.message.contains("org.springframework.cloud.contract.verifier.stubs:bootService:0.0.1-SNAPSHOT:stubs=")
     	}
     
    -}

    86.6.4 Stub Runner Boot with Service Discovery

    One of the possibilities of using Stub Runner Boot is to use it as a feed of stubs for "smoke-tests". What does it mean? +}

    87.6.4 Stub Runner Boot with Service Discovery

    One of the possibilities of using Stub Runner Boot is to use it as a feed of stubs for "smoke-tests". What does it mean? Let’s assume that you don’t want to deploy 50 microservice to a test environment in order to check if your application is working fine. You’ve already executed a suite of tests during the build process but you would also like to ensure that the packaging of your application is fine. What you can do @@ -621,7 +621,7 @@ and we want to have the stub runner feature turned on @Aut (4) - we provide a list of artifactId to serviceId mapping

    That way your deployed application can send requests to started WireMock servers via the service discovery. Most likely points 1-3 could be set by default in application.yml cause they are not likely to change. That way you can provide only the list of stubs to download whenever you start -the Stub Runner Boot.

    86.7 Stubs Per Consumer

    There are cases in which 2 consumers of the same endpoint want to have 2 different responses.

    [Tip]Tip

    This approach also allows you to immediately know which consumer is using which part of your API. +the Stub Runner Boot.

    87.7 Stubs Per Consumer

    There are cases in which 2 consumers of the same endpoint want to have 2 different responses.

    [Tip]Tip

    This approach also allows you to immediately know which consumer is using which part of your API. You can remove part of a response that your API produces and you can see which of your autogenerated tests fails. If none fails then you can safely delete that part of the response cause nobody is using it.

    Let’s look at the following example for contract defined for the producer called producer. There are 2 consumers: foo-consumer and bar-consumer.

    Consumer foo-service

    request {
    @@ -676,25 +676,25 @@ Or set the test as follows:

    foo-consumer in its name (i.e. those from the
     src/test/resources/contracts/foo-consumer/some/contracts/…​ folder) will be allowed to be referenced.

    You can check out issue 224 for more -information about the reasons behind this change.

    86.8 Common

    This section briefly describes common properties, including:

    86.8.1 Common Properties for JUnit and Spring

    You can set repetitive properties by using system properties or Spring configuration +information about the reasons behind this change.

    87.8 Common

    This section briefly describes common properties, including:

    87.8.1 Common Properties for JUnit and Spring

    You can set repetitive properties by using system properties or Spring configuration properties. Here are their names with their default values:

    Property nameDefault valueDescription

    stubrunner.minPort

    10000

    Minimum value of a port for a started WireMock with stubs.

    stubrunner.maxPort

    15000

    Maximum value of a port for a started WireMock with stubs.

    stubrunner.repositoryRoot

     

    Maven repo URL. If blank, then call the local maven repo.

    stubrunner.classifier

    stubs

    Default classifier for the stub artifacts.

    stubrunner.stubsMode

    CLASSPATH

    The way you want to fetch and register the stubs

    stubrunner.ids

     

    Array of Ivy notation stubs to download.

    stubrunner.username

     

    Optional username to access the tool that stores the JARs with stubs.

    stubrunner.password

     

    Optional password to access the tool that stores the JARs with stubs.

    stubrunner.stubsPerConsumer

    false

    Set to true if you want to use different stubs for each consumer instead of registering all stubs for every consumer.

    stubrunner.consumerName

     

    If you want to use a stub for each consumer and want to -override the consumer name just change this value.

    86.8.2 Stub Runner Stubs IDs

    You can provide the stubs to download via the stubrunner.ids system property. They +override the consumer name just change this value.

    87.8.2 Stub Runner Stubs IDs

    You can provide the stubs to download via the stubrunner.ids system property. They follow this pattern:

    groupId:artifactId:version:classifier:port

    Note that version, classifier and port are optional.

    • If you do not provide the port, a random one will be picked.
    • If you do not provide the classifier, the default is used. (Note that you can pass an empty classifier this way: groupId:artifactId:version:).
    • If you do not provide the version, then the + will be passed and the latest one is downloaded.

    port means the port of the WireMock server.

    [Important]Important

    Starting with version 1.0.4, you can provide a range of versions that you would like the Stub Runner to take into consideration. You can read more about the Aether versioning -ranges here.

    86.9 Stub Runner Docker

    We’re publishing a spring-cloud/spring-cloud-contract-stub-runner Docker image +ranges here.

    87.9 Stub Runner Docker

    We’re publishing a spring-cloud/spring-cloud-contract-stub-runner Docker image that will start the standalone version of Stub Runner.

    If you want to learn more about the basics of Maven, artifact ids, -group ids, classifiers and Artifact Managers, just click here Section 84.6, “Docker Project”.

    86.9.1 How to use it

    Just execute the docker image. You can pass any of the Section 86.8.1, “Common Properties for JUnit and Spring” +group ids, classifiers and Artifact Managers, just click here Section 85.6, “Docker Project”.

    87.9.1 How to use it

    Just execute the docker image. You can pass any of the Section 87.8.1, “Common Properties for JUnit and Spring” as environment variables. The convention is that all the letters should be upper case. The camel case notation should and the dot (.) should be separated via underscore (_). E.g. the stubrunner.repositoryRoot property should be represented - as a STUBRUNNER_REPOSITORY_ROOT environment variable.

    86.9.2 Example of client side usage in a non JVM project

    We’d like to use the stubs created in this Section 84.6.4, “Server side (nodejs)” step. + as a STUBRUNNER_REPOSITORY_ROOT environment variable.

    87.9.2 Example of client side usage in a non JVM project

    We’d like to use the stubs created in this Section 85.6.4, “Server side (nodejs)” step. Let’s assume that we want to run the stubs on port 9876. The NodeJS code is available here:

    $ git clone https://github.com/spring-cloud-samples/spring-cloud-contract-nodejs
     $ cd bookstore

    Let’s run the Stub Runner Boot application with the stubs.

    # Provide the Spring Cloud Contract Docker version
    @@ -712,4 +712,4 @@ that the stubs are setup properly.

    "Content-Type:application/json" -X POST --data '{ "title" : "Title", "genre" : "Genre", "description" : "Description", "author" : "Author", "publisher" : "Publisher", "pages" : 100, "image_url" : "https://d213dhlpdb53mu.cloudfront.net/assets/pivotal-square-logo-41418bd391196c3022f3cd9f3959b3f6d7764c47873d858583384e759c7db435.svg", "buy_url" : "https://pivotal.io" }' http://localhost:9876/api/books
     # Now time for the second request
     $ curl -X GET http://localhost:9876/api/books
    -# You will receive contents of the JSON
    \ No newline at end of file +# You will receive contents of the JSON
    \ No newline at end of file diff --git a/Finchley.M7/multi/multi__spring_cloud_contract_verifier_introduction.html b/Finchley.M7/multi/multi__spring_cloud_contract_verifier_introduction.html index f623d9ea..489f2b28 100644 --- a/Finchley.M7/multi/multi__spring_cloud_contract_verifier_introduction.html +++ b/Finchley.M7/multi/multi__spring_cloud_contract_verifier_introduction.html @@ -1,6 +1,6 @@ - 82. Spring Cloud Contract Verifier Introduction

    82. Spring Cloud Contract Verifier Introduction

    [Tip]Tip

    The Accurest project was initially started by Marcin Grzejszczak and Jakub Kubrynski + 83. Spring Cloud Contract Verifier Introduction

    83. Spring Cloud Contract Verifier Introduction

    [Tip]Tip

    The Accurest project was initially started by Marcin Grzejszczak and Jakub Kubrynski (codearte.io)

    Spring Cloud Contract Verifier enables Consumer Driven Contract (CDC) development of JVM-based applications. It moves TDD to the level of software architecture.

    Spring Cloud Contract Verifier ships with Contract Definition Language (CDL). Contract definitions are used to produce the following resources:

    • JSON stub definitions to be used by WireMock when doing integration testing on the @@ -9,7 +9,7 @@ produced by Spring Cloud Contract Verifier.
    • Messaging r Integration, Spring Cloud Stream, Spring AMQP, and Apache Camel. You can also set your own integrations.
    • Acceptance tests (in JUnit or Spock) are used to verify if server-side implementation of the API is compliant with the contract (server tests). A full test is generated by -Spring Cloud Contract Verifier.

    82.1 Why a Contract Verifier?

    Assume that we have a system consisting of multiple microservices:

    Microservices Architecture

    82.1.1 Testing issues

    If we wanted to test the application in top left corner to determine whether it can +Spring Cloud Contract Verifier.

    83.1 Why a Contract Verifier?

    Assume that we have a system consisting of multiple microservices:

    Microservices Architecture

    83.1.1 Testing issues

    If we wanted to test the application in top left corner to determine whether it can communicate with other services, we could do one of two things:

    • Deploy all microservices and perform end-to-end tests.
    • Mock other microservices in unit/integration tests.

    Both have their advantages but also a lot of disadvantages.

    Deploy all microservices and perform end to end tests

    Advantages:

    • Simulates production.
    • Tests real communication between services.

    Disadvantages:

    • To test one microservice, we have to deploy 6 microservices, a couple of databases, etc.
    • The environment where the tests run is locked for a single suite of tests (nobody else would be able to run the tests in the meantime).
    • They take a long time to run.
    • The feedback comes very late in the process.
    • They are extremely hard to debug.

    Mock other microservices in unit/integration tests

    Advantages:

    • They provide very fast feedback.
    • They have no infrastructure requirements.

    Disadvantages:

    • The implementor of the service creates stubs that might have nothing to do with @@ -18,13 +18,13 @@ created. The main idea is to give you very fast feedback, without the need to se whole world of microservices. If you work on stubs, then the only applications you need are those that your application directly uses.

      Stubbed Services

      Spring Cloud Contract Verifier gives you the certainty that the stubs that you use were created by the service that you’re calling. Also, if you can use them, it means that they -were tested against the producer’s side. In short, you can trust those stubs.

    82.2 Purposes

    The main purposes of Spring Cloud Contract Verifier with Stub Runner are:

    • To ensure that WireMock/Messaging stubs (used when developing the client) do exactly +were tested against the producer’s side. In short, you can trust those stubs.

    83.2 Purposes

    The main purposes of Spring Cloud Contract Verifier with Stub Runner are:

    • To ensure that WireMock/Messaging stubs (used when developing the client) do exactly what the actual server-side implementation does.
    • To promote ATDD method and Microservices architectural style.
    • To provide a way to publish changes in contracts that are immediately visible on both sides.
    • To generate boilerplate test code to be used on the server side.
    [Important]Important

    Spring Cloud Contract Verifier’s purpose is NOT to start writing business features in the contracts. Assume that we have a business use case of fraud check. If a user can be a fraud for 100 different reasons, we would assume that you would create 2 contracts, one for the positive case and one for the negative case. Contract tests are -used to test contracts between applications and not to simulate full behavior.

    82.3 How It Works

    This section explores how Spring Cloud Contract Verifier with Stub Runner works.

    82.3.1 Defining the contract

    As consumers of services, we need to define what exactly we want to achieve. We need to +used to test contracts between applications and not to simulate full behavior.

    83.3 How It Works

    This section explores how Spring Cloud Contract Verifier with Stub Runner works.

    83.3.1 Defining the contract

    As consumers of services, we need to define what exactly we want to achieve. We need to formulate our expectations. That is why we write contracts.

    Assume that you want to send a request containing the ID of a client company and the amount it wants to borrow from us. You also want to send it to the /fraudcheck url via the PUT method.

    Groovy DSL.  @@ -138,7 +138,7 @@ response: # (7) #(9) - and JSON body equal to # { "fraudCheckStatus": "FRAUD", "rejectionReason": "Amount too high" } #(10) - with header `Content-Type` equal to `application/json;charset=UTF-8`

    -

    82.3.2 Client Side

    Spring Cloud Contract generates stubs, which you can use during client-side testing. +

    83.3.2 Client Side

    Spring Cloud Contract generates stubs, which you can use during client-side testing. You get a running WireMock instance/Messaging route that simulates the service. You would like to feed that instance with a proper stub definition.

    At some point in time, you need to send a request to the Fraud Detection service.

    ResponseEntity<FraudServiceResponse> response =
     		restTemplate.exchange("http://localhost:" + port + "/fraudcheck", HttpMethod.PUT,
    @@ -150,7 +150,7 @@ You would like to feed that instance with a proper stub definition.

    At som @DirtiesContext public class LoanApplicationServiceTests {

    After that, during the tests, Spring Cloud Contract automatically finds the stubs (simulating the real service) in the Maven repository and exposes them on a configured -(or random) port.

    82.3.3 Server Side

    Since you are developing your stub, you need to be sure that it actually resembles your +(or random) port.

    83.3.3 Server Side

    Since you are developing your stub, you need to be sure that it actually resembles your concrete implementation. You cannot have a situation where your stub acts in one way and your application behaves in a different way, especially in production.

    To ensure that your application behaves the way you define in your stub, tests are generated from the stub you provide.

    The autogenerated test looks, more or less, like this:

    @Test
    @@ -171,7 +171,7 @@ generated from the stub you provide.

    The autogenerated test looks, more or DocumentContext parsedJson = JsonPath.parse(response.getBody().asString()); assertThatJson(parsedJson).field("['fraudCheckStatus']").matches("[A-Z]{5}"); assertThatJson(parsedJson).field("['rejection.reason']").isEqualTo("Amount too high"); -}

    82.4 Step-by-step Guide to Consumer Driven Contracts (CDC)

    Consider an example of Fraud Detection and the Loan Issuance process. The business +}

    83.4 Step-by-step Guide to Consumer Driven Contracts (CDC)

    Consider an example of Fraud Detection and the Loan Issuance process. The business scenario is such that we want to issue loans to people but do not want them to steal from us. The current implementation of our system grants loans to everybody.

    Assume that Loan Issuance is a client to the Fraud Detection server. In the current sprint, we must develop a new feature: if a client wants to borrow too much money, then @@ -180,7 +180,7 @@ Issuance has an artifact-id of http-client, and bot discuss changes while going through the process. CDC is all about communication.

    The server side code is available here and the client code here.

    [Tip]Tip

    In this case, the producer owns the contracts. Physically, all the contract are -in the producer’s repository.

    82.4.1 Technical note

    If using the SNAPSHOT / Milestone / Release Candidate versions please add the +in the producer’s repository.

    83.4.1 Technical note

    If using the SNAPSHOT / Milestone / Release Candidate versions please add the following section to your build:

    Maven. 

    <repositories>
     	<repository>
    @@ -242,7 +242,7 @@ following section to your build:

    Maven.  maven { url "http://repo.spring.io/milestone" } maven { url "http://repo.spring.io/release" } }

    -

    82.4.2 Consumer side (Loan Issuance)

    As a developer of the Loan Issuance service (a consumer of the Fraud Detection server), you might do the following steps:

    1. Start doing TDD by writing a test for your feature.
    2. Write the missing implementation.
    3. Clone the Fraud Detection service repository locally.
    4. Define the contract locally in the repo of Fraud Detection service.
    5. Add the Spring Cloud Contract Verifier plugin.
    6. Run the integration tests.
    7. File a pull request.
    8. Create an initial implementation.
    9. Take over the pull request.
    10. Write the missing implementation.
    11. Deploy your app.
    12. Work online.

    Start doing TDD by writing a test for your feature.

    @Test
    +

    83.4.2 Consumer side (Loan Issuance)

    As a developer of the Loan Issuance service (a consumer of the Fraud Detection server), you might do the following steps:

    1. Start doing TDD by writing a test for your feature.
    2. Write the missing implementation.
    3. Clone the Fraud Detection service repository locally.
    4. Define the contract locally in the repo of Fraud Detection service.
    5. Add the Spring Cloud Contract Verifier plugin.
    6. Run the integration tests.
    7. File a pull request.
    8. Create an initial implementation.
    9. Take over the pull request.
    10. Write the missing implementation.
    11. Deploy your app.
    12. Work online.

    Start doing TDD by writing a test for your feature.

    @Test
     public void shouldBeRejectedDueToAbnormalLoanAmount() {
     	// given:
     	LoanApplication application = new LoanApplication(new Client("1234567890"),
    @@ -457,7 +457,7 @@ with group id com.example, artifact id stubs classifier on port 8080.

    File a pull request.

    What you have done until now is an iterative process. You can play around with the contract, install it locally, and work on the consumer side until the contract works as you wish.

    Once you are satisfied with the results and the test passes, publish a pull request to -the server side. Currently, the consumer side work is done.

    82.4.3 Producer side (Fraud Detection server)

    As a developer of the Fraud Detection server (a server to the Loan Issuance service):

    Create an initial implementation.

    As a reminder, you can see the initial implementation here:

    @RequestMapping(value = "/fraudcheck", method = PUT)
    +the server side. Currently, the consumer side work is done.

    83.4.3 Producer side (Fraud Detection server)

    As a developer of the Fraud Detection server (a server to the Loan Issuance service):

    Create an initial implementation.

    As a reminder, you can see the initial implementation here:

    @RequestMapping(value = "/fraudcheck", method = PUT)
     public FraudCheckResult fraudCheck(@RequestBody FraudCheck fraudCheck) {
     return new FraudCheckResult(FraudCheckStatus.OK, NO_REASON);
     }

    Take over the pull request.

    $ git checkout -b contract-change-pr master
    @@ -549,15 +549,15 @@ Contract Verifier plugin adds the tests to the gene
     actually run those tests from your IDE.

    Deploy your app.

    Once you finish your work, you can deploy your change. First, merge the branch:

    $ git checkout master
     $ git merge --no-ff contract-change-pr
     $ git push origin master

    Your CI might run something like ./mvnw clean deploy, which would publish both the -application and the stub artifacts.

    82.4.4 Consumer Side (Loan Issuance) Final Step

    As a developer of the Loan Issuance service (a consumer of the Fraud Detection server):

    Merge branch to master.

    $ git checkout master
    +application and the stub artifacts.

    83.4.4 Consumer Side (Loan Issuance) Final Step

    As a developer of the Loan Issuance service (a consumer of the Fraud Detection server):

    Merge branch to master.

    $ git checkout master
     $ git merge --no-ff contract-change-pr

    Work online.

    Now you can disable the offline work for Spring Cloud Contract Stub Runner and indicate where the repository with your stubs is located. At this moment the stubs of the server side are automatically downloaded from Nexus/Artifactory. You can set the value of stubsMode to REMOTE. The following code shows an example of achieving the same thing by changing the properties.

    stubrunner:
       ids: 'com.example:http-server-dsl:+:stubs:8080'
    -  repositoryRoot: http://repo.spring.io/libs-snapshot

    That’s it!

    82.5 Dependencies

    The best way to add dependencies is to use the proper starter dependency.

    For stub-runner, use spring-cloud-starter-stub-runner. When you use a plugin, add -spring-cloud-starter-contract-verifier.

    82.6 Additional Links

    Here are some resources related to Spring Cloud Contract Verifier and Stub Runner. Note + repositoryRoot: http://repo.spring.io/libs-snapshot

    That’s it!

    83.5 Dependencies

    The best way to add dependencies is to use the proper starter dependency.

    For stub-runner, use spring-cloud-starter-stub-runner. When you use a plugin, add +spring-cloud-starter-contract-verifier.

    83.6 Additional Links

    Here are some resources related to Spring Cloud Contract Verifier and Stub Runner. Note that some may be outdated, because the Spring Cloud Contract Verifier project is under -constant development.

    82.6.1 Spring Cloud Contract video

    You can check out the video from the Warsaw JUG about Spring Cloud Contract:

    82.7 Samples

    You can find some samples at -samples.

    \ No newline at end of file +constant development.

    83.6.1 Spring Cloud Contract video

    You can check out the video from the Warsaw JUG about Spring Cloud Contract:

    83.7 Samples

    You can find some samples at +samples.

    \ No newline at end of file diff --git a/Finchley.M7/multi/multi__spring_cloud_contract_verifier_messaging.html b/Finchley.M7/multi/multi__spring_cloud_contract_verifier_messaging.html index 645d1cf1..3db7f067 100644 --- a/Finchley.M7/multi/multi__spring_cloud_contract_verifier_messaging.html +++ b/Finchley.M7/multi/multi__spring_cloud_contract_verifier_messaging.html @@ -1,8 +1,8 @@ - 85. Spring Cloud Contract Verifier Messaging

    85. Spring Cloud Contract Verifier Messaging

    Spring Cloud Contract Verifier lets you verify applications that uses messaging as a + 86. Spring Cloud Contract Verifier Messaging

    86. Spring Cloud Contract Verifier Messaging

    Spring Cloud Contract Verifier lets you verify applications that uses messaging as a means of communication. All of the integrations shown in this document work with Spring, -but you can also create one of your own and use that.

    85.1 Integrations

    You can use one of the following four integration configurations:

    • Apache Camel
    • Spring Integration
    • Spring Cloud Stream
    • Spring AMQP

    Since we use Spring Boot, if you have added one of these libraries to the classpath, all +but you can also create one of your own and use that.

    86.1 Integrations

    You can use one of the following four integration configurations:

    • Apache Camel
    • Spring Integration
    • Spring Cloud Stream
    • Spring AMQP

    Since we use Spring Boot, if you have added one of these libraries to the classpath, all the messaging configuration is automatically set up.

    [Important]Important

    Remember to put @AutoConfigureMessageVerifier on the base class of your generated tests. Otherwise, messaging part of Spring Cloud Contract Verifier does not work.

    [Important]Important

    If you want to use Spring Cloud Stream, remember to add a dependency on @@ -14,7 +14,7 @@ work.

    </dependency>

    Gradle. 

    testCompile "org.springframework.cloud:spring-cloud-stream-test-support"

    -

    85.2 Manual Integration Testing

    The main interface used by the tests is +

    86.2 Manual Integration Testing

    The main interface used by the tests is org.springframework.cloud.contract.verifier.messaging.MessageVerifier. It defines how to send and receive messages. You can create your own implementation to achieve the same goal.

    In a test, you can inject a ContractVerifierMessageExchange to send and receive @@ -28,14 +28,14 @@ Here’s an example:

    private MessageVerifier verifier;
       ...
     }
    [Note]Note

    If your tests require stubs as well, then @AutoConfigureStubRunner includes the -messaging configuration, so you only need the one annotation.

    85.3 Publisher-Side Test Generation

    Having the input or outputMessage sections in your DSL results in creation of tests +messaging configuration, so you only need the one annotation.

    86.3 Publisher-Side Test Generation

    Having the input or outputMessage sections in your DSL results in creation of tests on the publisher’s side. By default, JUnit tests are created. However, there is also a possibility to create Spock tests.

    There are 3 main scenarios that we should take into consideration:

    • Scenario 1: There is no input message that produces an output message. The output message is triggered by a component inside the application (for example, scheduler).
    • Scenario 2: The input message triggers an output message.
    • Scenario 3: The input message is consumed and there is no output message.
    [Important]Important

    The destination passed to messageFrom or sentTo can have different meanings for different messaging implementations. For Stream and Integration it is first resolved as a destination of a channel. Then, if there is no such destination it is resolved as a channel name. For Camel, that’s a certain component (for example, -jms).

    85.3.1 Scenario 1: No Input Message

    Here is an example for Camel. For the given contract:

    Groovy DSL.  +jms).

    86.3.1 Scenario 1: No Input Message

    Here is an example for Camel. For the given contract:

    Groovy DSL. 

    def contractDsl = Contract.make {
     	label 'some_label'
     	input {
    @@ -88,7 +88,7 @@ outputMessage:
       DocumentContext parsedJson = JsonPath.parse(contractVerifierObjectMapper.writeValueAsString(response.payload))
       assertThatJson(parsedJson).field("bookName").isEqualTo("foo")
     
    -'''

    85.3.2 Scenario 2: Output Triggered by Input

    Here is an example for Camel. For the given contract:

    Groovy DSL.  +'''

    86.3.2 Scenario 2: Output Triggered by Input

    Here is an example for Camel. For the given contract:

    Groovy DSL. 

    def contractDsl = Contract.make {
     	label 'some_label'
     	input {
    @@ -159,7 +159,7 @@ then:
     and:
        DocumentContext parsedJson = JsonPath.parse(contractVerifierObjectMapper.writeValueAsString(response.payload))
        assertThatJson(parsedJson).field("bookName").isEqualTo("foo")
    -"""

    85.3.3 Scenario 3: No Output Message

    Here is an example for Camel. For the given contract:

    Groovy DSL.  +"""

    86.3.3 Scenario 3: No Output Message

    Here is an example for Camel. For the given contract:

    Groovy DSL. 

    def contractDsl = Contract.make {
     	label 'some_label'
     	input {
    @@ -207,7 +207,7 @@ when:
     then:
     	 noExceptionThrown()
     	 bookWasDeleted()
    -'''

    85.4 Consumer Stub Generation

    Unlike the HTTP part, in messaging, we need to publish the Groovy DSL inside the JAR with +'''

    86.4 Consumer Stub Generation

    Unlike the HTTP part, in messaging, we need to publish the Groovy DSL inside the JAR with a stub. Then it is parsed on the consumer side and proper stubbed routes are created.

    For more information, see the Stub Runner Messaging sections.

    Maven.  @@ -259,4 +259,4 @@ publishing { } } }

    -

    \ No newline at end of file +

    \ No newline at end of file diff --git a/Finchley.M7/multi/multi__spring_cloud_contract_verifier_setup.html b/Finchley.M7/multi/multi__spring_cloud_contract_verifier_setup.html index 7cbb08b5..2f43ec81 100644 --- a/Finchley.M7/multi/multi__spring_cloud_contract_verifier_setup.html +++ b/Finchley.M7/multi/multi__spring_cloud_contract_verifier_setup.html @@ -1,10 +1,10 @@ - 84. Spring Cloud Contract Verifier Setup

    84. Spring Cloud Contract Verifier Setup

    You can set up Spring Cloud Contract Verifier in the following ways:

    84.1 Gradle Project

    To learn how to set up the Gradle project for Spring Cloud Contract Verifier, read the -following sections:

    84.1.1 Prerequisites

    In order to use Spring Cloud Contract Verifier with WireMock, you muse use either a + 85. Spring Cloud Contract Verifier Setup

    85. Spring Cloud Contract Verifier Setup

    You can set up Spring Cloud Contract Verifier in the following ways:

    85.1 Gradle Project

    To learn how to set up the Gradle project for Spring Cloud Contract Verifier, read the +following sections:

    85.1.1 Prerequisites

    In order to use Spring Cloud Contract Verifier with WireMock, you muse use either a Gradle or a Maven plugin.

    [Warning]Warning

    If you want to use Spock in your projects, you must add separately the spock-core and spock-spring modules. Check Spock -docs for more information

    84.1.2 Add Gradle Plugin with Dependencies

    To add a Gradle plugin with dependencies, use code similar to this:

    buildscript {
    +docs for more information

    85.1.2 Add Gradle Plugin with Dependencies

    To add a Gradle plugin with dependencies, use code similar to this:

    buildscript {
     	repositories {
     		mavenCentral()
     	}
    @@ -29,7 +29,7 @@ dependencies {
     	testCompile 'org.spockframework:spock-core:1.0-groovy-2.4'
     	testCompile 'org.spockframework:spock-spring:1.0-groovy-2.4'
     	testCompile 'org.springframework.cloud:spring-cloud-starter-contract-verifier'
    -}

    84.1.3 Gradle and Rest Assured 2.0

    By default, Rest Assured 3.x is added to the classpath. However, to use Rest Assured 2.x +}

    85.1.3 Gradle and Rest Assured 2.0

    By default, Rest Assured 3.x is added to the classpath. However, to use Rest Assured 2.x you can add it to the plugins classpath, as shown here:

    buildscript {
     	repositories {
     		mavenCentral()
    @@ -48,7 +48,7 @@ depenendencies {
         testCompile "com.jayway.restassured:rest-assured:2.5.0"
         testCompile "com.jayway.restassured:spring-mock-mvc:2.5.0"
     }

    That way, the plugin automatically sees that Rest Assured 2.x is present on the classpath -and modifies the imports accordingly.

    84.1.4 Snapshot Versions for Gradle

    Add the additional snapshot repository to your build.gradle to use snapshot versions, +and modifies the imports accordingly.

    85.1.4 Snapshot Versions for Gradle

    Add the additional snapshot repository to your build.gradle to use snapshot versions, which are automatically uploaded after every successful build, as shown here:

    buildscript {
     	repositories {
     		mavenCentral()
    @@ -57,16 +57,16 @@ which are automatically uploaded after every successful build, as shown here:

    "http://repo.spring.io/milestone" } maven { url "http://repo.spring.io/release" } } -}

    84.1.5 Add stubs

    By default, Spring Cloud Contract Verifier is looking for stubs in the +}

    85.1.5 Add stubs

    By default, Spring Cloud Contract Verifier is looking for stubs in the src/test/resources/contracts directory.

    The directory containing stub definitions is treated as a class name, and each stub definition is treated as a single test. Spring Cloud Contract Verifier assumes that it contains at least one level of directories that are to be used as the test class name. If more than one level of nested directories is present, all except the last one is used as the package name. For example, with following structure:

    src/test/resources/contracts/myservice/shouldCreateUser.groovy
     src/test/resources/contracts/myservice/shouldReturnUser.groovy

    Spring Cloud Contract Verifier creates a test class named defaultBasePackage.MyService -with two methods:

    • shouldCreateUser()
    • shouldReturnUser()

    84.1.6 Run the Plugin

    The plugin registers itself to be invoked before a check task. If you want it to be +with two methods:

    • shouldCreateUser()
    • shouldReturnUser()

    85.1.6 Run the Plugin

    The plugin registers itself to be invoked before a check task. If you want it to be part of your build process, you need to do nothing more. If you just want to generate -tests, invoke the generateContractTests task.

    84.1.7 Default Setup

    The default Gradle Plugin setup creates the following Gradle part of the build (in +tests, invoke the generateContractTests task.

    85.1.7 Default Setup

    The default Gradle Plugin setup creates the following Gradle part of the build (in pseudocode):

    contracts {
         targetFramework = 'JUNIT'
         testMode = 'MockMvc'
    @@ -110,12 +110,12 @@ publishing {
                 artifact verifierStubsJar
             }
         }
    -}

    84.1.8 Configure Plugin

    To change the default configuration, add a contracts snippet to your Gradle config, as +}

    85.1.8 Configure Plugin

    To change the default configuration, add a contracts snippet to your Gradle config, as shown here:

    contracts {
     	testMode = 'MockMvc'
     	baseClassForTests = 'org.mycompany.tests'
     	generatedTestSourcesDir = project.file('src/generatedContract')
    -}

    84.1.9 Configuration Options

    • testMode: Defines the mode for acceptance tests. By default, the mode is MockMvc, +}

    85.1.9 Configuration Options

    • testMode: Defines the mode for acceptance tests. By default, the mode is MockMvc, which is based on Spring’s MockMvc. It can also be changed to JaxRsClient or to Explicit for real HTTP calls.
    • imports: Creates an array with imports that should be included in generated tests (for example ['org.myorg.Matchers']). By default, it creates an empty array.
    • staticImports: Creates an array with static imports that should be included in @@ -144,7 +144,7 @@ closure to set it up. * contractsMode: Specifies the mode of downloading contracts (whether the JAR is available offline, remotely etc.) * contractsSnapshotCheckSkip: If set to true will not assert whether the -downloaded stubs / contract JAR was downloaded from a remote location or a local one

    84.1.10 Single Base Class for All Tests

    When using Spring Cloud Contract Verifier in default MockMvc, you need to create a base +downloaded stubs / contract JAR was downloaded from a remote location or a local one

    85.1.10 Single Base Class for All Tests

    When using Spring Cloud Contract Verifier in default MockMvc, you need to create a base specification for all generated acceptance tests. In this class, you need to point to an endpoint, which should be verified.

    abstract class BaseMockMvcSpec extends Specification {
     
    @@ -163,7 +163,7 @@ endpoint, which should be verified.

    If you use Explicit mode, you can use a base class to initialize the whole tested app as you might see in regular integration tests. If you use the JAXRSCLIENT mode, this base class should also contain a protected WebTarget webTarget field. Right now, the -only option to test the JAX-RS API is to start a web server.

    84.1.11 Different Base Classes for Contracts

    If your base classes differ between contracts, you can tell the Spring Cloud Contract +only option to test the JAX-RS API is to start a web server.

    85.1.11 Different Base Classes for Contracts

    If your base classes differ between contracts, you can tell the Spring Cloud Contract plugin which class should get extended by the autogenerated tests. You have two options:

    • Follow a convention by providing the packageWithBaseClasses
    • Provide explicit mapping via baseClassMappings

    By Convention

    The convention is such that if you have a contract under (for example) src/test/resources/contract/foo/bar/baz/ and set the value of the packageWithBaseClasses property to com.example.base, then Spring Cloud Contract @@ -182,7 +182,7 @@ baseClassMappings { - src/test/resources/contract/foo/

    By providing the baseClassForTests, we have a fallback in case mapping did not succeed. (You could also provide the packageWithBaseClasses as a fallback.) That way, the tests generated from src/test/resources/contract/com/ contracts extend the -com.example.ComBase, whereas the rest of the tests extend com.example.FooBase.

    84.1.12 Invoking Generated Tests

    To ensure that the provider side is compliant with defined contracts, you need to invoke:

    ./gradlew generateContractTests test

    84.1.13 Spring Cloud Contract Verifier on the Consumer Side

    In a consuming service, you need to configure the Spring Cloud Contract Verifier plugin +com.example.ComBase, whereas the rest of the tests extend com.example.FooBase.

    85.1.12 Invoking Generated Tests

    To ensure that the provider side is compliant with defined contracts, you need to invoke:

    ./gradlew generateContractTests test

    85.1.13 Spring Cloud Contract Verifier on the Consumer Side

    In a consuming service, you need to configure the Spring Cloud Contract Verifier plugin in exactly the same way as in case of provider. If you do not want to use Stub Runner then you need to copy contracts stored in src/test/resources/contracts and generate WireMock JSON stubs using:

    ./gradlew generateClientStubs
    [Note]Note

    The stubsOutputDir option has to be set for stub generation to work.

    When present, JSON stubs can be used in automated tests of consuming a service.

    @ContextConfiguration(loader == SpringApplicationContextLoader, classes == Application)
    @@ -206,8 +206,8 @@ WireMock JSON stubs using:

    ./gradlew generateClie
     	loanApplication.rejectionReason == null
      }
     }

    LoanApplication makes a call to FraudDetection service. This request is handled by a -WireMock server configured with stubs generated by Spring Cloud Contract Verifier.

    85.2 Maven Project

    To learn how to set up the Maven project for Spring Cloud Contract Verifier, read the +following sections:

    85.2.1 Add maven plugin

    Add the Spring Cloud Contract BOM in a fashion similar to this:

    <dependencyManagement>
     	<dependencies>
     		<dependency>
     			<groupId>org.springframework.cloud</groupId>
    @@ -227,7 +227,7 @@ following sections:

      </configuration> </plugin>

    You can read more in the Spring -Cloud Contract Maven Plugin Documentation.

    84.2.2 Maven and Rest Assured 2.0

    By default, Rest Assured 3.x is added to the classpath. However, you can use Rest +Cloud Contract Maven Plugin Documentation.

    85.2.2 Maven and Rest Assured 2.0

    By default, Rest Assured 3.x is added to the classpath. However, you can use Rest Assured 2.x by adding it to the plugins classpath, as shown here:

    <plugin>
         <groupId>org.springframework.cloud</groupId>
         <artifactId>spring-cloud-contract-maven-plugin</artifactId>
    @@ -273,7 +273,7 @@ Assured 2.x by adding it to the plugins classpath, as shown here:

    That way, the plugin automatically sees that Rest Assured 3.x is present on the classpath -and modifies the imports accordingly.

    84.2.3 Snapshot versions for Maven

    For Snapshot and Milestone versions, you have to add the following section to your +and modifies the imports accordingly.

    85.2.3 Snapshot versions for Maven

    For Snapshot and Milestone versions, you have to add the following section to your pom.xml, as shown here:

    <repositories>
     	<repository>
     		<id>spring-snapshots</id>
    @@ -325,16 +325,16 @@ and modifies the imports accordingly.

    <enabled>false</enabled> </snapshots> </pluginRepository> -</pluginRepositories>

    84.2.4 Add stubs

    By default, Spring Cloud Contract Verifier is looking for stubs in the +</pluginRepositories>

    85.2.4 Add stubs

    By default, Spring Cloud Contract Verifier is looking for stubs in the src/test/resources/contracts directory. The directory containing stub definitions is treated as a class name, and each stub definition is treated as a single test. We assume that it contains at least one directory to be used as test class name. If there is more than one level of nested directories, all except the last one is used as package name. For example, with following structure:

    src/test/resources/contracts/myservice/shouldCreateUser.groovy
     src/test/resources/contracts/myservice/shouldReturnUser.groovy

    Spring Cloud Contract Verifier creates a test class named defaultBasePackage.MyService -with two methods

    • shouldCreateUser()
    • shouldReturnUser()

    84.2.5 Run plugin

    The plugin goal generateTests is assigned to be invoked in the phase called +with two methods

    • shouldCreateUser()
    • shouldReturnUser()

    85.2.5 Run plugin

    The plugin goal generateTests is assigned to be invoked in the phase called generate-test-sources. If you want it to be part of your build process, you need not do -anything. If you just want to generate tests, invoke the generateTests goal.

    84.2.6 Configure plugin

    To change the default configuration, just add a configuration section to the plugin +anything. If you just want to generate tests, invoke the generateTests goal.

    85.2.6 Configure plugin

    To change the default configuration, just add a configuration section to the plugin definition or the execution definition, as shown here:

    <plugin>
         <groupId>org.springframework.cloud</groupId>
         <artifactId>spring-cloud-contract-maven-plugin</artifactId>
    @@ -351,7 +351,7 @@ definition or the execution definition, as shown he
             <basePackageForTests>org.springframework.cloud.verifier.twitter.place</basePackageForTests>
             <baseClassForTests>org.springframework.cloud.verifier.twitter.place.BaseMockMvcSpec</baseClassForTests>
         </configuration>
    -</plugin>

    84.2.7 Configuration Options

    • testMode: Defines the mode for acceptance tests. By default, the mode is MockMvc, +</plugin>

    85.2.7 Configuration Options

    • testMode: Defines the mode for acceptance tests. By default, the mode is MockMvc, which is based on Spring’s MockMvc. It can also be changed to JaxRsClient or to Explicit for real HTTP calls.
    • basePackageForTests: Specifies the base package for all generated tests. If not set, the value is picked from baseClassForTests’s package and from `packageWithBaseClasses. @@ -378,7 +378,7 @@ the following options:

        groupid/artifactid where gropuid is slash separated.
      • contractsMode: Picks the mode in which stubs will be found and registered
      • contractsSnapshotCheckSkip: If true then will not assert whether a stub / contract JAR was downloaded from local or remote location
      • contractsRepositoryUrl: URL to a repo with the artifacts that have contracts. If it is not provided, use the current Maven ones.
      • contractsRepositoryUsername: The user name to be used to connect to the repo with contracts.
      • contractsRepositoryPassword: The password to be used to connect to the repo with contracts.
      • contractsRepositoryProxyHost: The proxy host to be used to connect to the repo with contracts.
      • contractsRepositoryProxyPort: The proxy port to be used to connect to the repo with contracts.

      We cache only non-snapshot, explicitly provided versions (for example -+ or 1.0.0.BUILD-SNAPSHOT won’t get cached). By default, this feature is turned on.

    84.2.8 Single Base Class for All Tests

    When using Spring Cloud Contract Verifier in default MockMvc, you need to create a base ++ or 1.0.0.BUILD-SNAPSHOT won’t get cached). By default, this feature is turned on.

    85.2.8 Single Base Class for All Tests

    When using Spring Cloud Contract Verifier in default MockMvc, you need to create a base specification for all generated acceptance tests. In this class, you need to point to an endpoint, which should be verified.

    package org.mycompany.tests
     
    @@ -393,7 +393,7 @@ endpoint, which should be verified.

    If you use Explicit mode, you can use a base class to initialize the whole tested app similarly, as you might find in regular integration tests. If you use the JAXRSCLIENT mode, this base class should also contain a protected WebTarget webTarget field. Right -now, the only option to test the JAX-RS API is to start a web server.

    84.2.9 Different base classes for contracts

    If your base classes differ between contracts, you can tell the Spring Cloud Contract +now, the only option to test the JAX-RS API is to start a web server.

    85.2.9 Different base classes for contracts

    If your base classes differ between contracts, you can tell the Spring Cloud Contract plugin which class should get extended by the autogenerated tests. You have two options:

    • Follow a convention by providing the packageWithBaseClasses
    • provide explicit mapping via baseClassMappings

    By Convention

    The convention is such that if you have a contract under (for example) src/test/resources/contract/foo/bar/baz/ and set the value of the packageWithBaseClasses property to com.example.base, then Spring Cloud Contract @@ -426,7 +426,7 @@ name of the base class for the matched contract. You have to provide a list call * src/test/resources/contract/foo/

    By providing the baseClassForTests, we have a fallback in case mapping did not succeed. (You can also provide the packageWithBaseClasses as a fallback.) That way, the tests generated from src/test/resources/contract/com/ contracts extend the -com.example.ComBase, whereas the rest of the tests extend com.example.FooBase.

    84.2.10 Invoking generated tests

    The Spring Cloud Contract Maven Plugin generates verification code in a directory called +com.example.ComBase, whereas the rest of the tests extend com.example.FooBase.

    85.2.10 Invoking generated tests

    The Spring Cloud Contract Maven Plugin generates verification code in a directory called /generated-test-sources/contractVerifier and attaches this directory to testCompile goal.

    For Groovy Spock code, use the following:

    <plugin>
     	<groupId>org.codehaus.gmavenplus</groupId>
    @@ -456,7 +456,7 @@ goal.

    For Groovy Spock code, use the following:

    </testSources>
     	</configuration>
     </plugin>

    To ensure that provider side is compliant with defined contracts, you need to invoke -mvn generateTest test.

    84.2.11 Maven Plugin and STS

    If you see the following exception while using STS:

    STS Exception

    When you click on the error marker you should see something like this:

     plugin:1.1.0.M1:convert:default-convert:process-test-resources) org.apache.maven.plugin.PluginExecutionException: Execution default-convert of goal org.springframework.cloud:spring-
    +mvn generateTest test.

    85.2.11 Maven Plugin and STS

    If you see the following exception while using STS:

    STS Exception

    When you click on the error marker you should see something like this:

     plugin:1.1.0.M1:convert:default-convert:process-test-resources) org.apache.maven.plugin.PluginExecutionException: Execution default-convert of goal org.springframework.cloud:spring-
      cloud-contract-maven-plugin:1.1.0.M1:convert failed. at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:145) at
      org.eclipse.m2e.core.internal.embedder.MavenImpl.execute(MavenImpl.java:331) at org.eclipse.m2e.core.internal.embedder.MavenImpl$11.call(MavenImpl.java:1362) at
     ...
    @@ -493,7 +493,7 @@ goal.

    For Groovy Spock code, use the following:

    </plugin>
             </plugins>
         </pluginManagement>
    -</build>

    84.3 Stubs and Transitive Dependencies

    The Maven and Gradle plugin that add the tasks that create the stubs jar for you. One +</build>

    85.3 Stubs and Transitive Dependencies

    The Maven and Gradle plugin that add the tasks that create the stubs jar for you. One problem that arises is that, when reusing the stubs, you can mistakenly import all of that stub’s dependencies. When building a Maven artifact, even though you have a couple of different jars, all of them share one pom:

    ├── github-webhook-0.0.1.BUILD-20160903.075506-1-stubs.jar
    @@ -510,7 +510,7 @@ when you include the github-webhook stubs in anothe
     dependency gets downloaded by Stub Runner) then, since all of the dependencies are
     optional, they will not get downloaded.

    Create a separate artifactid for the stubs

    If you create a separate artifactid, then you can set it up in whatever way you wish. For example, you might decide to have no dependencies at all.

    Exclude dependencies on the consumer side

    As a consumer, if you add the stub dependency to your classpath, you can explicitly -exclude the unwanted dependencies.

    84.4 CI Server setup

    When fetching stubs / contracts in a CI, shared environment, what might happen is that +exclude the unwanted dependencies.

    85.4 CI Server setup

    When fetching stubs / contracts in a CI, shared environment, what might happen is that both the producer and the consumer reuse the same local Maven repository. Due to this, the framework, responsible for downloading a stub JAR from remote location, can’t decide which JAR should be picked, local or remote one. That caused @@ -518,7 +518,7 @@ the "The artifact was found in the local repository but yo stated that it should be downloaded from a remote one" exception and failed the build.

    For such cases we’re introducing the property and plugin setup mechanism:

    • via stubrunner.snapshot-check-skip system property
    • via STUBRUNNER_SNAPSHOT_CHECK_SKIP environment variable

    if either of these values is set to true, then the stub downloader will not verify the origin of the downloaded JAR.

    For the plugins you need to set the contractsSnapshotSkipCheck property -to true.

    84.5 Scenarios

    You can handle scenarios with Spring Cloud Contract Verifier. All you need to do is to +to true.

    85.5 Scenarios

    You can handle scenarios with Spring Cloud Contract Verifier. All you need to do is to stick to the proper naming convention while creating your contracts. The convention requires including an order number followed by an underscore. This will work regardles of whether you’re working with YAML or Groovy. Example:

    my_contracts_dir\
    @@ -527,10 +527,10 @@ requires including an order number followed by an underscore. This will work reg
         2_showCart.groovy
         3_logout.groovy

    Such a tree causes Spring Cloud Contract Verifier to generate WireMock’s scenario with a name of scenario1 and the three following steps:

    1. login marked as Started pointing to…​
    2. showCart marked as Step1 pointing to…​
    3. logout marked as Step2 which will close the scenario.

    More details about WireMock scenarios can be found at -http://wiremock.org/stateful-behaviour.html

    Spring Cloud Contract Verifier also generates tests with a guaranteed order of execution.

    84.6 Docker Project

    We’re publishing a springcloud/spring-cloud-contract Docker image +http://wiremock.org/stateful-behaviour.html

    Spring Cloud Contract Verifier also generates tests with a guaranteed order of execution.

    85.6 Docker Project

    We’re publishing a springcloud/spring-cloud-contract Docker image that contains a project that will generate tests and execute them in EXPLICIT mode against a running application.

    [Tip]Tip

    The EXPLICIT mode means that the tests generated from contracts will send -real requests and not the mocked ones.

    84.6.1 Short intro to Maven, JARs and Binary storage

    Since the Docker image can be used by non JVM projects, it’s good to +real requests and not the mocked ones.

    85.6.1 Short intro to Maven, JARs and Binary storage

    Since the Docker image can be used by non JVM projects, it’s good to explain the basic terms behind Spring Cloud Contract packaging defaults.

    Part of the following definitions were taken from the Maven Glossary

    • Project: Maven thinks in terms of projects. Everything that you will build are projects. Those projects follow a well defined “Project Object Model”. Projects can depend on other projects, @@ -557,7 +557,7 @@ like them to be available for others to download / reference or reuse. In case of the JVM world those artifacts would be JARs, for Ruby these are gems and for Docker those would be Docker images. You can store those artifacts in a manager. Examples of such managers can be Artifactory -or Nexus.

    84.6.2 How it works

    The image searches for contracts under the /contracts folder. +or Nexus.

    85.6.2 How it works

    The image searches for contracts under the /contracts folder. The output from running the tests will be available under /spring-cloud-contract/build folder (it’s useful for debugging purposes).

    It’s enough for you to mount your contracts, pass the environment variables @@ -565,8 +565,8 @@ purposes).

    It’s enough for you to mount your contracts, pass the env your running application, to the Artifact manager instance etc.

    • PROJECT_GROUP - your project’s group id. Defaults to com.example.
    • PROJECT_VERSION - your project’s version. Defaults to 0.0.1-SNAPSHOT
    • PROJECT_NAME - artifact id. Defaults to example
    • REPO_WITH_BINARIES_URL - URL of your Artifact Manager. Defaults to http://localhost:8081/artifactory/libs-release-local which is the default URL of Artifactory running locally
    • REPO_WITH_BINARIES_USERNAME - (optional) username when the Artifact Manager is secured
    • REPO_WITH_BINARIES_PASSWORD - (optional) password when the Artifact Manager is secured
    • PUBLISH_ARTIFACTS - if set to true then will publish artifact to binary storage. Defaults to true.

    These environment variables are used when tests are executed:

    • APPLICATION_BASE_URL - url against which tests should be executed. Remember that it has to be accessible from the Docker container (e.g. localhost -will not work)
    • APPLICATION_USERNAME - (optional) username for basic authentication to your application
    • APPLICATION_PASSWORD - (optional) password for basic authentication to your application

    84.6.3 Example of usage

    Let’s take a look at a simple MVC application

    $ git clone https://github.com/spring-cloud-samples/spring-cloud-contract-nodejs
    -$ cd bookstore

    The contracts are available under /contracts folder.

    84.6.4 Server side (nodejs)

    Since we want to run tests, we could just execute:

    $ npm test

    however, for learning purposes, let’s split it into pieces:

    # Stop docker infra (nodejs, artifactory)
    +will not work)
  • APPLICATION_USERNAME - (optional) username for basic authentication to your application
  • APPLICATION_PASSWORD - (optional) password for basic authentication to your application
  • 85.6.3 Example of usage

    Let’s take a look at a simple MVC application

    $ git clone https://github.com/spring-cloud-samples/spring-cloud-contract-nodejs
    +$ cd bookstore

    The contracts are available under /contracts folder.

    85.6.4 Server side (nodejs)

    Since we want to run tests, we could just execute:

    $ npm test

    however, for learning purposes, let’s split it into pieces:

    # Stop docker infra (nodejs, artifactory)
     $ ./stop_infra.sh
     # Start docker infra (nodejs, artifactory)
     $ ./setup_infra.sh
    @@ -598,4 +598,4 @@ stateful situation

      • the contracts will be taken from /contracts folder.
      • the output of the test execution is available under node_modules/spring-cloud-contract/output.
  • the stubs will be uploaded to Artifactory. You can check them out under http://localhost:8081/artifactory/libs-release-local/com/example/bookstore/0.0.1.RELEASE/ . -The stubs will be here http://localhost:8081/artifactory/libs-release-local/com/example/bookstore/0.0.1.RELEASE/bookstore-0.0.1.RELEASE-stubs.jar.
  • To see how the client side looks like check out the Section 86.9, “Stub Runner Docker” section.

    \ No newline at end of file +The stubs will be here http://localhost:8081/artifactory/libs-release-local/com/example/bookstore/0.0.1.RELEASE/bookstore-0.0.1.RELEASE-stubs.jar.

    To see how the client side looks like check out the Section 87.9, “Stub Runner Docker” section.

    \ No newline at end of file diff --git a/Finchley.M7/multi/multi__spring_cloud_contract_wiremock.html b/Finchley.M7/multi/multi__spring_cloud_contract_wiremock.html index 1e76a0a0..66f4e899 100644 --- a/Finchley.M7/multi/multi__spring_cloud_contract_wiremock.html +++ b/Finchley.M7/multi/multi__spring_cloud_contract_wiremock.html @@ -1,6 +1,6 @@ - 91. Spring Cloud Contract WireMock

    91. Spring Cloud Contract WireMock

    The Spring Cloud Contract WireMock modules let you use WireMock in a + 92. Spring Cloud Contract WireMock

    92. Spring Cloud Contract WireMock

    The Spring Cloud Contract WireMock modules let you use WireMock in a Spring Boot application. Check out the samples for more details.

    If you have a Spring Boot application that uses Tomcat as an embedded server (which is @@ -30,7 +30,7 @@ your test. The following code shows an example:

    <
     server port can be bound in the test application context with the "wiremock.server.port"
     property. Using @AutoConfigureWireMock adds a bean of type WiremockConfiguration to
     your test application context, where it will be cached in between methods and classes
    -having the same context, the same as for Spring integration tests.

    91.1 Registering Stubs Automatically

    If you use @AutoConfigureWireMock, it registers WireMock JSON stubs from the file +having the same context, the same as for Spring integration tests.

    92.1 Registering Stubs Automatically

    If you use @AutoConfigureWireMock, it registers WireMock JSON stubs from the file system or classpath (by default, from file:src/test/resources/mappings). You can customize the locations using the stubs attribute in the annotation, which can be an Ant-style resource pattern or a directory. In the case of a directory, */.json is @@ -49,7 +49,7 @@ public class WiremockImportApplicationTests { }

    [Note]Note

    Actually, WireMock always loads mappings from src/test/resources/mappings as well as the custom locations in the stubs attribute. To change this behavior, you can -also specify a files root as described in the next section of this document.

    91.2 Using Files to Specify the Stub Bodies

    WireMock can read response bodies from files on the classpath or the file system. In that +also specify a files root as described in the next section of this document.

    92.2 Using Files to Specify the Stub Bodies

    WireMock can read response bodies from files on the classpath or the file system. In that case, you can see in the JSON DSL that the response has a bodyFileName instead of a (literal) body. The files are resolved relative to a root directory (by default, src/test/resources/__files). To customize this location you can set the files @@ -60,7 +60,7 @@ supported. A list of values can be given, in which case WireMock resolves the fi that exists when it needs to find a response body.

    [Note]Note

    When you configure the files root, it also affects the automatic loading of stubs, because they come from the root location in a subdirectory called "mappings". The value of files has no -effect on the stubs loaded explicitly from the stubs attribute.

    91.3 Alternative: Using JUnit Rules

    For a more conventional WireMock experience, you can use JUnit @Rules to start and stop +effect on the stubs loaded explicitly from the stubs attribute.

    92.3 Alternative: Using JUnit Rules

    For a more conventional WireMock experience, you can use JUnit @Rules to start and stop the server. To do so, use the WireMockSpring convenience class to obtain an Options instance, as shown in the following example:

    @RunWith(SpringRunner.class)
     @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
    @@ -86,7 +86,7 @@ instance, as shown in the following example:

    
     	}
     
     }

    The @ClassRule means that the server shuts down after all the methods in this class -have been run.

    91.4 Relaxed SSL Validation for Rest Template

    WireMock lets you stub a "secure" server with an "https" URL protocol. If your +have been run.

    92.4 Relaxed SSL Validation for Rest Template

    WireMock lets you stub a "secure" server with an "https" URL protocol. If your application wants to contact that stub server in an integration test, it will find that the SSL certificates are not valid (the usual problem with self-installed certificates). The best option is often to re-configure the client to use "http". If that’s not an @@ -112,7 +112,7 @@ annotation or the stub runner. If you use the JUnit @Rule< classpath and it is selected by the RestTemplateBuilder and configured to ignore SSL errors. If you use the default java.net client, you do not need the annotation (but it won’t do any harm). There is no support currently for other clients, but it may be added -in future releases.

    91.5 WireMock and Spring MVC Mocks

    Spring Cloud Contract provides a convenience class that can load JSON WireMock stubs into +in future releases.

    92.5 WireMock and Spring MVC Mocks

    Spring Cloud Contract provides a convenience class that can load JSON WireMock stubs into a Spring MockRestServiceServer. The following code shows an example:

    @RunWith(SpringRunner.class)
     @SpringBootTest(webEnvironment = WebEnvironment.NONE)
     public class WiremockForDocsMockServerApplicationTests {
    @@ -143,7 +143,7 @@ pattern. The JSON format is the normal WireMock format, which you can read about
     WireMock website.

    Currently, the Spring Cloud Contract Verifier supports Tomcat, Jetty, and Undertow as Spring Boot embedded servers, and Wiremock itself has "native" support for a particular version of Jetty (currently 9.2). To use the native Jetty, you need to add the native -Wiremock dependencies and exclude the Spring Boot container (if there is one).

    91.6 Customization of WireMock configuration

    You can register a bean of org.springframework.cloud.contract.wiremock.WireMockConfigurationCustomizer type +Wiremock dependencies and exclude the Spring Boot container (if there is one).

    92.6 Customization of WireMock configuration

    You can register a bean of org.springframework.cloud.contract.wiremock.WireMockConfigurationCustomizer type in order to customize the WireMock configuration (e.g. add custom transformers). Example:

    		@Bean WireMockConfigurationCustomizer optionsCustomizer() {
     			return new WireMockConfigurationCustomizer() {
    @@ -151,7 +151,7 @@ Example:

    		// perform your customization here
     				}
     			};
    -		}

    91.7 Generating Stubs using REST Docs

    Spring REST Docs can be used to generate + }

    92.7 Generating Stubs using REST Docs

    Spring REST Docs can be used to generate documentation (for example in Asciidoctor format) for an HTTP API with Spring MockMvc or WebTestClient or Rest Assured. At the same time that you generate documentation for your API, you can also @@ -255,7 +255,7 @@ available on the classpath (by stubs as JARs, for example). After that, you can create a stub using WireMock in a number of different ways, including by using @AutoConfigureWireMock(stubs="classpath:resource.json"), as described earlier in this -document.

    91.8 Generating Contracts by Using REST Docs

    You can also generate Spring Cloud Contract DSL files and documentation with Spring REST +document.

    92.8 Generating Contracts by Using REST Docs

    You can also generate Spring Cloud Contract DSL files and documentation with Spring REST Docs. If you do so in combination with Spring Cloud WireMock, you get both the contracts and the stubs.

    Why would you want to use this feature? Some people in the community asked questions about a situation in which they would like to move to DSL-based contract definition, @@ -305,4 +305,4 @@ Contract.make { } } }

    The generated document (formatted in Asciidoc in this case) contains a formatted -contract. The location of this file would be index/dsl-contract.adoc.

    \ No newline at end of file +contract. The location of this file would be index/dsl-contract.adoc.

    \ No newline at end of file diff --git a/Finchley.M7/multi/multi__spring_cloud_for_cloud_foundry.html b/Finchley.M7/multi/multi__spring_cloud_for_cloud_foundry.html index 053946bb..cda16477 100644 --- a/Finchley.M7/multi/multi__spring_cloud_for_cloud_foundry.html +++ b/Finchley.M7/multi/multi__spring_cloud_for_cloud_foundry.html @@ -1,6 +1,6 @@ - Part XI. Spring Cloud for Cloud Foundry

    Part XI. Spring Cloud for Cloud Foundry

    Spring Cloud for Cloudfoundry makes it easy to run + Part XII. Spring Cloud for Cloud Foundry

    Part XII. Spring Cloud for Cloud Foundry

    Spring Cloud for Cloudfoundry makes it easy to run Spring Cloud apps in Cloud Foundry (the Platform as a Service). Cloud Foundry has the notion of a "service", which is @@ -15,4 +15,4 @@ implementation of Spring Cloud Commons DiscoveryClient@EnableDiscoveryClient and provide your credentials as spring.cloud.cloudfoundry.discovery.[username,password] (also *.url if you are not connecting to Pivotal Web Services) and then you can use the DiscoveryClient directly or via a LoadBalancerClient.

    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.

    \ No newline at end of file +the fact that it has to get an access token from Cloud Foundry.

    \ No newline at end of file diff --git a/Finchley.M7/multi/multi__spring_cloud_gateway.html b/Finchley.M7/multi/multi__spring_cloud_gateway.html new file mode 100644 index 00000000..040a91fa --- /dev/null +++ b/Finchley.M7/multi/multi__spring_cloud_gateway.html @@ -0,0 +1,3 @@ + + + Part XV. Spring Cloud Gateway

    Part XV. Spring Cloud Gateway

    1.3.5.BUILD-SNAPSHOT

    This project provides an API Gateway built on top of the Spring Ecosystem, including: Spring 5, Spring Boot 2 and Project Reactor. Spring Cloud Gateway aims to provide a simple, yet effective way to route to APIs and provide cross cutting concerns to them such as: security, monitoring/metrics, and resiliency.

    \ No newline at end of file diff --git a/Finchley.M7/multi/multi__spring_cloud_openfeign.html b/Finchley.M7/multi/multi__spring_cloud_openfeign.html new file mode 100644 index 00000000..3017f297 --- /dev/null +++ b/Finchley.M7/multi/multi__spring_cloud_openfeign.html @@ -0,0 +1,4 @@ + + + Part IV. Spring Cloud OpenFeign

    Part IV. Spring Cloud OpenFeign

    1.3.5.BUILD-SNAPSHOT

    This project provides OpenFeign integrations for Spring Boot apps through autoconfiguration +and binding to the Spring Environment and other Spring programming model idioms.

    \ No newline at end of file diff --git a/Finchley.M7/multi/multi__spring_cloud_security.html b/Finchley.M7/multi/multi__spring_cloud_security.html index 5ab20e60..25dc07ec 100644 --- a/Finchley.M7/multi/multi__spring_cloud_security.html +++ b/Finchley.M7/multi/multi__spring_cloud_security.html @@ -1,6 +1,6 @@ - Part X. Spring Cloud Security

    Part X. Spring Cloud Security

    Spring Cloud Security offers a set of primitives for building secure + Part XI. Spring Cloud Security

    Part XI. Spring Cloud Security

    Spring Cloud Security offers a set of primitives for building secure applications and services with minimum fuss. A declarative model which can be heavily configured externally (or centrally) lends itself to the implementation of large systems of co-operating, remote components, @@ -8,4 +8,4 @@ usually with a central indentity management service. It is also extremely easy to use in a service platform like Cloud Foundry. Building on Spring Boot and Spring Security OAuth2 we can quickly create systems that implement common patterns like single sign on, token relay and token -exchange.

    [Note]Note

    Spring Cloud is released under the non-restrictive Apache 2.0 license. If you would like to contribute to this section of the documentation or if you find an error, please find the source code and issue trackers in the project at github.

    \ No newline at end of file +exchange.

    [Note]Note

    Spring Cloud is released under the non-restrictive Apache 2.0 license. If you would like to contribute to this section of the documentation or if you find an error, please find the source code and issue trackers in the project at github.

    \ No newline at end of file diff --git a/Finchley.M7/multi/multi__spring_cloud_sleuth.html b/Finchley.M7/multi/multi__spring_cloud_sleuth.html index cd824b23..20d94121 100644 --- a/Finchley.M7/multi/multi__spring_cloud_sleuth.html +++ b/Finchley.M7/multi/multi__spring_cloud_sleuth.html @@ -1,3 +1,3 @@ - Part VII. Spring Cloud Sleuth

    Part VII. Spring Cloud Sleuth

    Adrian Cole, Spencer Gibb, Marcin Grzejszczak, Dave Syer

    1.3.5.BUILD-SNAPSHOT

    \ No newline at end of file + Part VIII. Spring Cloud Sleuth

    Part VIII. Spring Cloud Sleuth

    Adrian Cole, Spencer Gibb, Marcin Grzejszczak, Dave Syer

    1.3.5.BUILD-SNAPSHOT

    \ No newline at end of file diff --git a/Finchley.M7/multi/multi__spring_cloud_stream.html b/Finchley.M7/multi/multi__spring_cloud_stream.html index 70222009..4f646dab 100644 --- a/Finchley.M7/multi/multi__spring_cloud_stream.html +++ b/Finchley.M7/multi/multi__spring_cloud_stream.html @@ -1,4 +1,4 @@ - Part IV. Spring Cloud Stream

    Part IV. Spring Cloud Stream

    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.

    \ No newline at end of file + Part V. Spring Cloud Stream

    Part V. Spring Cloud Stream

    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.

    \ No newline at end of file diff --git a/Finchley.M7/multi/multi__spring_cloud_vault.html b/Finchley.M7/multi/multi__spring_cloud_vault.html index f904abef..35a67838 100644 --- a/Finchley.M7/multi/multi__spring_cloud_vault.html +++ b/Finchley.M7/multi/multi__spring_cloud_vault.html @@ -1,3 +1,3 @@ - Part XIII. Spring Cloud Vault

    Part XIII. Spring Cloud Vault

    © 2016-2018 The original authors.

    [Note]Note

    Copies of this document may be made for your own use and for distribution to others, provided that you do not charge any fee for such copies and further provided that each copy contains this Copyright Notice, whether distributed in print or electronically.

    Spring Cloud Vault Config provides client-side support for externalized configuration in a distributed system. With HashiCorp’s Vault you have a central place to manage external secret properties for applications across all environments. Vault can manage static and dynamic secrets such as username/password for remote applications/resources and provide credentials for external services such as MySQL, PostgreSQL, Apache Cassandra, MongoDB, Consul, AWS and more.

    \ No newline at end of file + Part XIV. Spring Cloud Vault

    Part XIV. Spring Cloud Vault

    © 2016-2018 The original authors.

    [Note]Note

    Copies of this document may be made for your own use and for distribution to others, provided that you do not charge any fee for such copies and further provided that each copy contains this Copyright Notice, whether distributed in print or electronically.

    Spring Cloud Vault Config provides client-side support for externalized configuration in a distributed system. With HashiCorp’s Vault you have a central place to manage external secret properties for applications across all environments. Vault can manage static and dynamic secrets such as username/password for remote applications/resources and provide credentials for external services such as MySQL, PostgreSQL, Apache Cassandra, MongoDB, Consul, AWS and more.

    \ No newline at end of file diff --git a/Finchley.M7/multi/multi__spring_cloud_zookeeper.html b/Finchley.M7/multi/multi__spring_cloud_zookeeper.html index a5a395a3..e46ff4eb 100644 --- a/Finchley.M7/multi/multi__spring_cloud_zookeeper.html +++ b/Finchley.M7/multi/multi__spring_cloud_zookeeper.html @@ -1,9 +1,9 @@ - Part IX. Spring Cloud Zookeeper

    Part IX. Spring Cloud Zookeeper

    This project provides Zookeeper integrations for Spring Boot apps through autoconfiguration + Part X. Spring Cloud Zookeeper

    Part X. 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 application and build large distributed systems with Zookeeper based components. The 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.

    \ No newline at end of file +(Hystrix) are provided by integration with Spring Cloud Netflix.

    \ No newline at end of file diff --git a/Finchley.M7/multi/multi__stub_runner_for_messaging.html b/Finchley.M7/multi/multi__stub_runner_for_messaging.html index 87d984f1..5ebb5780 100644 --- a/Finchley.M7/multi/multi__stub_runner_for_messaging.html +++ b/Finchley.M7/multi/multi__stub_runner_for_messaging.html @@ -1,10 +1,10 @@ - 87. Stub Runner for Messaging

    87. Stub Runner for Messaging

    Stub Runner can run the published stubs in memory. It can integrate with the following + 88. Stub Runner for Messaging

    88. Stub Runner for Messaging

    Stub Runner can run the published stubs in memory. It can integrate with the following frameworks:

    • Spring Integration
    • Spring Cloud Stream
    • Spring AMQP

    It also provides entry points to integrate with any other solution on the market.

    [Important]Important

    If you have multiple frameworks on the classpath Stub Runner will need to define which one should be used. Let’s assume that you have both AMQP, Spring Cloud Stream and Spring Integration on the classpath. Then you need to set stubrunner.stream.enabled=false and stubrunner.integration.enabled=false. -That way the only remaining framework is Spring AMQP.

    87.1 Stub triggering

    To trigger a message, use the StubTrigger interface:

    package org.springframework.cloud.contract.stubrunner;
    +That way the only remaining framework is Spring AMQP.

    88.1 Stub triggering

    To trigger a message, use the StubTrigger interface:

    package org.springframework.cloud.contract.stubrunner;
     
     import java.util.Collection;
     import java.util.Map;
    @@ -45,10 +45,10 @@ That way the only remaining framework is Spring AMQP.

    Map<String, Collection<String>> labels(); }

    For convenience, the StubFinder interface extends StubTrigger, so you only need one -or the other in your tests.

    StubTrigger gives you the following options to trigger a message:

    87.1.1 Trigger by Label

    stubFinder.trigger('return_book_1')

    87.1.2 Trigger by Group and Artifact Ids

    stubFinder.trigger('org.springframework.cloud.contract.verifier.stubs:streamService', 'return_book_1')

    87.1.3 Trigger by Artifact Ids

    stubFinder.trigger('streamService', 'return_book_1')

    87.1.4 Trigger All Messages

    stubFinder.trigger()

    87.2 Stub Runner Integration

    Spring Cloud Contract Verifier Stub Runner’s messaging module gives you an easy way to +or the other in your tests.

    StubTrigger gives you the following options to trigger a message:

    88.1.1 Trigger by Label

    stubFinder.trigger('return_book_1')

    88.1.2 Trigger by Group and Artifact Ids

    stubFinder.trigger('org.springframework.cloud.contract.verifier.stubs:streamService', 'return_book_1')

    88.1.3 Trigger by Artifact Ids

    stubFinder.trigger('streamService', 'return_book_1')

    88.1.4 Trigger All Messages

    stubFinder.trigger()

    88.2 Stub Runner Integration

    Spring Cloud Contract Verifier Stub Runner’s messaging module gives you an easy way to integrate with Spring Integration. For the provided artifacts, it automatically downloads -the stubs and registers the required routes.

    87.2.1 Adding the Runner to the Project

    You can have both Spring Integration and Spring Cloud Contract Stub Runner on the -classpath. Remember to annotate your test class with @AutoConfigureStubRunner.

    87.2.2 Disabling the functionality

    If you need to disable this functionality, set the +the stubs and registers the required routes.

    88.2.1 Adding the Runner to the Project

    You can have both Spring Integration and Spring Cloud Contract Stub Runner on the +classpath. Remember to annotate your test class with @AutoConfigureStubRunner.

    88.2.2 Disabling the functionality

    If you need to disable this functionality, set the stubrunner.integration.enabled=false property.

    Assume that you have the following Maven repository with deployed stubs for the integrationService application:

    └── .m2
         └── repository
    @@ -124,7 +124,7 @@ assertJsons(receivedMessage.payload)
     receivedMessage.headers.get('BOOK-NAME') == 'foo'

    Scenario 2 (output triggered by input)

    Since the route is set for you, you can send a message to the output destination:

    messaging.send(new BookReturned('foo'), [sample: 'header'], 'input')

    To listen to the output of the message sent to output:

    Message<?> receivedMessage = messaging.receive('outputTest')

    The received message passes the following assertions:

    receivedMessage != null
     assertJsons(receivedMessage.payload)
    -receivedMessage.headers.get('BOOK-NAME') == 'foo'

    Scenario 3 (input with no output)

    Since the route is set for you, you can send a message to the input destination:

    messaging.send(new BookReturned('foo'), [sample: 'header'], 'delete')

    87.3 Stub Runner Stream

    Spring Cloud Contract Verifier Stub Runner’s messaging module gives you an easy way to +receivedMessage.headers.get('BOOK-NAME') == 'foo'

    Scenario 3 (input with no output)

    Since the route is set for you, you can send a message to the input destination:

    messaging.send(new BookReturned('foo'), [sample: 'header'], 'delete')

    88.3 Stub Runner Stream

    Spring Cloud Contract Verifier Stub Runner’s messaging module gives you an easy way to integrate with Spring Stream. For the provided artifacts, it automatically downloads the stubs and registers the required routes.

    [Warning]Warning

    If Stub Runner’s integration with Stream the messageFrom or sentTo Strings are resolved first as a destination of a channel and no such destination exists, the @@ -137,8 +137,8 @@ destination is resolved as a channel name.

    </dependency>

    Gradle. 

    testCompile "org.springframework.cloud:spring-cloud-stream-test-support"

    -

    87.3.1 Adding the Runner to the Project

    You can have both Spring Cloud Stream and Spring Cloud Contract Stub Runner on the -classpath. Remember to annotate your test class with @AutoConfigureStubRunner.

    87.3.2 Disabling the functionality

    If you need to disable this functionality, set the stubrunner.stream.enabled=false +

    88.3.1 Adding the Runner to the Project

    You can have both Spring Cloud Stream and Spring Cloud Contract Stub Runner on the +classpath. Remember to annotate your test class with @AutoConfigureStubRunner.

    88.3.2 Disabling the functionality

    If you need to disable this functionality, set the stubrunner.stream.enabled=false property.

    Assume that you have the following Maven repository with a deployed stubs for the streamService application:

    └── .m2
         └── repository
    @@ -205,7 +205,7 @@ receivedMessage.headers.get(destination:

    messaging.send(new BookReturned('foo'), [sample: 'header'], 'bookStorage')

    To listen to the output of the message sent to returnBook:

    Message<?> receivedMessage = messaging.receive('returnBook')

    The received message passes the following assertions:

    receivedMessage != null
     assertJsons(receivedMessage.payload)
     receivedMessage.headers.get('BOOK-NAME') == 'foo'

    Scenario 3 (input with no output)

    Since the route is set for you, you can send a message to the output -destination:

    messaging.send(new BookReturned('foo'), [sample: 'header'], 'delete')

    87.4 Stub Runner Spring AMQP

    Spring Cloud Contract Verifier Stub Runner’s messaging module provides an easy way to +destination:

    messaging.send(new BookReturned('foo'), [sample: 'header'], 'delete')

    88.4 Stub Runner Spring AMQP

    Spring Cloud Contract Verifier Stub Runner’s messaging module provides an easy way to integrate with Spring AMQP’s Rabbit Template. For the provided artifacts, it automatically downloads the stubs and registers the required routes.

    The integration tries to work standalone (that is, without interaction with a running RabbitMQ message broker). It expects a RabbitTemplate on the application context and @@ -217,7 +217,7 @@ queues. Bindings connect an exchange to a queue. If message contracts are trigge Spring AMQP stub runner integration looks for bindings on the application context that match this exchange. Then it collects the queues from the Spring exchanges and tries to find message listeners bound to these queues. The message is triggered for all matching -message listeners.

    87.4.1 Adding the Runner to the Project

    You can have both Spring AMQP and Spring Cloud Contract Stub Runner on the classpath and +message listeners.

    88.4.1 Adding the Runner to the Project

    You can have both Spring AMQP and Spring Cloud Contract Stub Runner on the classpath and set the property stubrunner.amqp.enabled=true. Remember to annotate your test class with @AutoConfigureStubRunner.

    [Important]Important

    If you already have Stream and Integration on the classpath, you need to disable them explicitly by setting the stubrunner.stream.enabled=false and @@ -290,4 +290,4 @@ definition is matched and invoked with the contract message.

    ConnectionFactory.

    To disable the mocked ConnectionFactory, set the following property: stubrunner.amqp.mockConnection=false

    stubrunner:
       amqp:
    -    mockConnection: false
    \ No newline at end of file + mockConnection: false
    \ No newline at end of file diff --git a/Finchley.M7/multi/multi__testing.html b/Finchley.M7/multi/multi__testing.html index aa81155c..a8a91d06 100644 --- a/Finchley.M7/multi/multi__testing.html +++ b/Finchley.M7/multi/multi__testing.html @@ -1,6 +1,6 @@ - 31. Testing

    31. Testing

    Spring Cloud Stream provides support for testing your microservice applications without connecting to a messaging system. + 32. Testing

    32. 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 provided by the spring-cloud-stream-test-support library, which can be added as a test dependency to the application:

       <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-stream-test-support</artifactId>
    @@ -43,7 +43,7 @@ The following example shows how to test both input and output channels on a proc
     }

    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.

    31.1 Disabling the test binder autoconfiguration

    The intent behind the test binder superseding all the other binders on the classpath is to make it easy to test your applications without making changes to your production dependencies. +Once we have received the message, we can validate that the component functions correctly.

    32.1 Disabling the test binder autoconfiguration

    The intent behind the test binder superseding all the other binders on the classpath is to make it easy to test your applications without making changes to your production dependencies. In some cases (e.g. integration tests) it is useful to use the actual production binders instead, and that requires disabling the test binder autoconfiguration. In order to do so, you can exclude the org.springframework.cloud.stream.test.binder.TestSupportBinderAutoConfiguration class using one of the Spring Boot autoconfiguration exclusion mechanisms, as in the following example.

        @SpringBootApplication(exclude = TestSupportBinderAutoConfiguration.class)
         @EnableBinding(Processor.class)
    @@ -53,4 +53,4 @@ In order to do so, you can exclude the org.springframework
             public String transform(String in) {
                 return in + " world";
             }
    -    }

    When autoconfiguration is disabled, the test binder is available on the classpath, and its defaultCandidate property is set to false, so that it does not interfere with the regular user configuration. It can be referenced under the name test e.g.:

    spring.cloud.stream.defaultBinder=test
    \ No newline at end of file + }

    When autoconfiguration is disabled, the test binder is available on the classpath, and its defaultCandidate property is set to false, so that it does not interfere with the regular user configuration. It can be referenced under the name test e.g.:

    spring.cloud.stream.defaultBinder=test
    \ No newline at end of file diff --git a/Finchley.M7/multi/multi__tracing_bus_events.html b/Finchley.M7/multi/multi__tracing_bus_events.html index c348d6ac..9456d5a2 100644 --- a/Finchley.M7/multi/multi__tracing_bus_events.html +++ b/Finchley.M7/multi/multi__tracing_bus_events.html @@ -1,6 +1,6 @@ - 43. Tracing Bus Events

    43. Tracing Bus Events

    Bus events (subclasses of RemoteApplicationEvent) can be traced by + 44. Tracing Bus Events

    44. 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 @@ -40,4 +40,4 @@ for the AckRemoteApplicationEvent and TraceRepository and mine the data from there.

    [Note]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.

    \ No newline at end of file +queries on the data. Or forward it to a specialized tracing service.

    \ No newline at end of file diff --git a/Finchley.M7/multi/multi__using_the_pluggable_architecture.html b/Finchley.M7/multi/multi__using_the_pluggable_architecture.html index bd7d1f61..e3dd7a6a 100644 --- a/Finchley.M7/multi/multi__using_the_pluggable_architecture.html +++ b/Finchley.M7/multi/multi__using_the_pluggable_architecture.html @@ -1,11 +1,11 @@ - 90. Using the Pluggable Architecture

    90. Using the Pluggable Architecture

    You may encounter cases where you have your contracts have been defined in other formats, + 91. Using the Pluggable Architecture

    91. Using the Pluggable Architecture

    You may encounter cases where you have your contracts have been defined in other formats, such as YAML, RAML or PACT. In those cases, you still want to benefit from the automatic generation of tests and stubs. You can add your own implementation for generating both tests and stubs. Also, you can customize the way tests are generated (for example, you can generate tests for other languages) and the way stubs are generated (for example, you -can generate stubs for other HTTP server implementations).

    90.1 Custom Contract Converter

    The ContractConverter interface lets you register your own implementation of a contract +can generate stubs for other HTTP server implementations).

    91.1 Custom Contract Converter

    The ContractConverter interface lets you register your own implementation of a contract structure converter. The following code listing shows the ContractConverter interface:

    package org.springframework.cloud.contract.spec
     
     /**
    @@ -47,9 +47,9 @@ structure converter. The following code listing shows the 
     conversion. Also, you must define how to perform that conversion in both directions.

    [Important]Important

    Once you create your implementation, you must create a /META-INF/spring.factories file in which you provide the fully qualified name of your implementation.

    The following example shows a typical spring.factories file:

    org.springframework.cloud.contract.spec.ContractConverter=\
    -org.springframework.cloud.contract.verifier.converter.YamlContractConverter

    90.1.1 Pact Converter

    Spring Cloud Contract includes support for Pact representation of +org.springframework.cloud.contract.verifier.converter.YamlContractConverter

    91.1.1 Pact Converter

    Spring Cloud Contract includes support for Pact representation of contracts. Instead of using the Groovy DSL, you can use Pact files. In this section, we -present how to add Pact support for your project.

    90.1.2 Pact Contract

    Consider following example of a Pact contract, which is a file under the +present how to add Pact support for your project.

    91.1.2 Pact Contract

    Consider following example of a Pact contract, which is a file under the src/test/resources/contracts folder.

    {
       "provider": {
         "name": "Provider"
    @@ -103,7 +103,7 @@ present how to add Pact support for your project.

    "version": "2.4.18" } } -}

    The remainder of this section about using Pact refers to the preceding file.

    90.1.3 Pact for Producers

    On the producer side, you mustadd two additional dependencies to your plugin +}

    The remainder of this section about using Pact refers to the preceding file.

    91.1.3 Pact for Producers

    On the producer side, you mustadd two additional dependencies to your plugin configuration. One is the Spring Cloud Contract Pact support, and the other represents the current Pact version that you use.

    Maven. 

    <plugin>
    @@ -173,7 +173,7 @@ test might be as follows:

    "Content-Type" : "application/vnd.fraud.v1+json;charset=UTF-8"
         }
       }
    -}

    90.1.4 Pact for Consumers

    On the producer side, you must add two additional dependencies to your project +}

    91.1.4 Pact for Consumers

    On the producer side, you must add two additional dependencies to your project dependencies. One is the Spring Cloud Contract Pact support, and the other represents the current Pact version that you use.

    Maven. 

    <dependency>
    @@ -190,7 +190,7 @@ current Pact version that you use.

    Maven. 

    Gradle. 

    testCompile "org.springframework.cloud:spring-cloud-contract-spec-pact"
     testCompile 'au.com.dius:pact-jvm-model:2.4.18'

    -

    90.2 Using the Custom Test Generator

    If you want to generate tests for languages other than Java or you are not happy with the +

    91.2 Using the Custom Test Generator

    If you want to generate tests for languages other than Java or you are not happy with the way the verifier builds Java tests, you can register your own implementation.

    The SingleTestGenerator interface lets you register your own implementation. The following code listing shows the SingleTestGenerator interface:

    package org.springframework.cloud.contract.verifier.builder
     
    @@ -225,7 +225,7 @@ following code listing shows the SingleTestGenerator

    Again, you must provide a spring.factories file, such as the one shown in the following example:

    org.springframework.cloud.contract.verifier.builder.SingleTestGenerator=/
    -com.example.MyGenerator

    90.3 Using the Custom Stub Generator

    If you want to generate stubs for stub servers other than WireMock, you can plug in your +com.example.MyGenerator

    91.3 Using the Custom Stub Generator

    If you want to generate stubs for stub servers other than WireMock, you can plug in your own implementation of the StubGenerator interface. The following code listing shows the StubGenerator interface:

    package org.springframework.cloud.contract.verifier.converter
     
    @@ -267,7 +267,7 @@ own implementation of the StubGenerator interface.
     example:

    # Stub converters
     org.springframework.cloud.contract.verifier.converter.StubGenerator=\
     org.springframework.cloud.contract.verifier.wiremock.DslToWireMockClientConverter

    The default implementation is the WireMock stub generation.

    [Tip]Tip

    You can provide multiple stub generator implementations. For example, from a single -DSL, you can produce both WireMock stubs and Pact files.

    90.4 Using the Custom Stub Runner

    If you decide to use a custom stub generation, you also need a custom way of running +DSL, you can produce both WireMock stubs and Pact files.

    91.4 Using the Custom Stub Runner

    If you decide to use a custom stub generation, you also need a custom way of running stubs with your different stub provider.

    Assume that you use Moco to build your stubs and that you have written a stub generator and placed your stubs in a JAR file.

    In order for Stub Runner to know how to run your stubs, you have to define a custom HTTP Stub server implementation, which might resemble the following example:

    package org.springframework.cloud.contract.stubrunner.provider.moco
    @@ -350,7 +350,7 @@ HTTP Stub server implementation, which might resemble the following example:

    }

    Then, you can register it in your spring.factories file, as shown in the following example:

    org.springframework.cloud.contract.stubrunner.HttpServerStub=\
     org.springframework.cloud.contract.stubrunner.provider.moco.MocoHttpServerStub

    Now you can run stubs with Moco.

    [Important]Important

    If you do not provide any implementation, then the default (WireMock) -implementation is used. If you provide more than one, the first one on the list is used.

    90.5 Using the Custom Stub Downloader

    You can customize the way your stubs are downloaded by creating an implementation of the +implementation is used. If you provide more than one, the first one on the list is used.

    91.5 Using the Custom Stub Downloader

    You can customize the way your stubs are downloaded by creating an implementation of the StubDownloaderBuilder interface, as shown in the following example:

    package com.example;
     
     class CustomStubDownloaderBuilder implements StubDownloaderBuilder {
    @@ -376,4 +376,4 @@ org.springframework.cloud.contract.stubrunner.StubDownloaderBuilder=\
     com.example.CustomStubDownloaderBuilder

    Now you can pick a folder with the source of your stubs.

    [Important]Important

    If you do not provide any implementation, then the default is used (scan classpath). If you provide the stubsMode = StubRunnerProperties.StubsMode.LOCAL or , stubsMode = StubRunnerProperties.StubsMode.REMOTE then the Aether implementation will be used -If you provide more than one, then the first one on the list is used.

    \ No newline at end of file +If you provide more than one, then the first one on the list is used.

    \ No newline at end of file diff --git a/Finchley.M7/multi/multi__zipkin_stream_span_consumer.html b/Finchley.M7/multi/multi__zipkin_stream_span_consumer.html index 437cec45..015a0cc0 100644 --- a/Finchley.M7/multi/multi__zipkin_stream_span_consumer.html +++ b/Finchley.M7/multi/multi__zipkin_stream_span_consumer.html @@ -1,7 +1,7 @@ - 58. Zipkin Stream Span Consumer

    58. Zipkin Stream Span Consumer

    [Important]Important

    The suggested approach is to use the Zipkin’s + 59. Zipkin Stream Span Consumer

    59. Zipkin Stream Span Consumer

    [Important]Important

    The suggested approach is to use the Zipkin’s native support for message based span sending. Starting from Edgware Zipkin Stream server is deprecated and in Finchley it got removed.

    Please refer to the Dalston Documentaion -on how to create a Stream Zipkin server.

    \ No newline at end of file +on how to create a Stream Zipkin server.

    \ No newline at end of file diff --git a/Finchley.M7/multi/multi_contenttypemanagement.html b/Finchley.M7/multi/multi_contenttypemanagement.html index 9f14c1cf..124e98de 100644 --- a/Finchley.M7/multi/multi_contenttypemanagement.html +++ b/Finchley.M7/multi/multi_contenttypemanagement.html @@ -1,17 +1,17 @@ - 28. Content Type and Transformation

    28. Content Type and Transformation

    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. + 29. Content Type and Transformation

    29. Content Type and Transformation

    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.

    The content type resolution process have been redesigned for Spring Cloud Stream 2.0.

    Please read the migrating from 1.3 section to understand the changes when interacting with applications using versions of the framework.

    The framework depends on a contentType to be present as a header in order to know how serialize/deserialize a payload.

    Spring Cloud Stream allows you to declaratively configure type conversion for inputs and outputs using the spring.cloud.stream.bindings.<channelName>.content-type property of a binding. Note that general type conversion may also be accomplished easily by using a transformer inside your application.

    [Note]Note

    For both input and output channel, setting a contentType via a property or via annotation only triggers the default converter if a message header with value contentType is not present. This is useful for cases where you just want to send a POJO without sending any header information, or to consume messages that do not have a contentType header present. The framework will always override any default settings with the value found on the message headers.

    [Tip]Tip

    Although contentType became a required property, the framework will set a default value of application/json for all input/output channels if one is not -provided by the user.

    28.1 MIME types

    The content-type values are parsed as media types, e.g., application/json or text/plain;charset=UTF-8.

    MIME types are especially useful for indicating how to convert to String or byte[] content. +provided by the user.

    29.1 MIME types

    The content-type values are parsed as media types, e.g., application/json or text/plain;charset=UTF-8.

    MIME types are especially useful for indicating how to convert to String or byte[] content. Spring Cloud Stream also uses MIME type format to represent Java types, using the general type application/x-java-object with a type parameter. For example, application/x-java-object;type=java.util.Map or application/x-java-object;type=com.bar.Foo can be set as the content-type property of an input binding. -In addition, Spring Cloud Stream provides custom MIME types, notably, application/x-spring-tuple to specify a Tuple.

    28.2 Channel contentType and Message Headers

    You can configure a message channel content type using spring.cloud.stream.bindings.<channelName>.content-type property, or using the @Input and @Output annotations. +In addition, Spring Cloud Stream provides custom MIME types, notably, application/x-spring-tuple to specify a Tuple.

    29.2 Channel contentType and Message Headers

    You can configure a message channel content type using spring.cloud.stream.bindings.<channelName>.content-type property, or using the @Input and @Output annotations. By doing so, even if you send a POJO with no contentType information, the framework will set the MessageHeader contentType to the specified value set for the channel.

    However, if you send a Message<T> and sets the contentType manually, that takes precedence over the configured property value. -This is valid for both input and output channels. The MessageHeader will always take precedence over the default configured contentType for the channel.

    28.3 ContentType handling for output channels

    Starting with version 2.0, the framework will no longer try to infer a contentType based on the payload T of a Message<T>. +This is valid for both input and output channels. The MessageHeader will always take precedence over the default configured contentType for the channel.

    29.3 ContentType handling for output channels

    Starting with version 2.0, the framework will no longer try to infer a contentType based on the payload T of a Message<T>. It will instead use the contentType header (or the default provided by the framework) to configure the right MessageConverter to serialize the payload into byte[].

    The contentType you set is a hint to activate the corresponding MessageConverter. The converter can then modify the contentType to augment the information, such as the case with Kryo and Avro conveters.

    For outbound messages, if your payload is of typ byte[], the framework will skip the conversion logic, and just write those bytes to the wire. In this case, if contentType of the message is absent, it will set the default value specified to channel.

    [Tip]Tip

    If you intend to bypass conversion, just make sure you set the appropriate contentType header, otherwise you could be sending some arbitrary binary data, and the framework may set the header as application/json (default).

    The following snippet shows how you can bypass conversion and set the correct contentType header.

    @Autowired
     private Source source;
    @@ -22,8 +22,8 @@ In this case, if contentType of the message is abse
         source.output().send(MessageBuilder.withPayload(data)
                 .setHeader(MessageHeaders.CONTENT_TYPE, mimeType)
                 .build());
    -}

    Regardless of contentType used, the result is always a Message<byte[]> with a header contentType set. This is what gets passed to the binder to be sent over the wire.

    content-type headerMessageConvertercontent-type augmentedSupported typesComments

    application/json

    CustomMappingJackson2MessageConverter

    application/json

    POJO, primitives and Strings that represent JSON data

    It’s the default converter if none is specified. Note that if you send a raw String it will be quoted

    text/plain

    ObjectStringMessageConverter

    text/plain

    Invokes toString() of the object

     

    application/x-spring-tuple

    TupleJsonMessageConverter

    application/x-spring-tuple

    org.springframework.tuple.Tuple

     

    application/x-java-serialized-object

    JavaSerializationMessageConverter

    application/x-java-serialized-object

    Any Java type that implements Serializable

    This converter uses java native serialization. Receivers of this data must have the same class on the classpath.

    application/x-java-object

    KryoMessageConverter

    application/x-java-object;type=<Class being serialized>

    Any Java type that can be serialized using Kryo

    Receivers of this data must have the same class on the classpath.

    application/avro

    AvroMessageConverter

    application/avro

    A Generic or SpecificRecord from Avro types, a POJO if reflection is used

    Avro needs an associated schema to write/read data. Please refer to the section on the docs on how to use it properly

    28.4 ContentType handling for input channels

    For input channels, Spring Cloud Stream uses @StreamListener and @ServiceActivator content handling to support the conversion. -It does so by checking either the channel content-type set via @Input(contentType="text/plain") annotation or via spring.cloud.stream.bindings.<channel>.contentType property, or the presense of a header contentType.

    The framework will check the contentType set for the Message, select the appropriate MessageConverter and apply conversion passing the argument as the target type.

    If the converter does not support the target type it will return null, if all configured converters return null, a MessageConversionException is thrown.

    Just like output channels, if your method payload argument is of type Message<byte[]>, byte[] or Message<?> conversion is skipped and you get the raw bytes from the wire, plus the corresponding headers.

    [Tip]Tip

    Remember, the MessageHeader always takes precedence over the annotation or property configuration.

    content-type headerMessageConverterSupported target typeComments

    application/json

    CustomMappingJackson2MessageConverter

    POJO or String

     

    text/plain

    ObjectStringMessageConverter

    String

     

    application/x-spring-tuple

    TupleJsonMessageConverter

    org.springframework.tuple.Tuple

     

    application/x-java-serialized-object

    JavaSerializationMessageConverter

    Any Java type that implements Serializable

     

    application/x-java-object

    KryoMessageConverter

    Any Java type that can be serialized using Kryo

     

    application/avro

    AvroMessageConverter

    A Generic or SpecificRecord from Avro types, a POJO if reflection is used

    Avro needs an associated schema to write/read data. Please refer to the section on the docs on how to use it properly

    28.5 Customizing message conversion

    Besides the conversions that it supports out of the box, Spring Cloud Stream also supports registering your own message conversion implementations. +}

    Regardless of contentType used, the result is always a Message<byte[]> with a header contentType set. This is what gets passed to the binder to be sent over the wire.

    content-type headerMessageConvertercontent-type augmentedSupported typesComments

    application/json

    CustomMappingJackson2MessageConverter

    application/json

    POJO, primitives and Strings that represent JSON data

    It’s the default converter if none is specified. Note that if you send a raw String it will be quoted

    text/plain

    ObjectStringMessageConverter

    text/plain

    Invokes toString() of the object

     

    application/x-spring-tuple

    TupleJsonMessageConverter

    application/x-spring-tuple

    org.springframework.tuple.Tuple

     

    application/x-java-serialized-object

    JavaSerializationMessageConverter

    application/x-java-serialized-object

    Any Java type that implements Serializable

    This converter uses java native serialization. Receivers of this data must have the same class on the classpath.

    application/x-java-object

    KryoMessageConverter

    application/x-java-object;type=<Class being serialized>

    Any Java type that can be serialized using Kryo

    Receivers of this data must have the same class on the classpath.

    application/avro

    AvroMessageConverter

    application/avro

    A Generic or SpecificRecord from Avro types, a POJO if reflection is used

    Avro needs an associated schema to write/read data. Please refer to the section on the docs on how to use it properly

    29.4 ContentType handling for input channels

    For input channels, Spring Cloud Stream uses @StreamListener and @ServiceActivator content handling to support the conversion. +It does so by checking either the channel content-type set via @Input(contentType="text/plain") annotation or via spring.cloud.stream.bindings.<channel>.contentType property, or the presense of a header contentType.

    The framework will check the contentType set for the Message, select the appropriate MessageConverter and apply conversion passing the argument as the target type.

    If the converter does not support the target type it will return null, if all configured converters return null, a MessageConversionException is thrown.

    Just like output channels, if your method payload argument is of type Message<byte[]>, byte[] or Message<?> conversion is skipped and you get the raw bytes from the wire, plus the corresponding headers.

    [Tip]Tip

    Remember, the MessageHeader always takes precedence over the annotation or property configuration.

    content-type headerMessageConverterSupported target typeComments

    application/json

    CustomMappingJackson2MessageConverter

    POJO or String

     

    text/plain

    ObjectStringMessageConverter

    String

     

    application/x-spring-tuple

    TupleJsonMessageConverter

    org.springframework.tuple.Tuple

     

    application/x-java-serialized-object

    JavaSerializationMessageConverter

    Any Java type that implements Serializable

     

    application/x-java-object

    KryoMessageConverter

    Any Java type that can be serialized using Kryo

     

    application/avro

    AvroMessageConverter

    A Generic or SpecificRecord from Avro types, a POJO if reflection is used

    Avro needs an associated schema to write/read data. Please refer to the section on the docs on how to use it properly

    29.5 Customizing message conversion

    Besides the conversions that it supports out of the box, Spring Cloud Stream also supports registering your own message conversion implementations. This allows you to send and receive data in a variety of custom formats, including binary, and associate them with specific contentTypes.

    Spring Cloud Stream registers all the beans of type org.springframework.messaging.converter.MessageConverter that are qualifeied using @StreamConverter annotation, as custom message converters along with the out of the box message converters.

    [Note]Note

    The framework requires the @StreamConverter qualifier annotation to avoid picking up other converters that may be present on the ApplicationContext and could overlap with the default ones.

    If your message converter needs to work with a specific content-type and target class (for both input and output), then the message converter needs to extend org.springframework.messaging.converter.AbstractMessageConverter. For conversion when using @StreamListener, a message converter that implements org.springframework.messaging.converter.MessageConverter would suffice.

    Here is an example of creating a message converter bean (with the content-type application/bar) inside a Spring Cloud Stream application:

    @EnableBinding(Sink.class)
     @SpringBootApplication
    @@ -53,7 +53,7 @@ For conversion when using @StreamListener, a messag
             return (payload instanceof Bar ? payload : new Bar((byte[]) payload));
         }
     }

    Spring Cloud Stream also provides support for Avro-based converters and schema evolution. -See the specific section for details.

    28.6 @StreamListener and Message Conversion

    The @StreamListener annotation provides a convenient way for converting incoming messages without the need to specify the content type of an input channel. +See the specific section for details.

    29.6 @StreamListener and Message Conversion

    The @StreamListener annotation provides a convenient way for converting incoming messages without the need to specify the content type of an input channel. During the dispatching process to methods annotated with @StreamListener, a conversion will be applied automatically if the argument requires it.

    For example, let’s consider a message with the String content {"greeting":"Hello, world"} and a content-type header of application/json is received on the input channel. Let us consider the following application that receives it:

    public class GreetingMessage {
     
    @@ -76,4 +76,4 @@ Let us consider the following application that receives it:

    public void receive(Greeting greeting) {
                 // handle Greeting
             }
    -    }

    The argument of the method will be populated automatically with the POJO containing the unmarshalled form of the JSON String.

    \ No newline at end of file + }

    The argument of the method will be populated automatically with the POJO containing the unmarshalled form of the JSON String.

    \ No newline at end of file diff --git a/Finchley.M7/multi/multi_gateway-how-it-works.html b/Finchley.M7/multi/multi_gateway-how-it-works.html new file mode 100644 index 00000000..a3597f2e --- /dev/null +++ b/Finchley.M7/multi/multi_gateway-how-it-works.html @@ -0,0 +1,3 @@ + + + 107. How It Works

    107. How It Works

    Spring Cloud Gateway Diagram

    Clients make requests to Spring Cloud Gateway. If the Gateway Handler Mapping determines that a request matches a Route, it is sent to the Gateway Web Handler. This handler runs sends the request through a filter chain that is specific to the request. The reason the filters are divided by the dotted line, is that filters may execute logic before the proxy request is sent or after. All "pre" filter logic is executed, then the proxy request is made. After the proxy request is made, the "post" filter logic is executed.

    [Note]Note

    URIs defined in routes without a port will get a default port set to 80 and 443 for HTTP and HTTPS URIs respectively.

    \ No newline at end of file diff --git a/Finchley.M7/multi/multi_gateway-request-predicates-factories.html b/Finchley.M7/multi/multi_gateway-request-predicates-factories.html new file mode 100644 index 00000000..7a9df5ff --- /dev/null +++ b/Finchley.M7/multi/multi_gateway-request-predicates-factories.html @@ -0,0 +1,102 @@ + + + 108. Route Predicate Factories

    108. Route Predicate Factories

    Spring Cloud Gateway matches routes as part of the Spring WebFlux HandlerMapping infrastructure. Spring Cloud Gateway includes many built-in Route Predicate Factories. All of these predicates match on different attributes of the HTTP request. Multiple Route Predicate Factories can be combined and are combined via logical and.

    108.1 After Route Predicate Factory

    The After Route Predicate Factory takes one parameter, a datetime. This predicate matches requests that happen after the current datetime.

    application.yml.  +

    spring:
    +  cloud:
    +    gateway:
    +      routes:
    +      - id: after_route
    +        uri: http://example.org
    +        predicates:
    +        - After=2017-01-20T17:42:47.789-07:00[America/Denver]

    +

    This route matches any request after Jan 20, 2017 17:42 Mountain Time (Denver).

    108.2 Before Route Predicate Factory

    The Before Route Predicate Factory takes one parameter, a datetime. This predicate matches requests that happen before the current datetime.

    application.yml.  +

    spring:
    +  cloud:
    +    gateway:
    +      routes:
    +      - id: before_route
    +        uri: http://example.org
    +        predicates:
    +        - Before=2017-01-20T17:42:47.789-07:00[America/Denver]

    +

    This route matches any request before Jan 20, 2017 17:42 Mountain Time (Denver).

    108.3 Between Route Predicate Factory

    The Between Route Predicate Factory takes two parameters, datetime1 and datetime2. This predicate matches requests that happen after datetime1 and before datetime2. The datetime2 parameter must be after datetime1.

    application.yml.  +

    spring:
    +  cloud:
    +    gateway:
    +      routes:
    +      - id: between_route
    +        uri: http://example.org
    +        predicates:
    +        - Betweeen=2017-01-20T17:42:47.789-07:00[America/Denver], 2017-01-21T17:42:47.789-07:00[America/Denver]

    +

    This route matches any request after Jan 20, 2017 17:42 Mountain Time (Denver) and before Jan 21, 2017 17:42 Mountain Time (Denver). This could be useful for maintenance windows.

    108.4 Cookie Route Predicate Factory

    The Cookie Route Predicate Factory takes two parameters, the cookie name and a regular expression. This predicate matches cookies that have the given name and the value matches the regular expression.

    application.yml.  +

    spring:
    +  cloud:
    +    gateway:
    +      routes:
    +      - id: cookie_route
    +        uri: http://example.org
    +        predicates:
    +        - Cookie=chocolate, ch.p

    +

    This route matches the request has a cookie named chocolate who’s value matches the ch.p regular expression.

    108.5 Header Route Predicate Factory

    The Header Route Predicate Factory takes two parameters, the header name and a regular expression. This predicate matches with a header that has the given name and the value matches the regular expression.

    application.yml.  +

    spring:
    +  cloud:
    +    gateway:
    +      routes:
    +      - id: header_route
    +        uri: http://example.org
    +        predicates:
    +        - Header=X-Request-Id, \d+

    +

    This route matches if the request has a header named X-Request-Id whos value matches the \d+ regular expression (has a value of one or more digits).

    108.6 Host Route Predicate Factory

    The Host Route Predicate Factory takes one parameter: the host name pattern. The pattern is an Ant style pattern with . as the separator. This predicates matches the Host header that matches the pattern.

    application.yml.  +

    spring:
    +  cloud:
    +    gateway:
    +      routes:
    +      - id: host_route
    +        uri: http://example.org
    +        predicates:
    +        - Host=**.somehost.org

    +

    This route would match if the request has a Host header has the value www.somehost.org or beta.somehost.org.

    108.7 Method Route Predicate Factory

    The Method Route Predicate Factory takes one parameter: the HTTP method to match.

    application.yml.  +

    spring:
    +  cloud:
    +    gateway:
    +      routes:
    +      - id: method_route
    +        uri: http://example.org
    +        predicates:
    +        - Method=GET

    +

    This route would match if the request method was a GET.

    108.8 Path Route Predicate Factory

    The Path Route Predicate Factory takes one parameter: a Spring PathMatcher pattern.

    application.yml.  +

    spring:
    +  cloud:
    +    gateway:
    +      routes:
    +      - id: host_route
    +        uri: http://example.org
    +        predicates:
    +        - Path=/foo/{segment}

    +

    This route would match if the request path was, for example: /foo/1 or /foo/bar.

    This predicate extracts the URI template variables (like segment defined in the example above) as a map of names and values and places it in the ServerWebExchange.getAttributes() with a key defined in PathRoutePredicate.URL_PREDICATE_VARS_ATTR. Those values are then available for use by GatewayFilter Factories

    108.9 Query Route Predicate Factory

    The Query Route Predicate Factory takes two parameters: a required param and an optional regexp.

    application.yml.  +

    spring:
    +  cloud:
    +    gateway:
    +      routes:
    +      - id: query_route
    +        uri: http://example.org
    +        predicates:
    +        - Query=baz

    +

    This route would match if the request contained a baz query parameter.

    application.yml.  +

    spring:
    +  cloud:
    +    gateway:
    +      routes:
    +      - id: query_route
    +        uri: http://example.org
    +        predicates:
    +        - Query=foo, ba.

    +

    This route would match if the request contained a foo query parameter whose value matched the ba. regexp, so bar and baz would match.

    108.10 RemoteAddr Route Predicate Factory

    The RemoteAddr Route Predicate Factory takes a list (min size 1) of CIDR-notation (IPv4 or IPv6) strings, e.g. 192.168.0.1/16 (where 192.168.0.1 is an IP address and 16 is a subnet mask.

    application.yml.  +

    spring:
    +  cloud:
    +    gateway:
    +      routes:
    +      - id: remoteaddr_route
    +        uri: http://example.org
    +        predicates:
    +        - RemoteAddr=192.168.1.1/24

    +

    This route would match if the remote address of the request was, for example, 192.168.1.10.

    \ No newline at end of file diff --git a/Finchley.M7/multi/multi_gateway-route-filters.html b/Finchley.M7/multi/multi_gateway-route-filters.html new file mode 100644 index 00000000..0de624a8 --- /dev/null +++ b/Finchley.M7/multi/multi_gateway-route-filters.html @@ -0,0 +1,183 @@ + + + 109. GatewayFilter Factories

    109. GatewayFilter Factories

    Route filters allow the modification of the incoming HTTP request or outgoing HTTP response in some manner. Route filters are scoped to a particular route. Spring Cloud Gateway includes many built-in GatewayFilter Factories.

    109.1 AddRequestHeader GatewayFilter Factory

    The AddRequestHeader GatewayFilter Factory takes a name and value parameter.

    application.yml.  +

    spring:
    +  cloud:
    +    gateway:
    +      routes:
    +      - id: add_request_header_route
    +        uri: http://example.org
    +        filters:
    +        - AddRequestHeader=X-Request-Foo, Bar

    +

    This will add X-Request-Foo:Bar header to the downstream request’s headers for all matching requests.

    109.2 AddRequestParameter GatewayFilter Factory

    The AddRequestParameter GatewayFilter Factory takes a name and value parameter.

    application.yml.  +

    spring:
    +  cloud:
    +    gateway:
    +      routes:
    +      - id: add_request_parameter_route
    +        uri: http://example.org
    +        filters:
    +        - AddRequestParameter=foo, bar

    +

    This will add foo=bar to the downstream request’s query string for all matching requests.

    109.3 AddResponseHeader GatewayFilter Factory

    The AddResponseHeader GatewayFilter Factory takes a name and value parameter.

    application.yml.  +

    spring:
    +  cloud:
    +    gateway:
    +      routes:
    +      - id: add_request_header_route
    +        uri: http://example.org
    +        filters:
    +        - AddResponseHeader=X-Response-Foo, Bar

    +

    This will add X-Response-Foo:Bar header to the downstream response’s headers for all matching requests.

    109.4 Hystrix GatewayFilter Factory

    The Hystrix GatewayFilter Factory takes a single name parameters, which is the name of the HystrixCommand. (More options might be added in future releases).

    application.yml.  +

    spring:
    +  cloud:
    +    gateway:
    +      routes:
    +      - id: hytstrix_route
    +        uri: http://example.org
    +        filters:
    +        - Hystrix=myCommandName

    +

    This wraps the remaining filters in a HystrixCommand with command name myCommandName.

    The Hystrix filter takes an optional fallbackUri parameter. Currently, only forward: schemed URIs are supported. If the fallback is called, the request will be forwarded to the controller matched by the URI.

    application.yml.  +

    spring:
    +  cloud:
    +    gateway:
    +      routes:
    +      - id: hytstrix_route
    +        uri: http://example.org
    +        filters:
    +        - name: Hystrix
    +          args:
    +            name: fallbackcmd
    +            fallbackUri: forward:/fallbackcontroller
    +
    +This will forward to the `/fallbackcontroller` when the Hystrix fallback is called.

    +

    109.5 PrefixPath GatewayFilter Factory

    The PrefixPath GatewayFilter Factory takes a single prefix parameter.

    application.yml.  +

    spring:
    +  cloud:
    +    gateway:
    +      routes:
    +      - id: prefixpath_route
    +        uri: http://example.org
    +        filters:
    +        - PrefixPath=/mypath

    +

    This will prefix /mypath to the path of all matching requests. So a request to /hello, would be sent to /mypath/hello.

    109.6 PreserveHostHeader GatewayFilter Factory

    The PreserveHostHeader GatewayFilter Factory has not parameters. This filter, sets a request attribute that the routing filter will inspect to determine if the original host header should be sent, rather than the host header determined by the http client.

    application.yml.  +

    spring:
    +  cloud:
    +    gateway:
    +      routes:
    +      - id: preserve_host_route
    +        uri: http://example.org
    +        filters:
    +        - PreserveHostHeader

    +

    This will prefix /mypath to the path of all matching requests. So a request to /hello, would be sent to /mypath/hello.

    109.7 RequestRateLimiter GatewayFilter Factory

    The RequestRateLimiter GatewayFilter Factory takes three parameters: replenishRate, burstCapacity & keyResolverName.

    replenishRate is how many requests per second do you want a user to be allowed to do.

    burstCapacity TODO: document burst capacity

    keyResolver is a bean that implements the KeyResolver interface. In configuration, reference the bean by name using SpEL. #{@myKeyResolver} is a SpEL expression referencing a bean with the name myKeyResolver.

    KeyResolver.java.  +

    public interface KeyResolver {
    +	Mono<String> resolve(ServerWebExchange exchange);
    +}

    +

    The KeyResolver interface allows pluggable strategies to derive the key for limiting requests. In future milestones, there will be some KeyResolver implementations.

    The redis implementation is based off of work done at Stripe. It requires the use of the spring-boot-starter-data-redis-reactive Spring Boot starter.

    application.yml.  +

    spring:
    +  cloud:
    +    gateway:
    +      routes:
    +      - id: requestratelimiter_route
    +        uri: http://example.org
    +        filters:
    +        - RequestRateLimiter=10, 20, #{@userKeyResolver}

    +

    Config.java.  +

    @Bean
    +KeyResolver userKeyResolver() {
    +    return exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst("user"));
    +}

    +

    This defines a request rate limit of 10 per user. The KeyResolver is a simple one that gets the user request parameter (note: this is not recommended for production).

    109.8 RedirectTo GatewayFilter Factory

    The RedirectTo GatewayFilter Factory takes a status and a url parameter. The status should be a 300 series redirect http code, such as 301. The url should be a valid url. This will be the value of the Location header.

    application.yml.  +

    spring:
    +  cloud:
    +    gateway:
    +      routes:
    +      - id: prefixpath_route
    +        uri: http://example.org
    +        filters:
    +        - RedirectTo=302, http://acme.org

    +

    This will send a status 302 with a Location:http://acme.org header to perform a redirect.

    109.9 RemoveNonProxyHeaders GatewayFilter Factory

    The RemoveNonProxyHeaders GatewayFilter Factory removes headers from forwarded requests. The default list of headers that is removed comes from the IETF.

    The default removed headers are:

    • Connection
    • Keep-Alive
    • Proxy-Authenticate
    • Proxy-Authorization
    • TE
    • Trailer
    • Transfer-Encoding
    • Upgrade

    To change this, set the spring.cloud.gateway.filter.remove-non-proxy-headers.headers property to the list of header names to remove.

    109.10 RemoveRequestHeader GatewayFilter Factory

    The RemoveRequestHeader GatewayFilter Factory takes a name parameter. It is the name of the header to be removed.

    application.yml.  +

    spring:
    +  cloud:
    +    gateway:
    +      routes:
    +      - id: removerequestheader_route
    +        uri: http://example.org
    +        filters:
    +        - RemoveRequestHeader=X-Request-Foo

    +

    This will remove the X-Request-Foo header before it is sent downstream.

    109.11 RemoveResponseHeader GatewayFilter Factory

    The RemoveResponseHeader GatewayFilter Factory takes a name parameter. It is the name of the header to be removed.

    application.yml.  +

    spring:
    +  cloud:
    +    gateway:
    +      routes:
    +      - id: removeresponseheader_route
    +        uri: http://example.org
    +        filters:
    +        - RemoveResponseHeader=X-Response-Foo

    +

    This will remove the X-Response-Foo header from the response before it is returned to the gateway client.

    109.12 RewritePath GatewayFilter Factory

    The RewritePath GatewayFilter Factory takes a path regexp parameter and a replacement parameter. This uses Java regular expressions for a flexible way to rewrite the request path.

    application.yml.  +

    spring:
    +  cloud:
    +    gateway:
    +      routes:
    +      - id: rewritepath_route
    +        uri: http://example.org
    +        predicates:
    +        - Path=/foo/**
    +        filters:
    +        - RewritePath=/foo/(?<segment>.*), /$\{segment}

    +

    For a request path of /foo/bar, this will set the path to /bar before making the downstream request. Notice the $\ which is replaced with $ because of the YAML spec.

    109.13 SaveSession GatewayFilter Factory

    The SaveSession GatewayFilter Factory forces a WebSession::save operation before forwarding the call downstream. This is of particular use when +using something like Spring Session with a lazy data store and need to ensure the session state has been saved before making the forwarded call.

    application.yml.  +

    spring:
    +  cloud:
    +    gateway:
    +      routes:
    +      - id: save_session
    +        uri: http://example.org
    +        predicates:
    +        - Path=/foo/**
    +        filters:
    +        - SaveSession

    +

    If you are integrating Spring Security with Spring Session, and want to ensure security details have been forwarded to the remote process, this is critical.

    109.14 SecureHeaders GatewayFilter Factory

    The SecureHeaders GatewayFilter Factory adds a number of headers to the response at the reccomendation from this blog post.

    The following headers are added (allong with default values):

    • X-Xss-Protection:1; mode=block
    • Strict-Transport-Security:max-age=631138519
    • X-Frame-Options:DENY
    • X-Content-Type-Options:nosniff
    • Referrer-Policy:no-referrer
    • Content-Security-Policy:default-src 'self' https:; font-src 'self' https: data:; img-src 'self' https: data:; object-src 'none'; script-src https:; style-src 'self' https: 'unsafe-inline'
    • X-Download-Options:noopen
    • X-Permitted-Cross-Domain-Policies:none

    To change the default values set the appropriate property in the spring.cloud.gateway.filter.secure-headers namespace:

    Property to change:

    • xss-protection-header
    • strict-transport-security
    • frame-options
    • content-type-options
    • referrer-policy
    • content-security-policy
    • download-options
    • permitted-cross-domain-policies

    109.15 SetPath GatewayFilter Factory

    The SetPath GatewayFilter Factory takes a path template parameter. It offers a simple way to manipulate the request path by allowing templated segments of the path. This uses the uri templates from Spring Framework. Multiple matching segments are allowed.

    application.yml.  +

    spring:
    +  cloud:
    +    gateway:
    +      routes:
    +      - id: setpath_route
    +        uri: http://example.org
    +        predicates:
    +        - Path=/foo/{segment}
    +        filters:
    +        - SetPath=/{segment}

    +

    For a request path of /foo/bar, this will set the path to /bar before making the downstream request.

    109.16 SetResponseHeader GatewayFilter Factory

    The SetResponseHeader GatewayFilter Factory takes name and value parameters.

    application.yml.  +

    spring:
    +  cloud:
    +    gateway:
    +      routes:
    +      - id: setresponseheader_route
    +        uri: http://example.org
    +        filters:
    +        - SetResponseHeader=X-Response-Foo, Bar

    +

    This GatewayFilter replaces all headers with the given name, rather than adding. So if the downstream server responded with a X-Response-Foo:1234, this would be replaced with X-Response-Foo:Bar, which is what the gateway client would receive.

    109.17 SetStatus GatewayFilter Factory

    The SetStatus GatewayFilter Factory takes a single status parameter. It must be a valid Spring HttpStatus. It may be the integer value 404 or the string representation of the enumeration NOT_FOUND.

    application.yml.  +

    spring:
    +  cloud:
    +    gateway:
    +      routes:
    +      - id: setstatusstring_route
    +        uri: http://example.org
    +        filters:
    +        - SetStatus=BAD_REQUEST
    +      - id: setstatusint_route
    +        uri: http://example.org
    +        filters:
    +        - SetStatus=401

    +

    In either case, the HTTP status of the response will be set to 401.

    109.18 StripPrefix GatewayFilter Factory

    The StripPrefix GatewayFilter Factory takes one paramter, parts. The parts parameter indicated the number of parts in the path to strip from the request before sending it downstream.

    application.yml.  +

    spring:
    +  cloud:
    +    gateway:
    +      routes:
    +      - id: nameRoot
    +        uri: http://nameservice
    +        predicates:
    +        - Path=/name/**
    +        filters:
    +        - StripPrefix=2

    +

    When a request is made through the gateway to /name/bar/foo the request made to nameservice will look like http://nameservice/foo.

    \ No newline at end of file diff --git a/Finchley.M7/multi/multi_gateway-starter.html b/Finchley.M7/multi/multi_gateway-starter.html new file mode 100644 index 00000000..5add88c2 --- /dev/null +++ b/Finchley.M7/multi/multi_gateway-starter.html @@ -0,0 +1,5 @@ + + + 105. How to Include Spring Cloud Gateway

    105. How to Include Spring Cloud Gateway

    To include Spring Cloud Gateway in your project use the starter with group org.springframework.cloud +and artifact id spring-cloud-starter-gateway. See the Spring Cloud Project page +for details on setting up your build system with the current Spring Cloud Release Train.

    If you include the starter, but, for some reason, you do not want the gateway to be enabled, set spring.cloud.gateway.enabled=false.

    \ No newline at end of file diff --git a/Finchley.M7/multi/multi_schema-evolution.html b/Finchley.M7/multi/multi_schema-evolution.html index 691c1293..ab829c4c 100644 --- a/Finchley.M7/multi/multi_schema-evolution.html +++ b/Finchley.M7/multi/multi_schema-evolution.html @@ -1,7 +1,7 @@ - 29. Schema evolution support

    29. Schema evolution support

    Spring Cloud Stream provides support for schema-based message converters through its spring-cloud-stream-schema module. -Currently, the only serialization format supported out of the box for schema-based message converters is Apache Avro, with more formats to be added in future versions.

    29.1 Apache Avro Message Converters

    The spring-cloud-stream-schema module contains two types of message converters that can be used for Apache Avro serialization:

    • converters using the class information of the serialized/deserialized objects, or a schema with a location known at startup;
    • converters using a schema registry - they locate the schemas at runtime, as well as dynamically registering new schemas as domain objects evolve.

    29.2 Converters with schema support

    The AvroSchemaMessageConverter supports serializing and deserializing messages either using a predefined schema or by using the schema information available in the class (either reflectively, or contained in the SpecificRecord). + 30. Schema evolution support

    30. Schema evolution support

    Spring Cloud Stream provides support for schema-based message converters through its spring-cloud-stream-schema module. +Currently, the only serialization format supported out of the box for schema-based message converters is Apache Avro, with more formats to be added in future versions.

    30.1 Apache Avro Message Converters

    The spring-cloud-stream-schema module contains two types of message converters that can be used for Apache Avro serialization:

    • converters using the class information of the serialized/deserialized objects, or a schema with a location known at startup;
    • converters using a schema registry - they locate the schemas at runtime, as well as dynamically registering new schemas as domain objects evolve.

    30.2 Converters with schema support

    The AvroSchemaMessageConverter supports serializing and deserializing messages either using a predefined schema or by using the schema information available in the class (either reflectively, or contained in the SpecificRecord). If the target type of the conversion is a GenericRecord, then a schema must be set.

    For using it, you can simply add it to the application context, optionally specifying one ore more MimeTypes to associate it with. The default MimeType is application/avro.

    Here is an example of configuring it in a sink application registering the Apache Avro MessageConverter, without a predefined schema:

    @EnableBinding(Sink.class)
     @SpringBootApplication
    @@ -25,11 +25,11 @@ The default MimeType is appli
           converter.setSchemaLocation(new ClassPathResource("schemas/User.avro"));
           return converter;
       }
    -}

    In order to understand the schema registry client converter, we will describe the schema registry support first.

    29.3 Schema Registry Support

    Most serialization models, especially the ones that aim for portability across different platforms and languages, rely on a schema that describes how the data is serialized in the binary payload. +}

    In order to understand the schema registry client converter, we will describe the schema registry support first.

    30.3 Schema Registry Support

    Most serialization models, especially the ones that aim for portability across different platforms and languages, rely on a schema that describes how the data is serialized in the binary payload. In order to serialize the data and then to interpret it, both the sending and receiving sides must have access to a schema that describes the binary format. In certain cases, the schema can be inferred from the payload type on serialization, or from the target type on deserialization, but in a lot of cases applications benefit from having access to an explicit schema that describes the binary data format. A schema registry allows you to store schema information in a textual format (typically JSON) and makes that information accessible to various applications that need it to receive and send data in binary format. -A schema is referenceable as a tuple consisting of:

    • a subject that is the logical name of the schema;
    • the schema version;
    • the schema format which describes the binary format of the data.

    29.4 Schema Registry Server

    Spring Cloud Stream provides a schema registry server implementation. +A schema is referenceable as a tuple consisting of:

    • a subject that is the logical name of the schema;
    • the schema version;
    • the schema format which describes the binary format of the data.

    30.4 Schema Registry Server

    Spring Cloud Stream provides a schema registry server implementation. In order to use it, you can simply add the spring-cloud-stream-schema-server artifact to your project and use the @EnableSchemaRegistryServer annotation, adding the schema registry server REST controller to your application. This annotation is intended to be used with Spring Boot web applications, and the listening port of the server is controlled by the server.port setting. The spring.cloud.stream.schema.server.path setting can be used to control the root path of the schema server (especially when it is embedded in other applications). @@ -41,10 +41,10 @@ You can customize the schema storage using the public static void main(String[] args) { SpringApplication.run(SchemaRegistryServerApplication.class, args); } -}

    29.4.1 Schema Registry Server API

    The Schema Registry Server API consists of the following operations:

    POST /

    Register a new schema.

    Accepts JSON payload with the following fields:

    • subject the schema subject;
    • format the schema format;
    • definition the schema definition.

    Response is a schema object in JSON format, with the following fields:

    • id the schema id;
    • subject the schema subject;
    • format the schema format;
    • version the schema version;
    • definition the schema definition.

    GET /{subject}/{format}/{version}

    Retrieve an existing schema by its subject, format and version.

    Response is a schema object in JSON format, with the following fields:

    • id the schema id;
    • subject the schema subject;
    • format the schema format;
    • version the schema version;
    • definition the schema definition.

    GET /{subject}/{format}

    Retrieve a list of existing schema by its subject and format.

    Response is a list of schemas with each schema object in JSON format, with the following fields:

    • id the schema id;
    • subject the schema subject;
    • format the schema format;
    • version the schema version;
    • definition the schema definition.

    GET /schemas/{id}

    Retrieve an existing schema by its id.

    Response is a schema object in JSON format, with the following fields:

    • id the schema id;
    • subject the schema subject;
    • format the schema format;
    • version the schema version;
    • definition the schema definition.

    DELETE /{subject}/{format}/{version}

    Delete an existing schema by its subject, format and version.

    DELETE /schemas/{id}

    Delete an existing schema by its id.

    DELETE /{subject}

    Delete existing schemas by their subject.

    [Note]Note

    This note applies to users of Spring Cloud Stream 1.1.0.RELEASE only. +}

    30.4.1 Schema Registry Server API

    The Schema Registry Server API consists of the following operations:

    POST /

    Register a new schema.

    Accepts JSON payload with the following fields:

    • subject the schema subject;
    • format the schema format;
    • definition the schema definition.

    Response is a schema object in JSON format, with the following fields:

    • id the schema id;
    • subject the schema subject;
    • format the schema format;
    • version the schema version;
    • definition the schema definition.

    GET /{subject}/{format}/{version}

    Retrieve an existing schema by its subject, format and version.

    Response is a schema object in JSON format, with the following fields:

    • id the schema id;
    • subject the schema subject;
    • format the schema format;
    • version the schema version;
    • definition the schema definition.

    GET /{subject}/{format}

    Retrieve a list of existing schema by its subject and format.

    Response is a list of schemas with each schema object in JSON format, with the following fields:

    • id the schema id;
    • subject the schema subject;
    • format the schema format;
    • version the schema version;
    • definition the schema definition.

    GET /schemas/{id}

    Retrieve an existing schema by its id.

    Response is a schema object in JSON format, with the following fields:

    • id the schema id;
    • subject the schema subject;
    • format the schema format;
    • version the schema version;
    • definition the schema definition.

    DELETE /{subject}/{format}/{version}

    Delete an existing schema by its subject, format and version.

    DELETE /schemas/{id}

    Delete an existing schema by its id.

    DELETE /{subject}

    Delete existing schemas by their subject.

    [Note]Note

    This note applies to users of Spring Cloud Stream 1.1.0.RELEASE only. Spring Cloud Stream 1.1.0.RELEASE used the table name schema for storing Schema objects, which is a keyword in a number of database implementations. To avoid any conflicts in the future, starting with 1.1.1.RELEASE we have opted for the name SCHEMA_REPOSITORY for the storage table. -Any Spring Cloud Stream 1.1.0.RELEASE users that are upgrading are advised to migrate their existing schemas to the new table before upgrading.

    29.5 Schema Registry Client

    The client-side abstraction for interacting with schema registry servers is the SchemaRegistryClient interface, with the following structure:

    public interface SchemaRegistryClient {
    +Any Spring Cloud Stream 1.1.0.RELEASE users that are upgrading are advised to migrate their existing schemas to the new table before upgrading.

    30.5 Schema Registry Client

    The client-side abstraction for interacting with schema registry servers is the SchemaRegistryClient interface, with the following structure:

    public interface SchemaRegistryClient {
     
         SchemaRegistrationResponse register(String subject, String format, String schema);
     
    @@ -60,24 +60,24 @@ Any Spring Cloud Stream 1.1.0.RELEASE users that are upgrading are advised to mi
       }
    [Note]Note

    The default converter is optimized to cache not only the schemas from the remote server but also the parse() and toString() methods that are quite expensive. Because of this, it uses a DefaultSchemaRegistryClient that does not caches responses. If you intend to use the client directly on your code, you can request a bean that also caches responses to be created. -To do that, just add the property spring.cloud.stream.schemaRegistryClient.cached=true to your application properties.

    29.5.1 Using Confluent’s Schema Registry

    The default configuration will create a DefaultSchemaRegistryClient bean. +To do that, just add the property spring.cloud.stream.schemaRegistryClient.cached=true to your application properties.

    30.5.1 Using Confluent’s Schema Registry

    The default configuration will create a DefaultSchemaRegistryClient bean. If you want to use the Confluent schema registry, you need to create a bean of type ConfluentSchemaRegistryClient, which will supersede the one configured by default by the framework.

    @Bean
     public SchemaRegistryClient schemaRegistryClient(@Value("${spring.cloud.stream.schemaRegistryClient.endpoint}") String endpoint){
       ConfluentSchemaRegistryClient client = new ConfluentSchemaRegistryClient();
       client.setEndpoint(endpoint);
       return client;
    -}
    [Note]Note

    The ConfluentSchemaRegistryClient is tested against Confluent platform version 3.2.2.

    29.5.2 Schema Registry Client properties

    The Schema Registry Client supports the following properties:

    spring.cloud.stream.schemaRegistryClient.endpoint
    The location of the schema-server. +}
    [Note]Note

    The ConfluentSchemaRegistryClient is tested against Confluent platform version 3.2.2.

    30.5.2 Schema Registry Client properties

    The Schema Registry Client supports the following properties:

    spring.cloud.stream.schemaRegistryClient.endpoint
    The location of the schema-server. Use a full URL when setting this, including protocol (http or https) , port and context path.
    Default
    http://localhost:8990/
    spring.cloud.stream.schemaRegistryClient.cached
    Whether the client should cache schema server responses. Normally set to false, as the caching happens in the message converter. -Clients using the schema registry client should set this to true.
    Default
    true

    29.6 Avro Schema Registry Client Message Converters

    For Spring Boot applications that have a SchemaRegistryClient bean registered with the application context, Spring Cloud Stream will auto-configure an Apache Avro message converter that uses the schema registry client for schema management. +Clients using the schema registry client should set this to true.

    Default
    true

    30.6 Avro Schema Registry Client Message Converters

    For Spring Boot applications that have a SchemaRegistryClient bean registered with the application context, Spring Cloud Stream will auto-configure an Apache Avro message converter that uses the schema registry client for schema management. This eases schema evolution, as applications that receive messages can get easy access to a writer schema that can be reconciled with their own reader schema.

    For outbound messages, the MessageConverter will be activated if the content type of the channel is set to application/*+avro, e.g.:

    spring.cloud.stream.bindings.output.contentType=application/*+avro

    During the outbound conversion, the message converter will try to infer the schemas of the outbound messages based on their type and register them to a subject based on the payload type using the SchemaRegistryClient. If an identical schema is already found, then a reference to it will be retrieved. If not, the schema will be registered and a new version number will be provided. -The message will be sent with a contentType header using the scheme application/[prefix].[subject].v[version]+avro, where prefix is configurable and subject is deduced from the payload type.

    For example, a message of the type User may be sent as a binary payload with a content type of application/vnd.user.v2+avro, where user is the subject and 2 is the version number.

    When receiving messages, the converter will infer the schema reference from the header of the incoming message and will try to retrieve it. The schema will be used as the writer schema in the deserialization process.

    29.6.1 Avro Schema Registry Message Converter properties

    If you have enabled Avro based schema registry client by setting spring.cloud.stream.bindings.output.contentType=application/*+avro you can customize the behavior of the registration with the following properties.

    spring.cloud.stream.schema.avro.dynamicSchemaGenerationEnabled
    Enable if you want the converter to use reflection to infer a Schema from a POJO.
    Default
    false
    spring.cloud.stream.schema.avro.readerSchema
    Avro compares schema versions by looking at a writer schema (origin payload) and a reader schema (your application payload), check Avro documentation for more information. If set, this overrides any lookups at the schema server and uses the local schema as the reader schema.
    Default
    null
    spring.cloud.stream.schema.avro.schemaLocations
    Register any .avsc files listed in this property with the Schema Server.
    Default
    empty
    spring.cloud.stream.schema.avro.prefix
    The prefix to be used on the Content-Type header.
    Default
    vnd

    29.7 Schema Registration and Resolution

    To better understand how Spring Cloud Stream registers and resolves new schemas, as well as its use of Avro schema comparison features, we will provide two separate subsections below: one for the registration, and one for the resolution of schemas.

    29.7.1 Schema Registration Process (Serialization)

    The first part of the registration process is extracting a schema from the payload that is being sent over a channel. +The message will be sent with a contentType header using the scheme application/[prefix].[subject].v[version]+avro, where prefix is configurable and subject is deduced from the payload type.

    For example, a message of the type User may be sent as a binary payload with a content type of application/vnd.user.v2+avro, where user is the subject and 2 is the version number.

    When receiving messages, the converter will infer the schema reference from the header of the incoming message and will try to retrieve it. The schema will be used as the writer schema in the deserialization process.

    30.6.1 Avro Schema Registry Message Converter properties

    If you have enabled Avro based schema registry client by setting spring.cloud.stream.bindings.output.contentType=application/*+avro you can customize the behavior of the registration with the following properties.

    spring.cloud.stream.schema.avro.dynamicSchemaGenerationEnabled
    Enable if you want the converter to use reflection to infer a Schema from a POJO.
    Default
    false
    spring.cloud.stream.schema.avro.readerSchema
    Avro compares schema versions by looking at a writer schema (origin payload) and a reader schema (your application payload), check Avro documentation for more information. If set, this overrides any lookups at the schema server and uses the local schema as the reader schema.
    Default
    null
    spring.cloud.stream.schema.avro.schemaLocations
    Register any .avsc files listed in this property with the Schema Server.
    Default
    empty
    spring.cloud.stream.schema.avro.prefix
    The prefix to be used on the Content-Type header.
    Default
    vnd

    30.7 Schema Registration and Resolution

    To better understand how Spring Cloud Stream registers and resolves new schemas, as well as its use of Avro schema comparison features, we will provide two separate subsections below: one for the registration, and one for the resolution of schemas.

    30.7.1 Schema Registration Process (Serialization)

    The first part of the registration process is extracting a schema from the payload that is being sent over a channel. Avro types such as SpecificRecord or GenericRecord already contain a schema, which can be retrieved immediately from the instance. -In the case of POJOs a schema will be inferred if the property spring.cloud.stream.schema.avro.dynamicSchemaGenerationEnabled is set to true (the default).

    Figure 29.1. Schema Writer Resolution Process

    schema resolution

    Once a schema is obtained, the converter will then load its metadata (version) from the remote server. +In the case of POJOs a schema will be inferred if the property spring.cloud.stream.schema.avro.dynamicSchemaGenerationEnabled is set to true (the default).

    Figure 30.1. Schema Writer Resolution Process

    schema resolution

    Once a schema is obtained, the converter will then load its metadata (version) from the remote server. First it queries a local cache, and if not found it then submits the data to the server that will reply with versioning information. -The converter will always cache the results to avoid the overhead of querying the Schema Server for every new message that needs to be serialized.

    Figure 29.2. Schema Registration Process

    registration

    With the schema version information, the converter sets the contentType header of the message to carry the version information such as application/vnd.user.v1+avro

    29.7.2 Schema Resolution Process (Deserialization)

    When reading messages that contain version information (i.e. a contentType header with a scheme like above), the converter will query the Schema server to fetch the writer schema of the message. -Once it has found the correct schema of the incoming message, it then retrieves the reader schema and using Avro’s schema resolution support reads it into the reader definition (setting defaults and missing properties).

    Figure 29.3. Schema Reading Resolution Process

    schema reading

    [Note]Note

    It’s important to understand the difference between a writer schema (the application that wrote the message) and a reader schema (the receiving application). +The converter will always cache the results to avoid the overhead of querying the Schema Server for every new message that needs to be serialized.

    Figure 30.2. Schema Registration Process

    registration

    With the schema version information, the converter sets the contentType header of the message to carry the version information such as application/vnd.user.v1+avro

    30.7.2 Schema Resolution Process (Deserialization)

    When reading messages that contain version information (i.e. a contentType header with a scheme like above), the converter will query the Schema server to fetch the writer schema of the message. +Once it has found the correct schema of the incoming message, it then retrieves the reader schema and using Avro’s schema resolution support reads it into the reader definition (setting defaults and missing properties).

    Figure 30.3. Schema Reading Resolution Process

    schema reading

    [Note]Note

    It’s important to understand the difference between a writer schema (the application that wrote the message) and a reader schema (the receiving application). Please take a moment to read the Avro terminology and understand the process. -Spring Cloud Stream will always fetch the writer schema to determine how to read a message. If you want to get Avro’s schema evolution support working you need to make sure that a readerSchema was properly set for your application.

    \ No newline at end of file +Spring Cloud Stream will always fetch the writer schema to determine how to read a message. If you want to get Avro’s schema evolution support working you need to make sure that a readerSchema was properly set for your application.

    \ No newline at end of file diff --git a/Finchley.M7/multi/multi_spring-cloud-consul-agent.html b/Finchley.M7/multi/multi_spring-cloud-consul-agent.html index 427f6ce3..da064503 100644 --- a/Finchley.M7/multi/multi_spring-cloud-consul-agent.html +++ b/Finchley.M7/multi/multi_spring-cloud-consul-agent.html @@ -1,3 +1,3 @@ - 62. Consul Agent

    62. 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

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

    \ No newline at end of file + 63. Consul Agent

    63. 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

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

    \ No newline at end of file diff --git a/Finchley.M7/multi/multi_spring-cloud-consul-bus.html b/Finchley.M7/multi/multi_spring-cloud-consul-bus.html index 16b7f160..e8496ca9 100644 --- a/Finchley.M7/multi/multi_spring-cloud-consul-bus.html +++ b/Finchley.M7/multi/multi_spring-cloud-consul-bus.html @@ -1,3 +1,3 @@ - 66. Spring Cloud Bus with Consul

    66. Spring Cloud Bus with Consul

    66.1 How to activate

    To get started with the Consul Bus use the starter with group org.springframework.cloud and artifact id spring-cloud-starter-consul-bus. See the Spring Cloud Project page for details on setting up your build system with the current Spring Cloud Release Train.

    See the Spring Cloud Bus documentation for the available actuator endpoints and howto send custom messages.

    \ No newline at end of file + 67. Spring Cloud Bus with Consul

    67. Spring Cloud Bus with Consul

    67.1 How to activate

    To get started with the Consul Bus use the starter with group org.springframework.cloud and artifact id spring-cloud-starter-consul-bus. See the Spring Cloud Project page for details on setting up your build system with the current Spring Cloud Release Train.

    See the Spring Cloud Bus documentation for the available actuator endpoints and howto send custom messages.

    \ No newline at end of file diff --git a/Finchley.M7/multi/multi_spring-cloud-consul-config.html b/Finchley.M7/multi/multi_spring-cloud-consul-config.html index b2167e99..f96316ae 100644 --- a/Finchley.M7/multi/multi_spring-cloud-consul-config.html +++ b/Finchley.M7/multi/multi_spring-cloud-consul-config.html @@ -1,9 +1,9 @@ - 64. Distributed Configuration with Consul

    64. 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/
    +   65. Distributed Configuration with Consul

    65. 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/
     config/testApp/
     config/application,dev/
    -config/application/

    The most specific property source is at the top, with the least specific at the bottom. Properties in 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. Section 64.3, “Config Watch” will also automatically detect changes and reload the application context.

    64.1 How to activate

    To get started with Consul Configuration use the starter with group org.springframework.cloud and artifact id spring-cloud-starter-consul-config. See the Spring Cloud Project page for details on setting up your build system with the current Spring Cloud Release Train.

    This will enable auto-configuration that will setup Spring Cloud Consul Config.

    64.2 Customizing

    Consul Config may be customized using the following properties:

    bootstrap.yml.  +config/application/

    The most specific property source is at the top, with the least specific at the bottom. Properties in 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. Section 65.3, “Config Watch” will also automatically detect changes and reload the application context.

    65.1 How to activate

    To get started with Consul Configuration use the starter with group org.springframework.cloud and artifact id spring-cloud-starter-consul-config. See the Spring Cloud Project page for details on setting up your build system with the current Spring Cloud Release Train.

    This will enable auto-configuration that will setup Spring Cloud Consul Config.

    65.2 Customizing

    Consul Config may be customized using the following properties:

    bootstrap.yml. 

    spring:
       cloud:
         consul:
    @@ -12,7 +12,7 @@ config/application/

    The most specific property source is at the top, wit 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

    64.3 Config Watch

    The Consul Config Watch takes advantage of the ability of consul to watch a key prefix. The Config Watch makes a blocking Consul HTTP API call to determine if any relevant configuration data has changed for the current application. If there is new configuration data a Refresh Event is published. This is equivalent to calling the /refresh actuator endpoint.

    To change the frequency of when the Config Watch is called change spring.cloud.consul.config.watch.delay. The default value is 1000, which is in milliseconds.

    To disable the Config Watch set spring.cloud.consul.config.watch.enabled=false.

    64.4 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.  +

    • 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

    65.3 Config Watch

    The Consul Config Watch takes advantage of the ability of consul to watch a key prefix. The Config Watch makes a blocking Consul HTTP API call to determine if any relevant configuration data has changed for the current application. If there is new configuration data a Refresh Event is published. This is equivalent to calling the /refresh actuator endpoint.

    To change the frequency of when the Config Watch is called change spring.cloud.consul.config.watch.delay. The default value is 1000, which is in milliseconds.

    To disable the Config Watch set spring.cloud.consul.config.watch.enabled=false.

    65.4 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:
    @@ -21,7 +21,7 @@ config/application/

    The most specific property source is at the top, wit

    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.

    64.5 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.  +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.

    65.5 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:
    @@ -35,4 +35,4 @@ foo-production.yml
     foo.properties
     master.ref

    the following property sources would be created:

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

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

    64.6 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.

    \ No newline at end of file +config/application.yml

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

    65.6 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.

    \ No newline at end of file diff --git a/Finchley.M7/multi/multi_spring-cloud-consul-discovery.html b/Finchley.M7/multi/multi_spring-cloud-consul-discovery.html index 9bcb5d71..8b226254 100644 --- a/Finchley.M7/multi/multi_spring-cloud-consul-discovery.html +++ b/Finchley.M7/multi/multi_spring-cloud-consul-discovery.html @@ -1,6 +1,6 @@ - 63. Service Discovery with Consul

    63. 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.

    63.1 How to activate

    To activate Consul Service Discovery use the starter with group org.springframework.cloud and artifact id spring-cloud-starter-consul-discovery. See the Spring Cloud Project page for details on setting up your build system with the current Spring Cloud Release Train.

    63.2 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
    +   64. Service Discovery with Consul

    64. 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.

    64.1 How to activate

    To activate Consul Service Discovery use the starter with group org.springframework.cloud and artifact id spring-cloud-starter-consul-discovery. See the Spring Cloud Project page for details on setting up your build system with the current Spring Cloud Release Train.

    64.2 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
     @RestController
     public class Application {
     
    @@ -19,26 +19,26 @@
         consul:
           host: localhost
           port: 8500

    -

    [Caution]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.

    To disable the Consul Discovery Client you can set spring.cloud.consul.discovery.enabled to false.

    To disable the service registration you can set spring.cloud.consul.discovery.register to false.

    63.3 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.context-path=/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.  +

    [Caution]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.

    To disable the Consul Discovery Client you can set spring.cloud.consul.discovery.enabled to false.

    To disable the service registration you can set spring.cloud.consul.discovery.register to false.

    64.3 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.context-path=/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.context-path}/health
             healthCheckInterval: 15s

    -

    63.3.1 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.  +

    64.3.1 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:
             tags: foo=bar, baz

    -

    The above configuration will result in a map with foo→bar and baz→baz.

    63.3.2 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.  +

    The above configuration will result in a map with foo→bar and baz→baz.

    64.3.2 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}:${vcap.application.instance_id:${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 vcap.application.instance_id will be populated automatically in a Spring Boot application, so the random value will not be needed.

    63.4 Looking up services

    63.4.1 Using Ribbon

    Spring Cloud has support for Feign (a REST client builder) and also Spring RestTemplate +

    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 vcap.application.instance_id will be populated automatically in a Spring Boot application, so the random value will not be needed.

    64.4 Looking up services

    64.4.1 Using Ribbon

    Spring Cloud has support for Feign (a REST client builder) and also Spring RestTemplate for looking up services using the logical service names/ids instead of physical URLs. Both Feign and the discovery-aware RestTemplate utilize Ribbon for client-side load balancing.

    If you want to access service STORES using the RestTemplate simply declare:

    @LoadBalanced
     @Bean
     public RestTemplate loadbalancedRestTemplate() {
    @@ -50,7 +50,7 @@ public String getFirstProduct() {
        return this.restTemplate.getForObject("https://STORES/products/1", String.class);
     }

    If you have Consul clusters in multiple datacenters and you want to access a service in another datacenter a service name/id alone is not enough. In that case you use property spring.cloud.consul.discovery.datacenters.STORES=dc-west where STORES is the service name/id and dc-west is the datacenter -where the STORES service lives.

    63.4.2 Using the DiscoveryClient

    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
    +where the STORES service lives.

    64.4.2 Using the DiscoveryClient

    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() {
    @@ -59,4 +59,4 @@ public String serviceUrl() {
             return list.get(0).getUri();
         }
         return null;
    -}
    \ No newline at end of file +}
    \ No newline at end of file diff --git a/Finchley.M7/multi/multi_spring-cloud-consul-hystrix.html b/Finchley.M7/multi/multi_spring-cloud-consul-hystrix.html index d8d2e406..d537bf93 100644 --- a/Finchley.M7/multi/multi_spring-cloud-consul-hystrix.html +++ b/Finchley.M7/multi/multi_spring-cloud-consul-hystrix.html @@ -1,3 +1,3 @@ - 67. Circuit Breaker with Hystrix

    67. 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.

    \ No newline at end of file + 68. Circuit Breaker with Hystrix

    68. 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.

    \ No newline at end of file diff --git a/Finchley.M7/multi/multi_spring-cloud-consul-install.html b/Finchley.M7/multi/multi_spring-cloud-consul-install.html index 72533495..fcb7e639 100644 --- a/Finchley.M7/multi/multi_spring-cloud-consul-install.html +++ b/Finchley.M7/multi/multi_spring-cloud-consul-install.html @@ -1,3 +1,3 @@ - 61. Install Consul

    61. Install Consul

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

    \ No newline at end of file + 62. Install Consul

    62. Install Consul

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

    \ No newline at end of file diff --git a/Finchley.M7/multi/multi_spring-cloud-consul-retry.html b/Finchley.M7/multi/multi_spring-cloud-consul-retry.html index 3ca1c8f0..d1e993c9 100644 --- a/Finchley.M7/multi/multi_spring-cloud-consul-retry.html +++ b/Finchley.M7/multi/multi_spring-cloud-consul-retry.html @@ -1,6 +1,6 @@ - 65. Consul Retry

    65. Consul Retry

    If you expect that the consul agent may occasionally be unavailable when + 66. Consul Retry

    66. 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 behaviour is to retry 6 times with an initial backoff interval of 1000ms and an @@ -8,4 +8,4 @@ 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]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.

    \ No newline at end of file +Retry has a RetryInterceptorBuilder that makes it easy to create one.

    \ No newline at end of file diff --git a/Finchley.M7/multi/multi_spring-cloud-consul-turbine.html b/Finchley.M7/multi/multi_spring-cloud-consul-turbine.html index d10d6804..58c227e5 100644 --- a/Finchley.M7/multi/multi_spring-cloud-consul-turbine.html +++ b/Finchley.M7/multi/multi_spring-cloud-consul-turbine.html @@ -1,6 +1,6 @@ - 68. Hystrix metrics aggregation with Turbine and Consul

    68. 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.  + 69. Hystrix metrics aggregation with Turbine and Consul

    69. 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>
         <groupId>org.springframework.cloud</groupId>
         <artifactId>spring-cloud-netflix-turbine</artifactId>
    @@ -24,4 +24,4 @@ public class Turbine {
             SpringApplication.run(DemoturbinecommonsApplication.class, args);
         }
     }

    -

    \ No newline at end of file +

    \ No newline at end of file diff --git a/Finchley.M7/multi/multi_spring-cloud-feign.html b/Finchley.M7/multi/multi_spring-cloud-feign.html new file mode 100644 index 00000000..2dd68f26 --- /dev/null +++ b/Finchley.M7/multi/multi_spring-cloud-feign.html @@ -0,0 +1,199 @@ + + + 23. Declarative REST Client: Feign

    23. Declarative REST Client: Feign

    Feign is a declarative web service client. It makes writing web service clients easier. To use Feign create an interface and annotate it. It has pluggable annotation support including Feign annotations and JAX-RS annotations. Feign also supports pluggable encoders and decoders. Spring Cloud adds support for Spring MVC annotations and for using the same HttpMessageConverters used by default in Spring Web. Spring Cloud integrates Ribbon and Eureka to provide a load balanced http client when using Feign.

    23.1 How to Include Feign

    To include Feign in your project use the starter with group org.springframework.cloud +and artifact id spring-cloud-starter-openfeign. See the Spring Cloud Project page +for details on setting up your build system with the current Spring Cloud Release Train.

    Example spring boot app

    @SpringBootApplication
    +@EnableFeignClients
    +public class Application {
    +
    +    public static void main(String[] args) {
    +        SpringApplication.run(Application.class, args);
    +    }
    +
    +}

    StoreClient.java.  +

    @FeignClient("stores")
    +public interface StoreClient {
    +    @RequestMapping(method = RequestMethod.GET, value = "/stores")
    +    List<Store> getStores();
    +
    +    @RequestMapping(method = RequestMethod.POST, value = "/stores/{storeId}", consumes = "application/json")
    +    Store update(@PathVariable("storeId") Long storeId, Store store);
    +}

    +

    In the @FeignClient annotation the String value ("stores" above) is +an arbitrary client name, which is used to create a Ribbon load +balancer (see below for details of Ribbon +support). You can also specify a URL using the url attribute +(absolute value or just a hostname). The name of the bean in the +application context is the fully qualified name of the interface. +To specify your own alias value you can use the qualifier value +of the @FeignClient annotation.

    The Ribbon client above will want to discover the physical addresses +for the "stores" service. If your application is a Eureka client then +it will resolve the service in the Eureka service registry. If you +don’t want to use Eureka, you can simply configure a list of servers +in your external configuration (see +above for example).

    23.2 Overriding Feign Defaults

    A central concept in Spring Cloud’s Feign support is that of the named client. Each feign client is part of an ensemble of components that work together to contact a remote server on demand, and the ensemble has a name that you give it as an application developer using the @FeignClient annotation. Spring Cloud creates a new ensemble as an +ApplicationContext on demand for each named client using FeignClientsConfiguration. This contains (amongst other things) an feign.Decoder, a feign.Encoder, and a feign.Contract.

    Spring Cloud lets you take full control of the feign client by declaring additional configuration (on top of the FeignClientsConfiguration) using @FeignClient. Example:

    @FeignClient(name = "stores", configuration = FooConfiguration.class)
    +public interface StoreClient {
    +    //..
    +}

    In this case the client is composed from the components already in FeignClientsConfiguration together with any in FooConfiguration (where the latter will override the former).

    [Note]Note

    FooConfiguration does not need to be annotated with @Configuration. However, if it is, then take care to exclude it from any @ComponentScan that would otherwise include this configuration as it will become the default source for feign.Decoder, feign.Encoder, feign.Contract, etc., when specified. This can be avoided by putting it in a separate, non-overlapping package from any @ComponentScan or @SpringBootApplication, or it can be explicitly excluded in @ComponentScan.

    [Note]Note

    The serviceId attribute is now deprecated in favor of the name attribute.

    [Warning]Warning

    Previously, using the url attribute, did not require the name attribute. Using name is now required.

    Placeholders are supported in the name and url attributes.

    @FeignClient(name = "${feign.name}", url = "${feign.url}")
    +public interface StoreClient {
    +    //..
    +}

    Spring Cloud Netflix provides the following beans by default for feign (BeanType beanName: ClassName):

    • Decoder feignDecoder: ResponseEntityDecoder (which wraps a SpringDecoder)
    • Encoder feignEncoder: SpringEncoder
    • Logger feignLogger: Slf4jLogger
    • Contract feignContract: SpringMvcContract
    • Feign.Builder feignBuilder: HystrixFeign.Builder
    • Client feignClient: if Ribbon is enabled it is a LoadBalancerFeignClient, otherwise the default feign client is used.

    The OkHttpClient and ApacheHttpClient feign clients can be used by setting feign.okhttp.enabled or feign.httpclient.enabled to true, respectively, and having them on the classpath. +You can customize the HTTP client used by providing a bean of either ClosableHttpClient when using Apache or OkHttpClient whe using OK HTTP.

    Spring Cloud Netflix does not provide the following beans by default for feign, but still looks up beans of these types from the application context to create the feign client:

    • Logger.Level
    • Retryer
    • ErrorDecoder
    • Request.Options
    • Collection<RequestInterceptor>
    • SetterFactory

    Creating a bean of one of those type and placing it in a @FeignClient configuration (such as FooConfiguration above) allows you to override each one of the beans described. Example:

    @Configuration
    +public class FooConfiguration {
    +    @Bean
    +    public Contract feignContract() {
    +        return new feign.Contract.Default();
    +    }
    +
    +    @Bean
    +    public BasicAuthRequestInterceptor basicAuthRequestInterceptor() {
    +        return new BasicAuthRequestInterceptor("user", "password");
    +    }
    +}

    This replaces the SpringMvcContract with feign.Contract.Default and adds a RequestInterceptor to the collection of RequestInterceptor.

    @FeignClient also can be configured using configuration properties.

    application.yml

    feign:
    +  client:
    +    config:
    +      feignName:
    +        connectTimeout: 5000
    +        readTimeout: 5000
    +        loggerLevel: full
    +        errorDecoder: com.example.SimpleErrorDecoder
    +        retryer: com.example.SimpleRetryer
    +        requestInterceptors:
    +          - com.example.FooRequestInterceptor
    +          - com.example.BarRequestInterceptor
    +        decode404: false
    +        encoder: com.example.SimpleEncoder
    +        decoder: com.example.SimpleDecoder
    +        contract: com.example.SimpleContract

    Default configurations can be specified in the @EnableFeignClients attribute defaultConfiguration in a similar manner as described above. The difference is that this configuration will apply to all feign clients.

    If you prefer using configuration properties to configured all @FeignClient, you can create configuration properties with default feign name.

    application.yml

    feign:
    +  client:
    +    config:
    +      default:
    +        connectTimeout: 5000
    +        readTimeout: 5000
    +        loggerLevel: basic

    If we create both @Configuration bean and configuration properties, configuration properties will win. +It will override @Configuration values. But if you want to change the priority to @Configuration, +you can change feign.client.default-to-properties to false.

    [Note]Note

    If you need to use ThreadLocal bound variables in your RequestInterceptor`s you will need to either set the +thread isolation strategy for Hystrix to `SEMAPHORE or disable Hystrix in Feign.

    application.yml

    # To disable Hystrix in Feign
    +feign:
    +  hystrix:
    +    enabled: false
    +
    +# To set thread isolation to SEMAPHORE
    +hystrix:
    +  command:
    +    default:
    +      execution:
    +        isolation:
    +          strategy: SEMAPHORE

    23.3 Creating Feign Clients Manually

    In some cases it might be necessary to customize your Feign Clients in a way that is not +possible using the methods above. In this case you can create Clients using the +Feign Builder API. Below is an example +which creates two Feign Clients with the same interface but configures each one with +a separate request interceptor.

    @Import(FeignClientsConfiguration.class)
    +class FooController {
    +
    +	private FooClient fooClient;
    +
    +	private FooClient adminClient;
    +
    +    	@Autowired
    +	public FooController(
    +			Decoder decoder, Encoder encoder, Client client, Contract contract) {
    +		this.fooClient = Feign.builder().client(client)
    +				.encoder(encoder)
    +				.decoder(decoder)
    +                .contract(contract)
    +				.requestInterceptor(new BasicAuthRequestInterceptor("user", "user"))
    +				.target(FooClient.class, "http://PROD-SVC");
    +		this.adminClient = Feign.builder().client(client)
    +				.encoder(encoder)
    +				.decoder(decoder)
    +				.contract(contract)
    +				.requestInterceptor(new BasicAuthRequestInterceptor("admin", "admin"))
    +				.target(FooClient.class, "http://PROD-SVC");
    +    }
    +}
    [Note]Note

    In the above example FeignClientsConfiguration.class is the default configuration +provided by Spring Cloud Netflix.

    [Note]Note

    PROD-SVC is the name of the service the Clients will be making requests to.

    [Note]Note

    The Feign Contract object defines what annotations and values are valid on interfaces. The +autowired Contract bean provides supports for SpringMVC annotations, instead of +the default Feign native annotations.

    23.4 Feign Hystrix Support

    If Hystrix is on the classpath and feign.hystrix.enabled=true, Feign will wrap all methods with a circuit breaker. Returning a com.netflix.hystrix.HystrixCommand is also available. This lets you use reactive patterns (with a call to .toObservable() or .observe() or asynchronous use (with a call to .queue()).

    To disable Hystrix support on a per-client basis create a vanilla Feign.Builder with the "prototype" scope, e.g.:

    @Configuration
    +public class FooConfiguration {
    +    	@Bean
    +	@Scope("prototype")
    +	public Feign.Builder feignBuilder() {
    +		return Feign.builder();
    +	}
    +}
    [Warning]Warning

    Prior to the Spring Cloud Dalston release, if Hystrix was on the classpath Feign would have wrapped +all methods in a circuit breaker by default. This default behavior was changed in Spring Cloud Dalston in +favor for an opt-in approach.

    23.5 Feign Hystrix Fallbacks

    Hystrix supports the notion of a fallback: a default code path that is executed when they circuit is open or there is an error. To enable fallbacks for a given @FeignClient set the fallback attribute to the class name that implements the fallback. You also need to declare your implementation as a Spring bean.

    @FeignClient(name = "hello", fallback = HystrixClientFallback.class)
    +protected interface HystrixClient {
    +    @RequestMapping(method = RequestMethod.GET, value = "/hello")
    +    Hello iFailSometimes();
    +}
    +
    +static class HystrixClientFallback implements HystrixClient {
    +    @Override
    +    public Hello iFailSometimes() {
    +        return new Hello("fallback");
    +    }
    +}

    If one needs access to the cause that made the fallback trigger, one can use the fallbackFactory attribute inside @FeignClient.

    @FeignClient(name = "hello", fallbackFactory = HystrixClientFallbackFactory.class)
    +protected interface HystrixClient {
    +	@RequestMapping(method = RequestMethod.GET, value = "/hello")
    +	Hello iFailSometimes();
    +}
    +
    +@Component
    +static class HystrixClientFallbackFactory implements FallbackFactory<HystrixClient> {
    +	@Override
    +	public HystrixClient create(Throwable cause) {
    +		return new HystrixClient() {
    +			@Override
    +			public Hello iFailSometimes() {
    +				return new Hello("fallback; reason was: " + cause.getMessage());
    +			}
    +		};
    +	}
    +}
    [Warning]Warning

    There is a limitation with the implementation of fallbacks in Feign and how Hystrix fallbacks work. Fallbacks are currently not supported for methods that return com.netflix.hystrix.HystrixCommand and rx.Observable.

    23.6 Feign and @Primary

    When using Feign with Hystrix fallbacks, there are multiple beans in the ApplicationContext of the same type. This will cause @Autowired to not work because there isn’t exactly one bean, or one marked as primary. To work around this, Spring Cloud Netflix marks all Feign instances as @Primary, so Spring Framework will know which bean to inject. In some cases, this may not be desirable. To turn off this behavior set the primary attribute of @FeignClient to false.

    @FeignClient(name = "hello", primary = false)
    +public interface HelloClient {
    +	// methods here
    +}

    23.7 Feign Inheritance Support

    Feign supports boilerplate apis via single-inheritance interfaces. +This allows grouping common operations into convenient base interfaces.

    UserService.java.  +

    public interface UserService {
    +
    +    @RequestMapping(method = RequestMethod.GET, value ="/users/{id}")
    +    User getUser(@PathVariable("id") long id);
    +}

    +

    UserResource.java.  +

    @RestController
    +public class UserResource implements UserService {
    +
    +}

    +

    UserClient.java.  +

    package project.user;
    +
    +@FeignClient("users")
    +public interface UserClient extends UserService {
    +
    +}

    +

    [Note]Note

    It is generally not advisable to share an interface between a +server and a client. It introduces tight coupling, and also actually +doesn’t work with Spring MVC in its current form (method parameter +mapping is not inherited).

    23.8 Feign request/response compression

    You may consider enabling the request or response GZIP compression for your +Feign requests. You can do this by enabling one of the properties:

    feign.compression.request.enabled=true
    +feign.compression.response.enabled=true

    Feign request compression gives you settings similar to what you may set for your web server:

    feign.compression.request.enabled=true
    +feign.compression.request.mime-types=text/xml,application/xml,application/json
    +feign.compression.request.min-request-size=2048

    These properties allow you to be selective about the compressed media types and minimum request threshold length.

    23.9 Feign logging

    A logger is created for each Feign client created. By default the name of the logger is the full class name of the interface used to create the Feign client. Feign logging only responds to the DEBUG level.

    application.yml.  +

    logging.level.project.user.UserClient: DEBUG

    +

    The Logger.Level object that you may configure per client, tells Feign how much to log. Choices are:

    • NONE, No logging (DEFAULT).
    • BASIC, Log only the request method and URL and the response status code and execution time.
    • HEADERS, Log the basic information along with request and response headers.
    • FULL, Log the headers, body, and metadata for both requests and responses.

    For example, the following would set the Logger.Level to FULL:

    @Configuration
    +public class FooConfiguration {
    +    @Bean
    +    Logger.Level feignLoggerLevel() {
    +        return Logger.Level.FULL;
    +    }
    +}
            OtherClass.someMethod(myprop.get());
    +    }
    +}
    +stripped). The proxy uses Ribbon to locate an instance to forward to
    +via discovery, and all requests are executed in a
    +<<hystrix-fallbacks-for-routes, hystrix command>>, so
    +failures will show up in Hystrix metrics, and once the circuit is open
    +the proxy will not try to contact the service.
    \ No newline at end of file diff --git a/Finchley.M7/multi/multi_spring-cloud-zookeeper-config.html b/Finchley.M7/multi/multi_spring-cloud-zookeeper-config.html index 2509b3ec..1559f334 100644 --- a/Finchley.M7/multi/multi_spring-cloud-zookeeper-config.html +++ b/Finchley.M7/multi/multi_spring-cloud-zookeeper-config.html @@ -1,9 +1,9 @@ - 75. Distributed Configuration with Zookeeper

    75. 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
    +   76. Distributed Configuration with Zookeeper

    76. 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
     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.

    75.1 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.

    75.2 Customizing

    Zookeeper Config may be customized using the following properties:

    bootstrap.yml.  +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.

    76.1 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.

    76.2 Customizing

    Zookeeper Config may be customized using the following properties:

    bootstrap.yml. 

    spring:
       cloud:
         zookeeper:
    @@ -12,7 +12,7 @@ config/application

    The most specific property source is at the top, with root: configuration defaultContext: apps 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

    75.3 ACLs

    You can add authentication information for Zookeeper ACLs by calling the addAuthInfo method of a +

    • 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

    76.3 ACLs

    You can add authentication information for Zookeeper ACLs by calling the addAuthInfo method of a CuratorFramework bean. One way to accomplish this is by providing your own CuratorFramework bean:

    @BoostrapConfiguration
     public class CustomCuratorFrameworkConfig {
     
    @@ -40,4 +40,4 @@ comma-separated list set as the value of the property
     

    org.springframework.cloud.bootstrap.BootstrapConfiguration=\
     my.project.CustomCuratorFrameworkConfig,\
     my.project.DefaultCuratorFrameworkConfig

    -

    Unresolved directive in spring-cloud.adoc - include::../../../../cli/docs/src/main/asciidoc/spring-cloud-cli.adoc[]

    \ No newline at end of file +

    Unresolved directive in spring-cloud.adoc - include::../../../../cli/docs/src/main/asciidoc/spring-cloud-cli.adoc[]

    \ No newline at end of file diff --git a/Finchley.M7/multi/multi_spring-cloud-zookeeper-dependencies.html b/Finchley.M7/multi/multi_spring-cloud-zookeeper-dependencies.html index e4a56288..b77d8d71 100644 --- a/Finchley.M7/multi/multi_spring-cloud-zookeeper-dependencies.html +++ b/Finchley.M7/multi/multi_spring-cloud-zookeeper-dependencies.html @@ -1,8 +1,8 @@ - 73. Zookeeper Dependencies

    73. Zookeeper Dependencies

    73.1 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 + 74. Zookeeper Dependencies

    74. Zookeeper Dependencies

    74.1 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.

    73.2 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).

    73.3 Setting up Zookeeper Dependencies

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

    application.yml.  +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.

    74.2 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).

    74.3 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:
    @@ -24,25 +24,25 @@ spring.cloud.zookeeper:
           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.

    73.3.1 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 +

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

    74.3.1 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();
    -}

    73.3.2 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.

    73.3.3 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

    73.3.4 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 +}

    74.3.2 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.

    74.3.3 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

    74.3.4 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

    and the following version:

    v1

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

    application/vnd.newsletter.v1+json

    73.3.5 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. +version yaml property. Let’s take a look at an example.

    Having the following contentTypeTemplate:

    application/vnd.newsletter.$version+json

    and the following version:

    v1

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

    application/vnd.newsletter.v1+json

    74.3.5 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.

    73.3.6 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.

    73.3.7 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.

    73.4 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 + - no-cache

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

    74.3.6 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.

    74.3.7 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.

    74.4 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.
    \ No newline at end of file +headers and content type with version set in Dependency configuration. Wihtout this setting of those two parameters will not be operational.
    \ No newline at end of file diff --git a/Finchley.M7/multi/multi_spring-cloud-zookeeper-dependency-watcher.html b/Finchley.M7/multi/multi_spring-cloud-zookeeper-dependency-watcher.html index d1314d16..dc066db0 100644 --- a/Finchley.M7/multi/multi_spring-cloud-zookeeper-dependency-watcher.html +++ b/Finchley.M7/multi/multi_spring-cloud-zookeeper-dependency-watcher.html @@ -1,8 +1,8 @@ - 74. Spring Cloud Zookeeper Dependency Watcher

    74. 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.

    74.1 How to activate

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

    74.2 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. + 75. Spring Cloud Zookeeper Dependency Watcher

    75. 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.

    75.1 How to activate

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

    75.2 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.

    74.3 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 + whether your dependency has changed to CONNECTED or DISCONNECTED.

    75.3 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 overridden since the DefaultDependencyPresenceOnStartupVerifier is registered only when there is no bean of DependencyPresenceOnStartupVerifier.

    \ No newline at end of file +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 overridden since the DefaultDependencyPresenceOnStartupVerifier is registered only when there is no bean of DependencyPresenceOnStartupVerifier.

    \ No newline at end of file diff --git a/Finchley.M7/multi/multi_spring-cloud-zookeeper-discovery.html b/Finchley.M7/multi/multi_spring-cloud-zookeeper-discovery.html index 70bc1f95..4706a5a0 100644 --- a/Finchley.M7/multi/multi_spring-cloud-zookeeper-discovery.html +++ b/Finchley.M7/multi/multi_spring-cloud-zookeeper-discovery.html @@ -1,6 +1,6 @@ - 70. Service Discovery with Zookeeper

    70. 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.

    70.1 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.

    [Note]Note

    You still need to include org.springframework.boot:spring-boot-starter-web for web functionality.

    70.2 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
    +   71. Service Discovery with Zookeeper

    71. 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.

    71.1 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.

    [Note]Note

    You still need to include org.springframework.boot:spring-boot-starter-web for web functionality.

    71.2 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
     @RestController
     public class Application {
     
    @@ -18,7 +18,7 @@
       cloud:
         zookeeper:
           connect-string: localhost:2181

    -

    [Caution]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.

    Having spring-cloud-starter-zookeeper-discovery on the classpath 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).

    If you would like to disable the Zookeeper Discovery Client you can set spring.cloud.zookeeper.discovery.enabled to false.

    70.3 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.

    @Autowired
    +

    [Caution]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.

    Having spring-cloud-starter-zookeeper-discovery on the classpath 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).

    If you would like to disable the Zookeeper Discovery Client you can set spring.cloud.zookeeper.discovery.enabled to false.

    71.3 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.

    @Autowired
     private DiscoveryClient discoveryClient;
     
     public String serviceUrl() {
    @@ -27,4 +27,4 @@
             return list.get(0).getUri().toString();
         }
         return null;
    -}
    \ No newline at end of file +}
    \ No newline at end of file diff --git a/Finchley.M7/multi/multi_spring-cloud-zookeeper-install.html b/Finchley.M7/multi/multi_spring-cloud-zookeeper-install.html index 46bb54da..97af31af 100644 --- a/Finchley.M7/multi/multi_spring-cloud-zookeeper-install.html +++ b/Finchley.M7/multi/multi_spring-cloud-zookeeper-install.html @@ -1,3 +1,3 @@ - 69. Install Zookeeper

    69. Install Zookeeper

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

    \ No newline at end of file + 70. Install Zookeeper

    70. Install Zookeeper

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

    \ No newline at end of file diff --git a/Finchley.M7/multi/multi_spring-cloud-zookeeper-netflix.html b/Finchley.M7/multi/multi_spring-cloud-zookeeper-netflix.html index 55d7fa1a..d9cc3994 100644 --- a/Finchley.M7/multi/multi_spring-cloud-zookeeper-netflix.html +++ b/Finchley.M7/multi/multi_spring-cloud-zookeeper-netflix.html @@ -1,3 +1,3 @@ - 71. Using Spring Cloud Zookeeper with Spring Cloud Netflix Components

    71. Using Spring Cloud Zookeeper with Spring Cloud Netflix Components

    Spring Cloud Netflix supplies useful tools that work regardless of which DiscoveryClient implementation is used. Feign, Turbine, Ribbon and Zuul all work with Spring Cloud Zookeeper.

    71.1 Ribbon with Zookeeper

    Spring Cloud Zookeeper provides an implementation of Ribbon’s ServerList. When the spring-cloud-starter-zookeeper-discovery is used, Ribbon is auto-configured to use the ZookeeperServerList by default.

    \ No newline at end of file + 72. Using Spring Cloud Zookeeper with Spring Cloud Netflix Components

    72. Using Spring Cloud Zookeeper with Spring Cloud Netflix Components

    Spring Cloud Netflix supplies useful tools that work regardless of which DiscoveryClient implementation is used. Feign, Turbine, Ribbon and Zuul all work with Spring Cloud Zookeeper.

    72.1 Ribbon with Zookeeper

    Spring Cloud Zookeeper provides an implementation of Ribbon’s ServerList. When the spring-cloud-starter-zookeeper-discovery is used, Ribbon is auto-configured to use the ZookeeperServerList by default.

    \ No newline at end of file diff --git a/Finchley.M7/multi/multi_spring-cloud-zookeeper-service-registry.html b/Finchley.M7/multi/multi_spring-cloud-zookeeper-service-registry.html index 49295f08..6af36f8f 100644 --- a/Finchley.M7/multi/multi_spring-cloud-zookeeper-service-registry.html +++ b/Finchley.M7/multi/multi_spring-cloud-zookeeper-service-registry.html @@ -1,6 +1,6 @@ - 72. Spring Cloud Zookeeper and Service Registry

    72. Spring Cloud Zookeeper and Service Registry

    Spring Cloud Zookeeper implements the ServiceRegistry interface allowing developers to register arbitrary service in a programmatic way.

    The ServiceInstanceRegistration class offers a builder() method to create a Registration object that can be used by the ServiceRegistry.

    @Autowired
    +   73. Spring Cloud Zookeeper and Service Registry

    73. Spring Cloud Zookeeper and Service Registry

    Spring Cloud Zookeeper implements the ServiceRegistry interface allowing developers to register arbitrary service in a programmatic way.

    The ServiceInstanceRegistration class offers a builder() method to create a Registration object that can be used by the ServiceRegistry.

    @Autowired
     private ZookeeperServiceRegistry serviceRegistry;
     
     public void registerThings() {
    @@ -11,4 +11,4 @@
                 .name("/a/b/c/d/anotherservice")
                 .build();
         this.serviceRegistry.register(registration);
    -}

    72.1 Instance Status

    Netflix Eureka supports having instances registered with the server that are OUT_OF_SERVICE and not returned as active service instances. This is very useful for behaviors such as blue/green deployments. The Curator Service Discovery recipe does not support this behavior. Taking advantage of the flexible payload has let Spring Cloud Zookeeper implement OUT_OF_SERVICE by updating some specific metadata and then filtering on that metadata in the Ribbon ZookeeperServerList. The ZookeeperServerList filters out all non-null instance statuses that do not equal UP. If the instance status field is empty, it is considered UP for backwards compatibility. To change the status of an instance POST OUT_OF_SERVICE to the ServiceRegistry instance status actuator endpoint.

    $ http POST http://localhost:8081/service-registry status=OUT_OF_SERVICE
    NOTE: The above example uses the `http` command from https://httpie.org
    \ No newline at end of file +}

    73.1 Instance Status

    Netflix Eureka supports having instances registered with the server that are OUT_OF_SERVICE and not returned as active service instances. This is very useful for behaviors such as blue/green deployments. The Curator Service Discovery recipe does not support this behavior. Taking advantage of the flexible payload has let Spring Cloud Zookeeper implement OUT_OF_SERVICE by updating some specific metadata and then filtering on that metadata in the Ribbon ZookeeperServerList. The ZookeeperServerList filters out all non-null instance statuses that do not equal UP. If the instance status field is empty, it is considered UP for backwards compatibility. To change the status of an instance POST OUT_OF_SERVICE to the ServiceRegistry instance status actuator endpoint.

    $ http POST http://localhost:8081/service-registry status=OUT_OF_SERVICE
    NOTE: The above example uses the `http` command from https://httpie.org
    \ No newline at end of file diff --git a/Finchley.M7/multi/multi_spring-cloud.html b/Finchley.M7/multi/multi_spring-cloud.html index 42904ffb..3a86af53 100644 --- a/Finchley.M7/multi/multi_spring-cloud.html +++ b/Finchley.M7/multi/multi_spring-cloud.html @@ -1,3 +1,3 @@ - Spring Cloud

    Spring Cloud


    Table of Contents

    1. Features
    I. Cloud Native Applications
    2. Spring Cloud Context: Application Context Services
    2.1. The Bootstrap Application Context
    2.2. Application Context Hierarchies
    2.3. Changing the Location of Bootstrap Properties
    2.4. Overriding the Values of Remote Properties
    2.5. Customizing the Bootstrap Configuration
    2.6. Customizing the Bootstrap Property Sources
    2.7. Environment Changes
    2.8. Refresh Scope
    2.9. Encryption and Decryption
    2.10. Endpoints
    3. Spring Cloud Commons: Common Abstractions
    3.1. @EnableDiscoveryClient
    3.1.1. Health Indicator
    3.2. ServiceRegistry
    3.2.1. ServiceRegistry Auto-Registration
    3.2.2. Service Registry Actuator Endpoint
    3.3. Spring RestTemplate as a Load Balancer Client
    3.4. Spring WebClient as a Load Balancer Client
    3.4.1. Retrying Failed Requests
    3.5. Multiple RestTemplate objects
    3.6. Spring WebFlux WebClient as a Load Balancer Client
    3.7. Ignore Network Interfaces
    3.8. HTTP Client Factories
    3.9. Enabled Features
    3.9.1. Feature types
    3.9.2. Declaring features
    II. Spring Cloud Config
    4. Quick Start
    4.1. Client Side Usage
    5. Spring Cloud Config Server
    5.1. Environment Repository
    5.1.1. Git Backend
    Placeholders in Git URI
    Pattern Matching and Multiple Repositories
    Authentication
    Authentication with AWS CodeCommit
    Git SSH configuration using properties
    Placeholders in Git Search Paths
    Force pull in Git Repositories
    5.1.2. Version Control Backend Filesystem Use
    5.1.3. File System Backend
    5.1.4. Vault Backend
    Multiple Properties Sources
    5.1.5. Sharing Configuration With All Applications
    File Based Repositories
    Vault Server
    5.1.6. JDBC Backend
    5.1.7. Composite Environment Repositories
    Custom Composite Environment Repositories
    5.1.8. Property Overrides
    5.2. Health Indicator
    5.3. Security
    5.4. Encryption and Decryption
    5.5. Key Management
    5.6. Creating a Key Store for Testing
    5.7. Using Multiple Keys and Key Rotation
    5.8. Serving Encrypted Properties
    6. Serving Alternative Formats
    7. Serving Plain Text
    8. Embedding the Config Server
    9. Push Notifications and Spring Cloud Bus
    10. Spring Cloud Config Client
    10.1. Config First Bootstrap
    10.2. Discovery First Bootstrap
    10.3. Config Client Fail Fast
    10.4. Config Client Retry
    10.5. Locating Remote Configuration Resources
    10.6. Security
    10.6.1. Health Indicator
    10.6.2. Providing A Custom RestTemplate
    10.6.3. Vault
    10.7. Vault
    10.7.1. Nested Keys In Vault
    III. Spring Cloud Netflix
    11. Service Discovery: Eureka Clients
    11.1. How to Include Eureka Client
    11.2. Registering with Eureka
    11.3. Authenticating with the Eureka Server
    11.4. Status Page and Health Indicator
    11.5. Registering a Secure Application
    11.6. Eureka’s Health Checks
    11.7. Eureka Metadata for Instances and Clients
    11.7.1. Using Eureka on Cloudfoundry
    11.7.2. Using Eureka on AWS
    11.7.3. Changing the Eureka Instance ID
    11.8. Using the EurekaClient
    11.8.1. EurekaClient without Jersey
    11.9. Alternatives to the native Netflix EurekaClient
    11.10. Why is it so Slow to Register a Service?
    11.11. Zones
    12. Service Discovery: Eureka Server
    12.1. How to Include Eureka Server
    12.2. How to Run a Eureka Server
    12.3. High Availability, Zones and Regions
    12.4. Standalone Mode
    12.5. Peer Awareness
    12.6. Prefer IP Address
    13. Circuit Breaker: Hystrix Clients
    13.1. How to Include Hystrix
    13.2. Propagating the Security Context or using Spring Scopes
    13.3. Health Indicator
    13.4. Hystrix Metrics Stream
    14. Circuit Breaker: Hystrix Dashboard
    15. Hystrix Timeouts And Ribbon Clients
    15.1. How to Include Hystrix Dashboard
    15.2. Turbine
    15.3. Turbine Stream
    16. Client Side Load Balancer: Ribbon
    16.1. How to Include Ribbon
    16.2. Customizing the Ribbon Client
    16.3. Customizing default for all Ribbon Clients
    16.4. Customizing the Ribbon Client using properties
    16.5. Using Ribbon with Eureka
    16.6. Example: How to Use Ribbon Without Eureka
    16.7. Example: Disable Eureka use in Ribbon
    16.8. Using the Ribbon API Directly
    16.9. Caching of Ribbon Configuration
    16.10. How to Configure Hystrix thread pools
    16.11. How to Provide a Key to Ribbon’s IRule
    17. External Configuration: Archaius
    18. Router and Filter: Zuul
    18.1. How to Include Zuul
    18.2. Embedded Zuul Reverse Proxy
    18.3. Zuul Http Client
    18.4. Cookies and Sensitive Headers
    18.5. Ignored Headers
    18.6. Management Endpoints
    18.6.1. Routes Endpoint
    18.6.2. Filters Endpoint
    18.7. Strangulation Patterns and Local Forwards
    18.8. Uploading Files through Zuul
    18.9. Query String Encoding
    18.10. Plain Embedded Zuul
    18.11. Disable Zuul Filters
    18.12. Providing Hystrix Fallbacks For Routes
    18.13. Zuul Timeouts
    18.14. Rewriting Location header
    18.15. Zuul Developer Guide
    18.15.1. The Zuul Servlet
    18.15.2. Zuul RequestContext
    18.15.3. @EnableZuulProxy vs. @EnableZuulServer
    18.15.4. @EnableZuulServer Filters
    18.15.5. @EnableZuulProxy Filters
    18.15.6. Custom Zuul Filter examples
    18.15.7. How to Write a Pre Filter
    18.15.8. How to Write a Route Filter
    18.15.9. How to Write a Post Filter
    18.15.10. How Zuul Errors Work
    18.15.11. Zuul Eager Application Context Loading
    19. Polyglot support with Sidecar
    20. Metrics Backend: Atlas
    20.1. Using Atlas
    21. Retrying Failed Requests
    21.1. BackOff Policies
    21.2. Configuration
    21.2.1. Zuul
    22. HTTP Clients
    IV. Spring Cloud Stream
    23. Introducing Spring Cloud Stream
    24. Main Concepts
    24.1. Application Model
    24.1.1. Fat JAR
    24.2. The Binder Abstraction
    24.3. Persistent Publish-Subscribe Support
    24.4. Consumer Groups
    24.5. Consumer Types
    24.5.1. Durability
    24.6. Partitioning Support
    25. Programming Model
    25.1. Declaring and Binding Producers and Consumers
    25.1.1. Triggering Binding Via @EnableBinding
    25.1.2. @Input and @Output
    Customizing Channel Names
    Source, Sink, and Processor
    25.1.3. Accessing Bound Channels
    Injecting the Bound Interfaces
    Injecting Channels Directly
    25.1.4. Producing and Consuming Messages
    Native Spring Integration Support
    Spring Integration Error Channel Support
    Message Channel Binders and Error Channels
    Using @StreamListener for Automatic Content Type Handling
    Using @StreamListener for dispatching messages to multiple methods
    Using Polled Consumers
    25.1.5. Reactive Programming Support
    Reactor-based handlers
    Reactive Sources
    25.1.6. Aggregation
    Configuring aggregate application
    Configuring binding service properties for non self contained aggregate application
    26. Binders
    26.1. Producers and Consumers
    26.2. Binder SPI
    26.3. Binder Detection
    26.3.1. Classpath Detection
    26.4. Multiple Binders on the Classpath
    26.5. Connecting to Multiple Systems
    26.6. Binder configuration properties
    27. Configuration Options
    27.1. Spring Cloud Stream Properties
    27.2. Binding Properties
    27.2.1. Properties for Use of Spring Cloud Stream
    27.2.2. Consumer properties
    27.2.3. Producer Properties
    27.3. Using dynamically bound destinations
    28. Content Type and Transformation
    28.1. MIME types
    28.2. Channel contentType and Message Headers
    28.3. ContentType handling for output channels
    28.4. ContentType handling for input channels
    28.5. Customizing message conversion
    28.6. @StreamListener and Message Conversion
    29. Schema evolution support
    29.1. Apache Avro Message Converters
    29.2. Converters with schema support
    29.3. Schema Registry Support
    29.4. Schema Registry Server
    29.4.1. Schema Registry Server API
    POST /
    GET /{subject}/{format}/{version}
    GET /{subject}/{format}
    GET /schemas/{id}
    DELETE /{subject}/{format}/{version}
    DELETE /schemas/{id}
    DELETE /{subject}
    29.5. Schema Registry Client
    29.5.1. Using Confluent’s Schema Registry
    29.5.2. Schema Registry Client properties
    29.6. Avro Schema Registry Client Message Converters
    29.6.1. Avro Schema Registry Message Converter properties
    29.7. Schema Registration and Resolution
    29.7.1. Schema Registration Process (Serialization)
    29.7.2. Schema Resolution Process (Deserialization)
    30. Inter-Application Communication
    30.1. Connecting Multiple Application Instances
    30.2. Instance Index and Instance Count
    30.3. Partitioning
    30.3.1. Configuring Output Bindings for Partitioning
    Configuring Input Bindings for Partitioning
    31. Testing
    31.1. Disabling the test binder autoconfiguration
    32. Health Indicator
    33. Metrics Emitter
    34. Samples
    35. Getting Started
    35.1. Deploying Stream applications on CloudFoundry
    V. Binder Implementations
    36. Apache Kafka Binder
    36.1. Usage
    36.2. Apache Kafka Binder Overview
    36.3. Configuration Options
    36.3.1. Kafka Binder Properties
    36.3.2. Kafka Consumer Properties
    36.3.3. Kafka Producer Properties
    36.3.4. Usage examples
    Example: Setting autoCommitOffset false and relying on manual acking.
    Example: security configuration
    Example: Pausing and Resuming the Consumer
    Using the binder with Apache Kafka 0.10
    Excluding Kafka broker jar from the classpath of the binder based application
    36.4. Error Channels
    36.5. Kafka Metrics
    36.6. Dead-Letter Topic Processing
    36.7. Partitioning with the Kafka Binder
    36.8. Kafka Streams Binding Capabilities of Spring Cloud Stream
    36.8.1. Usage example of high level streams DSL
    36.8.2. Multiple Input bindings on the inbound
    36.8.3. Support for branching in Kafka Streams API
    36.8.4. Message conversion in Spring Cloud Stream Kafka Streams applications
    Outbound serialization
    Inbound Deserialization
    Error handling on Deserialization exceptions
    Handling Non-Deserialization exceptions
    36.8.5. Support for interactive queries
    36.8.6. Kafka Streams properties
    37. RabbitMQ Binder
    37.1. Usage
    37.2. RabbitMQ Binder Overview
    37.3. Configuration Options
    37.3.1. RabbitMQ Binder Properties
    37.3.2. RabbitMQ Consumer Properties
    37.3.3. Rabbit Producer Properties
    37.4. Retry With the RabbitMQ Binder
    37.4.1. Overview
    37.4.2. Putting it All Together
    37.5. Error Channels
    37.6. Dead-Letter Queue Processing
    37.6.1. Non-Partitioned Destinations
    37.6.2. Partitioned Destinations
    republishToDlq=false
    republishToDlq=true
    37.7. Partitioning with the RabbitMQ Binder
    VI. Spring Cloud Bus
    38. Quick Start
    39. Addressing an Instance
    40. Addressing all instances of a service
    41. Service ID must be unique
    42. Customizing the Message Broker
    43. Tracing Bus Events
    44. Broadcasting Your Own Events
    44.1. Registering events in custom packages
    VII. Spring Cloud Sleuth
    45. Introduction
    45.1. Terminology
    45.2. Purpose
    45.2.1. Distributed tracing with Zipkin
    45.2.2. Visualizing errors
    45.2.3. Distributed tracing with Brave
    45.2.4. Live examples
    45.2.5. Log correlation
    JSON Logback with Logstash
    45.2.6. Propagating Span Context
    Baggage vs. Span Tags
    45.3. Adding to the project
    45.3.1. Only Sleuth (log correlation)
    45.3.2. Sleuth with Zipkin via HTTP
    45.3.3. Sleuth with Zipkin via RabbitMQ or Kafka
    46. Additional resources
    47. Features
    47.1. Introduction to Brave
    47.1.1. Tracing
    47.1.2. Tracing
    47.1.3. Local Tracing
    47.1.4. Customizing spans
    47.1.5. Implicitly looking up the current span
    47.1.6. RPC tracing
    One-Way tracing
    48. Sampling
    48.1. Declarative sampling
    48.2. Custom sampling
    48.3. Sampling in Spring Cloud Sleuth
    49. Propagation
    49.1. Propagating extra fields
    49.1.1. Prefixed fields
    49.1.2. Extracting a propagated context
    49.1.3. Sharing span IDs between client and server
    49.1.4. Implementing Propagation
    50. Current Tracing Component
    51. Current Span
    51.1. Setting a span in scope manually
    52. Instrumentation
    53. Span lifecycle
    53.1. Creating and finishing spans
    53.2. Continuing spans
    53.3. Creating spans with an explicit parent
    54. Naming spans
    54.1. @SpanName annotation
    54.2. toString() method
    55. Managing spans with annotations
    55.1. Rationale
    55.2. Creating new spans
    55.3. Continuing spans
    55.4. More advanced tag setting
    55.4.1. Custom extractor
    55.4.2. Resolving expressions for value
    55.4.3. Using toString method
    56. Customizations
    56.1. Spring Integration
    56.2. HTTP
    56.3. TraceFilter
    56.4. Custom service name
    56.5. Customization of reported spans
    56.6. Host locator
    57. Sending spans to Zipkin
    58. Zipkin Stream Span Consumer
    59. Integrations
    59.1. OpenTracing
    59.2. Runnable and Callable
    59.3. Hystrix
    59.3.1. Custom Concurrency Strategy
    59.3.2. Manual Command setting
    59.4. RxJava
    59.5. HTTP integration
    59.5.1. HTTP Filter
    59.5.2. HandlerInterceptor
    59.5.3. Async Servlet support
    59.5.4. WebFlux support
    59.6. HTTP client integration
    59.6.1. Synchronous Rest Template
    59.6.2. Asynchronous Rest Template
    Multiple Asynchronous Rest Templates
    59.6.3. WebClient
    59.6.4. Traverson
    59.7. Feign
    59.8. Asynchronous communication
    59.8.1. @Async annotated methods
    59.8.2. @Scheduled annotated methods
    59.8.3. Executor, ExecutorService and ScheduledExecutorService
    Customization of Executors
    59.9. Messaging
    59.10. Zuul
    60. Running examples
    VIII. Spring Cloud Consul
    61. Install Consul
    62. Consul Agent
    63. Service Discovery with Consul
    63.1. How to activate
    63.2. Registering with Consul
    63.3. HTTP Health Check
    63.3.1. Metadata and Consul tags
    63.3.2. Making the Consul Instance ID Unique
    63.4. Looking up services
    63.4.1. Using Ribbon
    63.4.2. Using the DiscoveryClient
    64. Distributed Configuration with Consul
    64.1. How to activate
    64.2. Customizing
    64.3. Config Watch
    64.4. YAML or Properties with Config
    64.5. git2consul with Config
    64.6. Fail Fast
    65. Consul Retry
    66. Spring Cloud Bus with Consul
    66.1. How to activate
    67. Circuit Breaker with Hystrix
    68. Hystrix metrics aggregation with Turbine and Consul
    IX. Spring Cloud Zookeeper
    69. Install Zookeeper
    70. Service Discovery with Zookeeper
    70.1. How to activate
    70.2. Registering with Zookeeper
    70.3. Using the DiscoveryClient
    71. Using Spring Cloud Zookeeper with Spring Cloud Netflix Components
    71.1. Ribbon with Zookeeper
    72. Spring Cloud Zookeeper and Service Registry
    72.1. Instance Status
    73. Zookeeper Dependencies
    73.1. Using the Zookeeper Dependencies
    73.2. How to activate Zookeeper Dependencies
    73.3. Setting up Zookeeper Dependencies
    73.3.1. Aliases
    73.3.2. Path
    73.3.3. Load balancer type
    73.3.4. Content-Type template and version
    73.3.5. Default headers
    73.3.6. Obligatory dependencies
    73.3.7. Stubs
    73.4. Configuring Spring Cloud Zookeeper Dependencies
    74. Spring Cloud Zookeeper Dependency Watcher
    74.1. How to activate
    74.2. Registering a listener
    74.3. Presence Checker
    75. Distributed Configuration with Zookeeper
    75.1. How to activate
    75.2. Customizing
    75.3. ACLs
    X. Spring Cloud Security
    76. Quickstart
    76.1. OAuth2 Single Sign On
    76.2. OAuth2 Protected Resource
    77. More Detail
    77.1. Single Sign On
    77.2. Token Relay
    77.2.1. Client Token Relay
    77.2.2. Client Token Relay in Zuul Proxy
    77.2.3. Resource Server Token Relay
    78. Configuring Authentication Downstream of a Zuul Proxy
    XI. Spring Cloud for Cloud Foundry
    79. Discovery
    80. Single Sign On
    XII. Spring Cloud Contract
    81. Spring Cloud Contract
    82. Spring Cloud Contract Verifier Introduction
    82.1. Why a Contract Verifier?
    82.1.1. Testing issues
    82.2. Purposes
    82.3. How It Works
    82.3.1. Defining the contract
    82.3.2. Client Side
    82.3.3. Server Side
    82.4. Step-by-step Guide to Consumer Driven Contracts (CDC)
    82.4.1. Technical note
    82.4.2. Consumer side (Loan Issuance)
    82.4.3. Producer side (Fraud Detection server)
    82.4.4. Consumer Side (Loan Issuance) Final Step
    82.5. Dependencies
    82.6. Additional Links
    82.6.1. Spring Cloud Contract video
    82.6.2. Readings
    82.7. Samples
    83. Spring Cloud Contract FAQ
    83.1. Why use Spring Cloud Contract Verifier and not X ?
    83.2. I don’t want to write a contract in Groovy!
    83.3. What is this value(consumer(), producer()) ?
    83.4. How to do Stubs versioning?
    83.4.1. API Versioning
    83.4.2. JAR versioning
    83.4.3. Dev or prod stubs
    83.5. Common repo with contracts
    83.5.1. Repo structure
    83.5.2. Workflow
    83.5.3. Consumer
    83.5.4. Producer
    83.5.5. How can I define messaging contracts per topic not per producer?
    For Maven Project
    For Gradle Project
    83.6. Can I have multiple base classes for tests?
    83.7. How can I debug the request/response being sent by the generated tests client?
    83.7.1. How can I debug the mapping/request/response being sent by WireMock?
    83.7.2. How can I see what got registered in the HTTP server stub?
    83.7.3. Can I reference the request from the response?
    83.7.4. Can I reference text from file?
    84. Spring Cloud Contract Verifier Setup
    84.1. Gradle Project
    84.1.1. Prerequisites
    84.1.2. Add Gradle Plugin with Dependencies
    84.1.3. Gradle and Rest Assured 2.0
    84.1.4. Snapshot Versions for Gradle
    84.1.5. Add stubs
    84.1.6. Run the Plugin
    84.1.7. Default Setup
    84.1.8. Configure Plugin
    84.1.9. Configuration Options
    84.1.10. Single Base Class for All Tests
    84.1.11. Different Base Classes for Contracts
    84.1.12. Invoking Generated Tests
    84.1.13. Spring Cloud Contract Verifier on the Consumer Side
    84.2. Maven Project
    84.2.1. Add maven plugin
    84.2.2. Maven and Rest Assured 2.0
    84.2.3. Snapshot versions for Maven
    84.2.4. Add stubs
    84.2.5. Run plugin
    84.2.6. Configure plugin
    84.2.7. Configuration Options
    84.2.8. Single Base Class for All Tests
    84.2.9. Different base classes for contracts
    84.2.10. Invoking generated tests
    84.2.11. Maven Plugin and STS
    84.3. Stubs and Transitive Dependencies
    84.4. CI Server setup
    84.5. Scenarios
    84.6. Docker Project
    84.6.1. Short intro to Maven, JARs and Binary storage
    84.6.2. How it works
    Environment Variables
    84.6.3. Example of usage
    84.6.4. Server side (nodejs)
    85. Spring Cloud Contract Verifier Messaging
    85.1. Integrations
    85.2. Manual Integration Testing
    85.3. Publisher-Side Test Generation
    85.3.1. Scenario 1: No Input Message
    85.3.2. Scenario 2: Output Triggered by Input
    85.3.3. Scenario 3: No Output Message
    85.4. Consumer Stub Generation
    86. Spring Cloud Contract Stub Runner
    86.1. Snapshot versions
    86.2. Publishing Stubs as JARs
    86.3. Stub Runner Core
    86.3.1. Retrieving stubs
    Stub downloading
    Classpath scanning
    86.3.2. Running stubs
    Limitations
    Running using main app
    HTTP Stubs
    Viewing registered mappings
    Messaging Stubs
    86.4. Stub Runner JUnit Rule
    86.4.1. Maven settings
    86.4.2. Providing fixed ports
    86.4.3. Fluent API
    86.4.4. Stub Runner with Spring
    86.5. Stub Runner Spring Cloud
    86.5.1. Stubbing Service Discovery
    Test profiles and service discovery
    86.5.2. Additional Configuration
    86.6. Stub Runner Boot Application
    86.6.1. How to use it?
    Stub Runner Server
    Stub Runner Server Fat Jar
    Spring Cloud CLI
    86.6.2. Endpoints
    HTTP
    Messaging
    86.6.3. Example
    86.6.4. Stub Runner Boot with Service Discovery
    86.7. Stubs Per Consumer
    86.8. Common
    86.8.1. Common Properties for JUnit and Spring
    86.8.2. Stub Runner Stubs IDs
    86.9. Stub Runner Docker
    86.9.1. How to use it
    86.9.2. Example of client side usage in a non JVM project
    87. Stub Runner for Messaging
    87.1. Stub triggering
    87.1.1. Trigger by Label
    87.1.2. Trigger by Group and Artifact Ids
    87.1.3. Trigger by Artifact Ids
    87.1.4. Trigger All Messages
    87.2. Stub Runner Integration
    87.2.1. Adding the Runner to the Project
    87.2.2. Disabling the functionality
    Scenario 1 (no input message)
    Scenario 2 (output triggered by input)
    Scenario 3 (input with no output)
    87.3. Stub Runner Stream
    87.3.1. Adding the Runner to the Project
    87.3.2. Disabling the functionality
    Scenario 1 (no input message)
    Scenario 2 (output triggered by input)
    Scenario 3 (input with no output)
    87.4. Stub Runner Spring AMQP
    87.4.1. Adding the Runner to the Project
    Triggering the message
    Spring AMQP Test Configuration
    88. Contract DSL
    88.1. Limitations
    88.2. Common Top-Level elements
    88.2.1. Description
    88.2.2. Name
    88.2.3. Ignoring Contracts
    88.2.4. Passing Values from Files
    88.2.5. HTTP Top-Level Elements
    88.3. Request
    88.4. Response
    88.5. Dynamic properties
    88.5.1. Dynamic properties inside the body
    88.5.2. Regular expressions
    88.5.3. Passing Optional Parameters
    88.5.4. Executing Custom Methods on the Server Side
    88.5.5. Referencing the Request from the Response
    88.5.6. Registering Your Own WireMock Extension
    88.5.7. Dynamic Properties in the Matchers Sections
    88.6. JAX-RS Support
    88.7. Async Support
    88.8. Working with Context Paths
    88.9. Messaging Top-Level Elements
    88.9.1. Output Triggered by a Method
    88.9.2. Output Triggered by a Message
    88.9.3. Consumer/Producer
    88.9.4. Common
    88.10. Multiple Contracts in One File
    89. Customization
    89.1. Extending the DSL
    89.1.1. Common JAR
    89.1.2. Adding the Dependency to the Project
    89.1.3. Test the Dependency in the Project’s Dependencies
    89.1.4. Test a Dependency in the Plugin’s Dependencies
    89.1.5. Referencing classes in DSLs
    90. Using the Pluggable Architecture
    90.1. Custom Contract Converter
    90.1.1. Pact Converter
    90.1.2. Pact Contract
    90.1.3. Pact for Producers
    90.1.4. Pact for Consumers
    90.2. Using the Custom Test Generator
    90.3. Using the Custom Stub Generator
    90.4. Using the Custom Stub Runner
    90.5. Using the Custom Stub Downloader
    91. Spring Cloud Contract WireMock
    91.1. Registering Stubs Automatically
    91.2. Using Files to Specify the Stub Bodies
    91.3. Alternative: Using JUnit Rules
    91.4. Relaxed SSL Validation for Rest Template
    91.5. WireMock and Spring MVC Mocks
    91.6. Customization of WireMock configuration
    91.7. Generating Stubs using REST Docs
    91.8. Generating Contracts by Using REST Docs
    92. Migrations
    92.1. 1.0.x → 1.1.x
    92.1.1. New structure of generated stubs
    92.2. 1.1.x → 1.2.x
    92.2.1. Custom HttpServerStub
    92.2.2. New packages for generated tests
    92.2.3. New Methods in TemplateProcessor
    92.2.4. RestAssured 3.0
    92.3. 1.2.x → 2.0.x
    92.3.1. No Camel support
    93. Links
    XIII. Spring Cloud Vault
    94. Quick Start
    95. Client Side Usage
    95.1. Authentication
    96. Authentication methods
    96.1. Token authentication
    96.2. AppId authentication
    96.2.1. Custom UserId
    96.3. AppRole authentication
    96.4. AWS-EC2 authentication
    96.5. AWS-IAM authentication
    96.6. TLS certificate authentication
    96.7. Cubbyhole authentication
    96.8. Kubernetes authentication
    97. Secret Backends
    97.1. Generic Backend
    97.2. Consul
    97.3. RabbitMQ
    97.4. AWS
    98. Database backends
    98.1. Database
    98.2. Apache Cassandra
    98.3. MongoDB
    98.4. MySQL
    98.5. PostgreSQL
    99. Configure PropertySourceLocator behavior
    100. Service Registry Configuration
    101. Vault Client Fail Fast
    102. Vault Client SSL configuration
    103. Lease lifecycle management (renewal and revocation)
    XIV. Appendix: Compendium of Configuration Properties
    \ No newline at end of file + Spring Cloud

    Spring Cloud


    Table of Contents

    1. Features
    I. Cloud Native Applications
    2. Spring Cloud Context: Application Context Services
    2.1. The Bootstrap Application Context
    2.2. Application Context Hierarchies
    2.3. Changing the Location of Bootstrap Properties
    2.4. Overriding the Values of Remote Properties
    2.5. Customizing the Bootstrap Configuration
    2.6. Customizing the Bootstrap Property Sources
    2.7. Environment Changes
    2.8. Refresh Scope
    2.9. Encryption and Decryption
    2.10. Endpoints
    3. Spring Cloud Commons: Common Abstractions
    3.1. @EnableDiscoveryClient
    3.1.1. Health Indicator
    3.2. ServiceRegistry
    3.2.1. ServiceRegistry Auto-Registration
    3.2.2. Service Registry Actuator Endpoint
    3.3. Spring RestTemplate as a Load Balancer Client
    3.4. Spring WebClient as a Load Balancer Client
    3.4.1. Retrying Failed Requests
    3.5. Multiple RestTemplate objects
    3.6. Spring WebFlux WebClient as a Load Balancer Client
    3.7. Ignore Network Interfaces
    3.8. HTTP Client Factories
    3.9. Enabled Features
    3.9.1. Feature types
    3.9.2. Declaring features
    II. Spring Cloud Config
    4. Quick Start
    4.1. Client Side Usage
    5. Spring Cloud Config Server
    5.1. Environment Repository
    5.1.1. Git Backend
    Placeholders in Git URI
    Pattern Matching and Multiple Repositories
    Authentication
    Authentication with AWS CodeCommit
    Git SSH configuration using properties
    Placeholders in Git Search Paths
    Force pull in Git Repositories
    5.1.2. Version Control Backend Filesystem Use
    5.1.3. File System Backend
    5.1.4. Vault Backend
    Multiple Properties Sources
    5.1.5. Sharing Configuration With All Applications
    File Based Repositories
    Vault Server
    5.1.6. JDBC Backend
    5.1.7. Composite Environment Repositories
    Custom Composite Environment Repositories
    5.1.8. Property Overrides
    5.2. Health Indicator
    5.3. Security
    5.4. Encryption and Decryption
    5.5. Key Management
    5.6. Creating a Key Store for Testing
    5.7. Using Multiple Keys and Key Rotation
    5.8. Serving Encrypted Properties
    6. Serving Alternative Formats
    7. Serving Plain Text
    8. Embedding the Config Server
    9. Push Notifications and Spring Cloud Bus
    10. Spring Cloud Config Client
    10.1. Config First Bootstrap
    10.2. Discovery First Bootstrap
    10.3. Config Client Fail Fast
    10.4. Config Client Retry
    10.5. Locating Remote Configuration Resources
    10.6. Security
    10.6.1. Health Indicator
    10.6.2. Providing A Custom RestTemplate
    10.6.3. Vault
    10.7. Vault
    10.7.1. Nested Keys In Vault
    III. Spring Cloud Netflix
    11. Service Discovery: Eureka Clients
    11.1. How to Include Eureka Client
    11.2. Registering with Eureka
    11.3. Authenticating with the Eureka Server
    11.4. Status Page and Health Indicator
    11.5. Registering a Secure Application
    11.6. Eureka’s Health Checks
    11.7. Eureka Metadata for Instances and Clients
    11.7.1. Using Eureka on Cloudfoundry
    11.7.2. Using Eureka on AWS
    11.7.3. Changing the Eureka Instance ID
    11.8. Using the EurekaClient
    11.8.1. EurekaClient without Jersey
    11.9. Alternatives to the native Netflix EurekaClient
    11.10. Why is it so Slow to Register a Service?
    11.11. Zones
    12. Service Discovery: Eureka Server
    12.1. How to Include Eureka Server
    12.2. How to Run a Eureka Server
    12.3. High Availability, Zones and Regions
    12.4. Standalone Mode
    12.5. Peer Awareness
    12.6. Prefer IP Address
    13. Circuit Breaker: Hystrix Clients
    13.1. How to Include Hystrix
    13.2. Propagating the Security Context or using Spring Scopes
    13.3. Health Indicator
    13.4. Hystrix Metrics Stream
    14. Circuit Breaker: Hystrix Dashboard
    15. Hystrix Timeouts And Ribbon Clients
    15.1. How to Include Hystrix Dashboard
    15.2. Turbine
    15.3. Turbine Stream
    16. Client Side Load Balancer: Ribbon
    16.1. How to Include Ribbon
    16.2. Customizing the Ribbon Client
    16.3. Customizing default for all Ribbon Clients
    16.4. Customizing the Ribbon Client using properties
    16.5. Using Ribbon with Eureka
    16.6. Example: How to Use Ribbon Without Eureka
    16.7. Example: Disable Eureka use in Ribbon
    16.8. Using the Ribbon API Directly
    16.9. Caching of Ribbon Configuration
    16.10. How to Configure Hystrix thread pools
    16.11. How to Provide a Key to Ribbon’s IRule
    17. External Configuration: Archaius
    18. Router and Filter: Zuul
    18.1. How to Include Zuul
    18.2. Embedded Zuul Reverse Proxy
    18.3. Zuul Http Client
    18.4. Cookies and Sensitive Headers
    18.5. Ignored Headers
    18.6. Management Endpoints
    18.6.1. Routes Endpoint
    18.6.2. Filters Endpoint
    18.7. Strangulation Patterns and Local Forwards
    18.8. Uploading Files through Zuul
    18.9. Query String Encoding
    18.10. Plain Embedded Zuul
    18.11. Disable Zuul Filters
    18.12. Providing Hystrix Fallbacks For Routes
    18.13. Zuul Timeouts
    18.14. Rewriting Location header
    18.15. Zuul Developer Guide
    18.15.1. The Zuul Servlet
    18.15.2. Zuul RequestContext
    18.15.3. @EnableZuulProxy vs. @EnableZuulServer
    18.15.4. @EnableZuulServer Filters
    18.15.5. @EnableZuulProxy Filters
    18.15.6. Custom Zuul Filter examples
    18.15.7. How to Write a Pre Filter
    18.15.8. How to Write a Route Filter
    18.15.9. How to Write a Post Filter
    18.15.10. How Zuul Errors Work
    18.15.11. Zuul Eager Application Context Loading
    19. Polyglot support with Sidecar
    20. Metrics Backend: Atlas
    20.1. Using Atlas
    21. Retrying Failed Requests
    21.1. BackOff Policies
    21.2. Configuration
    21.2.1. Zuul
    22. HTTP Clients
    IV. Spring Cloud OpenFeign
    23. Declarative REST Client: Feign
    23.1. How to Include Feign
    23.2. Overriding Feign Defaults
    23.3. Creating Feign Clients Manually
    23.4. Feign Hystrix Support
    23.5. Feign Hystrix Fallbacks
    23.6. Feign and @Primary
    23.7. Feign Inheritance Support
    23.8. Feign request/response compression
    23.9. Feign logging
    V. Spring Cloud Stream
    24. Introducing Spring Cloud Stream
    25. Main Concepts
    25.1. Application Model
    25.1.1. Fat JAR
    25.2. The Binder Abstraction
    25.3. Persistent Publish-Subscribe Support
    25.4. Consumer Groups
    25.5. Consumer Types
    25.5.1. Durability
    25.6. Partitioning Support
    26. Programming Model
    26.1. Declaring and Binding Producers and Consumers
    26.1.1. Triggering Binding Via @EnableBinding
    26.1.2. @Input and @Output
    Customizing Channel Names
    Source, Sink, and Processor
    26.1.3. Accessing Bound Channels
    Injecting the Bound Interfaces
    Injecting Channels Directly
    26.1.4. Producing and Consuming Messages
    Native Spring Integration Support
    Spring Integration Error Channel Support
    Message Channel Binders and Error Channels
    Using @StreamListener for Automatic Content Type Handling
    Using @StreamListener for dispatching messages to multiple methods
    Using Polled Consumers
    26.1.5. Reactive Programming Support
    Reactor-based handlers
    Reactive Sources
    26.1.6. Aggregation
    Configuring aggregate application
    Configuring binding service properties for non self contained aggregate application
    27. Binders
    27.1. Producers and Consumers
    27.2. Binder SPI
    27.3. Binder Detection
    27.3.1. Classpath Detection
    27.4. Multiple Binders on the Classpath
    27.5. Connecting to Multiple Systems
    27.6. Binder configuration properties
    28. Configuration Options
    28.1. Spring Cloud Stream Properties
    28.2. Binding Properties
    28.2.1. Properties for Use of Spring Cloud Stream
    28.2.2. Consumer properties
    28.2.3. Producer Properties
    28.3. Using dynamically bound destinations
    29. Content Type and Transformation
    29.1. MIME types
    29.2. Channel contentType and Message Headers
    29.3. ContentType handling for output channels
    29.4. ContentType handling for input channels
    29.5. Customizing message conversion
    29.6. @StreamListener and Message Conversion
    30. Schema evolution support
    30.1. Apache Avro Message Converters
    30.2. Converters with schema support
    30.3. Schema Registry Support
    30.4. Schema Registry Server
    30.4.1. Schema Registry Server API
    POST /
    GET /{subject}/{format}/{version}
    GET /{subject}/{format}
    GET /schemas/{id}
    DELETE /{subject}/{format}/{version}
    DELETE /schemas/{id}
    DELETE /{subject}
    30.5. Schema Registry Client
    30.5.1. Using Confluent’s Schema Registry
    30.5.2. Schema Registry Client properties
    30.6. Avro Schema Registry Client Message Converters
    30.6.1. Avro Schema Registry Message Converter properties
    30.7. Schema Registration and Resolution
    30.7.1. Schema Registration Process (Serialization)
    30.7.2. Schema Resolution Process (Deserialization)
    31. Inter-Application Communication
    31.1. Connecting Multiple Application Instances
    31.2. Instance Index and Instance Count
    31.3. Partitioning
    31.3.1. Configuring Output Bindings for Partitioning
    Configuring Input Bindings for Partitioning
    32. Testing
    32.1. Disabling the test binder autoconfiguration
    33. Health Indicator
    34. Metrics Emitter
    35. Samples
    36. Getting Started
    36.1. Deploying Stream applications on CloudFoundry
    VI. Binder Implementations
    37. Apache Kafka Binder
    37.1. Usage
    37.2. Apache Kafka Binder Overview
    37.3. Configuration Options
    37.3.1. Kafka Binder Properties
    37.3.2. Kafka Consumer Properties
    37.3.3. Kafka Producer Properties
    37.3.4. Usage examples
    Example: Setting autoCommitOffset false and relying on manual acking.
    Example: security configuration
    Example: Pausing and Resuming the Consumer
    Using the binder with Apache Kafka 0.10
    Excluding Kafka broker jar from the classpath of the binder based application
    37.4. Error Channels
    37.5. Kafka Metrics
    37.6. Dead-Letter Topic Processing
    37.7. Partitioning with the Kafka Binder
    37.8. Kafka Streams Binding Capabilities of Spring Cloud Stream
    37.8.1. Usage example of high level streams DSL
    37.8.2. Multiple Input bindings on the inbound
    37.8.3. Support for branching in Kafka Streams API
    37.8.4. Message conversion in Spring Cloud Stream Kafka Streams applications
    Outbound serialization
    Inbound Deserialization
    Error handling on Deserialization exceptions
    Handling Non-Deserialization exceptions
    37.8.5. Support for interactive queries
    37.8.6. Kafka Streams properties
    38. RabbitMQ Binder
    38.1. Usage
    38.2. RabbitMQ Binder Overview
    38.3. Configuration Options
    38.3.1. RabbitMQ Binder Properties
    38.3.2. RabbitMQ Consumer Properties
    38.3.3. Rabbit Producer Properties
    38.4. Retry With the RabbitMQ Binder
    38.4.1. Overview
    38.4.2. Putting it All Together
    38.5. Error Channels
    38.6. Dead-Letter Queue Processing
    38.6.1. Non-Partitioned Destinations
    38.6.2. Partitioned Destinations
    republishToDlq=false
    republishToDlq=true
    38.7. Partitioning with the RabbitMQ Binder
    VII. Spring Cloud Bus
    39. Quick Start
    40. Addressing an Instance
    41. Addressing all instances of a service
    42. Service ID must be unique
    43. Customizing the Message Broker
    44. Tracing Bus Events
    45. Broadcasting Your Own Events
    45.1. Registering events in custom packages
    VIII. Spring Cloud Sleuth
    46. Introduction
    46.1. Terminology
    46.2. Purpose
    46.2.1. Distributed tracing with Zipkin
    46.2.2. Visualizing errors
    46.2.3. Distributed tracing with Brave
    46.2.4. Live examples
    46.2.5. Log correlation
    JSON Logback with Logstash
    46.2.6. Propagating Span Context
    Baggage vs. Span Tags
    46.3. Adding to the project
    46.3.1. Only Sleuth (log correlation)
    46.3.2. Sleuth with Zipkin via HTTP
    46.3.3. Sleuth with Zipkin via RabbitMQ or Kafka
    47. Additional resources
    48. Features
    48.1. Introduction to Brave
    48.1.1. Tracing
    48.1.2. Tracing
    48.1.3. Local Tracing
    48.1.4. Customizing spans
    48.1.5. Implicitly looking up the current span
    48.1.6. RPC tracing
    One-Way tracing
    49. Sampling
    49.1. Declarative sampling
    49.2. Custom sampling
    49.3. Sampling in Spring Cloud Sleuth
    50. Propagation
    50.1. Propagating extra fields
    50.1.1. Prefixed fields
    50.1.2. Extracting a propagated context
    50.1.3. Sharing span IDs between client and server
    50.1.4. Implementing Propagation
    51. Current Tracing Component
    52. Current Span
    52.1. Setting a span in scope manually
    53. Instrumentation
    54. Span lifecycle
    54.1. Creating and finishing spans
    54.2. Continuing spans
    54.3. Creating spans with an explicit parent
    55. Naming spans
    55.1. @SpanName annotation
    55.2. toString() method
    56. Managing spans with annotations
    56.1. Rationale
    56.2. Creating new spans
    56.3. Continuing spans
    56.4. More advanced tag setting
    56.4.1. Custom extractor
    56.4.2. Resolving expressions for value
    56.4.3. Using toString method
    57. Customizations
    57.1. Spring Integration
    57.2. HTTP
    57.3. TraceFilter
    57.4. Custom service name
    57.5. Customization of reported spans
    57.6. Host locator
    58. Sending spans to Zipkin
    59. Zipkin Stream Span Consumer
    60. Integrations
    60.1. OpenTracing
    60.2. Runnable and Callable
    60.3. Hystrix
    60.3.1. Custom Concurrency Strategy
    60.3.2. Manual Command setting
    60.4. RxJava
    60.5. HTTP integration
    60.5.1. HTTP Filter
    60.5.2. HandlerInterceptor
    60.5.3. Async Servlet support
    60.5.4. WebFlux support
    60.6. HTTP client integration
    60.6.1. Synchronous Rest Template
    60.6.2. Asynchronous Rest Template
    Multiple Asynchronous Rest Templates
    60.6.3. WebClient
    60.6.4. Traverson
    60.7. Feign
    60.8. Asynchronous communication
    60.8.1. @Async annotated methods
    60.8.2. @Scheduled annotated methods
    60.8.3. Executor, ExecutorService and ScheduledExecutorService
    Customization of Executors
    60.9. Messaging
    60.10. Zuul
    61. Running examples
    IX. Spring Cloud Consul
    62. Install Consul
    63. Consul Agent
    64. Service Discovery with Consul
    64.1. How to activate
    64.2. Registering with Consul
    64.3. HTTP Health Check
    64.3.1. Metadata and Consul tags
    64.3.2. Making the Consul Instance ID Unique
    64.4. Looking up services
    64.4.1. Using Ribbon
    64.4.2. Using the DiscoveryClient
    65. Distributed Configuration with Consul
    65.1. How to activate
    65.2. Customizing
    65.3. Config Watch
    65.4. YAML or Properties with Config
    65.5. git2consul with Config
    65.6. Fail Fast
    66. Consul Retry
    67. Spring Cloud Bus with Consul
    67.1. How to activate
    68. Circuit Breaker with Hystrix
    69. Hystrix metrics aggregation with Turbine and Consul
    X. Spring Cloud Zookeeper
    70. Install Zookeeper
    71. Service Discovery with Zookeeper
    71.1. How to activate
    71.2. Registering with Zookeeper
    71.3. Using the DiscoveryClient
    72. Using Spring Cloud Zookeeper with Spring Cloud Netflix Components
    72.1. Ribbon with Zookeeper
    73. Spring Cloud Zookeeper and Service Registry
    73.1. Instance Status
    74. Zookeeper Dependencies
    74.1. Using the Zookeeper Dependencies
    74.2. How to activate Zookeeper Dependencies
    74.3. Setting up Zookeeper Dependencies
    74.3.1. Aliases
    74.3.2. Path
    74.3.3. Load balancer type
    74.3.4. Content-Type template and version
    74.3.5. Default headers
    74.3.6. Obligatory dependencies
    74.3.7. Stubs
    74.4. Configuring Spring Cloud Zookeeper Dependencies
    75. Spring Cloud Zookeeper Dependency Watcher
    75.1. How to activate
    75.2. Registering a listener
    75.3. Presence Checker
    76. Distributed Configuration with Zookeeper
    76.1. How to activate
    76.2. Customizing
    76.3. ACLs
    XI. Spring Cloud Security
    77. Quickstart
    77.1. OAuth2 Single Sign On
    77.2. OAuth2 Protected Resource
    78. More Detail
    78.1. Single Sign On
    78.2. Token Relay
    78.2.1. Client Token Relay
    78.2.2. Client Token Relay in Zuul Proxy
    78.2.3. Resource Server Token Relay
    79. Configuring Authentication Downstream of a Zuul Proxy
    XII. Spring Cloud for Cloud Foundry
    80. Discovery
    81. Single Sign On
    XIII. Spring Cloud Contract
    82. Spring Cloud Contract
    83. Spring Cloud Contract Verifier Introduction
    83.1. Why a Contract Verifier?
    83.1.1. Testing issues
    83.2. Purposes
    83.3. How It Works
    83.3.1. Defining the contract
    83.3.2. Client Side
    83.3.3. Server Side
    83.4. Step-by-step Guide to Consumer Driven Contracts (CDC)
    83.4.1. Technical note
    83.4.2. Consumer side (Loan Issuance)
    83.4.3. Producer side (Fraud Detection server)
    83.4.4. Consumer Side (Loan Issuance) Final Step
    83.5. Dependencies
    83.6. Additional Links
    83.6.1. Spring Cloud Contract video
    83.6.2. Readings
    83.7. Samples
    84. Spring Cloud Contract FAQ
    84.1. Why use Spring Cloud Contract Verifier and not X ?
    84.2. I don’t want to write a contract in Groovy!
    84.3. What is this value(consumer(), producer()) ?
    84.4. How to do Stubs versioning?
    84.4.1. API Versioning
    84.4.2. JAR versioning
    84.4.3. Dev or prod stubs
    84.5. Common repo with contracts
    84.5.1. Repo structure
    84.5.2. Workflow
    84.5.3. Consumer
    84.5.4. Producer
    84.5.5. How can I define messaging contracts per topic not per producer?
    For Maven Project
    For Gradle Project
    84.6. Can I have multiple base classes for tests?
    84.7. How can I debug the request/response being sent by the generated tests client?
    84.7.1. How can I debug the mapping/request/response being sent by WireMock?
    84.7.2. How can I see what got registered in the HTTP server stub?
    84.7.3. Can I reference the request from the response?
    84.7.4. Can I reference text from file?
    85. Spring Cloud Contract Verifier Setup
    85.1. Gradle Project
    85.1.1. Prerequisites
    85.1.2. Add Gradle Plugin with Dependencies
    85.1.3. Gradle and Rest Assured 2.0
    85.1.4. Snapshot Versions for Gradle
    85.1.5. Add stubs
    85.1.6. Run the Plugin
    85.1.7. Default Setup
    85.1.8. Configure Plugin
    85.1.9. Configuration Options
    85.1.10. Single Base Class for All Tests
    85.1.11. Different Base Classes for Contracts
    85.1.12. Invoking Generated Tests
    85.1.13. Spring Cloud Contract Verifier on the Consumer Side
    85.2. Maven Project
    85.2.1. Add maven plugin
    85.2.2. Maven and Rest Assured 2.0
    85.2.3. Snapshot versions for Maven
    85.2.4. Add stubs
    85.2.5. Run plugin
    85.2.6. Configure plugin
    85.2.7. Configuration Options
    85.2.8. Single Base Class for All Tests
    85.2.9. Different base classes for contracts
    85.2.10. Invoking generated tests
    85.2.11. Maven Plugin and STS
    85.3. Stubs and Transitive Dependencies
    85.4. CI Server setup
    85.5. Scenarios
    85.6. Docker Project
    85.6.1. Short intro to Maven, JARs and Binary storage
    85.6.2. How it works
    Environment Variables
    85.6.3. Example of usage
    85.6.4. Server side (nodejs)
    86. Spring Cloud Contract Verifier Messaging
    86.1. Integrations
    86.2. Manual Integration Testing
    86.3. Publisher-Side Test Generation
    86.3.1. Scenario 1: No Input Message
    86.3.2. Scenario 2: Output Triggered by Input
    86.3.3. Scenario 3: No Output Message
    86.4. Consumer Stub Generation
    87. Spring Cloud Contract Stub Runner
    87.1. Snapshot versions
    87.2. Publishing Stubs as JARs
    87.3. Stub Runner Core
    87.3.1. Retrieving stubs
    Stub downloading
    Classpath scanning
    87.3.2. Running stubs
    Limitations
    Running using main app
    HTTP Stubs
    Viewing registered mappings
    Messaging Stubs
    87.4. Stub Runner JUnit Rule
    87.4.1. Maven settings
    87.4.2. Providing fixed ports
    87.4.3. Fluent API
    87.4.4. Stub Runner with Spring
    87.5. Stub Runner Spring Cloud
    87.5.1. Stubbing Service Discovery
    Test profiles and service discovery
    87.5.2. Additional Configuration
    87.6. Stub Runner Boot Application
    87.6.1. How to use it?
    Stub Runner Server
    Stub Runner Server Fat Jar
    Spring Cloud CLI
    87.6.2. Endpoints
    HTTP
    Messaging
    87.6.3. Example
    87.6.4. Stub Runner Boot with Service Discovery
    87.7. Stubs Per Consumer
    87.8. Common
    87.8.1. Common Properties for JUnit and Spring
    87.8.2. Stub Runner Stubs IDs
    87.9. Stub Runner Docker
    87.9.1. How to use it
    87.9.2. Example of client side usage in a non JVM project
    88. Stub Runner for Messaging
    88.1. Stub triggering
    88.1.1. Trigger by Label
    88.1.2. Trigger by Group and Artifact Ids
    88.1.3. Trigger by Artifact Ids
    88.1.4. Trigger All Messages
    88.2. Stub Runner Integration
    88.2.1. Adding the Runner to the Project
    88.2.2. Disabling the functionality
    Scenario 1 (no input message)
    Scenario 2 (output triggered by input)
    Scenario 3 (input with no output)
    88.3. Stub Runner Stream
    88.3.1. Adding the Runner to the Project
    88.3.2. Disabling the functionality
    Scenario 1 (no input message)
    Scenario 2 (output triggered by input)
    Scenario 3 (input with no output)
    88.4. Stub Runner Spring AMQP
    88.4.1. Adding the Runner to the Project
    Triggering the message
    Spring AMQP Test Configuration
    89. Contract DSL
    89.1. Limitations
    89.2. Common Top-Level elements
    89.2.1. Description
    89.2.2. Name
    89.2.3. Ignoring Contracts
    89.2.4. Passing Values from Files
    89.2.5. HTTP Top-Level Elements
    89.3. Request
    89.4. Response
    89.5. Dynamic properties
    89.5.1. Dynamic properties inside the body
    89.5.2. Regular expressions
    89.5.3. Passing Optional Parameters
    89.5.4. Executing Custom Methods on the Server Side
    89.5.5. Referencing the Request from the Response
    89.5.6. Registering Your Own WireMock Extension
    89.5.7. Dynamic Properties in the Matchers Sections
    89.6. JAX-RS Support
    89.7. Async Support
    89.8. Working with Context Paths
    89.9. Messaging Top-Level Elements
    89.9.1. Output Triggered by a Method
    89.9.2. Output Triggered by a Message
    89.9.3. Consumer/Producer
    89.9.4. Common
    89.10. Multiple Contracts in One File
    90. Customization
    90.1. Extending the DSL
    90.1.1. Common JAR
    90.1.2. Adding the Dependency to the Project
    90.1.3. Test the Dependency in the Project’s Dependencies
    90.1.4. Test a Dependency in the Plugin’s Dependencies
    90.1.5. Referencing classes in DSLs
    91. Using the Pluggable Architecture
    91.1. Custom Contract Converter
    91.1.1. Pact Converter
    91.1.2. Pact Contract
    91.1.3. Pact for Producers
    91.1.4. Pact for Consumers
    91.2. Using the Custom Test Generator
    91.3. Using the Custom Stub Generator
    91.4. Using the Custom Stub Runner
    91.5. Using the Custom Stub Downloader
    92. Spring Cloud Contract WireMock
    92.1. Registering Stubs Automatically
    92.2. Using Files to Specify the Stub Bodies
    92.3. Alternative: Using JUnit Rules
    92.4. Relaxed SSL Validation for Rest Template
    92.5. WireMock and Spring MVC Mocks
    92.6. Customization of WireMock configuration
    92.7. Generating Stubs using REST Docs
    92.8. Generating Contracts by Using REST Docs
    93. Migrations
    93.1. 1.0.x → 1.1.x
    93.1.1. New structure of generated stubs
    93.2. 1.1.x → 1.2.x
    93.2.1. Custom HttpServerStub
    93.2.2. New packages for generated tests
    93.2.3. New Methods in TemplateProcessor
    93.2.4. RestAssured 3.0
    93.3. 1.2.x → 2.0.x
    93.3.1. No Camel support
    94. Links
    XIV. Spring Cloud Vault
    95. Quick Start
    96. Client Side Usage
    96.1. Authentication
    97. Authentication methods
    97.1. Token authentication
    97.2. AppId authentication
    97.2.1. Custom UserId
    97.3. AppRole authentication
    97.4. AWS-EC2 authentication
    97.5. AWS-IAM authentication
    97.6. TLS certificate authentication
    97.7. Cubbyhole authentication
    97.8. Kubernetes authentication
    98. Secret Backends
    98.1. Generic Backend
    98.2. Consul
    98.3. RabbitMQ
    98.4. AWS
    99. Database backends
    99.1. Database
    99.2. Apache Cassandra
    99.3. MongoDB
    99.4. MySQL
    99.5. PostgreSQL
    100. Configure PropertySourceLocator behavior
    101. Service Registry Configuration
    102. Vault Client Fail Fast
    103. Vault Client SSL configuration
    104. Lease lifecycle management (renewal and revocation)
    XV. Spring Cloud Gateway
    105. How to Include Spring Cloud Gateway
    106. Glossary
    107. How It Works
    108. Route Predicate Factories
    108.1. After Route Predicate Factory
    108.2. Before Route Predicate Factory
    108.3. Between Route Predicate Factory
    108.4. Cookie Route Predicate Factory
    108.5. Header Route Predicate Factory
    108.6. Host Route Predicate Factory
    108.7. Method Route Predicate Factory
    108.8. Path Route Predicate Factory
    108.9. Query Route Predicate Factory
    108.10. RemoteAddr Route Predicate Factory
    109. GatewayFilter Factories
    109.1. AddRequestHeader GatewayFilter Factory
    109.2. AddRequestParameter GatewayFilter Factory
    109.3. AddResponseHeader GatewayFilter Factory
    109.4. Hystrix GatewayFilter Factory
    109.5. PrefixPath GatewayFilter Factory
    109.6. PreserveHostHeader GatewayFilter Factory
    109.7. RequestRateLimiter GatewayFilter Factory
    109.8. RedirectTo GatewayFilter Factory
    109.9. RemoveNonProxyHeaders GatewayFilter Factory
    109.10. RemoveRequestHeader GatewayFilter Factory
    109.11. RemoveResponseHeader GatewayFilter Factory
    109.12. RewritePath GatewayFilter Factory
    109.13. SaveSession GatewayFilter Factory
    109.14. SecureHeaders GatewayFilter Factory
    109.15. SetPath GatewayFilter Factory
    109.16. SetResponseHeader GatewayFilter Factory
    109.17. SetStatus GatewayFilter Factory
    109.18. StripPrefix GatewayFilter Factory
    110. Global Filters
    110.1. Combined Global Filter and GatewayFilter Ordering
    110.2. Forward Routing Filter
    110.3. LoadBalancerClient Filter
    110.4. Netty Routing Filter
    110.5. Netty Write Response Filter
    110.6. RouteToRequestUrl Filter
    110.7. Websocket Routing Filter
    111. Configuration
    111.1. Fluent Java Routes API
    111.2. DiscoveryClient Route Definition Locator
    112. Actuator API
    113. Developer Guide
    113.1. Writing Custom Route Predicate Factories
    113.2. Writing Custom GatewayFilter Factories
    113.3. Writing Custom Global Filters
    113.4. Writing Custom Route Locators and Writers
    114. Building a Simple Gateway Using Spring MVC
    XVI. Appendix: Compendium of Configuration Properties
    \ No newline at end of file diff --git a/Finchley.M7/multi/multi_vault-lease-renewal.html b/Finchley.M7/multi/multi_vault-lease-renewal.html index fa1e4a11..b8e15f07 100644 --- a/Finchley.M7/multi/multi_vault-lease-renewal.html +++ b/Finchley.M7/multi/multi_vault-lease-renewal.html @@ -1,6 +1,6 @@ - 103. Lease lifecycle management (renewal and revocation)

    103. Lease lifecycle management (renewal and revocation)

    With every secret, Vault creates a lease: + 104. Lease lifecycle management (renewal and revocation)

    104. Lease lifecycle management (renewal and revocation)

    With every secret, Vault creates a lease: metadata containing information such as a time duration, renewability, and more.

    Vault promises that the data will be valid for the given duration, or Time To Live (TTL). Once the lease is expired, Vault can @@ -19,4 +19,4 @@ to false. This is not recommended as leases can exp Spring Cloud Vault cannot longer access Vault or services using generated credentials and valid credentials remain active after application shutdown.

    spring.cloud.vault:
    -    config.lifecycle.enabled: true

    See also: Vault Documentation: Lease, Renew, and Revoke

    \ No newline at end of file + config.lifecycle.enabled: true

    See also: Vault Documentation: Lease, Renew, and Revoke

    \ No newline at end of file diff --git a/Finchley.M7/multi/multi_vault.config.authentication.html b/Finchley.M7/multi/multi_vault.config.authentication.html index 527b2560..2a96ab1f 100644 --- a/Finchley.M7/multi/multi_vault.config.authentication.html +++ b/Finchley.M7/multi/multi_vault.config.authentication.html @@ -1,22 +1,22 @@ - 96. Authentication methods

    96. Authentication methods

    Different organizations have different requirements for security + 97. Authentication methods

    97. Authentication methods

    Different organizations have different requirements for security and authentication. Vault reflects that need by shipping multiple authentication -methods. Spring Cloud Vault supports token and AppId authentication.

    96.1 Token authentication

    Tokens are the core method for authentication within Vault. +methods. Spring Cloud Vault supports token and AppId authentication.

    97.1 Token authentication

    Tokens are the core method for authentication within Vault. Token authentication requires a static token to be provided using the Bootstrap Application Context.

    [Note]Note

    Token authentication is the default authentication method. If a token is disclosed an unintended party gains access to Vault and -can access secrets for the intended client.

    Example 96.1. bootstrap.yml

    spring.cloud.vault:
    +can access secrets for the intended client.

    Example 97.1. bootstrap.yml

    spring.cloud.vault:
         authentication: TOKEN
         token: 00000000-0000-0000-0000-000000000000

    • authentication setting this value to TOKEN selects the Token -authentication method
    • token sets the static token to use

    See also: Vault Documentation: Tokens

    96.2 AppId authentication

    Vault supports AppId +authentication method

  • token sets the static token to use
  • See also: Vault Documentation: Tokens

    97.2 AppId authentication

    Vault supports AppId authentication that consists of two hard to guess tokens. The AppId defaults to spring.application.name that is statically configured. The second token is the UserId which is a part determined by the application, usually related to the runtime environment. IP address, Mac address or a Docker container name are good examples. Spring Cloud Vault Config supports IP address, Mac address and static UserId’s (e.g. supplied via System properties). -The IP and Mac address are represented as Hex-encoded SHA256 hash.

    IP address-based UserId’s use the local host’s IP address.

    Example 96.2. bootstrap.yml using SHA256 IP-Address UserId’s

    spring.cloud.vault:
    +The IP and Mac address are represented as Hex-encoded SHA256 hash.

    IP address-based UserId’s use the local host’s IP address.

    Example 97.2. bootstrap.yml using SHA256 IP-Address UserId’s

    spring.cloud.vault:
         authentication: APPID
         app-id:
             user-id: IP_ADDRESS

    • authentication setting this value to APPID selects the AppId @@ -26,42 +26,42 @@ so make sure to include the -n flag.

      < localhost-bound device. The configuration also allows specifying a network-interface hint to pick the right device. The value of network-interface is optional and can be either an interface -name or interface index (0-based).

      Example 96.3. bootstrap.yml using SHA256 Mac-Address UserId’s

      spring.cloud.vault:
      +name or interface index (0-based).

      Example 97.3. bootstrap.yml using SHA256 Mac-Address UserId’s

      spring.cloud.vault:
           authentication: APPID
           app-id:
               user-id: MAC_ADDRESS
               network-interface: eth0

      • network-interface sets network interface to obtain the physical address

      The corresponding command to generate the IP address UserId from a command line is:

      $ echo -n 0AFEDE1234AC | sha256sum
      [Note]Note

      The Mac address is specified uppercase and without colons. Including the line break of echo leads to a different hash value -so make sure to include the -n flag.

      96.2.1 Custom UserId

      The UserId generation is an open mechanism. You can set +so make sure to include the -n flag.

      97.2.1 Custom UserId

      The UserId generation is an open mechanism. You can set spring.cloud.vault.app-id.user-id to any string and the configured value will be used as static UserId.

      A more advanced approach lets you set spring.cloud.vault.app-id.user-id to a classname. This class must be on your classpath and must implement the org.springframework.cloud.vault.AppIdUserIdMechanism interface and the createUserId method. Spring Cloud Vault will obtain the UserId by calling createUserId each time it authenticates using AppId to -obtain a token.

      Example 96.4. bootstrap.yml

      spring.cloud.vault:
      +obtain a token.

      Example 97.4. bootstrap.yml

      spring.cloud.vault:
           authentication: APPID
           app-id:
      -        user-id: com.examlple.MyUserIdMechanism

      Example 96.5. MyUserIdMechanism.java

      public class MyUserIdMechanism implements AppIdUserIdMechanism {
      +        user-id: com.examlple.MyUserIdMechanism

      Example 97.5. MyUserIdMechanism.java

      public class MyUserIdMechanism implements AppIdUserIdMechanism {
       
         @Override
         public String createUserId() {
           String userId = ...
           return userId;
         }
      -}

      See also: Vault Documentation: Using the App ID auth backend

      96.3 AppRole authentication

      AppRole is intended for machine -authentication, like the deprecated (since Vault 0.6.1) Section 96.2, “AppId authentication”. +}


      See also: Vault Documentation: Using the App ID auth backend

    97.3 AppRole authentication

    AppRole is intended for machine +authentication, like the deprecated (since Vault 0.6.1) Section 97.2, “AppId authentication”. AppRole authentication consists of two hard to guess (secret) tokens: RoleId and SecretId.

    Spring Vault supports various AppRole scenarios (push/pull mode and wrapped).

    RoleId and optionally SecretId must be provided by configuration, -Spring Vault will not look up these or create a custom SecretId.

    Example 96.6. bootstrap.yml with AppRole authentication properties

    spring.cloud.vault:
    +Spring Vault will not look up these or create a custom SecretId.

    Example 97.6. bootstrap.yml with AppRole authentication properties

    spring.cloud.vault:
         authentication: APPROLE
         app-role:
    -        role-id: bde2076b-cccb-3cf0-d57e-bca7b1e83a52

    The following scenarios are supported along the required configuration details:

    Table 96.1. Configuration

    Method

    RoleId

    SecretId

    RoleName

    Token

    Provided RoleId/SecretId

    Provided

    Provided

      

    Provided RoleId without SecretId

    Provided

       

    Provided RoleId, Pull SecretId

    Provided

    Provided

    Provided

    Provided

    Pull RoleId, provided SecretId

     

    Provided

    Provided

    Provided

    Full Pull Mode

      

    Provided

    Provided

    Wrapped

       

    Provided

    Wrapped RoleId, provided SecretId

    Provided

      

    Provided

    Provided RoleId, wrapped SecretId

     

    Provided

     

    Provided


    Table 96.2. Pull/Push/Wrapped Matrix

    RoleId

    SecretId

    Supported

    Provided

    Provided

    Provided

    Pull

    Provided

    Wrapped

    Provided

    Absent

    Pull

    Provided

    Pull

    Pull

    Pull

    Wrapped

    Pull

    Absent

    Wrapped

    Provided

    Wrapped

    Pull

    Wrapped

    Wrapped

    Wrapped

    Absent


    [Note]Note

    You can use still all combinations of push/pull/wrapped modes by providing a configured AppRoleAuthentication bean within the boostrap context. Spring Cloud Vault cannot derive all possible AppRole combinations from the configuration properties.

    Example 96.7. bootstrap.yml with all AppRole authentication properties

    spring.cloud.vault:
    +        role-id: bde2076b-cccb-3cf0-d57e-bca7b1e83a52

    The following scenarios are supported along the required configuration details:

    Table 97.1. Configuration

    Method

    RoleId

    SecretId

    RoleName

    Token

    Provided RoleId/SecretId

    Provided

    Provided

      

    Provided RoleId without SecretId

    Provided

       

    Provided RoleId, Pull SecretId

    Provided

    Provided

    Provided

    Provided

    Pull RoleId, provided SecretId

     

    Provided

    Provided

    Provided

    Full Pull Mode

      

    Provided

    Provided

    Wrapped

       

    Provided

    Wrapped RoleId, provided SecretId

    Provided

      

    Provided

    Provided RoleId, wrapped SecretId

     

    Provided

     

    Provided


    Table 97.2. Pull/Push/Wrapped Matrix

    RoleId

    SecretId

    Supported

    Provided

    Provided

    Provided

    Pull

    Provided

    Wrapped

    Provided

    Absent

    Pull

    Provided

    Pull

    Pull

    Pull

    Wrapped

    Pull

    Absent

    Wrapped

    Provided

    Wrapped

    Pull

    Wrapped

    Wrapped

    Wrapped

    Absent


    [Note]Note

    You can use still all combinations of push/pull/wrapped modes by providing a configured AppRoleAuthentication bean within the boostrap context. Spring Cloud Vault cannot derive all possible AppRole combinations from the configuration properties.

    Example 97.7. bootstrap.yml with all AppRole authentication properties

    spring.cloud.vault:
         authentication: APPROLE
         app-role:
             role-id: bde2076b-cccb-3cf0-d57e-bca7b1e83a52
             secret-id: 1696536f-1976-73b1-b241-0b4213908d39
             role: my-role
    -        app-role-path: approle

    • role-id sets the RoleId.
    • secret-id sets the SecretId. SecretId can be omitted if AppRole is configured without requiring SecretId (See bind_secret_id).
    • role: sets the AppRole name for pull mode.
    • app-role-path sets the path of the approle authentication mount to use.

    See also: Vault Documentation: Using the AppRole auth backend

    96.4 AWS-EC2 authentication

    The aws-ec2 + app-role-path: approle


    • role-id sets the RoleId.
    • secret-id sets the SecretId. SecretId can be omitted if AppRole is configured without requiring SecretId (See bind_secret_id).
    • role: sets the AppRole name for pull mode.
    • app-role-path sets the path of the approle authentication mount to use.

    See also: Vault Documentation: Using the AppRole auth backend

    97.4 AWS-EC2 authentication

    The aws-ec2 auth backend provides a secure introduction mechanism for AWS EC2 instances, allowing automated retrieval of a Vault token. Unlike most Vault authentication backends, this backend @@ -69,7 +69,7 @@ does not require first-deploying, or provisioning security-sensitive credentials (tokens, username/password, client certificates, etc.). Instead, it treats AWS as a Trusted Third Party and uses the cryptographically signed dynamic metadata information that uniquely -represents each EC2 instance.

    Example 96.8. bootstrap.yml using AWS-EC2 Authentication

    spring.cloud.vault:
    +represents each EC2 instance.

    Example 97.8. bootstrap.yml using AWS-EC2 Authentication

    spring.cloud.vault:
         authentication: AWS_EC2

    AWS-EC2 authentication enables nonce by default to follow the Trust On First Use (TOFU) principle. Any unintended party that gains access to the PKCS#7 identity metadata can authenticate @@ -80,17 +80,17 @@ party does not have the nonce and can raise an alert in Vault for further investigation.

    The nonce is kept in memory and is lost during application restart. You can configure a static nonce with spring.cloud.vault.aws-ec2.nonce.

    AWS-EC2 authentication roles are optional and default to the AMI. You can configure the authentication role by setting the -spring.cloud.vault.aws-ec2.role property.

    Example 96.9. bootstrap.yml with configured role

    spring.cloud.vault:
    +spring.cloud.vault.aws-ec2.role property.

    Example 97.9. bootstrap.yml with configured role

    spring.cloud.vault:
         authentication: AWS_EC2
         aws-ec2:
    -        role: application-server

    Example 96.10. bootstrap.yml with all AWS EC2 authentication properties

    spring.cloud.vault:
    +        role: application-server

    Example 97.10. bootstrap.yml with all AWS EC2 authentication properties

    spring.cloud.vault:
         authentication: AWS_EC2
         aws-ec2:
             role: application-server
             aws-ec2-path: aws-ec2
             identity-document: http://...
             nonce: my-static-nonce

    • authentication setting this value to AWS_EC2 selects the AWS EC2 -authentication method
    • role sets the name of the role against which the login is being attempted.
    • aws-ec2-path sets the path of the AWS EC2 mount to use
    • identity-document sets URL of the PKCS#7 AWS EC2 identity document
    • nonce used for AWS-EC2 authentication. An empty nonce defaults to nonce generation

    See also: Vault Documentation: Using the aws auth backend

    96.5 AWS-IAM authentication

    The aws backend provides a secure +authentication method

  • role sets the name of the role against which the login is being attempted.
  • aws-ec2-path sets the path of the AWS EC2 mount to use
  • identity-document sets URL of the PKCS#7 AWS EC2 identity document
  • nonce used for AWS-EC2 authentication. An empty nonce defaults to nonce generation
  • See also: Vault Documentation: Using the aws auth backend

    97.5 AWS-IAM authentication

    The aws backend provides a secure authentication mechanism for AWS IAM roles, allowing the automatic authentication with vault based on the current IAM role of the running application. Unlike most Vault authentication backends, this backend @@ -104,36 +104,36 @@ will use the IAM role assigned to the ECS task of the running container. If you are running your application naked on top of an EC2 instance then the IAM role used will be the one assigned to the EC2 instance.

    When using the AWS-IAM authentication you must create a role in Vault and assign it to your IAM role. An empty role defaults to -the friendly name the current IAM role.

    Example 96.11. bootstrap.yml with required AWS-IAM Authentication properties

    spring.cloud.vault:
    -    authentication: AWS_IAM

    Example 96.12. bootstrap.yml with all AWS-IAM Authentication properties

    spring.cloud.vault:
    +the friendly name the current IAM role.

    Example 97.11. bootstrap.yml with required AWS-IAM Authentication properties

    spring.cloud.vault:
    +    authentication: AWS_IAM

    Example 97.12. bootstrap.yml with all AWS-IAM Authentication properties

    spring.cloud.vault:
         authentication: AWS_IAM
         aws-iam:
             role: my-dev-role
             aws-path: aws
             server-id: some.server.name

    • role sets the name of the role against which the login is being attempted. This should be bound to your IAM role. If one is not supplied then the friendly name of the current IAM user will be used as the vault role.
    • aws-path sets the path of the AWS mount to use
    • server-id sets the value to use for the X-Vault-AWS-IAM-Server-ID header preventing certain types of replay attacks.

    AWS-IAM requires the AWS Java SDK dependency (com.amazonaws:aws-java-sdk-core) -as the authentication implementation uses AWS SDK types for credentials and request signing.

    See also: Vault Documentation: Using the aws auth backend

    96.6 TLS certificate authentication

    The cert auth backend allows authentication using SSL/TLS client -certificates that are either signed by a CA or self-signed.

    To enable cert authentication you need to:

    1. Use SSL, see Chapter 102, Vault Client SSL configuration
    2. Configure a Java Keystore that contains the client -certificate and the private key
    3. Set the spring.cloud.vault.authentication to CERT

    Example 96.13. bootstrap.yml

    spring.cloud.vault:
    +as the authentication implementation uses AWS SDK types for credentials and request signing.

    See also: Vault Documentation: Using the aws auth backend

    97.6 TLS certificate authentication

    The cert auth backend allows authentication using SSL/TLS client +certificates that are either signed by a CA or self-signed.

    To enable cert authentication you need to:

    1. Use SSL, see Chapter 103, Vault Client SSL configuration
    2. Configure a Java Keystore that contains the client +certificate and the private key
    3. Set the spring.cloud.vault.authentication to CERT

    Example 97.13. bootstrap.yml

    spring.cloud.vault:
         authentication: CERT
         ssl:
             key-store: classpath:keystore.jks
             key-store-password: changeit
    -        cert-auth-path: cert

    See also: Vault Documentation: Using the Cert auth backend

    96.7 Cubbyhole authentication

    Cubbyhole authentication uses Vault primitives to provide a secured authentication + cert-auth-path: cert


    See also: Vault Documentation: Using the Cert auth backend

    97.7 Cubbyhole authentication

    Cubbyhole authentication uses Vault primitives to provide a secured authentication workflow. Cubbyhole authentication uses tokens as primary login method. An ephemeral token is used to obtain a second, login VaultToken from Vault’s Cubbyhole secret backend. The login token is usually longer-lived and used to interact with Vault. The login token will be retrieved from a wrapped -response stored at /cubbyhole/response.

    Creating a wrapped token

    [Note]Note

    Response Wrapping for token creation requires Vault 0.6.0 or higher.

    Example 96.14. Creating and storing tokens

    $ vault token-create -wrap-ttl="10m"
    +response stored at /cubbyhole/response.

    Creating a wrapped token

    [Note]Note

    Response Wrapping for token creation requires Vault 0.6.0 or higher.

    Example 97.14. Creating and storing tokens

    $ vault token-create -wrap-ttl="10m"
     Key                            Value
     ---                            -----
     wrapping_token:                397ccb93-ff6c-b17b-9389-380b01ca2645
     wrapping_token_ttl:            0h10m0s
     wrapping_token_creation_time:  2016-09-18 20:29:48.652957077 +0200 CEST
    -wrapped_accessor:              46b6aebb-187f-932a-26d7-4f3d86a68319

    Example 96.15. bootstrap.yml

    spring.cloud.vault:
    +wrapped_accessor:              46b6aebb-187f-932a-26d7-4f3d86a68319

    Example 97.15. bootstrap.yml

    spring.cloud.vault:
         authentication: CUBBYHOLE
    -    token: 397ccb93-ff6c-b17b-9389-380b01ca2645

    See also:

    96.8 Kubernetes authentication

    Kubernetes authentication mechanism (since Vault 0.8.3) allows to authenticate with Vault using a Kubernetes Service Account Token. -The authentication is role based and the role is bound to a service account name and a namespace.

    A file containing a JWT token for a pod’s service account is automatically mounted at /var/run/secrets/kubernetes.io/serviceaccount/token.

    Example 96.16. bootstrap.yml with all Kubernetes authentication properties

    spring.cloud.vault:
    +    token: 397ccb93-ff6c-b17b-9389-380b01ca2645

    See also:

    97.8 Kubernetes authentication

    Kubernetes authentication mechanism (since Vault 0.8.3) allows to authenticate with Vault using a Kubernetes Service Account Token. +The authentication is role based and the role is bound to a service account name and a namespace.

    A file containing a JWT token for a pod’s service account is automatically mounted at /var/run/secrets/kubernetes.io/serviceaccount/token.

    Example 97.16. bootstrap.yml with all Kubernetes authentication properties

    spring.cloud.vault:
         authentication: KUBERNETES
         kubernetes:
             role: my-dev-role
    -        service-account-token-file: /var/run/secrets/kubernetes.io/serviceaccount/token

    • role sets the Role.
    • service-account-token-file sets the location of the file containing the Kubernetes Service Account Token. Defaults to /var/run/secrets/kubernetes.io/serviceaccount/token.

    See also:

    \ No newline at end of file + service-account-token-file: /var/run/secrets/kubernetes.io/serviceaccount/token

    • role sets the Role.
    • service-account-token-file sets the location of the file containing the Kubernetes Service Account Token. Defaults to /var/run/secrets/kubernetes.io/serviceaccount/token.

    See also:

    \ No newline at end of file diff --git a/Finchley.M7/multi/multi_vault.config.backends.configurer.html b/Finchley.M7/multi/multi_vault.config.backends.configurer.html index 5fbac81b..6a4cc1a0 100644 --- a/Finchley.M7/multi/multi_vault.config.backends.configurer.html +++ b/Finchley.M7/multi/multi_vault.config.backends.configurer.html @@ -1,6 +1,6 @@ - 99. Configure PropertySourceLocator behavior

    99. Configure PropertySourceLocator behavior

    Spring Cloud Vault uses property-based configuration to create PropertySources + 100. Configure PropertySourceLocator behavior

    100. Configure PropertySourceLocator behavior

    Spring Cloud Vault uses property-based configuration to create PropertySources for generic and discovered secret backends.

    Discovered backends provide VaultSecretBackendDescriptor beans to describe the configuration state to use secret backend as PropertySource. A SecretBackendMetadataFactory is required to create a SecretBackendMetadata object which contains path, name and property transformation @@ -19,4 +19,4 @@ at least one VaultConfigurer bean. You can however } }

    [Note]Note

    All customization is required to happen in the bootstrap context. Add your configuration classes to META-INF/spring.factories at org.springframework.cloud.bootstrap.BootstrapConfiguration -in your application.

    \ No newline at end of file +in your application.

    \ No newline at end of file diff --git a/Finchley.M7/multi/multi_vault.config.backends.database-backends.html b/Finchley.M7/multi/multi_vault.config.backends.database-backends.html index d04caf0a..b369cb8d 100644 --- a/Finchley.M7/multi/multi_vault.config.backends.database-backends.html +++ b/Finchley.M7/multi/multi_vault.config.backends.database-backends.html @@ -1,15 +1,15 @@ - 98. Database backends

    98. Database backends

    Vault supports several database secret backends to generate database + 99. Database backends

    99. Database backends

    Vault supports several database secret backends to generate database credentials dynamically based on configured roles. This means services that need to access a database no longer need to configure credentials: they can request them from Vault, and use Vault’s leasing -mechanism to more easily roll keys.

    Spring Cloud Vault integrates with these backends:

    Using a database secret backend requires to enable the +mechanism to more easily roll keys.

    Spring Cloud Vault integrates with these backends:

    Using a database secret backend requires to enable the backend in the configuration and the spring-cloud-vault-config-databases dependency.

    Vault ships since 0.7.1 with a dedicated database secret backend that allows database integration via plugins. You can use that specific backend by using the generic database backend. Make sure to specify the appropriate -backend path, e.g. spring.cloud.vault.mysql.role.backend=database.

    Example 98.1. pom.xml

    <dependencies>
    +backend path, e.g. spring.cloud.vault.mysql.role.backend=database.

    Example 99.1. pom.xml

    <dependencies>
         <dependency>
             <groupId>org.springframework.cloud</groupId>
             <artifactId>spring-cloud-vault-config-databases</artifactId>
    @@ -17,7 +17,7 @@ backend path, e.g. spring.cloud.vault.mysql.role.backend=d
         </dependency>
     </dependencies>

    [Note]Note

    Enabling multiple JDBC-compliant databases will generate credentials and store them by default in the same property keys hence property names for -JDBC secrets need to be configured separately.

    98.1 Database

    Spring Cloud Vault can obtain credentials for any database listed at +JDBC secrets need to be configured separately.

    99.1 Database

    Spring Cloud Vault can obtain credentials for any database listed at https://www.vaultproject.io/api/secret/databases/index.html. The integration can be enabled by setting spring.cloud.vault.database.enabled=true (default false) and @@ -34,7 +34,7 @@ You can configure the property names by setting role: readonly backend: database username-property: spring.datasource.username - password-property: spring.datasource.username

    • enabled setting this value to true enables the Database backend config usage
    • role sets the role name of the Database role definition
    • backend sets the path of the Database mount to use
    • username-property sets the property name in which the Database username is stored
    • password-property sets the property name in which the Database password is stored

    See also: Vault Documentation: Database Secrets backend

    98.2 Apache Cassandra

    [Note]Note

    The cassandra backend has been deprecated in Vault 0.7.1 and + password-property: spring.datasource.username

    • enabled setting this value to true enables the Database backend config usage
    • role sets the role name of the Database role definition
    • backend sets the path of the Database mount to use
    • username-property sets the property name in which the Database username is stored
    • password-property sets the property name in which the Database password is stored

    See also: Vault Documentation: Database Secrets backend

    99.2 Apache Cassandra

    [Note]Note

    The cassandra backend has been deprecated in Vault 0.7.1 and it is recommended to use the database backend and mount it as cassandra.

    Spring Cloud Vault can obtain credentials for Apache Cassandra. The integration can be enabled by setting spring.cloud.vault.cassandra.enabled=true (default false) and @@ -49,7 +49,7 @@ You can configure the property names by setting role: readonly backend: cassandra username-property: spring.data.cassandra.username - password-property: spring.data.cassandra.username

    • enabled setting this value to true enables the Cassandra backend config usage
    • role sets the role name of the Cassandra role definition
    • backend sets the path of the Cassandra mount to use
    • username-property sets the property name in which the Cassandra username is stored
    • password-property sets the property name in which the Cassandra password is stored

    See also: Vault Documentation: Setting up Apache Cassandra with Vault

    98.3 MongoDB

    [Note]Note

    The mongodb backend has been deprecated in Vault 0.7.1 and + password-property: spring.data.cassandra.username

    • enabled setting this value to true enables the Cassandra backend config usage
    • role sets the role name of the Cassandra role definition
    • backend sets the path of the Cassandra mount to use
    • username-property sets the property name in which the Cassandra username is stored
    • password-property sets the property name in which the Cassandra password is stored

    See also: Vault Documentation: Setting up Apache Cassandra with Vault

    99.3 MongoDB

    [Note]Note

    The mongodb backend has been deprecated in Vault 0.7.1 and it is recommended to use the database backend and mount it as mongodb.

    Spring Cloud Vault can obtain credentials for MongoDB. The integration can be enabled by setting spring.cloud.vault.mongodb.enabled=true (default false) and @@ -64,7 +64,7 @@ You can configure the property names by setting role: readonly backend: mongodb username-property: spring.data.mongodb.username - password-property: spring.data.mongodb.password

    • enabled setting this value to true enables the MongodB backend config usage
    • role sets the role name of the MongoDB role definition
    • backend sets the path of the MongoDB mount to use
    • username-property sets the property name in which the MongoDB username is stored
    • password-property sets the property name in which the MongoDB password is stored

    See also: Vault Documentation: Setting up MongoDB with Vault

    98.4 MySQL

    [Note]Note

    The mysql backend has been deprecated in Vault 0.7.1 and + password-property: spring.data.mongodb.password

    • enabled setting this value to true enables the MongodB backend config usage
    • role sets the role name of the MongoDB role definition
    • backend sets the path of the MongoDB mount to use
    • username-property sets the property name in which the MongoDB username is stored
    • password-property sets the property name in which the MongoDB password is stored

    See also: Vault Documentation: Setting up MongoDB with Vault

    99.4 MySQL

    [Note]Note

    The mysql backend has been deprecated in Vault 0.7.1 and it is recommended to use the database backend and mount it as mysql. Configuration for spring.cloud.vault.mysql will be removed in a future version.

    Spring Cloud Vault can obtain credentials for MySQL. The integration can be enabled by setting @@ -80,7 +80,7 @@ You can configure the property names by setting role: readonly backend: mysql username-property: spring.datasource.username - password-property: spring.datasource.username

    • enabled setting this value to true enables the MySQL backend config usage
    • role sets the role name of the MySQL role definition
    • backend sets the path of the MySQL mount to use
    • username-property sets the property name in which the MySQL username is stored
    • password-property sets the property name in which the MySQL password is stored

    See also: Vault Documentation: Setting up MySQL with Vault

    98.5 PostgreSQL

    [Note]Note

    The postgresql backend has been deprecated in Vault 0.7.1 and + password-property: spring.datasource.username

    • enabled setting this value to true enables the MySQL backend config usage
    • role sets the role name of the MySQL role definition
    • backend sets the path of the MySQL mount to use
    • username-property sets the property name in which the MySQL username is stored
    • password-property sets the property name in which the MySQL password is stored

    See also: Vault Documentation: Setting up MySQL with Vault

    99.5 PostgreSQL

    [Note]Note

    The postgresql backend has been deprecated in Vault 0.7.1 and it is recommended to use the database backend and mount it as postgresql. Configuration for spring.cloud.vault.postgresql will be removed in a future version.

    Spring Cloud Vault can obtain credentials for PostgreSQL. The integration can be enabled by setting @@ -96,4 +96,4 @@ You can configure the property names by setting role: readonly backend: postgresql username-property: spring.datasource.username - password-property: spring.datasource.username

    • enabled setting this value to true enables the PostgreSQL backend config usage
    • role sets the role name of the PostgreSQL role definition
    • backend sets the path of the PostgreSQL mount to use
    • username-property sets the property name in which the PostgreSQL username is stored
    • password-property sets the property name in which the PostgreSQL password is stored

    See also: Vault Documentation: Setting up PostgreSQL with Vault

    \ No newline at end of file + password-property: spring.datasource.username
    • enabled setting this value to true enables the PostgreSQL backend config usage
    • role sets the role name of the PostgreSQL role definition
    • backend sets the path of the PostgreSQL mount to use
    • username-property sets the property name in which the PostgreSQL username is stored
    • password-property sets the property name in which the PostgreSQL password is stored

    See also: Vault Documentation: Setting up PostgreSQL with Vault

    \ No newline at end of file diff --git a/Finchley.M7/multi/multi_vault.config.backends.html b/Finchley.M7/multi/multi_vault.config.backends.html index 33655422..439083f9 100644 --- a/Finchley.M7/multi/multi_vault.config.backends.html +++ b/Finchley.M7/multi/multi_vault.config.backends.html @@ -1,6 +1,6 @@ - 97. Secret Backends

    97. Secret Backends

    97.1 Generic Backend

    Spring Cloud Vault supports at the basic level the generic secret + 98. Secret Backends

    98. Secret Backends

    98.1 Generic Backend

    Spring Cloud Vault supports at the basic level the generic secret backend. The generic secret backend allows storage of arbitrary values as key-value store. A single context can store one or many key-value tuples. Contexts can be organized hierarchically. @@ -20,9 +20,9 @@ No active profiles will skip accessing contexts with a profile name.

    Prope default-context: application application-name: my-app

    • enabled setting this value to false disables the secret backend config usage
    • backend sets the path of the secret mount to use
    • default-context sets the context name used by all applications
    • application-name overrides the application name for use in the generic backend
    • profile-separator separates the profile name from the context in -property sources with profiles

    See also: Vault Documentation: Using the generic secret backend

    97.2 Consul

    Spring Cloud Vault can obtain credentials for HashiCorp Consul. +property sources with profiles

    See also: Vault Documentation: Using the generic secret backend

    98.2 Consul

    Spring Cloud Vault can obtain credentials for HashiCorp Consul. The Consul integration requires the spring-cloud-vault-config-consul -dependency.

    Example 97.1. pom.xml

    <dependencies>
    +dependency.

    Example 98.1. pom.xml

    <dependencies>
         <dependency>
             <groupId>org.springframework.cloud</groupId>
             <artifactId>spring-cloud-vault-config-consul</artifactId>
    @@ -38,8 +38,8 @@ the property name by setting spring.cloud.vault.consul.tok
             enabled: true
             role: readonly
             backend: consul
    -        token-property: spring.cloud.consul.token
    • enabled setting this value to true enables the Consul backend config usage
    • role sets the role name of the Consul role definition
    • backend sets the path of the Consul mount to use
    • token-property sets the property name in which the Consul ACL token is stored

    See also: Vault Documentation: Setting up Consul with Vault

    97.3 RabbitMQ

    Spring Cloud Vault can obtain credentials for RabbitMQ.

    The RabbitMQ integration requires the spring-cloud-vault-config-rabbitmq -dependency.

    Example 97.2. pom.xml

    <dependencies>
    +        token-property: spring.cloud.consul.token
    • enabled setting this value to true enables the Consul backend config usage
    • role sets the role name of the Consul role definition
    • backend sets the path of the Consul mount to use
    • token-property sets the property name in which the Consul ACL token is stored

    See also: Vault Documentation: Setting up Consul with Vault

    98.3 RabbitMQ

    Spring Cloud Vault can obtain credentials for RabbitMQ.

    The RabbitMQ integration requires the spring-cloud-vault-config-rabbitmq +dependency.

    Example 98.2. pom.xml

    <dependencies>
         <dependency>
             <groupId>org.springframework.cloud</groupId>
             <artifactId>spring-cloud-vault-config-rabbitmq</artifactId>
    @@ -57,8 +57,8 @@ by setting spring.cloud.vault.rabbitmq.username-property        role: readonly
             backend: rabbitmq
             username-property: spring.rabbitmq.username
    -        password-property: spring.rabbitmq.password
    • enabled setting this value to true enables the RabbitMQ backend config usage
    • role sets the role name of the RabbitMQ role definition
    • backend sets the path of the RabbitMQ mount to use
    • username-property sets the property name in which the RabbitMQ username is stored
    • password-property sets the property name in which the RabbitMQ password is stored

    See also: Vault Documentation: Setting up RabbitMQ with Vault

    97.4 AWS

    Spring Cloud Vault can obtain credentials for AWS.

    The AWS integration requires the spring-cloud-vault-config-aws -dependency.

    Example 97.3. pom.xml

    <dependencies>
    +        password-property: spring.rabbitmq.password
    • enabled setting this value to true enables the RabbitMQ backend config usage
    • role sets the role name of the RabbitMQ role definition
    • backend sets the path of the RabbitMQ mount to use
    • username-property sets the property name in which the RabbitMQ username is stored
    • password-property sets the property name in which the RabbitMQ password is stored

    See also: Vault Documentation: Setting up RabbitMQ with Vault

    98.4 AWS

    Spring Cloud Vault can obtain credentials for AWS.

    The AWS integration requires the spring-cloud-vault-config-aws +dependency.

    Example 98.3. pom.xml

    <dependencies>
         <dependency>
             <groupId>org.springframework.cloud</groupId>
             <artifactId>spring-cloud-vault-config-aws</artifactId>
    @@ -76,4 +76,4 @@ by setting spring.cloud.vault.aws.access-key-property        role: readonly
             backend: aws
             access-key-property: cloud.aws.credentials.accessKey
    -        secret-key-property: cloud.aws.credentials.secretKey
    • enabled setting this value to true enables the AWS backend config usage
    • role sets the role name of the AWS role definition
    • backend sets the path of the AWS mount to use
    • access-key-property sets the property name in which the AWS access key is stored
    • secret-key-property sets the property name in which the AWS secret key is stored

    See also: Vault Documentation: Setting up AWS with Vault

    \ No newline at end of file + secret-key-property: cloud.aws.credentials.secretKey
    • enabled setting this value to true enables the AWS backend config usage
    • role sets the role name of the AWS role definition
    • backend sets the path of the AWS mount to use
    • access-key-property sets the property name in which the AWS access key is stored
    • secret-key-property sets the property name in which the AWS secret key is stored

    See also: Vault Documentation: Setting up AWS with Vault

    \ No newline at end of file diff --git a/Finchley.M7/multi/multi_vault.config.fail-fast.html b/Finchley.M7/multi/multi_vault.config.fail-fast.html index e1410cdd..40bd5e10 100644 --- a/Finchley.M7/multi/multi_vault.config.fail-fast.html +++ b/Finchley.M7/multi/multi_vault.config.fail-fast.html @@ -1,8 +1,8 @@ - 101. Vault Client Fail Fast

    101. Vault Client Fail Fast

    In some cases, it may be desirable to fail startup of a service if + 102. Vault Client Fail Fast

    102. Vault Client Fail Fast

    In some cases, it may be desirable to fail startup of a service if it cannot connect to the Vault Server. If this is the desired behavior, set the bootstrap configuration property spring.cloud.vault.fail-fast=true and the client will halt with an Exception.

    spring.cloud.vault:
    -    fail-fast: true
    \ No newline at end of file + fail-fast: true
    \ No newline at end of file diff --git a/Finchley.M7/multi/multi_vault.config.ssl.html b/Finchley.M7/multi/multi_vault.config.ssl.html index 824f58a5..3399dbf0 100644 --- a/Finchley.M7/multi/multi_vault.config.ssl.html +++ b/Finchley.M7/multi/multi_vault.config.ssl.html @@ -1,6 +1,6 @@ - 102. Vault Client SSL configuration

    102. Vault Client SSL configuration

    SSL can be configured declaratively by setting various properties. + 103. Vault Client SSL configuration

    103. Vault Client SSL configuration

    SSL can be configured declaratively by setting various properties. You can set either javax.net.ssl.trustStore to configure JVM-wide SSL settings or spring.cloud.vault.ssl.trust-store to set SSL settings only for Spring Cloud Vault Config.

    spring.cloud.vault:
    @@ -10,4 +10,4 @@ to set SSL settings only for Spring Cloud Vault Config.

    trust-store-password sets the trust-store password

    Please note that configuring spring.cloud.vault.ssl.* can be only applied when either Apache Http Components or the OkHttp client -is on your class-path.

    \ No newline at end of file +is on your class-path.

    \ No newline at end of file diff --git a/Finchley.M7/single/spring-cloud.html b/Finchley.M7/single/spring-cloud.html index 65e879ec..10fb40b7 100644 --- a/Finchley.M7/single/spring-cloud.html +++ b/Finchley.M7/single/spring-cloud.html @@ -1,6 +1,6 @@ - Spring Cloud

    Spring Cloud


    Table of Contents

    1. Features
    I. Cloud Native Applications
    2. Spring Cloud Context: Application Context Services
    2.1. The Bootstrap Application Context
    2.2. Application Context Hierarchies
    2.3. Changing the Location of Bootstrap Properties
    2.4. Overriding the Values of Remote Properties
    2.5. Customizing the Bootstrap Configuration
    2.6. Customizing the Bootstrap Property Sources
    2.7. Environment Changes
    2.8. Refresh Scope
    2.9. Encryption and Decryption
    2.10. Endpoints
    3. Spring Cloud Commons: Common Abstractions
    3.1. @EnableDiscoveryClient
    3.1.1. Health Indicator
    3.2. ServiceRegistry
    3.2.1. ServiceRegistry Auto-Registration
    3.2.2. Service Registry Actuator Endpoint
    3.3. Spring RestTemplate as a Load Balancer Client
    3.4. Spring WebClient as a Load Balancer Client
    3.4.1. Retrying Failed Requests
    3.5. Multiple RestTemplate objects
    3.6. Spring WebFlux WebClient as a Load Balancer Client
    3.7. Ignore Network Interfaces
    3.8. HTTP Client Factories
    3.9. Enabled Features
    3.9.1. Feature types
    3.9.2. Declaring features
    II. Spring Cloud Config
    4. Quick Start
    4.1. Client Side Usage
    5. Spring Cloud Config Server
    5.1. Environment Repository
    5.1.1. Git Backend
    Placeholders in Git URI
    Pattern Matching and Multiple Repositories
    Authentication
    Authentication with AWS CodeCommit
    Git SSH configuration using properties
    Placeholders in Git Search Paths
    Force pull in Git Repositories
    5.1.2. Version Control Backend Filesystem Use
    5.1.3. File System Backend
    5.1.4. Vault Backend
    Multiple Properties Sources
    5.1.5. Sharing Configuration With All Applications
    File Based Repositories
    Vault Server
    5.1.6. JDBC Backend
    5.1.7. Composite Environment Repositories
    Custom Composite Environment Repositories
    5.1.8. Property Overrides
    5.2. Health Indicator
    5.3. Security
    5.4. Encryption and Decryption
    5.5. Key Management
    5.6. Creating a Key Store for Testing
    5.7. Using Multiple Keys and Key Rotation
    5.8. Serving Encrypted Properties
    6. Serving Alternative Formats
    7. Serving Plain Text
    8. Embedding the Config Server
    9. Push Notifications and Spring Cloud Bus
    10. Spring Cloud Config Client
    10.1. Config First Bootstrap
    10.2. Discovery First Bootstrap
    10.3. Config Client Fail Fast
    10.4. Config Client Retry
    10.5. Locating Remote Configuration Resources
    10.6. Security
    10.6.1. Health Indicator
    10.6.2. Providing A Custom RestTemplate
    10.6.3. Vault
    10.7. Vault
    10.7.1. Nested Keys In Vault
    III. Spring Cloud Netflix
    11. Service Discovery: Eureka Clients
    11.1. How to Include Eureka Client
    11.2. Registering with Eureka
    11.3. Authenticating with the Eureka Server
    11.4. Status Page and Health Indicator
    11.5. Registering a Secure Application
    11.6. Eureka’s Health Checks
    11.7. Eureka Metadata for Instances and Clients
    11.7.1. Using Eureka on Cloudfoundry
    11.7.2. Using Eureka on AWS
    11.7.3. Changing the Eureka Instance ID
    11.8. Using the EurekaClient
    11.8.1. EurekaClient without Jersey
    11.9. Alternatives to the native Netflix EurekaClient
    11.10. Why is it so Slow to Register a Service?
    11.11. Zones
    12. Service Discovery: Eureka Server
    12.1. How to Include Eureka Server
    12.2. How to Run a Eureka Server
    12.3. High Availability, Zones and Regions
    12.4. Standalone Mode
    12.5. Peer Awareness
    12.6. Prefer IP Address
    13. Circuit Breaker: Hystrix Clients
    13.1. How to Include Hystrix
    13.2. Propagating the Security Context or using Spring Scopes
    13.3. Health Indicator
    13.4. Hystrix Metrics Stream
    14. Circuit Breaker: Hystrix Dashboard
    15. Hystrix Timeouts And Ribbon Clients
    15.1. How to Include Hystrix Dashboard
    15.2. Turbine
    15.3. Turbine Stream
    16. Client Side Load Balancer: Ribbon
    16.1. How to Include Ribbon
    16.2. Customizing the Ribbon Client
    16.3. Customizing default for all Ribbon Clients
    16.4. Customizing the Ribbon Client using properties
    16.5. Using Ribbon with Eureka
    16.6. Example: How to Use Ribbon Without Eureka
    16.7. Example: Disable Eureka use in Ribbon
    16.8. Using the Ribbon API Directly
    16.9. Caching of Ribbon Configuration
    16.10. How to Configure Hystrix thread pools
    16.11. How to Provide a Key to Ribbon’s IRule
    17. External Configuration: Archaius
    18. Router and Filter: Zuul
    18.1. How to Include Zuul
    18.2. Embedded Zuul Reverse Proxy
    18.3. Zuul Http Client
    18.4. Cookies and Sensitive Headers
    18.5. Ignored Headers
    18.6. Management Endpoints
    18.6.1. Routes Endpoint
    18.6.2. Filters Endpoint
    18.7. Strangulation Patterns and Local Forwards
    18.8. Uploading Files through Zuul
    18.9. Query String Encoding
    18.10. Plain Embedded Zuul
    18.11. Disable Zuul Filters
    18.12. Providing Hystrix Fallbacks For Routes
    18.13. Zuul Timeouts
    18.14. Rewriting Location header
    18.15. Zuul Developer Guide
    18.15.1. The Zuul Servlet
    18.15.2. Zuul RequestContext
    18.15.3. @EnableZuulProxy vs. @EnableZuulServer
    18.15.4. @EnableZuulServer Filters
    18.15.5. @EnableZuulProxy Filters
    18.15.6. Custom Zuul Filter examples
    18.15.7. How to Write a Pre Filter
    18.15.8. How to Write a Route Filter
    18.15.9. How to Write a Post Filter
    18.15.10. How Zuul Errors Work
    18.15.11. Zuul Eager Application Context Loading
    19. Polyglot support with Sidecar
    20. Metrics Backend: Atlas
    20.1. Using Atlas
    21. Retrying Failed Requests
    21.1. BackOff Policies
    21.2. Configuration
    21.2.1. Zuul
    22. HTTP Clients
    IV. Spring Cloud Stream
    23. Introducing Spring Cloud Stream
    24. Main Concepts
    24.1. Application Model
    24.1.1. Fat JAR
    24.2. The Binder Abstraction
    24.3. Persistent Publish-Subscribe Support
    24.4. Consumer Groups
    24.5. Consumer Types
    24.5.1. Durability
    24.6. Partitioning Support
    25. Programming Model
    25.1. Declaring and Binding Producers and Consumers
    25.1.1. Triggering Binding Via @EnableBinding
    25.1.2. @Input and @Output
    Customizing Channel Names
    Source, Sink, and Processor
    25.1.3. Accessing Bound Channels
    Injecting the Bound Interfaces
    Injecting Channels Directly
    25.1.4. Producing and Consuming Messages
    Native Spring Integration Support
    Spring Integration Error Channel Support
    Message Channel Binders and Error Channels
    Using @StreamListener for Automatic Content Type Handling
    Using @StreamListener for dispatching messages to multiple methods
    Using Polled Consumers
    25.1.5. Reactive Programming Support
    Reactor-based handlers
    Reactive Sources
    25.1.6. Aggregation
    Configuring aggregate application
    Configuring binding service properties for non self contained aggregate application
    26. Binders
    26.1. Producers and Consumers
    26.2. Binder SPI
    26.3. Binder Detection
    26.3.1. Classpath Detection
    26.4. Multiple Binders on the Classpath
    26.5. Connecting to Multiple Systems
    26.6. Binder configuration properties
    27. Configuration Options
    27.1. Spring Cloud Stream Properties
    27.2. Binding Properties
    27.2.1. Properties for Use of Spring Cloud Stream
    27.2.2. Consumer properties
    27.2.3. Producer Properties
    27.3. Using dynamically bound destinations
    28. Content Type and Transformation
    28.1. MIME types
    28.2. Channel contentType and Message Headers
    28.3. ContentType handling for output channels
    28.4. ContentType handling for input channels
    28.5. Customizing message conversion
    28.6. @StreamListener and Message Conversion
    29. Schema evolution support
    29.1. Apache Avro Message Converters
    29.2. Converters with schema support
    29.3. Schema Registry Support
    29.4. Schema Registry Server
    29.4.1. Schema Registry Server API
    POST /
    GET /{subject}/{format}/{version}
    GET /{subject}/{format}
    GET /schemas/{id}
    DELETE /{subject}/{format}/{version}
    DELETE /schemas/{id}
    DELETE /{subject}
    29.5. Schema Registry Client
    29.5.1. Using Confluent’s Schema Registry
    29.5.2. Schema Registry Client properties
    29.6. Avro Schema Registry Client Message Converters
    29.6.1. Avro Schema Registry Message Converter properties
    29.7. Schema Registration and Resolution
    29.7.1. Schema Registration Process (Serialization)
    29.7.2. Schema Resolution Process (Deserialization)
    30. Inter-Application Communication
    30.1. Connecting Multiple Application Instances
    30.2. Instance Index and Instance Count
    30.3. Partitioning
    30.3.1. Configuring Output Bindings for Partitioning
    Configuring Input Bindings for Partitioning
    31. Testing
    31.1. Disabling the test binder autoconfiguration
    32. Health Indicator
    33. Metrics Emitter
    34. Samples
    35. Getting Started
    35.1. Deploying Stream applications on CloudFoundry
    V. Binder Implementations
    36. Apache Kafka Binder
    36.1. Usage
    36.2. Apache Kafka Binder Overview
    36.3. Configuration Options
    36.3.1. Kafka Binder Properties
    36.3.2. Kafka Consumer Properties
    36.3.3. Kafka Producer Properties
    36.3.4. Usage examples
    Example: Setting autoCommitOffset false and relying on manual acking.
    Example: security configuration
    Example: Pausing and Resuming the Consumer
    Using the binder with Apache Kafka 0.10
    Excluding Kafka broker jar from the classpath of the binder based application
    36.4. Error Channels
    36.5. Kafka Metrics
    36.6. Dead-Letter Topic Processing
    36.7. Partitioning with the Kafka Binder
    36.8. Kafka Streams Binding Capabilities of Spring Cloud Stream
    36.8.1. Usage example of high level streams DSL
    36.8.2. Multiple Input bindings on the inbound
    36.8.3. Support for branching in Kafka Streams API
    36.8.4. Message conversion in Spring Cloud Stream Kafka Streams applications
    Outbound serialization
    Inbound Deserialization
    Error handling on Deserialization exceptions
    Handling Non-Deserialization exceptions
    36.8.5. Support for interactive queries
    36.8.6. Kafka Streams properties
    37. RabbitMQ Binder
    37.1. Usage
    37.2. RabbitMQ Binder Overview
    37.3. Configuration Options
    37.3.1. RabbitMQ Binder Properties
    37.3.2. RabbitMQ Consumer Properties
    37.3.3. Rabbit Producer Properties
    37.4. Retry With the RabbitMQ Binder
    37.4.1. Overview
    37.4.2. Putting it All Together
    37.5. Error Channels
    37.6. Dead-Letter Queue Processing
    37.6.1. Non-Partitioned Destinations
    37.6.2. Partitioned Destinations
    republishToDlq=false
    republishToDlq=true
    37.7. Partitioning with the RabbitMQ Binder
    VI. Spring Cloud Bus
    38. Quick Start
    39. Addressing an Instance
    40. Addressing all instances of a service
    41. Service ID must be unique
    42. Customizing the Message Broker
    43. Tracing Bus Events
    44. Broadcasting Your Own Events
    44.1. Registering events in custom packages
    VII. Spring Cloud Sleuth
    45. Introduction
    45.1. Terminology
    45.2. Purpose
    45.2.1. Distributed tracing with Zipkin
    45.2.2. Visualizing errors
    45.2.3. Distributed tracing with Brave
    45.2.4. Live examples
    45.2.5. Log correlation
    JSON Logback with Logstash
    45.2.6. Propagating Span Context
    Baggage vs. Span Tags
    45.3. Adding to the project
    45.3.1. Only Sleuth (log correlation)
    45.3.2. Sleuth with Zipkin via HTTP
    45.3.3. Sleuth with Zipkin via RabbitMQ or Kafka
    46. Additional resources
    47. Features
    47.1. Introduction to Brave
    47.1.1. Tracing
    47.1.2. Tracing
    47.1.3. Local Tracing
    47.1.4. Customizing spans
    47.1.5. Implicitly looking up the current span
    47.1.6. RPC tracing
    One-Way tracing
    48. Sampling
    48.1. Declarative sampling
    48.2. Custom sampling
    48.3. Sampling in Spring Cloud Sleuth
    49. Propagation
    49.1. Propagating extra fields
    49.1.1. Prefixed fields
    49.1.2. Extracting a propagated context
    49.1.3. Sharing span IDs between client and server
    49.1.4. Implementing Propagation
    50. Current Tracing Component
    51. Current Span
    51.1. Setting a span in scope manually
    52. Instrumentation
    53. Span lifecycle
    53.1. Creating and finishing spans
    53.2. Continuing spans
    53.3. Creating spans with an explicit parent
    54. Naming spans
    54.1. @SpanName annotation
    54.2. toString() method
    55. Managing spans with annotations
    55.1. Rationale
    55.2. Creating new spans
    55.3. Continuing spans
    55.4. More advanced tag setting
    55.4.1. Custom extractor
    55.4.2. Resolving expressions for value
    55.4.3. Using toString method
    56. Customizations
    56.1. Spring Integration
    56.2. HTTP
    56.3. TraceFilter
    56.4. Custom service name
    56.5. Customization of reported spans
    56.6. Host locator
    57. Sending spans to Zipkin
    58. Zipkin Stream Span Consumer
    59. Integrations
    59.1. OpenTracing
    59.2. Runnable and Callable
    59.3. Hystrix
    59.3.1. Custom Concurrency Strategy
    59.3.2. Manual Command setting
    59.4. RxJava
    59.5. HTTP integration
    59.5.1. HTTP Filter
    59.5.2. HandlerInterceptor
    59.5.3. Async Servlet support
    59.5.4. WebFlux support
    59.6. HTTP client integration
    59.6.1. Synchronous Rest Template
    59.6.2. Asynchronous Rest Template
    Multiple Asynchronous Rest Templates
    59.6.3. WebClient
    59.6.4. Traverson
    59.7. Feign
    59.8. Asynchronous communication
    59.8.1. @Async annotated methods
    59.8.2. @Scheduled annotated methods
    59.8.3. Executor, ExecutorService and ScheduledExecutorService
    Customization of Executors
    59.9. Messaging
    59.10. Zuul
    60. Running examples
    VIII. Spring Cloud Consul
    61. Install Consul
    62. Consul Agent
    63. Service Discovery with Consul
    63.1. How to activate
    63.2. Registering with Consul
    63.3. HTTP Health Check
    63.3.1. Metadata and Consul tags
    63.3.2. Making the Consul Instance ID Unique
    63.4. Looking up services
    63.4.1. Using Ribbon
    63.4.2. Using the DiscoveryClient
    64. Distributed Configuration with Consul
    64.1. How to activate
    64.2. Customizing
    64.3. Config Watch
    64.4. YAML or Properties with Config
    64.5. git2consul with Config
    64.6. Fail Fast
    65. Consul Retry
    66. Spring Cloud Bus with Consul
    66.1. How to activate
    67. Circuit Breaker with Hystrix
    68. Hystrix metrics aggregation with Turbine and Consul
    IX. Spring Cloud Zookeeper
    69. Install Zookeeper
    70. Service Discovery with Zookeeper
    70.1. How to activate
    70.2. Registering with Zookeeper
    70.3. Using the DiscoveryClient
    71. Using Spring Cloud Zookeeper with Spring Cloud Netflix Components
    71.1. Ribbon with Zookeeper
    72. Spring Cloud Zookeeper and Service Registry
    72.1. Instance Status
    73. Zookeeper Dependencies
    73.1. Using the Zookeeper Dependencies
    73.2. How to activate Zookeeper Dependencies
    73.3. Setting up Zookeeper Dependencies
    73.3.1. Aliases
    73.3.2. Path
    73.3.3. Load balancer type
    73.3.4. Content-Type template and version
    73.3.5. Default headers
    73.3.6. Obligatory dependencies
    73.3.7. Stubs
    73.4. Configuring Spring Cloud Zookeeper Dependencies
    74. Spring Cloud Zookeeper Dependency Watcher
    74.1. How to activate
    74.2. Registering a listener
    74.3. Presence Checker
    75. Distributed Configuration with Zookeeper
    75.1. How to activate
    75.2. Customizing
    75.3. ACLs
    X. Spring Cloud Security
    76. Quickstart
    76.1. OAuth2 Single Sign On
    76.2. OAuth2 Protected Resource
    77. More Detail
    77.1. Single Sign On
    77.2. Token Relay
    77.2.1. Client Token Relay
    77.2.2. Client Token Relay in Zuul Proxy
    77.2.3. Resource Server Token Relay
    78. Configuring Authentication Downstream of a Zuul Proxy
    XI. Spring Cloud for Cloud Foundry
    79. Discovery
    80. Single Sign On
    XII. Spring Cloud Contract
    81. Spring Cloud Contract
    82. Spring Cloud Contract Verifier Introduction
    82.1. Why a Contract Verifier?
    82.1.1. Testing issues
    82.2. Purposes
    82.3. How It Works
    82.3.1. Defining the contract
    82.3.2. Client Side
    82.3.3. Server Side
    82.4. Step-by-step Guide to Consumer Driven Contracts (CDC)
    82.4.1. Technical note
    82.4.2. Consumer side (Loan Issuance)
    82.4.3. Producer side (Fraud Detection server)
    82.4.4. Consumer Side (Loan Issuance) Final Step
    82.5. Dependencies
    82.6. Additional Links
    82.6.1. Spring Cloud Contract video
    82.6.2. Readings
    82.7. Samples
    83. Spring Cloud Contract FAQ
    83.1. Why use Spring Cloud Contract Verifier and not X ?
    83.2. I don’t want to write a contract in Groovy!
    83.3. What is this value(consumer(), producer()) ?
    83.4. How to do Stubs versioning?
    83.4.1. API Versioning
    83.4.2. JAR versioning
    83.4.3. Dev or prod stubs
    83.5. Common repo with contracts
    83.5.1. Repo structure
    83.5.2. Workflow
    83.5.3. Consumer
    83.5.4. Producer
    83.5.5. How can I define messaging contracts per topic not per producer?
    For Maven Project
    For Gradle Project
    83.6. Can I have multiple base classes for tests?
    83.7. How can I debug the request/response being sent by the generated tests client?
    83.7.1. How can I debug the mapping/request/response being sent by WireMock?
    83.7.2. How can I see what got registered in the HTTP server stub?
    83.7.3. Can I reference the request from the response?
    83.7.4. Can I reference text from file?
    84. Spring Cloud Contract Verifier Setup
    84.1. Gradle Project
    84.1.1. Prerequisites
    84.1.2. Add Gradle Plugin with Dependencies
    84.1.3. Gradle and Rest Assured 2.0
    84.1.4. Snapshot Versions for Gradle
    84.1.5. Add stubs
    84.1.6. Run the Plugin
    84.1.7. Default Setup
    84.1.8. Configure Plugin
    84.1.9. Configuration Options
    84.1.10. Single Base Class for All Tests
    84.1.11. Different Base Classes for Contracts
    84.1.12. Invoking Generated Tests
    84.1.13. Spring Cloud Contract Verifier on the Consumer Side
    84.2. Maven Project
    84.2.1. Add maven plugin
    84.2.2. Maven and Rest Assured 2.0
    84.2.3. Snapshot versions for Maven
    84.2.4. Add stubs
    84.2.5. Run plugin
    84.2.6. Configure plugin
    84.2.7. Configuration Options
    84.2.8. Single Base Class for All Tests
    84.2.9. Different base classes for contracts
    84.2.10. Invoking generated tests
    84.2.11. Maven Plugin and STS
    84.3. Stubs and Transitive Dependencies
    84.4. CI Server setup
    84.5. Scenarios
    84.6. Docker Project
    84.6.1. Short intro to Maven, JARs and Binary storage
    84.6.2. How it works
    Environment Variables
    84.6.3. Example of usage
    84.6.4. Server side (nodejs)
    85. Spring Cloud Contract Verifier Messaging
    85.1. Integrations
    85.2. Manual Integration Testing
    85.3. Publisher-Side Test Generation
    85.3.1. Scenario 1: No Input Message
    85.3.2. Scenario 2: Output Triggered by Input
    85.3.3. Scenario 3: No Output Message
    85.4. Consumer Stub Generation
    86. Spring Cloud Contract Stub Runner
    86.1. Snapshot versions
    86.2. Publishing Stubs as JARs
    86.3. Stub Runner Core
    86.3.1. Retrieving stubs
    Stub downloading
    Classpath scanning
    86.3.2. Running stubs
    Limitations
    Running using main app
    HTTP Stubs
    Viewing registered mappings
    Messaging Stubs
    86.4. Stub Runner JUnit Rule
    86.4.1. Maven settings
    86.4.2. Providing fixed ports
    86.4.3. Fluent API
    86.4.4. Stub Runner with Spring
    86.5. Stub Runner Spring Cloud
    86.5.1. Stubbing Service Discovery
    Test profiles and service discovery
    86.5.2. Additional Configuration
    86.6. Stub Runner Boot Application
    86.6.1. How to use it?
    Stub Runner Server
    Stub Runner Server Fat Jar
    Spring Cloud CLI
    86.6.2. Endpoints
    HTTP
    Messaging
    86.6.3. Example
    86.6.4. Stub Runner Boot with Service Discovery
    86.7. Stubs Per Consumer
    86.8. Common
    86.8.1. Common Properties for JUnit and Spring
    86.8.2. Stub Runner Stubs IDs
    86.9. Stub Runner Docker
    86.9.1. How to use it
    86.9.2. Example of client side usage in a non JVM project
    87. Stub Runner for Messaging
    87.1. Stub triggering
    87.1.1. Trigger by Label
    87.1.2. Trigger by Group and Artifact Ids
    87.1.3. Trigger by Artifact Ids
    87.1.4. Trigger All Messages
    87.2. Stub Runner Integration
    87.2.1. Adding the Runner to the Project
    87.2.2. Disabling the functionality
    Scenario 1 (no input message)
    Scenario 2 (output triggered by input)
    Scenario 3 (input with no output)
    87.3. Stub Runner Stream
    87.3.1. Adding the Runner to the Project
    87.3.2. Disabling the functionality
    Scenario 1 (no input message)
    Scenario 2 (output triggered by input)
    Scenario 3 (input with no output)
    87.4. Stub Runner Spring AMQP
    87.4.1. Adding the Runner to the Project
    Triggering the message
    Spring AMQP Test Configuration
    88. Contract DSL
    88.1. Limitations
    88.2. Common Top-Level elements
    88.2.1. Description
    88.2.2. Name
    88.2.3. Ignoring Contracts
    88.2.4. Passing Values from Files
    88.2.5. HTTP Top-Level Elements
    88.3. Request
    88.4. Response
    88.5. Dynamic properties
    88.5.1. Dynamic properties inside the body
    88.5.2. Regular expressions
    88.5.3. Passing Optional Parameters
    88.5.4. Executing Custom Methods on the Server Side
    88.5.5. Referencing the Request from the Response
    88.5.6. Registering Your Own WireMock Extension
    88.5.7. Dynamic Properties in the Matchers Sections
    88.6. JAX-RS Support
    88.7. Async Support
    88.8. Working with Context Paths
    88.9. Messaging Top-Level Elements
    88.9.1. Output Triggered by a Method
    88.9.2. Output Triggered by a Message
    88.9.3. Consumer/Producer
    88.9.4. Common
    88.10. Multiple Contracts in One File
    89. Customization
    89.1. Extending the DSL
    89.1.1. Common JAR
    89.1.2. Adding the Dependency to the Project
    89.1.3. Test the Dependency in the Project’s Dependencies
    89.1.4. Test a Dependency in the Plugin’s Dependencies
    89.1.5. Referencing classes in DSLs
    90. Using the Pluggable Architecture
    90.1. Custom Contract Converter
    90.1.1. Pact Converter
    90.1.2. Pact Contract
    90.1.3. Pact for Producers
    90.1.4. Pact for Consumers
    90.2. Using the Custom Test Generator
    90.3. Using the Custom Stub Generator
    90.4. Using the Custom Stub Runner
    90.5. Using the Custom Stub Downloader
    91. Spring Cloud Contract WireMock
    91.1. Registering Stubs Automatically
    91.2. Using Files to Specify the Stub Bodies
    91.3. Alternative: Using JUnit Rules
    91.4. Relaxed SSL Validation for Rest Template
    91.5. WireMock and Spring MVC Mocks
    91.6. Customization of WireMock configuration
    91.7. Generating Stubs using REST Docs
    91.8. Generating Contracts by Using REST Docs
    92. Migrations
    92.1. 1.0.x → 1.1.x
    92.1.1. New structure of generated stubs
    92.2. 1.1.x → 1.2.x
    92.2.1. Custom HttpServerStub
    92.2.2. New packages for generated tests
    92.2.3. New Methods in TemplateProcessor
    92.2.4. RestAssured 3.0
    92.3. 1.2.x → 2.0.x
    92.3.1. No Camel support
    93. Links
    XIII. Spring Cloud Vault
    94. Quick Start
    95. Client Side Usage
    95.1. Authentication
    96. Authentication methods
    96.1. Token authentication
    96.2. AppId authentication
    96.2.1. Custom UserId
    96.3. AppRole authentication
    96.4. AWS-EC2 authentication
    96.5. AWS-IAM authentication
    96.6. TLS certificate authentication
    96.7. Cubbyhole authentication
    96.8. Kubernetes authentication
    97. Secret Backends
    97.1. Generic Backend
    97.2. Consul
    97.3. RabbitMQ
    97.4. AWS
    98. Database backends
    98.1. Database
    98.2. Apache Cassandra
    98.3. MongoDB
    98.4. MySQL
    98.5. PostgreSQL
    99. Configure PropertySourceLocator behavior
    100. Service Registry Configuration
    101. Vault Client Fail Fast
    102. Vault Client SSL configuration
    103. Lease lifecycle management (renewal and revocation)
    XIV. Appendix: Compendium of Configuration Properties

    Spring Cloud provides tools for developers to quickly build some of + Spring Cloud

    Spring Cloud


    Table of Contents

    1. Features
    I. Cloud Native Applications
    2. Spring Cloud Context: Application Context Services
    2.1. The Bootstrap Application Context
    2.2. Application Context Hierarchies
    2.3. Changing the Location of Bootstrap Properties
    2.4. Overriding the Values of Remote Properties
    2.5. Customizing the Bootstrap Configuration
    2.6. Customizing the Bootstrap Property Sources
    2.7. Environment Changes
    2.8. Refresh Scope
    2.9. Encryption and Decryption
    2.10. Endpoints
    3. Spring Cloud Commons: Common Abstractions
    3.1. @EnableDiscoveryClient
    3.1.1. Health Indicator
    3.2. ServiceRegistry
    3.2.1. ServiceRegistry Auto-Registration
    3.2.2. Service Registry Actuator Endpoint
    3.3. Spring RestTemplate as a Load Balancer Client
    3.4. Spring WebClient as a Load Balancer Client
    3.4.1. Retrying Failed Requests
    3.5. Multiple RestTemplate objects
    3.6. Spring WebFlux WebClient as a Load Balancer Client
    3.7. Ignore Network Interfaces
    3.8. HTTP Client Factories
    3.9. Enabled Features
    3.9.1. Feature types
    3.9.2. Declaring features
    II. Spring Cloud Config
    4. Quick Start
    4.1. Client Side Usage
    5. Spring Cloud Config Server
    5.1. Environment Repository
    5.1.1. Git Backend
    Placeholders in Git URI
    Pattern Matching and Multiple Repositories
    Authentication
    Authentication with AWS CodeCommit
    Git SSH configuration using properties
    Placeholders in Git Search Paths
    Force pull in Git Repositories
    5.1.2. Version Control Backend Filesystem Use
    5.1.3. File System Backend
    5.1.4. Vault Backend
    Multiple Properties Sources
    5.1.5. Sharing Configuration With All Applications
    File Based Repositories
    Vault Server
    5.1.6. JDBC Backend
    5.1.7. Composite Environment Repositories
    Custom Composite Environment Repositories
    5.1.8. Property Overrides
    5.2. Health Indicator
    5.3. Security
    5.4. Encryption and Decryption
    5.5. Key Management
    5.6. Creating a Key Store for Testing
    5.7. Using Multiple Keys and Key Rotation
    5.8. Serving Encrypted Properties
    6. Serving Alternative Formats
    7. Serving Plain Text
    8. Embedding the Config Server
    9. Push Notifications and Spring Cloud Bus
    10. Spring Cloud Config Client
    10.1. Config First Bootstrap
    10.2. Discovery First Bootstrap
    10.3. Config Client Fail Fast
    10.4. Config Client Retry
    10.5. Locating Remote Configuration Resources
    10.6. Security
    10.6.1. Health Indicator
    10.6.2. Providing A Custom RestTemplate
    10.6.3. Vault
    10.7. Vault
    10.7.1. Nested Keys In Vault
    III. Spring Cloud Netflix
    11. Service Discovery: Eureka Clients
    11.1. How to Include Eureka Client
    11.2. Registering with Eureka
    11.3. Authenticating with the Eureka Server
    11.4. Status Page and Health Indicator
    11.5. Registering a Secure Application
    11.6. Eureka’s Health Checks
    11.7. Eureka Metadata for Instances and Clients
    11.7.1. Using Eureka on Cloudfoundry
    11.7.2. Using Eureka on AWS
    11.7.3. Changing the Eureka Instance ID
    11.8. Using the EurekaClient
    11.8.1. EurekaClient without Jersey
    11.9. Alternatives to the native Netflix EurekaClient
    11.10. Why is it so Slow to Register a Service?
    11.11. Zones
    12. Service Discovery: Eureka Server
    12.1. How to Include Eureka Server
    12.2. How to Run a Eureka Server
    12.3. High Availability, Zones and Regions
    12.4. Standalone Mode
    12.5. Peer Awareness
    12.6. Prefer IP Address
    13. Circuit Breaker: Hystrix Clients
    13.1. How to Include Hystrix
    13.2. Propagating the Security Context or using Spring Scopes
    13.3. Health Indicator
    13.4. Hystrix Metrics Stream
    14. Circuit Breaker: Hystrix Dashboard
    15. Hystrix Timeouts And Ribbon Clients
    15.1. How to Include Hystrix Dashboard
    15.2. Turbine
    15.3. Turbine Stream
    16. Client Side Load Balancer: Ribbon
    16.1. How to Include Ribbon
    16.2. Customizing the Ribbon Client
    16.3. Customizing default for all Ribbon Clients
    16.4. Customizing the Ribbon Client using properties
    16.5. Using Ribbon with Eureka
    16.6. Example: How to Use Ribbon Without Eureka
    16.7. Example: Disable Eureka use in Ribbon
    16.8. Using the Ribbon API Directly
    16.9. Caching of Ribbon Configuration
    16.10. How to Configure Hystrix thread pools
    16.11. How to Provide a Key to Ribbon’s IRule
    17. External Configuration: Archaius
    18. Router and Filter: Zuul
    18.1. How to Include Zuul
    18.2. Embedded Zuul Reverse Proxy
    18.3. Zuul Http Client
    18.4. Cookies and Sensitive Headers
    18.5. Ignored Headers
    18.6. Management Endpoints
    18.6.1. Routes Endpoint
    18.6.2. Filters Endpoint
    18.7. Strangulation Patterns and Local Forwards
    18.8. Uploading Files through Zuul
    18.9. Query String Encoding
    18.10. Plain Embedded Zuul
    18.11. Disable Zuul Filters
    18.12. Providing Hystrix Fallbacks For Routes
    18.13. Zuul Timeouts
    18.14. Rewriting Location header
    18.15. Zuul Developer Guide
    18.15.1. The Zuul Servlet
    18.15.2. Zuul RequestContext
    18.15.3. @EnableZuulProxy vs. @EnableZuulServer
    18.15.4. @EnableZuulServer Filters
    18.15.5. @EnableZuulProxy Filters
    18.15.6. Custom Zuul Filter examples
    18.15.7. How to Write a Pre Filter
    18.15.8. How to Write a Route Filter
    18.15.9. How to Write a Post Filter
    18.15.10. How Zuul Errors Work
    18.15.11. Zuul Eager Application Context Loading
    19. Polyglot support with Sidecar
    20. Metrics Backend: Atlas
    20.1. Using Atlas
    21. Retrying Failed Requests
    21.1. BackOff Policies
    21.2. Configuration
    21.2.1. Zuul
    22. HTTP Clients
    IV. Spring Cloud OpenFeign
    23. Declarative REST Client: Feign
    23.1. How to Include Feign
    23.2. Overriding Feign Defaults
    23.3. Creating Feign Clients Manually
    23.4. Feign Hystrix Support
    23.5. Feign Hystrix Fallbacks
    23.6. Feign and @Primary
    23.7. Feign Inheritance Support
    23.8. Feign request/response compression
    23.9. Feign logging
    V. Spring Cloud Stream
    24. Introducing Spring Cloud Stream
    25. Main Concepts
    25.1. Application Model
    25.1.1. Fat JAR
    25.2. The Binder Abstraction
    25.3. Persistent Publish-Subscribe Support
    25.4. Consumer Groups
    25.5. Consumer Types
    25.5.1. Durability
    25.6. Partitioning Support
    26. Programming Model
    26.1. Declaring and Binding Producers and Consumers
    26.1.1. Triggering Binding Via @EnableBinding
    26.1.2. @Input and @Output
    Customizing Channel Names
    Source, Sink, and Processor
    26.1.3. Accessing Bound Channels
    Injecting the Bound Interfaces
    Injecting Channels Directly
    26.1.4. Producing and Consuming Messages
    Native Spring Integration Support
    Spring Integration Error Channel Support
    Message Channel Binders and Error Channels
    Using @StreamListener for Automatic Content Type Handling
    Using @StreamListener for dispatching messages to multiple methods
    Using Polled Consumers
    26.1.5. Reactive Programming Support
    Reactor-based handlers
    Reactive Sources
    26.1.6. Aggregation
    Configuring aggregate application
    Configuring binding service properties for non self contained aggregate application
    27. Binders
    27.1. Producers and Consumers
    27.2. Binder SPI
    27.3. Binder Detection
    27.3.1. Classpath Detection
    27.4. Multiple Binders on the Classpath
    27.5. Connecting to Multiple Systems
    27.6. Binder configuration properties
    28. Configuration Options
    28.1. Spring Cloud Stream Properties
    28.2. Binding Properties
    28.2.1. Properties for Use of Spring Cloud Stream
    28.2.2. Consumer properties
    28.2.3. Producer Properties
    28.3. Using dynamically bound destinations
    29. Content Type and Transformation
    29.1. MIME types
    29.2. Channel contentType and Message Headers
    29.3. ContentType handling for output channels
    29.4. ContentType handling for input channels
    29.5. Customizing message conversion
    29.6. @StreamListener and Message Conversion
    30. Schema evolution support
    30.1. Apache Avro Message Converters
    30.2. Converters with schema support
    30.3. Schema Registry Support
    30.4. Schema Registry Server
    30.4.1. Schema Registry Server API
    POST /
    GET /{subject}/{format}/{version}
    GET /{subject}/{format}
    GET /schemas/{id}
    DELETE /{subject}/{format}/{version}
    DELETE /schemas/{id}
    DELETE /{subject}
    30.5. Schema Registry Client
    30.5.1. Using Confluent’s Schema Registry
    30.5.2. Schema Registry Client properties
    30.6. Avro Schema Registry Client Message Converters
    30.6.1. Avro Schema Registry Message Converter properties
    30.7. Schema Registration and Resolution
    30.7.1. Schema Registration Process (Serialization)
    30.7.2. Schema Resolution Process (Deserialization)
    31. Inter-Application Communication
    31.1. Connecting Multiple Application Instances
    31.2. Instance Index and Instance Count
    31.3. Partitioning
    31.3.1. Configuring Output Bindings for Partitioning
    Configuring Input Bindings for Partitioning
    32. Testing
    32.1. Disabling the test binder autoconfiguration
    33. Health Indicator
    34. Metrics Emitter
    35. Samples
    36. Getting Started
    36.1. Deploying Stream applications on CloudFoundry
    VI. Binder Implementations
    37. Apache Kafka Binder
    37.1. Usage
    37.2. Apache Kafka Binder Overview
    37.3. Configuration Options
    37.3.1. Kafka Binder Properties
    37.3.2. Kafka Consumer Properties
    37.3.3. Kafka Producer Properties
    37.3.4. Usage examples
    Example: Setting autoCommitOffset false and relying on manual acking.
    Example: security configuration
    Example: Pausing and Resuming the Consumer
    Using the binder with Apache Kafka 0.10
    Excluding Kafka broker jar from the classpath of the binder based application
    37.4. Error Channels
    37.5. Kafka Metrics
    37.6. Dead-Letter Topic Processing
    37.7. Partitioning with the Kafka Binder
    37.8. Kafka Streams Binding Capabilities of Spring Cloud Stream
    37.8.1. Usage example of high level streams DSL
    37.8.2. Multiple Input bindings on the inbound
    37.8.3. Support for branching in Kafka Streams API
    37.8.4. Message conversion in Spring Cloud Stream Kafka Streams applications
    Outbound serialization
    Inbound Deserialization
    Error handling on Deserialization exceptions
    Handling Non-Deserialization exceptions
    37.8.5. Support for interactive queries
    37.8.6. Kafka Streams properties
    38. RabbitMQ Binder
    38.1. Usage
    38.2. RabbitMQ Binder Overview
    38.3. Configuration Options
    38.3.1. RabbitMQ Binder Properties
    38.3.2. RabbitMQ Consumer Properties
    38.3.3. Rabbit Producer Properties
    38.4. Retry With the RabbitMQ Binder
    38.4.1. Overview
    38.4.2. Putting it All Together
    38.5. Error Channels
    38.6. Dead-Letter Queue Processing
    38.6.1. Non-Partitioned Destinations
    38.6.2. Partitioned Destinations
    republishToDlq=false
    republishToDlq=true
    38.7. Partitioning with the RabbitMQ Binder
    VII. Spring Cloud Bus
    39. Quick Start
    40. Addressing an Instance
    41. Addressing all instances of a service
    42. Service ID must be unique
    43. Customizing the Message Broker
    44. Tracing Bus Events
    45. Broadcasting Your Own Events
    45.1. Registering events in custom packages
    VIII. Spring Cloud Sleuth
    46. Introduction
    46.1. Terminology
    46.2. Purpose
    46.2.1. Distributed tracing with Zipkin
    46.2.2. Visualizing errors
    46.2.3. Distributed tracing with Brave
    46.2.4. Live examples
    46.2.5. Log correlation
    JSON Logback with Logstash
    46.2.6. Propagating Span Context
    Baggage vs. Span Tags
    46.3. Adding to the project
    46.3.1. Only Sleuth (log correlation)
    46.3.2. Sleuth with Zipkin via HTTP
    46.3.3. Sleuth with Zipkin via RabbitMQ or Kafka
    47. Additional resources
    48. Features
    48.1. Introduction to Brave
    48.1.1. Tracing
    48.1.2. Tracing
    48.1.3. Local Tracing
    48.1.4. Customizing spans
    48.1.5. Implicitly looking up the current span
    48.1.6. RPC tracing
    One-Way tracing
    49. Sampling
    49.1. Declarative sampling
    49.2. Custom sampling
    49.3. Sampling in Spring Cloud Sleuth
    50. Propagation
    50.1. Propagating extra fields
    50.1.1. Prefixed fields
    50.1.2. Extracting a propagated context
    50.1.3. Sharing span IDs between client and server
    50.1.4. Implementing Propagation
    51. Current Tracing Component
    52. Current Span
    52.1. Setting a span in scope manually
    53. Instrumentation
    54. Span lifecycle
    54.1. Creating and finishing spans
    54.2. Continuing spans
    54.3. Creating spans with an explicit parent
    55. Naming spans
    55.1. @SpanName annotation
    55.2. toString() method
    56. Managing spans with annotations
    56.1. Rationale
    56.2. Creating new spans
    56.3. Continuing spans
    56.4. More advanced tag setting
    56.4.1. Custom extractor
    56.4.2. Resolving expressions for value
    56.4.3. Using toString method
    57. Customizations
    57.1. Spring Integration
    57.2. HTTP
    57.3. TraceFilter
    57.4. Custom service name
    57.5. Customization of reported spans
    57.6. Host locator
    58. Sending spans to Zipkin
    59. Zipkin Stream Span Consumer
    60. Integrations
    60.1. OpenTracing
    60.2. Runnable and Callable
    60.3. Hystrix
    60.3.1. Custom Concurrency Strategy
    60.3.2. Manual Command setting
    60.4. RxJava
    60.5. HTTP integration
    60.5.1. HTTP Filter
    60.5.2. HandlerInterceptor
    60.5.3. Async Servlet support
    60.5.4. WebFlux support
    60.6. HTTP client integration
    60.6.1. Synchronous Rest Template
    60.6.2. Asynchronous Rest Template
    Multiple Asynchronous Rest Templates
    60.6.3. WebClient
    60.6.4. Traverson
    60.7. Feign
    60.8. Asynchronous communication
    60.8.1. @Async annotated methods
    60.8.2. @Scheduled annotated methods
    60.8.3. Executor, ExecutorService and ScheduledExecutorService
    Customization of Executors
    60.9. Messaging
    60.10. Zuul
    61. Running examples
    IX. Spring Cloud Consul
    62. Install Consul
    63. Consul Agent
    64. Service Discovery with Consul
    64.1. How to activate
    64.2. Registering with Consul
    64.3. HTTP Health Check
    64.3.1. Metadata and Consul tags
    64.3.2. Making the Consul Instance ID Unique
    64.4. Looking up services
    64.4.1. Using Ribbon
    64.4.2. Using the DiscoveryClient
    65. Distributed Configuration with Consul
    65.1. How to activate
    65.2. Customizing
    65.3. Config Watch
    65.4. YAML or Properties with Config
    65.5. git2consul with Config
    65.6. Fail Fast
    66. Consul Retry
    67. Spring Cloud Bus with Consul
    67.1. How to activate
    68. Circuit Breaker with Hystrix
    69. Hystrix metrics aggregation with Turbine and Consul
    X. Spring Cloud Zookeeper
    70. Install Zookeeper
    71. Service Discovery with Zookeeper
    71.1. How to activate
    71.2. Registering with Zookeeper
    71.3. Using the DiscoveryClient
    72. Using Spring Cloud Zookeeper with Spring Cloud Netflix Components
    72.1. Ribbon with Zookeeper
    73. Spring Cloud Zookeeper and Service Registry
    73.1. Instance Status
    74. Zookeeper Dependencies
    74.1. Using the Zookeeper Dependencies
    74.2. How to activate Zookeeper Dependencies
    74.3. Setting up Zookeeper Dependencies
    74.3.1. Aliases
    74.3.2. Path
    74.3.3. Load balancer type
    74.3.4. Content-Type template and version
    74.3.5. Default headers
    74.3.6. Obligatory dependencies
    74.3.7. Stubs
    74.4. Configuring Spring Cloud Zookeeper Dependencies
    75. Spring Cloud Zookeeper Dependency Watcher
    75.1. How to activate
    75.2. Registering a listener
    75.3. Presence Checker
    76. Distributed Configuration with Zookeeper
    76.1. How to activate
    76.2. Customizing
    76.3. ACLs
    XI. Spring Cloud Security
    77. Quickstart
    77.1. OAuth2 Single Sign On
    77.2. OAuth2 Protected Resource
    78. More Detail
    78.1. Single Sign On
    78.2. Token Relay
    78.2.1. Client Token Relay
    78.2.2. Client Token Relay in Zuul Proxy
    78.2.3. Resource Server Token Relay
    79. Configuring Authentication Downstream of a Zuul Proxy
    XII. Spring Cloud for Cloud Foundry
    80. Discovery
    81. Single Sign On
    XIII. Spring Cloud Contract
    82. Spring Cloud Contract
    83. Spring Cloud Contract Verifier Introduction
    83.1. Why a Contract Verifier?
    83.1.1. Testing issues
    83.2. Purposes
    83.3. How It Works
    83.3.1. Defining the contract
    83.3.2. Client Side
    83.3.3. Server Side
    83.4. Step-by-step Guide to Consumer Driven Contracts (CDC)
    83.4.1. Technical note
    83.4.2. Consumer side (Loan Issuance)
    83.4.3. Producer side (Fraud Detection server)
    83.4.4. Consumer Side (Loan Issuance) Final Step
    83.5. Dependencies
    83.6. Additional Links
    83.6.1. Spring Cloud Contract video
    83.6.2. Readings
    83.7. Samples
    84. Spring Cloud Contract FAQ
    84.1. Why use Spring Cloud Contract Verifier and not X ?
    84.2. I don’t want to write a contract in Groovy!
    84.3. What is this value(consumer(), producer()) ?
    84.4. How to do Stubs versioning?
    84.4.1. API Versioning
    84.4.2. JAR versioning
    84.4.3. Dev or prod stubs
    84.5. Common repo with contracts
    84.5.1. Repo structure
    84.5.2. Workflow
    84.5.3. Consumer
    84.5.4. Producer
    84.5.5. How can I define messaging contracts per topic not per producer?
    For Maven Project
    For Gradle Project
    84.6. Can I have multiple base classes for tests?
    84.7. How can I debug the request/response being sent by the generated tests client?
    84.7.1. How can I debug the mapping/request/response being sent by WireMock?
    84.7.2. How can I see what got registered in the HTTP server stub?
    84.7.3. Can I reference the request from the response?
    84.7.4. Can I reference text from file?
    85. Spring Cloud Contract Verifier Setup
    85.1. Gradle Project
    85.1.1. Prerequisites
    85.1.2. Add Gradle Plugin with Dependencies
    85.1.3. Gradle and Rest Assured 2.0
    85.1.4. Snapshot Versions for Gradle
    85.1.5. Add stubs
    85.1.6. Run the Plugin
    85.1.7. Default Setup
    85.1.8. Configure Plugin
    85.1.9. Configuration Options
    85.1.10. Single Base Class for All Tests
    85.1.11. Different Base Classes for Contracts
    85.1.12. Invoking Generated Tests
    85.1.13. Spring Cloud Contract Verifier on the Consumer Side
    85.2. Maven Project
    85.2.1. Add maven plugin
    85.2.2. Maven and Rest Assured 2.0
    85.2.3. Snapshot versions for Maven
    85.2.4. Add stubs
    85.2.5. Run plugin
    85.2.6. Configure plugin
    85.2.7. Configuration Options
    85.2.8. Single Base Class for All Tests
    85.2.9. Different base classes for contracts
    85.2.10. Invoking generated tests
    85.2.11. Maven Plugin and STS
    85.3. Stubs and Transitive Dependencies
    85.4. CI Server setup
    85.5. Scenarios
    85.6. Docker Project
    85.6.1. Short intro to Maven, JARs and Binary storage
    85.6.2. How it works
    Environment Variables
    85.6.3. Example of usage
    85.6.4. Server side (nodejs)
    86. Spring Cloud Contract Verifier Messaging
    86.1. Integrations
    86.2. Manual Integration Testing
    86.3. Publisher-Side Test Generation
    86.3.1. Scenario 1: No Input Message
    86.3.2. Scenario 2: Output Triggered by Input
    86.3.3. Scenario 3: No Output Message
    86.4. Consumer Stub Generation
    87. Spring Cloud Contract Stub Runner
    87.1. Snapshot versions
    87.2. Publishing Stubs as JARs
    87.3. Stub Runner Core
    87.3.1. Retrieving stubs
    Stub downloading
    Classpath scanning
    87.3.2. Running stubs
    Limitations
    Running using main app
    HTTP Stubs
    Viewing registered mappings
    Messaging Stubs
    87.4. Stub Runner JUnit Rule
    87.4.1. Maven settings
    87.4.2. Providing fixed ports
    87.4.3. Fluent API
    87.4.4. Stub Runner with Spring
    87.5. Stub Runner Spring Cloud
    87.5.1. Stubbing Service Discovery
    Test profiles and service discovery
    87.5.2. Additional Configuration
    87.6. Stub Runner Boot Application
    87.6.1. How to use it?
    Stub Runner Server
    Stub Runner Server Fat Jar
    Spring Cloud CLI
    87.6.2. Endpoints
    HTTP
    Messaging
    87.6.3. Example
    87.6.4. Stub Runner Boot with Service Discovery
    87.7. Stubs Per Consumer
    87.8. Common
    87.8.1. Common Properties for JUnit and Spring
    87.8.2. Stub Runner Stubs IDs
    87.9. Stub Runner Docker
    87.9.1. How to use it
    87.9.2. Example of client side usage in a non JVM project
    88. Stub Runner for Messaging
    88.1. Stub triggering
    88.1.1. Trigger by Label
    88.1.2. Trigger by Group and Artifact Ids
    88.1.3. Trigger by Artifact Ids
    88.1.4. Trigger All Messages
    88.2. Stub Runner Integration
    88.2.1. Adding the Runner to the Project
    88.2.2. Disabling the functionality
    Scenario 1 (no input message)
    Scenario 2 (output triggered by input)
    Scenario 3 (input with no output)
    88.3. Stub Runner Stream
    88.3.1. Adding the Runner to the Project
    88.3.2. Disabling the functionality
    Scenario 1 (no input message)
    Scenario 2 (output triggered by input)
    Scenario 3 (input with no output)
    88.4. Stub Runner Spring AMQP
    88.4.1. Adding the Runner to the Project
    Triggering the message
    Spring AMQP Test Configuration
    89. Contract DSL
    89.1. Limitations
    89.2. Common Top-Level elements
    89.2.1. Description
    89.2.2. Name
    89.2.3. Ignoring Contracts
    89.2.4. Passing Values from Files
    89.2.5. HTTP Top-Level Elements
    89.3. Request
    89.4. Response
    89.5. Dynamic properties
    89.5.1. Dynamic properties inside the body
    89.5.2. Regular expressions
    89.5.3. Passing Optional Parameters
    89.5.4. Executing Custom Methods on the Server Side
    89.5.5. Referencing the Request from the Response
    89.5.6. Registering Your Own WireMock Extension
    89.5.7. Dynamic Properties in the Matchers Sections
    89.6. JAX-RS Support
    89.7. Async Support
    89.8. Working with Context Paths
    89.9. Messaging Top-Level Elements
    89.9.1. Output Triggered by a Method
    89.9.2. Output Triggered by a Message
    89.9.3. Consumer/Producer
    89.9.4. Common
    89.10. Multiple Contracts in One File
    90. Customization
    90.1. Extending the DSL
    90.1.1. Common JAR
    90.1.2. Adding the Dependency to the Project
    90.1.3. Test the Dependency in the Project’s Dependencies
    90.1.4. Test a Dependency in the Plugin’s Dependencies
    90.1.5. Referencing classes in DSLs
    91. Using the Pluggable Architecture
    91.1. Custom Contract Converter
    91.1.1. Pact Converter
    91.1.2. Pact Contract
    91.1.3. Pact for Producers
    91.1.4. Pact for Consumers
    91.2. Using the Custom Test Generator
    91.3. Using the Custom Stub Generator
    91.4. Using the Custom Stub Runner
    91.5. Using the Custom Stub Downloader
    92. Spring Cloud Contract WireMock
    92.1. Registering Stubs Automatically
    92.2. Using Files to Specify the Stub Bodies
    92.3. Alternative: Using JUnit Rules
    92.4. Relaxed SSL Validation for Rest Template
    92.5. WireMock and Spring MVC Mocks
    92.6. Customization of WireMock configuration
    92.7. Generating Stubs using REST Docs
    92.8. Generating Contracts by Using REST Docs
    93. Migrations
    93.1. 1.0.x → 1.1.x
    93.1.1. New structure of generated stubs
    93.2. 1.1.x → 1.2.x
    93.2.1. Custom HttpServerStub
    93.2.2. New packages for generated tests
    93.2.3. New Methods in TemplateProcessor
    93.2.4. RestAssured 3.0
    93.3. 1.2.x → 2.0.x
    93.3.1. No Camel support
    94. Links
    XIV. Spring Cloud Vault
    95. Quick Start
    96. Client Side Usage
    96.1. Authentication
    97. Authentication methods
    97.1. Token authentication
    97.2. AppId authentication
    97.2.1. Custom UserId
    97.3. AppRole authentication
    97.4. AWS-EC2 authentication
    97.5. AWS-IAM authentication
    97.6. TLS certificate authentication
    97.7. Cubbyhole authentication
    97.8. Kubernetes authentication
    98. Secret Backends
    98.1. Generic Backend
    98.2. Consul
    98.3. RabbitMQ
    98.4. AWS
    99. Database backends
    99.1. Database
    99.2. Apache Cassandra
    99.3. MongoDB
    99.4. MySQL
    99.5. PostgreSQL
    100. Configure PropertySourceLocator behavior
    101. Service Registry Configuration
    102. Vault Client Fail Fast
    103. Vault Client SSL configuration
    104. Lease lifecycle management (renewal and revocation)
    XV. Spring Cloud Gateway
    105. How to Include Spring Cloud Gateway
    106. Glossary
    107. How It Works
    108. Route Predicate Factories
    108.1. After Route Predicate Factory
    108.2. Before Route Predicate Factory
    108.3. Between Route Predicate Factory
    108.4. Cookie Route Predicate Factory
    108.5. Header Route Predicate Factory
    108.6. Host Route Predicate Factory
    108.7. Method Route Predicate Factory
    108.8. Path Route Predicate Factory
    108.9. Query Route Predicate Factory
    108.10. RemoteAddr Route Predicate Factory
    109. GatewayFilter Factories
    109.1. AddRequestHeader GatewayFilter Factory
    109.2. AddRequestParameter GatewayFilter Factory
    109.3. AddResponseHeader GatewayFilter Factory
    109.4. Hystrix GatewayFilter Factory
    109.5. PrefixPath GatewayFilter Factory
    109.6. PreserveHostHeader GatewayFilter Factory
    109.7. RequestRateLimiter GatewayFilter Factory
    109.8. RedirectTo GatewayFilter Factory
    109.9. RemoveNonProxyHeaders GatewayFilter Factory
    109.10. RemoveRequestHeader GatewayFilter Factory
    109.11. RemoveResponseHeader GatewayFilter Factory
    109.12. RewritePath GatewayFilter Factory
    109.13. SaveSession GatewayFilter Factory
    109.14. SecureHeaders GatewayFilter Factory
    109.15. SetPath GatewayFilter Factory
    109.16. SetResponseHeader GatewayFilter Factory
    109.17. SetStatus GatewayFilter Factory
    109.18. StripPrefix GatewayFilter Factory
    110. Global Filters
    110.1. Combined Global Filter and GatewayFilter Ordering
    110.2. Forward Routing Filter
    110.3. LoadBalancerClient Filter
    110.4. Netty Routing Filter
    110.5. Netty Write Response Filter
    110.6. RouteToRequestUrl Filter
    110.7. Websocket Routing Filter
    111. Configuration
    111.1. Fluent Java Routes API
    111.2. DiscoveryClient Route Definition Locator
    112. Actuator API
    113. Developer Guide
    113.1. Writing Custom Route Predicate Factories
    113.2. Writing Custom GatewayFilter Factories
    113.3. Writing Custom Global Filters
    113.4. Writing Custom Route Locators and Writers
    114. Building a Simple Gateway Using Spring MVC
    XVI. Appendix: Compendium of Configuration Properties

    Spring Cloud provides tools for developers to quickly build some of the common patterns in distributed systems (e.g. configuration management, service discovery, circuit breakers, intelligent routing, micro-proxy, control bus). Coordination of @@ -1456,7 +1456,7 @@ Spring Cloud will auto configure a transport client based on Spring </exclusions> </dependency>

    11.9 Alternatives to the native Netflix EurekaClient

    You don’t have to use the raw Netflix EurekaClient and usually it is more convenient to use it behind a wrapper of some sort. Spring -Cloud has support for Feign (a REST client +Cloud has support for Feign (a REST client builder) and also Spring RestTemplate using the logical Eureka service identifiers (VIPs) instead of physical URLs. To configure Ribbon with a fixed list of physical servers you @@ -2457,8 +2457,205 @@ Zuul for you. However you can also provide your own HTTP clients customized how yourself. To do this you can either create a bean of type ClosableHttpClient if you are using the Apache Http Cient, or OkHttpClient if you are using OK HTTP.

    [Note]Note

    When you create your own HTTP client you are also responsible for implementing the correct connection management strategies for these clients. Doing this improperly -can result in resource management issues.

    Part IV. Spring Cloud Stream

    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.

    23. Introducing Spring Cloud Stream

    Spring Cloud Stream is a framework for building message-driven microservice applications. +can result in resource management issues.

    Part IV. Spring Cloud OpenFeign

    1.3.5.BUILD-SNAPSHOT

    This project provides OpenFeign integrations for Spring Boot apps through autoconfiguration +and binding to the Spring Environment and other Spring programming model idioms.

    23. Declarative REST Client: Feign

    Feign is a declarative web service client. It makes writing web service clients easier. To use Feign create an interface and annotate it. It has pluggable annotation support including Feign annotations and JAX-RS annotations. Feign also supports pluggable encoders and decoders. Spring Cloud adds support for Spring MVC annotations and for using the same HttpMessageConverters used by default in Spring Web. Spring Cloud integrates Ribbon and Eureka to provide a load balanced http client when using Feign.

    23.1 How to Include Feign

    To include Feign in your project use the starter with group org.springframework.cloud +and artifact id spring-cloud-starter-openfeign. See the Spring Cloud Project page +for details on setting up your build system with the current Spring Cloud Release Train.

    Example spring boot app

    @SpringBootApplication
    +@EnableFeignClients
    +public class Application {
    +
    +    public static void main(String[] args) {
    +        SpringApplication.run(Application.class, args);
    +    }
    +
    +}

    StoreClient.java.  +

    @FeignClient("stores")
    +public interface StoreClient {
    +    @RequestMapping(method = RequestMethod.GET, value = "/stores")
    +    List<Store> getStores();
    +
    +    @RequestMapping(method = RequestMethod.POST, value = "/stores/{storeId}", consumes = "application/json")
    +    Store update(@PathVariable("storeId") Long storeId, Store store);
    +}

    +

    In the @FeignClient annotation the String value ("stores" above) is +an arbitrary client name, which is used to create a Ribbon load +balancer (see below for details of Ribbon +support). You can also specify a URL using the url attribute +(absolute value or just a hostname). The name of the bean in the +application context is the fully qualified name of the interface. +To specify your own alias value you can use the qualifier value +of the @FeignClient annotation.

    The Ribbon client above will want to discover the physical addresses +for the "stores" service. If your application is a Eureka client then +it will resolve the service in the Eureka service registry. If you +don’t want to use Eureka, you can simply configure a list of servers +in your external configuration (see +above for example).

    23.2 Overriding Feign Defaults

    A central concept in Spring Cloud’s Feign support is that of the named client. Each feign client is part of an ensemble of components that work together to contact a remote server on demand, and the ensemble has a name that you give it as an application developer using the @FeignClient annotation. Spring Cloud creates a new ensemble as an +ApplicationContext on demand for each named client using FeignClientsConfiguration. This contains (amongst other things) an feign.Decoder, a feign.Encoder, and a feign.Contract.

    Spring Cloud lets you take full control of the feign client by declaring additional configuration (on top of the FeignClientsConfiguration) using @FeignClient. Example:

    @FeignClient(name = "stores", configuration = FooConfiguration.class)
    +public interface StoreClient {
    +    //..
    +}

    In this case the client is composed from the components already in FeignClientsConfiguration together with any in FooConfiguration (where the latter will override the former).

    [Note]Note

    FooConfiguration does not need to be annotated with @Configuration. However, if it is, then take care to exclude it from any @ComponentScan that would otherwise include this configuration as it will become the default source for feign.Decoder, feign.Encoder, feign.Contract, etc., when specified. This can be avoided by putting it in a separate, non-overlapping package from any @ComponentScan or @SpringBootApplication, or it can be explicitly excluded in @ComponentScan.

    [Note]Note

    The serviceId attribute is now deprecated in favor of the name attribute.

    [Warning]Warning

    Previously, using the url attribute, did not require the name attribute. Using name is now required.

    Placeholders are supported in the name and url attributes.

    @FeignClient(name = "${feign.name}", url = "${feign.url}")
    +public interface StoreClient {
    +    //..
    +}

    Spring Cloud Netflix provides the following beans by default for feign (BeanType beanName: ClassName):

    • Decoder feignDecoder: ResponseEntityDecoder (which wraps a SpringDecoder)
    • Encoder feignEncoder: SpringEncoder
    • Logger feignLogger: Slf4jLogger
    • Contract feignContract: SpringMvcContract
    • Feign.Builder feignBuilder: HystrixFeign.Builder
    • Client feignClient: if Ribbon is enabled it is a LoadBalancerFeignClient, otherwise the default feign client is used.

    The OkHttpClient and ApacheHttpClient feign clients can be used by setting feign.okhttp.enabled or feign.httpclient.enabled to true, respectively, and having them on the classpath. +You can customize the HTTP client used by providing a bean of either ClosableHttpClient when using Apache or OkHttpClient whe using OK HTTP.

    Spring Cloud Netflix does not provide the following beans by default for feign, but still looks up beans of these types from the application context to create the feign client:

    • Logger.Level
    • Retryer
    • ErrorDecoder
    • Request.Options
    • Collection<RequestInterceptor>
    • SetterFactory

    Creating a bean of one of those type and placing it in a @FeignClient configuration (such as FooConfiguration above) allows you to override each one of the beans described. Example:

    @Configuration
    +public class FooConfiguration {
    +    @Bean
    +    public Contract feignContract() {
    +        return new feign.Contract.Default();
    +    }
    +
    +    @Bean
    +    public BasicAuthRequestInterceptor basicAuthRequestInterceptor() {
    +        return new BasicAuthRequestInterceptor("user", "password");
    +    }
    +}

    This replaces the SpringMvcContract with feign.Contract.Default and adds a RequestInterceptor to the collection of RequestInterceptor.

    @FeignClient also can be configured using configuration properties.

    application.yml

    feign:
    +  client:
    +    config:
    +      feignName:
    +        connectTimeout: 5000
    +        readTimeout: 5000
    +        loggerLevel: full
    +        errorDecoder: com.example.SimpleErrorDecoder
    +        retryer: com.example.SimpleRetryer
    +        requestInterceptors:
    +          - com.example.FooRequestInterceptor
    +          - com.example.BarRequestInterceptor
    +        decode404: false
    +        encoder: com.example.SimpleEncoder
    +        decoder: com.example.SimpleDecoder
    +        contract: com.example.SimpleContract

    Default configurations can be specified in the @EnableFeignClients attribute defaultConfiguration in a similar manner as described above. The difference is that this configuration will apply to all feign clients.

    If you prefer using configuration properties to configured all @FeignClient, you can create configuration properties with default feign name.

    application.yml

    feign:
    +  client:
    +    config:
    +      default:
    +        connectTimeout: 5000
    +        readTimeout: 5000
    +        loggerLevel: basic

    If we create both @Configuration bean and configuration properties, configuration properties will win. +It will override @Configuration values. But if you want to change the priority to @Configuration, +you can change feign.client.default-to-properties to false.

    [Note]Note

    If you need to use ThreadLocal bound variables in your RequestInterceptor`s you will need to either set the +thread isolation strategy for Hystrix to `SEMAPHORE or disable Hystrix in Feign.

    application.yml

    # To disable Hystrix in Feign
    +feign:
    +  hystrix:
    +    enabled: false
    +
    +# To set thread isolation to SEMAPHORE
    +hystrix:
    +  command:
    +    default:
    +      execution:
    +        isolation:
    +          strategy: SEMAPHORE

    23.3 Creating Feign Clients Manually

    In some cases it might be necessary to customize your Feign Clients in a way that is not +possible using the methods above. In this case you can create Clients using the +Feign Builder API. Below is an example +which creates two Feign Clients with the same interface but configures each one with +a separate request interceptor.

    @Import(FeignClientsConfiguration.class)
    +class FooController {
    +
    +	private FooClient fooClient;
    +
    +	private FooClient adminClient;
    +
    +    	@Autowired
    +	public FooController(
    +			Decoder decoder, Encoder encoder, Client client, Contract contract) {
    +		this.fooClient = Feign.builder().client(client)
    +				.encoder(encoder)
    +				.decoder(decoder)
    +                .contract(contract)
    +				.requestInterceptor(new BasicAuthRequestInterceptor("user", "user"))
    +				.target(FooClient.class, "http://PROD-SVC");
    +		this.adminClient = Feign.builder().client(client)
    +				.encoder(encoder)
    +				.decoder(decoder)
    +				.contract(contract)
    +				.requestInterceptor(new BasicAuthRequestInterceptor("admin", "admin"))
    +				.target(FooClient.class, "http://PROD-SVC");
    +    }
    +}
    [Note]Note

    In the above example FeignClientsConfiguration.class is the default configuration +provided by Spring Cloud Netflix.

    [Note]Note

    PROD-SVC is the name of the service the Clients will be making requests to.

    [Note]Note

    The Feign Contract object defines what annotations and values are valid on interfaces. The +autowired Contract bean provides supports for SpringMVC annotations, instead of +the default Feign native annotations.

    23.4 Feign Hystrix Support

    If Hystrix is on the classpath and feign.hystrix.enabled=true, Feign will wrap all methods with a circuit breaker. Returning a com.netflix.hystrix.HystrixCommand is also available. This lets you use reactive patterns (with a call to .toObservable() or .observe() or asynchronous use (with a call to .queue()).

    To disable Hystrix support on a per-client basis create a vanilla Feign.Builder with the "prototype" scope, e.g.:

    @Configuration
    +public class FooConfiguration {
    +    	@Bean
    +	@Scope("prototype")
    +	public Feign.Builder feignBuilder() {
    +		return Feign.builder();
    +	}
    +}
    [Warning]Warning

    Prior to the Spring Cloud Dalston release, if Hystrix was on the classpath Feign would have wrapped +all methods in a circuit breaker by default. This default behavior was changed in Spring Cloud Dalston in +favor for an opt-in approach.

    23.5 Feign Hystrix Fallbacks

    Hystrix supports the notion of a fallback: a default code path that is executed when they circuit is open or there is an error. To enable fallbacks for a given @FeignClient set the fallback attribute to the class name that implements the fallback. You also need to declare your implementation as a Spring bean.

    @FeignClient(name = "hello", fallback = HystrixClientFallback.class)
    +protected interface HystrixClient {
    +    @RequestMapping(method = RequestMethod.GET, value = "/hello")
    +    Hello iFailSometimes();
    +}
    +
    +static class HystrixClientFallback implements HystrixClient {
    +    @Override
    +    public Hello iFailSometimes() {
    +        return new Hello("fallback");
    +    }
    +}

    If one needs access to the cause that made the fallback trigger, one can use the fallbackFactory attribute inside @FeignClient.

    @FeignClient(name = "hello", fallbackFactory = HystrixClientFallbackFactory.class)
    +protected interface HystrixClient {
    +	@RequestMapping(method = RequestMethod.GET, value = "/hello")
    +	Hello iFailSometimes();
    +}
    +
    +@Component
    +static class HystrixClientFallbackFactory implements FallbackFactory<HystrixClient> {
    +	@Override
    +	public HystrixClient create(Throwable cause) {
    +		return new HystrixClient() {
    +			@Override
    +			public Hello iFailSometimes() {
    +				return new Hello("fallback; reason was: " + cause.getMessage());
    +			}
    +		};
    +	}
    +}
    [Warning]Warning

    There is a limitation with the implementation of fallbacks in Feign and how Hystrix fallbacks work. Fallbacks are currently not supported for methods that return com.netflix.hystrix.HystrixCommand and rx.Observable.

    23.6 Feign and @Primary

    When using Feign with Hystrix fallbacks, there are multiple beans in the ApplicationContext of the same type. This will cause @Autowired to not work because there isn’t exactly one bean, or one marked as primary. To work around this, Spring Cloud Netflix marks all Feign instances as @Primary, so Spring Framework will know which bean to inject. In some cases, this may not be desirable. To turn off this behavior set the primary attribute of @FeignClient to false.

    @FeignClient(name = "hello", primary = false)
    +public interface HelloClient {
    +	// methods here
    +}

    23.7 Feign Inheritance Support

    Feign supports boilerplate apis via single-inheritance interfaces. +This allows grouping common operations into convenient base interfaces.

    UserService.java.  +

    public interface UserService {
    +
    +    @RequestMapping(method = RequestMethod.GET, value ="/users/{id}")
    +    User getUser(@PathVariable("id") long id);
    +}

    +

    UserResource.java.  +

    @RestController
    +public class UserResource implements UserService {
    +
    +}

    +

    UserClient.java.  +

    package project.user;
    +
    +@FeignClient("users")
    +public interface UserClient extends UserService {
    +
    +}

    +

    [Note]Note

    It is generally not advisable to share an interface between a +server and a client. It introduces tight coupling, and also actually +doesn’t work with Spring MVC in its current form (method parameter +mapping is not inherited).

    23.8 Feign request/response compression

    You may consider enabling the request or response GZIP compression for your +Feign requests. You can do this by enabling one of the properties:

    feign.compression.request.enabled=true
    +feign.compression.response.enabled=true

    Feign request compression gives you settings similar to what you may set for your web server:

    feign.compression.request.enabled=true
    +feign.compression.request.mime-types=text/xml,application/xml,application/json
    +feign.compression.request.min-request-size=2048

    These properties allow you to be selective about the compressed media types and minimum request threshold length.

    23.9 Feign logging

    A logger is created for each Feign client created. By default the name of the logger is the full class name of the interface used to create the Feign client. Feign logging only responds to the DEBUG level.

    application.yml.  +

    logging.level.project.user.UserClient: DEBUG

    +

    The Logger.Level object that you may configure per client, tells Feign how much to log. Choices are:

    • NONE, No logging (DEFAULT).
    • BASIC, Log only the request method and URL and the response status code and execution time.
    • HEADERS, Log the basic information along with request and response headers.
    • FULL, Log the headers, body, and metadata for both requests and responses.

    For example, the following would set the Logger.Level to FULL:

    @Configuration
    +public class FooConfiguration {
    +    @Bean
    +    Logger.Level feignLoggerLevel() {
    +        return Logger.Level.FULL;
    +    }
    +}
            OtherClass.someMethod(myprop.get());
    +    }
    +}
    +stripped). The proxy uses Ribbon to locate an instance to forward to
    +via discovery, and all requests are executed in a
    +<<hystrix-fallbacks-for-routes, hystrix command>>, so
    +failures will show up in Hystrix metrics, and once the circuit is open
    +the proxy will not try to contact the service.

    Part V. Spring Cloud Stream

    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.

    24. Introducing Spring Cloud Stream

    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.

    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.

    @SpringBootApplication
    @@ -2495,39 +2692,39 @@ You can use this in the application by autowiring it, as in the following exampl
       public void contextLoads() {
         assertNotNull(this.sink.input());
       }
    -}

    24. Main Concepts

    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’s application model
    • The Binder abstraction
    • Persistent publish-subscribe support
    • Consumer group support
    • Partitioning support
    • A pluggable Binder API

    24.1 Application Model

    A Spring Cloud Stream application consists of a middleware-neutral core. +}

    25. Main Concepts

    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’s application model
    • The Binder abstraction
    • Persistent publish-subscribe support
    • Consumer group support
    • Partitioning support
    • A pluggable Binder API

    25.1 Application Model

    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.

    Figure 24.1. Spring Cloud Stream Application

    SCSt with binder

    24.1.1 Fat JAR

    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.

    24.2 The Binder Abstraction

    Spring Cloud Stream provides Binder implementations for Kafka and Rabbit MQ. +Channels are connected to external brokers through middleware-specific Binder implementations.

    Figure 25.1. Spring Cloud Stream Application

    SCSt with binder

    25.1.1 Fat JAR

    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.

    25.2 The Binder Abstraction

    Spring Cloud Stream provides Binder implementations for Kafka and Rabbit MQ. 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 Chapter 23, 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. +In the sink example from the Chapter 24, 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.

    24.3 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.

    Figure 24.2. Spring Cloud Stream Publish-Subscribe

    SCSt sensors

    Data reported by sensors to an HTTP endpoint is sent to a common destination named raw-sensor-data. +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.

    25.3 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.

    Figure 25.2. Spring Cloud Stream Publish-Subscribe

    SCSt sensors

    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. -By using native middleware support, Spring Cloud Stream also simplifies use of the publish-subscribe model across different platforms.

    24.4 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. +By using native middleware support, Spring Cloud Stream also simplifies use of the publish-subscribe model across different platforms.

    25.4 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.<channelName>.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.<channelName>.group=hdfsWrite or spring.cloud.stream.bindings.<channelName>.group=average.

    Figure 24.3. Spring Cloud Stream Consumer Groups

    SCSt 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.

    24.5 Consumer Types

    Two types of consumer are supported:

    • Message-driven (sometimes referred to as Asynchronous)
    • Polled (sometimes referred to as Synchronous)

    Prior to version 2.0, only asynchronous consumers were supported, where a message is delivered as soon as it is available (and there is a thread available to process it).

    You might want to use a synchronous consumer when you wish to control the rate at which messages are processed.

    24.5.1 Durability

    Consistent with the opinionated application model of Spring Cloud Stream, consumer group subscriptions are durable. +For the consumers shown in the following figure, this property would be set as spring.cloud.stream.bindings.<channelName>.group=hdfsWrite or spring.cloud.stream.bindings.<channelName>.group=average.

    Figure 25.3. Spring Cloud Stream Consumer Groups

    SCSt 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.

    25.5 Consumer Types

    Two types of consumer are supported:

    • Message-driven (sometimes referred to as Asynchronous)
    • Polled (sometimes referred to as Synchronous)

    Prior to version 2.0, only asynchronous consumers were supported, where a message is delivered as soon as it is available (and there is a thread available to process it).

    You might want to use a synchronous consumer when you wish to control the rate at which messages are processed.

    25.5.1 Durability

    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]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, 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).

    24.6 Partitioning Support

    Spring Cloud Stream provides support for partitioning data between multiple instances of a given application. +This prevents the application’s instances from receiving duplicate messages (unless that behavior is desired, which is unusual).

    25.6 Partitioning Support

    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).

    Figure 24.4. Spring Cloud Stream Partitioning

    SCSt partitioning

    Partitioning is a critical concept in stateful processing, where it is critical, 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]Note

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

    25. Programming Model

    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.

    25.1 Declaring and Binding Producers and Consumers

    25.1.1 Triggering Binding Via @EnableBinding

    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. +Partitioning can thus be used whether the broker itself is naturally partitioned (e.g., Kafka) or not (e.g., RabbitMQ).

    Figure 25.4. Spring Cloud Stream Partitioning

    SCSt partitioning

    Partitioning is a critical concept in stateful processing, where it is critical, 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]Note

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

    26. Programming Model

    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.

    26.1 Declaring and Binding Producers and Consumers

    26.1.1 Triggering Binding Via @EnableBinding

    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:

    ...
     @Import(...)
     @Configuration
    @@ -2536,7 +2733,7 @@ The @EnableBinding annotation itself is meta-annota
         ...
         Class<?>[] value() default {};
     }

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

    [Note]Note

    The @EnableBinding annotation is only required on your Configuration classes, you can provide as many binding interfaces as you need, for instance: @EnableBinding(value={Orders.class, Payment.class}. -Where both Order and Payment interfaces would declare @Input and @Output channels.

    25.1.2 @Input and @Output

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

    public interface Barista {
    +Where both Order and Payment interfaces would declare @Input and @Output channels.

    26.1.2 @Input and @Output

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

    public interface Barista {
     
         @Input
         SubscribableChannel orders();
    @@ -2583,7 +2780,7 @@ In this documentation, we will continue to refer to MessageChannels as the 

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

    public interface Processor extends Source, Sink {
    -}

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

    25.1.3 Accessing Bound Channels

    Injecting the Bound Interfaces

    For each bound interface, Spring Cloud Stream will generate a bean that implements the interface. +}

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

    26.1.3 Accessing Bound Channels

    Injecting the Bound Interfaces

    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.

    @Component
     public class SendingBean {
    @@ -2629,7 +2826,7 @@ Given the following declaration:

    public void sayHello(String name) {
              this.output.send(MessageBuilder.withPayload(name).build());
         }
    -}

    25.1.4 Producing and Consuming Messages

    You can write a Spring Cloud Stream application using either Spring Integration annotations or Spring Cloud Stream’s @StreamListener annotation. +}

    26.1.4 Producing and Consuming Messages

    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

    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:

    @EnableBinding(Source.class)
     public class TimerSource {
    @@ -2746,7 +2943,7 @@ You can override that behavior, by taking responsibility for the acknowledgment,
     			Map<String, Foo> payload = (Map<String, Foo>) received.getPayload();
                 ...
     
    -		}, new ParameterizedTypeReference<Map<String, Foo>>() {});

    25.1.5 Reactive Programming Support

    Spring Cloud Stream also supports the use of reactive APIs where incoming and outgoing data is handled as continuous data flows. + }, new ParameterizedTypeReference<Map<String, Foo>>() {});

    26.1.5 Reactive Programming Support

    Spring Cloud Stream also supports the use of reactive APIs where incoming and outgoing data is handled as continuous data flows. Support for reactive APIs is available via the spring-cloud-stream-reactive, which needs to be added explicitly to your project.

    The programming model with reactive APIs is declarative, where instead of specifying how each individual message should be handled, you can use operators that describe functional transformations from inbound to outbound data flows.

    Spring Cloud Stream supports the following reactive APIs:

    • Reactor

    In the future, it is intended to support a more generic model based on Reactive Streams.

    The reactive programming model is also using the @StreamListener annotation for setting up reactive handlers. The differences are that:

    • the @StreamListener annotation must not specify an input or output, as they are provided as arguments and return values from the method;
    • the arguments of the method must be annotated with @Input and @Output indicating which input or output will the incoming and respectively outgoing data flows connect to;
    • the return value of the method, if any, will be annotated with @Output, indicating the input where data shall be sent.
    [Note]Note

    Reactive programming support requires Java 1.8.

    [Note]Note

    As of Spring Cloud Stream 1.1.1 and later (starting with release train Brooklyn.SR2), reactive programming support requires the use of Reactor 3.0.4.RELEASE and higher. Earlier Reactor versions (including 3.0.1.RELEASE, 3.0.2.RELEASE and 3.0.3.RELEASE) are not supported. spring-cloud-stream-reactive will transitively retrieve the proper version, but it is possible for the project structure to manage the version of the io.projectreactor:reactor-core to an earlier release, especially when using Maven. @@ -2821,7 +3018,7 @@ The Publisher is still using Reactor Flux under the hood, but from an applicatio e -> e.poller(p -> p.fixedDelay(1))) .toReactivePublisher(); } -}

    25.1.6 Aggregation

    Spring Cloud Stream provides support for aggregating multiple applications together, connecting their input and output channels directly and avoiding the additional cost of exchanging messages via a broker. +}

    26.1.6 Aggregation

    Spring Cloud Stream provides support for aggregating multiple applications together, connecting their input and output channels directly and avoiding the additional cost of exchanging messages via a broker. As of version 1.0 of Spring Cloud Stream, aggregation is supported only for the following types of applications:

    • sources - applications with a single output channel named output, typically having a single binding of the type org.springframework.cloud.stream.messaging.Source
    • sinks - applications with a single input channel named input, typically having a single binding of the type org.springframework.cloud.stream.messaging.Sink
    • processors - applications with a single input channel named input and a single output channel named output, typically having a single binding of the type org.springframework.cloud.stream.messaging.Processor.

    They can be aggregated together by creating a sequence of interconnected applications, in which the output channel of an element in the sequence is connected to the input channel of the next element, if it exists. A sequence can start with either a source or a processor, it can contain an arbitrary number of processors and must end with either a processor or a sink.

    Depending on the nature of the starting and ending element, the sequence may have one or more bindable channels, as follows:

    • if the sequence starts with a source and ends with a sink, all communication between the applications is direct and no channels will be bound
    • if the sequence starts with a processor, then its input channel will become the input channel of the aggregate and will be bound accordingly
    • if the sequence ends with a processor, then its output channel will become the output channel of the aggregate and will be bound accordingly

    Aggregation is performed using the AggregateApplicationBuilder utility class, as in the following example. Let’s consider a project in which we have source, processor and a sink, which may be defined in the project, or may be contained in one of the project’s dependencies.

    [Note]Note

    Each component (source, sink or processor) in an aggregate application must be provided in a separate package if the configuration classes use @SpringBootApplication. @@ -2902,30 +3099,30 @@ For instance,

    class).namespace("source").args("--fixedDelay=5000")
                 .via(ProcessorApplication.class).namespace("processor1").args("--debug=true").run(args);
         }
    -}

    The binding properties like --spring.cloud.stream.bindings.output.destination=processor-output need to be specified as one of the external configuration properties (cmdline arg etc.).

    26. Binders

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

    26.1 Producers and Consumers

    Figure 26.1. Producers and Consumers

    producers consumers

    A producer is any component that sends messages to a channel. +}

    The binding properties like --spring.cloud.stream.bindings.output.destination=processor-output need to be specified as one of the external configuration properties (cmdline arg etc.).

    27. Binders

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

    27.1 Producers and Consumers

    Figure 27.1. Producers and Consumers

    producers consumers

    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 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).

    26.2 Binder SPI

    The Binder SPI consists of a number of interfaces, out-of-the box utility classes and discovery strategies that provide a pluggable mechanism for connecting to external middleware.

    The key point of the SPI is the Binder interface which is a strategy for connecting inputs and outputs to external middleware.

    public interface Binder<T, C extends ConsumerProperties, P extends ProducerProperties> {
    +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).

    27.2 Binder SPI

    The Binder SPI consists of a number of interfaces, out-of-the box utility classes and discovery strategies that provide a pluggable mechanism for connecting to external middleware.

    The key point of the SPI is the Binder interface which is a strategy for connecting inputs and outputs to external middleware.

    public interface Binder<T, C extends ConsumerProperties, P extends ProducerProperties> {
         Binding<T> bindConsumer(String name, String group, T inboundBindTarget, C consumerProperties);
     
         Binding<T> bindProducer(String name, T outboundBindTarget, P producerProperties);
     }

    The interface is parameterized, offering a number of extension points:

    • input and output bind targets - as of version 1.0, only MessageChannel is supported, but this is intended to be used as an extension point in the future;
    • extended consumer and producer properties - allowing specific Binder implementations to add supplemental properties which can be supported in a type-safe manner.

    A typical binder implementation consists of the following

    • a class that implements the Binder interface;
    • a Spring @Configuration class that creates a bean of the type above along with the middleware connection infrastructure;
    • a META-INF/spring.binders file found on the classpath containing one or more binder definitions, e.g.
    kafka:\
    -org.springframework.cloud.stream.binder.kafka.config.KafkaBinderConfiguration

    26.3 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.

    26.3.1 Classpath Detection

    By default, Spring Cloud Stream relies on Spring Boot’s auto-configuration to configure the binding process. +org.springframework.cloud.stream.binder.kafka.config.KafkaBinderConfiguration

    27.3 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.

    27.3.1 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. For example, a Spring Cloud Stream project that aims to bind only to RabbitMQ can simply add the following dependency:

    <dependency>
       <groupId>org.springframework.cloud</groupId>
       <artifactId>spring-cloud-stream-binder-rabbit</artifactId>
    -</dependency>

    For the specific maven coordinates of other binder dependencies, please refer to the documentation of that binder implementation.

    26.4 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. +</dependency>

    For the specific maven coordinates of other binder dependencies, please refer to the documentation of that binder implementation.

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

    rabbit:\
     org.springframework.cloud.stream.binder.rabbit.config.RabbitServiceAutoConfiguration

    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.

    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 (that has channels with the names input and output for read/write respectively) 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

    26.5 Connecting to Multiple Systems

    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. +spring.cloud.stream.bindings.output.binder=rabbit

    27.5 Connecting to Multiple Systems

    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]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. Frameworks that intend to use Spring Cloud Stream transparently may create binder configurations that can be referenced by name, but will not affect the default binder configuration. @@ -2952,30 +3149,30 @@ This denotes a configuration that will exist independently of the default binder environment: spring: rabbitmq: - host: <host2>

    26.6 Binder configuration properties

    The following properties are available when creating custom binder configurations. + host: <host2>

    27.6 Binder configuration properties

    The following properties are available when creating custom binder configurations. They must be prefixed with spring.cloud.stream.binders.<configurationName>.

    type

    The binder type. It typically references one of the binders found on the classpath, in particular a key in a META-INF/spring.binders file.

    By default, it has the same value as the configuration name.

    inheritEnvironment

    Whether the configuration will inherit the environment of the application itself.

    Default true.

    environment

    Root for a set of properties that can be used to customize the environment of the binder. When this is configured, the context in which the binder is being created is not a child of the application context. This allows for complete separation between the binder components and the application components.

    Default empty.

    defaultCandidate

    Whether the binder configuration is a candidate for being considered a default binder, or can be used only when explicitly referenced. -This allows adding binder configurations without interfering with the default processing.

    Default true.

    27. Configuration Options

    Spring Cloud Stream supports general configuration options as well as configuration for bindings and binders. +This allows adding binder configurations without interfering with the default processing.

    Default true.

    28. Configuration Options

    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.

    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.

    27.1 Spring Cloud Stream Properties

    spring.cloud.stream.instanceCount

    The number of deployed instances of an application. +This includes application arguments, environment variables, and YAML or .properties files.

    28.1 Spring Cloud Stream Properties

    spring.cloud.stream.instanceCount

    The number of deployed instances of an application. Must be set for partitioning on the producer side, and on the consumer side if using RabbitMQ and with Kafka if autoRebalanceEnabled=false.

    Default: 1.

    spring.cloud.stream.instanceIndex
    The instance index of the application: a number from 0 to instanceCount-1. Used for partitioning with RabbitMQ and with Kafka if autoRebalanceEnabled=false. 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). 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 multiple binders are configured. -See Multiple Binders on the Classpath.

    Default: empty.

    spring.cloud.stream.overrideCloudConnectors

    This property is only applicable when the cloud profile is active and Spring Cloud Connectors are provided with the application. +See Multiple Binders on the Classpath.

    Default: empty.

    spring.cloud.stream.overrideCloudConnectors

    This property is only applicable when the cloud profile is active and Spring Cloud Connectors are provided with the application. If the property is false (the default), the binder will detect a suitable bound service (e.g. a RabbitMQ service bound in Cloud Foundry for the RabbitMQ binder) and will use it for creating connections (usually via Spring Cloud Connectors). When set to true, this property instructs binders to completely ignore the bound services and rely on Spring Boot properties (e.g. relying on the spring.rabbitmq.* properties provided in the environment for the RabbitMQ binder). -The typical usage of this property is to be nested in a customized environment when connecting to multiple systems.

    Default: false.

    spring.cloud.stream.bindingRetryInterval

    The interval (seconds) between retrying binding creation when, for example, the binder doesn’t support late binding and the broker is down (e.g. Apache Kafka). -Set to zero to treat such conditions as fatal, preventing the application from starting.

    Default: 30

    27.2 Binding Properties

    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).

    To avoid repetition, Spring Cloud Stream supports setting values for all channels, in the format spring.cloud.stream.default.<property>=<value>.

    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.

    27.2.1 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>., e.g. spring.cloud.stream.bindings.input.destination=ticktock.

    Default values can be set by using the prefix spring.cloud.stream.default, e.g. spring.cloud.stream.default.contentType=application/json.

    destination
    The target destination of a channel on the bound middleware (e.g., the RabbitMQ exchange or Kafka topic). +The typical usage of this property is to be nested in a customized environment when connecting to multiple systems.

    Default: false.

    spring.cloud.stream.bindingRetryInterval

    The interval (seconds) between retrying binding creation when, for example, the binder doesn’t support late binding and the broker is down (e.g. Apache Kafka). +Set to zero to treat such conditions as fatal, preventing the application from starting.

    Default: 30

    28.2 Binding Properties

    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).

    To avoid repetition, Spring Cloud Stream supports setting values for all channels, in the format spring.cloud.stream.default.<property>=<value>.

    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.

    28.2.1 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>., e.g. spring.cloud.stream.bindings.input.destination=ticktock.

    Default values can be set by using the prefix spring.cloud.stream.default, e.g. spring.cloud.stream.default.contentType=application/json.

    destination
    The target destination of a channel on the bound middleware (e.g., the RabbitMQ exchange or Kafka topic). If the channel is bound as a consumer, it could be bound to multiple destinations and the destination names can be specified as comma separated String values. If not set, the channel name is used instead. The default value of this property cannot be overridden.
    group

    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.

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

    binder

    The binder used by this binding. -See Section 26.4, “Multiple Binders on the Classpath” for details.

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

    27.2.2 Consumer properties

    The following binding properties are available for input bindings only and must be prefixed with spring.cloud.stream.bindings.<channelName>.consumer., e.g. spring.cloud.stream.bindings.input.consumer.concurrency=3.

    Default values can be set by using the prefix spring.cloud.stream.default.consumer, e.g. spring.cloud.stream.default.consumer.headerMode=none.

    concurrency

    The concurrency of the inbound consumer.

    Default: 1.

    partitioned

    Whether the consumer receives data from a partitioned producer.

    Default: false.

    headerMode

    When set to none, disables header parsing on input. +See Consumer Groups.

    Default: null (indicating an anonymous consumer).

    contentType

    The content type of the channel.

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

    binder

    The binder used by this binding. +See Section 27.4, “Multiple Binders on the Classpath” for details.

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

    28.2.2 Consumer properties

    The following binding properties are available for input bindings only and must be prefixed with spring.cloud.stream.bindings.<channelName>.consumer., e.g. spring.cloud.stream.bindings.input.consumer.concurrency=3.

    Default values can be set by using the prefix spring.cloud.stream.default.consumer, e.g. spring.cloud.stream.default.consumer.headerMode=none.

    concurrency

    The concurrency of the inbound consumer.

    Default: 1.

    partitioned

    Whether the consumer receives data from a partitioned producer.

    Default: false.

    headerMode

    When set to none, disables header parsing on input. Effective only for messaging middleware that does not support message headers natively and requires header embedding. This option is useful when consuming data from non-Spring Cloud Stream applications when native headers are not supported. When set to headers, uses the middleware’s native header mechanism. @@ -2984,13 +3181,13 @@ Set to 1 to disable retry.

    Default: When set to a negative value, it will default to spring.cloud.stream.instanceIndex. See that property for more information.

    Default: -1.

    instanceCount

    When set to a value greater than equal to zero, allows customizing the instance count of this consumer (if different from spring.cloud.stream.instanceCount). When set to a negative value, it will default to spring.cloud.stream.instanceCount. -See that property for more information.

    Default: -1.

    27.2.3 Producer Properties

    The following binding properties are available for output bindings only and must be prefixed with spring.cloud.stream.bindings.<channelName>.producer., e.g. spring.cloud.stream.bindings.input.producer.partitionKeyExpression=payload.id.

    Default values can be set by using the prefix spring.cloud.stream.default.producer, e.g. spring.cloud.stream.default.producer.partitionKeyExpression=payload.id.

    partitionKeyExpression

    A SpEL expression that determines how to partition outbound data. +See that property for more information.

    Default: -1.

    28.2.3 Producer Properties

    The following binding properties are available for output bindings only and must be prefixed with spring.cloud.stream.bindings.<channelName>.producer., e.g. spring.cloud.stream.bindings.input.producer.partitionKeyExpression=payload.id.

    Default values can be set by using the prefix spring.cloud.stream.default.producer, e.g. spring.cloud.stream.default.producer.partitionKeyExpression=payload.id.

    partitionKeyExpression

    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 Section 24.6, “Partitioning Support”.

    Default: null.

    partitionKeyExtractorClass

    A PartitionKeyExtractorStrategy implementation. +See Section 25.6, “Partitioning Support”.

    Default: null.

    partitionKeyExtractorClass

    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 Section 24.6, “Partitioning Support”.

    Default: null.

    partitionSelectorClass

    A PartitionSelectorStrategy implementation. +See Section 25.6, “Partitioning Support”.

    Default: null.

    partitionSelectorClass

    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. Mutually exclusive with partitionSelectorClass. @@ -3006,7 +3203,7 @@ When set to embeddedHeaders, embeds headers into th When this configuration is being used, the outbound message marshalling is not based on the contentType of the binding. When native encoding is used, it is the responsibility of the consumer to use appropriate decoder (ex: Kafka consumer value de-serializer) to deserialize the inbound message. Also, when native encoding/decoding is used the headerMode=embeddedHeaders property is ignored and headers will not be embedded into the message.

    Default: false.

    errorChannelEnabled

    When set to true, if the binder supports async send results; send failures will be sent to an error channel for the destination. -See the section called “Message Channel Binders and Error Channels” for more information.

    Default: false.

    27.3 Using dynamically bound destinations

    Besides the channels defined via @EnableBinding, Spring Cloud Stream allows applications to send messages to dynamically bound destinations. +See the section called “Message Channel Binders and Error Channels” for more information.

    Default: false.

    28.3 Using dynamically bound destinations

    Besides the channels defined via @EnableBinding, Spring Cloud Stream allows applications to send messages to dynamically bound destinations. This is useful, for example, when the target destination needs to be determined at runtime. Applications can do so by using the BinderAwareChannelResolver bean, registered automatically by the @EnableBinding annotation.

    The property 'spring.cloud.stream.dynamicDestinations' can be used for restricting the dynamic destination names to a set known beforehand (whitelisting). If the property is not set, any destination can be bound dynamically.

    The BinderAwareChannelResolver can be used directly as in the following example, in which a REST controller uses a path variable to decide the target channel.

    @EnableBinding
    @@ -3074,18 +3271,18 @@ public NewBindingCallback
    [Note]Note

    If you need to support dynamic destinations with multiple binder types, use Object for the generic type and cast the extended argument as needed.

    28. Content Type and Transformation

    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. +}

    [Note]Note

    If you need to support dynamic destinations with multiple binder types, use Object for the generic type and cast the extended argument as needed.

    29. Content Type and Transformation

    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.

    The content type resolution process have been redesigned for Spring Cloud Stream 2.0.

    Please read the migrating from 1.3 section to understand the changes when interacting with applications using versions of the framework.

    The framework depends on a contentType to be present as a header in order to know how serialize/deserialize a payload.

    Spring Cloud Stream allows you to declaratively configure type conversion for inputs and outputs using the spring.cloud.stream.bindings.<channelName>.content-type property of a binding. Note that general type conversion may also be accomplished easily by using a transformer inside your application.

    [Note]Note

    For both input and output channel, setting a contentType via a property or via annotation only triggers the default converter if a message header with value contentType is not present. This is useful for cases where you just want to send a POJO without sending any header information, or to consume messages that do not have a contentType header present. The framework will always override any default settings with the value found on the message headers.

    [Tip]Tip

    Although contentType became a required property, the framework will set a default value of application/json for all input/output channels if one is not -provided by the user.

    28.1 MIME types

    The content-type values are parsed as media types, e.g., application/json or text/plain;charset=UTF-8.

    MIME types are especially useful for indicating how to convert to String or byte[] content. +provided by the user.

    29.1 MIME types

    The content-type values are parsed as media types, e.g., application/json or text/plain;charset=UTF-8.

    MIME types are especially useful for indicating how to convert to String or byte[] content. Spring Cloud Stream also uses MIME type format to represent Java types, using the general type application/x-java-object with a type parameter. For example, application/x-java-object;type=java.util.Map or application/x-java-object;type=com.bar.Foo can be set as the content-type property of an input binding. -In addition, Spring Cloud Stream provides custom MIME types, notably, application/x-spring-tuple to specify a Tuple.

    28.2 Channel contentType and Message Headers

    You can configure a message channel content type using spring.cloud.stream.bindings.<channelName>.content-type property, or using the @Input and @Output annotations. +In addition, Spring Cloud Stream provides custom MIME types, notably, application/x-spring-tuple to specify a Tuple.

    29.2 Channel contentType and Message Headers

    You can configure a message channel content type using spring.cloud.stream.bindings.<channelName>.content-type property, or using the @Input and @Output annotations. By doing so, even if you send a POJO with no contentType information, the framework will set the MessageHeader contentType to the specified value set for the channel.

    However, if you send a Message<T> and sets the contentType manually, that takes precedence over the configured property value. -This is valid for both input and output channels. The MessageHeader will always take precedence over the default configured contentType for the channel.

    28.3 ContentType handling for output channels

    Starting with version 2.0, the framework will no longer try to infer a contentType based on the payload T of a Message<T>. +This is valid for both input and output channels. The MessageHeader will always take precedence over the default configured contentType for the channel.

    29.3 ContentType handling for output channels

    Starting with version 2.0, the framework will no longer try to infer a contentType based on the payload T of a Message<T>. It will instead use the contentType header (or the default provided by the framework) to configure the right MessageConverter to serialize the payload into byte[].

    The contentType you set is a hint to activate the corresponding MessageConverter. The converter can then modify the contentType to augment the information, such as the case with Kryo and Avro conveters.

    For outbound messages, if your payload is of typ byte[], the framework will skip the conversion logic, and just write those bytes to the wire. In this case, if contentType of the message is absent, it will set the default value specified to channel.

    [Tip]Tip

    If you intend to bypass conversion, just make sure you set the appropriate contentType header, otherwise you could be sending some arbitrary binary data, and the framework may set the header as application/json (default).

    The following snippet shows how you can bypass conversion and set the correct contentType header.

    @Autowired
     private Source source;
    @@ -3096,8 +3293,8 @@ In this case, if contentType of the message is abse
         source.output().send(MessageBuilder.withPayload(data)
                 .setHeader(MessageHeaders.CONTENT_TYPE, mimeType)
                 .build());
    -}

    Regardless of contentType used, the result is always a Message<byte[]> with a header contentType set. This is what gets passed to the binder to be sent over the wire.

    content-type headerMessageConvertercontent-type augmentedSupported typesComments

    application/json

    CustomMappingJackson2MessageConverter

    application/json

    POJO, primitives and Strings that represent JSON data

    It’s the default converter if none is specified. Note that if you send a raw String it will be quoted

    text/plain

    ObjectStringMessageConverter

    text/plain

    Invokes toString() of the object

     

    application/x-spring-tuple

    TupleJsonMessageConverter

    application/x-spring-tuple

    org.springframework.tuple.Tuple

     

    application/x-java-serialized-object

    JavaSerializationMessageConverter

    application/x-java-serialized-object

    Any Java type that implements Serializable

    This converter uses java native serialization. Receivers of this data must have the same class on the classpath.

    application/x-java-object

    KryoMessageConverter

    application/x-java-object;type=<Class being serialized>

    Any Java type that can be serialized using Kryo

    Receivers of this data must have the same class on the classpath.

    application/avro

    AvroMessageConverter

    application/avro

    A Generic or SpecificRecord from Avro types, a POJO if reflection is used

    Avro needs an associated schema to write/read data. Please refer to the section on the docs on how to use it properly

    28.4 ContentType handling for input channels

    For input channels, Spring Cloud Stream uses @StreamListener and @ServiceActivator content handling to support the conversion. -It does so by checking either the channel content-type set via @Input(contentType="text/plain") annotation or via spring.cloud.stream.bindings.<channel>.contentType property, or the presense of a header contentType.

    The framework will check the contentType set for the Message, select the appropriate MessageConverter and apply conversion passing the argument as the target type.

    If the converter does not support the target type it will return null, if all configured converters return null, a MessageConversionException is thrown.

    Just like output channels, if your method payload argument is of type Message<byte[]>, byte[] or Message<?> conversion is skipped and you get the raw bytes from the wire, plus the corresponding headers.

    [Tip]Tip

    Remember, the MessageHeader always takes precedence over the annotation or property configuration.

    content-type headerMessageConverterSupported target typeComments

    application/json

    CustomMappingJackson2MessageConverter

    POJO or String

     

    text/plain

    ObjectStringMessageConverter

    String

     

    application/x-spring-tuple

    TupleJsonMessageConverter

    org.springframework.tuple.Tuple

     

    application/x-java-serialized-object

    JavaSerializationMessageConverter

    Any Java type that implements Serializable

     

    application/x-java-object

    KryoMessageConverter

    Any Java type that can be serialized using Kryo

     

    application/avro

    AvroMessageConverter

    A Generic or SpecificRecord from Avro types, a POJO if reflection is used

    Avro needs an associated schema to write/read data. Please refer to the section on the docs on how to use it properly

    28.5 Customizing message conversion

    Besides the conversions that it supports out of the box, Spring Cloud Stream also supports registering your own message conversion implementations. +}

    Regardless of contentType used, the result is always a Message<byte[]> with a header contentType set. This is what gets passed to the binder to be sent over the wire.

    content-type headerMessageConvertercontent-type augmentedSupported typesComments

    application/json

    CustomMappingJackson2MessageConverter

    application/json

    POJO, primitives and Strings that represent JSON data

    It’s the default converter if none is specified. Note that if you send a raw String it will be quoted

    text/plain

    ObjectStringMessageConverter

    text/plain

    Invokes toString() of the object

     

    application/x-spring-tuple

    TupleJsonMessageConverter

    application/x-spring-tuple

    org.springframework.tuple.Tuple

     

    application/x-java-serialized-object

    JavaSerializationMessageConverter

    application/x-java-serialized-object

    Any Java type that implements Serializable

    This converter uses java native serialization. Receivers of this data must have the same class on the classpath.

    application/x-java-object

    KryoMessageConverter

    application/x-java-object;type=<Class being serialized>

    Any Java type that can be serialized using Kryo

    Receivers of this data must have the same class on the classpath.

    application/avro

    AvroMessageConverter

    application/avro

    A Generic or SpecificRecord from Avro types, a POJO if reflection is used

    Avro needs an associated schema to write/read data. Please refer to the section on the docs on how to use it properly

    29.4 ContentType handling for input channels

    For input channels, Spring Cloud Stream uses @StreamListener and @ServiceActivator content handling to support the conversion. +It does so by checking either the channel content-type set via @Input(contentType="text/plain") annotation or via spring.cloud.stream.bindings.<channel>.contentType property, or the presense of a header contentType.

    The framework will check the contentType set for the Message, select the appropriate MessageConverter and apply conversion passing the argument as the target type.

    If the converter does not support the target type it will return null, if all configured converters return null, a MessageConversionException is thrown.

    Just like output channels, if your method payload argument is of type Message<byte[]>, byte[] or Message<?> conversion is skipped and you get the raw bytes from the wire, plus the corresponding headers.

    [Tip]Tip

    Remember, the MessageHeader always takes precedence over the annotation or property configuration.

    content-type headerMessageConverterSupported target typeComments

    application/json

    CustomMappingJackson2MessageConverter

    POJO or String

     

    text/plain

    ObjectStringMessageConverter

    String

     

    application/x-spring-tuple

    TupleJsonMessageConverter

    org.springframework.tuple.Tuple

     

    application/x-java-serialized-object

    JavaSerializationMessageConverter

    Any Java type that implements Serializable

     

    application/x-java-object

    KryoMessageConverter

    Any Java type that can be serialized using Kryo

     

    application/avro

    AvroMessageConverter

    A Generic or SpecificRecord from Avro types, a POJO if reflection is used

    Avro needs an associated schema to write/read data. Please refer to the section on the docs on how to use it properly

    29.5 Customizing message conversion

    Besides the conversions that it supports out of the box, Spring Cloud Stream also supports registering your own message conversion implementations. This allows you to send and receive data in a variety of custom formats, including binary, and associate them with specific contentTypes.

    Spring Cloud Stream registers all the beans of type org.springframework.messaging.converter.MessageConverter that are qualifeied using @StreamConverter annotation, as custom message converters along with the out of the box message converters.

    [Note]Note

    The framework requires the @StreamConverter qualifier annotation to avoid picking up other converters that may be present on the ApplicationContext and could overlap with the default ones.

    If your message converter needs to work with a specific content-type and target class (for both input and output), then the message converter needs to extend org.springframework.messaging.converter.AbstractMessageConverter. For conversion when using @StreamListener, a message converter that implements org.springframework.messaging.converter.MessageConverter would suffice.

    Here is an example of creating a message converter bean (with the content-type application/bar) inside a Spring Cloud Stream application:

    @EnableBinding(Sink.class)
     @SpringBootApplication
    @@ -3127,7 +3324,7 @@ For conversion when using @StreamListener, a messag
             return (payload instanceof Bar ? payload : new Bar((byte[]) payload));
         }
     }

    Spring Cloud Stream also provides support for Avro-based converters and schema evolution. -See the specific section for details.

    28.6 @StreamListener and Message Conversion

    The @StreamListener annotation provides a convenient way for converting incoming messages without the need to specify the content type of an input channel. +See the specific section for details.

    29.6 @StreamListener and Message Conversion

    The @StreamListener annotation provides a convenient way for converting incoming messages without the need to specify the content type of an input channel. During the dispatching process to methods annotated with @StreamListener, a conversion will be applied automatically if the argument requires it.

    For example, let’s consider a message with the String content {"greeting":"Hello, world"} and a content-type header of application/json is received on the input channel. Let us consider the following application that receives it:

    public class GreetingMessage {
     
    @@ -3150,8 +3347,8 @@ Let us consider the following application that receives it:

    public void receive(Greeting greeting) {
                 // handle Greeting
             }
    -    }

    The argument of the method will be populated automatically with the POJO containing the unmarshalled form of the JSON String.

    29. Schema evolution support

    Spring Cloud Stream provides support for schema-based message converters through its spring-cloud-stream-schema module. -Currently, the only serialization format supported out of the box for schema-based message converters is Apache Avro, with more formats to be added in future versions.

    29.1 Apache Avro Message Converters

    The spring-cloud-stream-schema module contains two types of message converters that can be used for Apache Avro serialization:

    • converters using the class information of the serialized/deserialized objects, or a schema with a location known at startup;
    • converters using a schema registry - they locate the schemas at runtime, as well as dynamically registering new schemas as domain objects evolve.

    29.2 Converters with schema support

    The AvroSchemaMessageConverter supports serializing and deserializing messages either using a predefined schema or by using the schema information available in the class (either reflectively, or contained in the SpecificRecord). + }

    The argument of the method will be populated automatically with the POJO containing the unmarshalled form of the JSON String.

    30. Schema evolution support

    Spring Cloud Stream provides support for schema-based message converters through its spring-cloud-stream-schema module. +Currently, the only serialization format supported out of the box for schema-based message converters is Apache Avro, with more formats to be added in future versions.

    30.1 Apache Avro Message Converters

    The spring-cloud-stream-schema module contains two types of message converters that can be used for Apache Avro serialization:

    • converters using the class information of the serialized/deserialized objects, or a schema with a location known at startup;
    • converters using a schema registry - they locate the schemas at runtime, as well as dynamically registering new schemas as domain objects evolve.

    30.2 Converters with schema support

    The AvroSchemaMessageConverter supports serializing and deserializing messages either using a predefined schema or by using the schema information available in the class (either reflectively, or contained in the SpecificRecord). If the target type of the conversion is a GenericRecord, then a schema must be set.

    For using it, you can simply add it to the application context, optionally specifying one ore more MimeTypes to associate it with. The default MimeType is application/avro.

    Here is an example of configuring it in a sink application registering the Apache Avro MessageConverter, without a predefined schema:

    @EnableBinding(Sink.class)
     @SpringBootApplication
    @@ -3175,11 +3372,11 @@ The default MimeType is appli
           converter.setSchemaLocation(new ClassPathResource("schemas/User.avro"));
           return converter;
       }
    -}

    In order to understand the schema registry client converter, we will describe the schema registry support first.

    29.3 Schema Registry Support

    Most serialization models, especially the ones that aim for portability across different platforms and languages, rely on a schema that describes how the data is serialized in the binary payload. +}

    In order to understand the schema registry client converter, we will describe the schema registry support first.

    30.3 Schema Registry Support

    Most serialization models, especially the ones that aim for portability across different platforms and languages, rely on a schema that describes how the data is serialized in the binary payload. In order to serialize the data and then to interpret it, both the sending and receiving sides must have access to a schema that describes the binary format. In certain cases, the schema can be inferred from the payload type on serialization, or from the target type on deserialization, but in a lot of cases applications benefit from having access to an explicit schema that describes the binary data format. A schema registry allows you to store schema information in a textual format (typically JSON) and makes that information accessible to various applications that need it to receive and send data in binary format. -A schema is referenceable as a tuple consisting of:

    • a subject that is the logical name of the schema;
    • the schema version;
    • the schema format which describes the binary format of the data.

    29.4 Schema Registry Server

    Spring Cloud Stream provides a schema registry server implementation. +A schema is referenceable as a tuple consisting of:

    • a subject that is the logical name of the schema;
    • the schema version;
    • the schema format which describes the binary format of the data.

    30.4 Schema Registry Server

    Spring Cloud Stream provides a schema registry server implementation. In order to use it, you can simply add the spring-cloud-stream-schema-server artifact to your project and use the @EnableSchemaRegistryServer annotation, adding the schema registry server REST controller to your application. This annotation is intended to be used with Spring Boot web applications, and the listening port of the server is controlled by the server.port setting. The spring.cloud.stream.schema.server.path setting can be used to control the root path of the schema server (especially when it is embedded in other applications). @@ -3191,10 +3388,10 @@ You can customize the schema storage using the public static void main(String[] args) { SpringApplication.run(SchemaRegistryServerApplication.class, args); } -}

    29.4.1 Schema Registry Server API

    The Schema Registry Server API consists of the following operations:

    POST /

    Register a new schema.

    Accepts JSON payload with the following fields:

    • subject the schema subject;
    • format the schema format;
    • definition the schema definition.

    Response is a schema object in JSON format, with the following fields:

    • id the schema id;
    • subject the schema subject;
    • format the schema format;
    • version the schema version;
    • definition the schema definition.

    GET /{subject}/{format}/{version}

    Retrieve an existing schema by its subject, format and version.

    Response is a schema object in JSON format, with the following fields:

    • id the schema id;
    • subject the schema subject;
    • format the schema format;
    • version the schema version;
    • definition the schema definition.

    GET /{subject}/{format}

    Retrieve a list of existing schema by its subject and format.

    Response is a list of schemas with each schema object in JSON format, with the following fields:

    • id the schema id;
    • subject the schema subject;
    • format the schema format;
    • version the schema version;
    • definition the schema definition.

    GET /schemas/{id}

    Retrieve an existing schema by its id.

    Response is a schema object in JSON format, with the following fields:

    • id the schema id;
    • subject the schema subject;
    • format the schema format;
    • version the schema version;
    • definition the schema definition.

    DELETE /{subject}/{format}/{version}

    Delete an existing schema by its subject, format and version.

    DELETE /schemas/{id}

    Delete an existing schema by its id.

    DELETE /{subject}

    Delete existing schemas by their subject.

    [Note]Note

    This note applies to users of Spring Cloud Stream 1.1.0.RELEASE only. +}

    30.4.1 Schema Registry Server API

    The Schema Registry Server API consists of the following operations:

    POST /

    Register a new schema.

    Accepts JSON payload with the following fields:

    • subject the schema subject;
    • format the schema format;
    • definition the schema definition.

    Response is a schema object in JSON format, with the following fields:

    • id the schema id;
    • subject the schema subject;
    • format the schema format;
    • version the schema version;
    • definition the schema definition.

    GET /{subject}/{format}/{version}

    Retrieve an existing schema by its subject, format and version.

    Response is a schema object in JSON format, with the following fields:

    • id the schema id;
    • subject the schema subject;
    • format the schema format;
    • version the schema version;
    • definition the schema definition.

    GET /{subject}/{format}

    Retrieve a list of existing schema by its subject and format.

    Response is a list of schemas with each schema object in JSON format, with the following fields:

    • id the schema id;
    • subject the schema subject;
    • format the schema format;
    • version the schema version;
    • definition the schema definition.

    GET /schemas/{id}

    Retrieve an existing schema by its id.

    Response is a schema object in JSON format, with the following fields:

    • id the schema id;
    • subject the schema subject;
    • format the schema format;
    • version the schema version;
    • definition the schema definition.

    DELETE /{subject}/{format}/{version}

    Delete an existing schema by its subject, format and version.

    DELETE /schemas/{id}

    Delete an existing schema by its id.

    DELETE /{subject}

    Delete existing schemas by their subject.

    [Note]Note

    This note applies to users of Spring Cloud Stream 1.1.0.RELEASE only. Spring Cloud Stream 1.1.0.RELEASE used the table name schema for storing Schema objects, which is a keyword in a number of database implementations. To avoid any conflicts in the future, starting with 1.1.1.RELEASE we have opted for the name SCHEMA_REPOSITORY for the storage table. -Any Spring Cloud Stream 1.1.0.RELEASE users that are upgrading are advised to migrate their existing schemas to the new table before upgrading.

    29.5 Schema Registry Client

    The client-side abstraction for interacting with schema registry servers is the SchemaRegistryClient interface, with the following structure:

    public interface SchemaRegistryClient {
    +Any Spring Cloud Stream 1.1.0.RELEASE users that are upgrading are advised to migrate their existing schemas to the new table before upgrading.

    30.5 Schema Registry Client

    The client-side abstraction for interacting with schema registry servers is the SchemaRegistryClient interface, with the following structure:

    public interface SchemaRegistryClient {
     
         SchemaRegistrationResponse register(String subject, String format, String schema);
     
    @@ -3210,31 +3407,31 @@ Any Spring Cloud Stream 1.1.0.RELEASE users that are upgrading are advised to mi
       }
    [Note]Note

    The default converter is optimized to cache not only the schemas from the remote server but also the parse() and toString() methods that are quite expensive. Because of this, it uses a DefaultSchemaRegistryClient that does not caches responses. If you intend to use the client directly on your code, you can request a bean that also caches responses to be created. -To do that, just add the property spring.cloud.stream.schemaRegistryClient.cached=true to your application properties.

    29.5.1 Using Confluent’s Schema Registry

    The default configuration will create a DefaultSchemaRegistryClient bean. +To do that, just add the property spring.cloud.stream.schemaRegistryClient.cached=true to your application properties.

    30.5.1 Using Confluent’s Schema Registry

    The default configuration will create a DefaultSchemaRegistryClient bean. If you want to use the Confluent schema registry, you need to create a bean of type ConfluentSchemaRegistryClient, which will supersede the one configured by default by the framework.

    @Bean
     public SchemaRegistryClient schemaRegistryClient(@Value("${spring.cloud.stream.schemaRegistryClient.endpoint}") String endpoint){
       ConfluentSchemaRegistryClient client = new ConfluentSchemaRegistryClient();
       client.setEndpoint(endpoint);
       return client;
    -}
    [Note]Note

    The ConfluentSchemaRegistryClient is tested against Confluent platform version 3.2.2.

    29.5.2 Schema Registry Client properties

    The Schema Registry Client supports the following properties:

    spring.cloud.stream.schemaRegistryClient.endpoint
    The location of the schema-server. +}
    [Note]Note

    The ConfluentSchemaRegistryClient is tested against Confluent platform version 3.2.2.

    30.5.2 Schema Registry Client properties

    The Schema Registry Client supports the following properties:

    spring.cloud.stream.schemaRegistryClient.endpoint
    The location of the schema-server. Use a full URL when setting this, including protocol (http or https) , port and context path.
    Default
    http://localhost:8990/
    spring.cloud.stream.schemaRegistryClient.cached
    Whether the client should cache schema server responses. Normally set to false, as the caching happens in the message converter. -Clients using the schema registry client should set this to true.
    Default
    true

    29.6 Avro Schema Registry Client Message Converters

    For Spring Boot applications that have a SchemaRegistryClient bean registered with the application context, Spring Cloud Stream will auto-configure an Apache Avro message converter that uses the schema registry client for schema management. +Clients using the schema registry client should set this to true.

    Default
    true

    30.6 Avro Schema Registry Client Message Converters

    For Spring Boot applications that have a SchemaRegistryClient bean registered with the application context, Spring Cloud Stream will auto-configure an Apache Avro message converter that uses the schema registry client for schema management. This eases schema evolution, as applications that receive messages can get easy access to a writer schema that can be reconciled with their own reader schema.

    For outbound messages, the MessageConverter will be activated if the content type of the channel is set to application/*+avro, e.g.:

    spring.cloud.stream.bindings.output.contentType=application/*+avro

    During the outbound conversion, the message converter will try to infer the schemas of the outbound messages based on their type and register them to a subject based on the payload type using the SchemaRegistryClient. If an identical schema is already found, then a reference to it will be retrieved. If not, the schema will be registered and a new version number will be provided. -The message will be sent with a contentType header using the scheme application/[prefix].[subject].v[version]+avro, where prefix is configurable and subject is deduced from the payload type.

    For example, a message of the type User may be sent as a binary payload with a content type of application/vnd.user.v2+avro, where user is the subject and 2 is the version number.

    When receiving messages, the converter will infer the schema reference from the header of the incoming message and will try to retrieve it. The schema will be used as the writer schema in the deserialization process.

    29.6.1 Avro Schema Registry Message Converter properties

    If you have enabled Avro based schema registry client by setting spring.cloud.stream.bindings.output.contentType=application/*+avro you can customize the behavior of the registration with the following properties.

    spring.cloud.stream.schema.avro.dynamicSchemaGenerationEnabled
    Enable if you want the converter to use reflection to infer a Schema from a POJO.
    Default
    false
    spring.cloud.stream.schema.avro.readerSchema
    Avro compares schema versions by looking at a writer schema (origin payload) and a reader schema (your application payload), check Avro documentation for more information. If set, this overrides any lookups at the schema server and uses the local schema as the reader schema.
    Default
    null
    spring.cloud.stream.schema.avro.schemaLocations
    Register any .avsc files listed in this property with the Schema Server.
    Default
    empty
    spring.cloud.stream.schema.avro.prefix
    The prefix to be used on the Content-Type header.
    Default
    vnd

    29.7 Schema Registration and Resolution

    To better understand how Spring Cloud Stream registers and resolves new schemas, as well as its use of Avro schema comparison features, we will provide two separate subsections below: one for the registration, and one for the resolution of schemas.

    29.7.1 Schema Registration Process (Serialization)

    The first part of the registration process is extracting a schema from the payload that is being sent over a channel. +The message will be sent with a contentType header using the scheme application/[prefix].[subject].v[version]+avro, where prefix is configurable and subject is deduced from the payload type.

    For example, a message of the type User may be sent as a binary payload with a content type of application/vnd.user.v2+avro, where user is the subject and 2 is the version number.

    When receiving messages, the converter will infer the schema reference from the header of the incoming message and will try to retrieve it. The schema will be used as the writer schema in the deserialization process.

    30.6.1 Avro Schema Registry Message Converter properties

    If you have enabled Avro based schema registry client by setting spring.cloud.stream.bindings.output.contentType=application/*+avro you can customize the behavior of the registration with the following properties.

    spring.cloud.stream.schema.avro.dynamicSchemaGenerationEnabled
    Enable if you want the converter to use reflection to infer a Schema from a POJO.
    Default
    false
    spring.cloud.stream.schema.avro.readerSchema
    Avro compares schema versions by looking at a writer schema (origin payload) and a reader schema (your application payload), check Avro documentation for more information. If set, this overrides any lookups at the schema server and uses the local schema as the reader schema.
    Default
    null
    spring.cloud.stream.schema.avro.schemaLocations
    Register any .avsc files listed in this property with the Schema Server.
    Default
    empty
    spring.cloud.stream.schema.avro.prefix
    The prefix to be used on the Content-Type header.
    Default
    vnd

    30.7 Schema Registration and Resolution

    To better understand how Spring Cloud Stream registers and resolves new schemas, as well as its use of Avro schema comparison features, we will provide two separate subsections below: one for the registration, and one for the resolution of schemas.

    30.7.1 Schema Registration Process (Serialization)

    The first part of the registration process is extracting a schema from the payload that is being sent over a channel. Avro types such as SpecificRecord or GenericRecord already contain a schema, which can be retrieved immediately from the instance. -In the case of POJOs a schema will be inferred if the property spring.cloud.stream.schema.avro.dynamicSchemaGenerationEnabled is set to true (the default).

    Figure 29.1. Schema Writer Resolution Process

    schema resolution

    Once a schema is obtained, the converter will then load its metadata (version) from the remote server. +In the case of POJOs a schema will be inferred if the property spring.cloud.stream.schema.avro.dynamicSchemaGenerationEnabled is set to true (the default).

    Figure 30.1. Schema Writer Resolution Process

    schema resolution

    Once a schema is obtained, the converter will then load its metadata (version) from the remote server. First it queries a local cache, and if not found it then submits the data to the server that will reply with versioning information. -The converter will always cache the results to avoid the overhead of querying the Schema Server for every new message that needs to be serialized.

    Figure 29.2. Schema Registration Process

    registration

    With the schema version information, the converter sets the contentType header of the message to carry the version information such as application/vnd.user.v1+avro

    29.7.2 Schema Resolution Process (Deserialization)

    When reading messages that contain version information (i.e. a contentType header with a scheme like above), the converter will query the Schema server to fetch the writer schema of the message. -Once it has found the correct schema of the incoming message, it then retrieves the reader schema and using Avro’s schema resolution support reads it into the reader definition (setting defaults and missing properties).

    Figure 29.3. Schema Reading Resolution Process

    schema reading

    [Note]Note

    It’s important to understand the difference between a writer schema (the application that wrote the message) and a reader schema (the receiving application). +The converter will always cache the results to avoid the overhead of querying the Schema Server for every new message that needs to be serialized.

    Figure 30.2. Schema Registration Process

    registration

    With the schema version information, the converter sets the contentType header of the message to carry the version information such as application/vnd.user.v1+avro

    30.7.2 Schema Resolution Process (Deserialization)

    When reading messages that contain version information (i.e. a contentType header with a scheme like above), the converter will query the Schema server to fetch the writer schema of the message. +Once it has found the correct schema of the incoming message, it then retrieves the reader schema and using Avro’s schema resolution support reads it into the reader definition (setting defaults and missing properties).

    Figure 30.3. Schema Reading Resolution Process

    schema reading

    [Note]Note

    It’s important to understand the difference between a writer schema (the application that wrote the message) and a reader schema (the receiving application). Please take a moment to read the Avro terminology and understand the process. -Spring Cloud Stream will always fetch the writer schema to determine how to read a message. If you want to get Avro’s schema evolution support working you need to make sure that a readerSchema was properly set for your application.

    30. Inter-Application Communication

    30.1 Connecting Multiple Application Instances

    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 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 (that has the channel name output) will set the following property:

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

    Log Sink (that has the channel name input) will set the following property:

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

    30.2 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. +Spring Cloud Stream will always fetch the writer schema to determine how to read a message. If you want to get Avro’s schema evolution support working you need to make sure that a readerSchema was properly set for your application.

    31. Inter-Application Communication

    31.1 Connecting Multiple Application Instances

    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 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 (that has the channel name output) will set the following property:

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

    Log Sink (that has the channel name input) will set the following property:

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

    31.2 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. 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.

    When Spring Cloud Stream applications are deployed via Spring Cloud Data Flow, 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.

    30.3 Partitioning

    30.3.1 Configuring Output Bindings for Partitioning

    An output binding is configured to send partitioned data by setting one and only one of its partitionKeyExpression or partitionKeyExtractorName (see next paragraph) properties, as well as its partitionCount property.

    For example, the following is a valid and typical configuration:

    spring.cloud.stream.bindings.output.producer.partitionKeyExpression=payload.id
    +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.

    31.3 Partitioning

    31.3.1 Configuring Output Bindings for Partitioning

    An output binding is configured to send partitioned data by setting one and only one of its partitionKeyExpression or partitionKeyExtractorName (see next paragraph) properties, as well as its partitionCount property.

    For example, the following is a valid and typical configuration:

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

    Based on the above example configuration, 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 which 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 providing implementation of org.springframework.cloud.stream.binder.PartitionKeyExtractorStrategy and configuring it as a bean (i.e., @Bean). In the event you have more then one bean of type org.springframework.cloud.stream.binder.PartitionKeyExtractorStrategy available in the Application Context you can further filter it by specifying its name via partitionKeyExtractorName property:

    --spring.cloud.stream.bindings.output.producer.partitionKeyExtractorName=customPartitionKeyExtractor
     --spring.cloud.stream.bindings.output.producer.partitionCount=5
    @@ -3258,7 +3455,7 @@ With Kafka, if autoRebalanceEnabled is autoRebalanceEnabled is set to false, the instanceCount and instanceIndex are used by the binder to determine which partition(s) the instance will subscribe to (you must have at least as many partitions as there are instances).
     The binder will allocate the partitions instead of Kafka.
     This might be useful if you want messages for a particular partition to always go to the same instance.
    -When a binder configuration that requires them, 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.

    31. Testing

    Spring Cloud Stream provides support for testing your microservice applications without connecting to a messaging system. +When a binder configuration that requires them, 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.

    32. 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 provided by the spring-cloud-stream-test-support library, which can be added as a test dependency to the application:

       <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-stream-test-support</artifactId>
    @@ -3301,7 +3498,7 @@ The following example shows how to test both input and output channels on a proc
     }

    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.

    31.1 Disabling the test binder autoconfiguration

    The intent behind the test binder superseding all the other binders on the classpath is to make it easy to test your applications without making changes to your production dependencies. +Once we have received the message, we can validate that the component functions correctly.

    32.1 Disabling the test binder autoconfiguration

    The intent behind the test binder superseding all the other binders on the classpath is to make it easy to test your applications without making changes to your production dependencies. In some cases (e.g. integration tests) it is useful to use the actual production binders instead, and that requires disabling the test binder autoconfiguration. In order to do so, you can exclude the org.springframework.cloud.stream.test.binder.TestSupportBinderAutoConfiguration class using one of the Spring Boot autoconfiguration exclusion mechanisms, as in the following example.

        @SpringBootApplication(exclude = TestSupportBinderAutoConfiguration.class)
         @EnableBinding(Processor.class)
    @@ -3311,8 +3508,8 @@ In order to do so, you can exclude the org.springframework
             public String transform(String in) {
                 return in + " world";
             }
    -    }

    When autoconfiguration is disabled, the test binder is available on the classpath, and its defaultCandidate property is set to false, so that it does not interfere with the regular user configuration. It can be referenced under the name test e.g.:

    spring.cloud.stream.defaultBinder=test

    32. Health Indicator

    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.

    33. Metrics Emitter

    Spring Cloud Stream provides a module called spring-cloud-stream-metrics that can be used to emit any available metric from Spring Boot metrics endpoint to a named channel. + }

    When autoconfiguration is disabled, the test binder is available on the classpath, and its defaultCandidate property is set to false, so that it does not interfere with the regular user configuration. It can be referenced under the name test e.g.:

    spring.cloud.stream.defaultBinder=test

    33. Health Indicator

    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.

    34. Metrics Emitter

    Spring Cloud Stream provides a module called spring-cloud-stream-metrics that can be used to emit any available metric from Spring Boot metrics endpoint to a named channel. This module allow operators to collect metrics from stream applications without relying on polling their endpoints.

    The module is activated when you set the destination name for metrics binding, e.g. spring.cloud.stream.bindings.applicationMetrics.destination=<DESTINATION_NAME>. applicationMetrics can be configured in a similar fashion to any other producer binding. The default contentType setting of applicationMetrics is application/json.

    The following properties can be used for customizing the emission of metrics:

    spring.cloud.stream.metrics.key
    The name of the metric being emitted. Should be an unique value per application.
    Default
    ${spring.application.name:${vcap.application.name:${spring.config.name:application}}}
    spring.cloud.stream.metrics.prefix

    Prefix string to be prepended to the metrics key.

    Default: ``

    spring.cloud.stream.metrics.properties

    Just like the includes option, it allows white listing application properties that will be added to the metrics payload

    Default: null.

    A detailed overview of the metrics export process can be found in the Spring Boot reference documentation. @@ -3386,7 +3583,7 @@ Alternatively, if it is intended to use configuration settings that are differen "spring.application.name":"time-source", "spring.application.index":"0" } -}

    34. Samples

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

    35. Getting Started

    To get started with creating Spring Cloud Stream applications, visit the Spring Initializr and create a new Maven project named "GreetingSource". +}

    35. Samples

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

    36. Getting Started

    To get started with creating Spring Cloud Stream applications, visit the Spring Initializr and create a new Maven project named "GreetingSource". Select Spring Boot {supported-spring-boot-version} in the dropdown. In the Search for dependencies text box type Stream Rabbit or Stream Kafka depending on what binder you want to use.

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

    import org.springframework.cloud.stream.annotation.EnableBinding;
    @@ -3438,15 +3635,15 @@ hello world 1458595076731
     hello world 1458595077732
     hello world 1458595078733
     hello world 1458595079734
    -hello world 1458595080735

    35.1 Deploying Stream applications on CloudFoundry

    On CloudFoundry services are usually exposed via a special environment variable called VCAP_SERVICES.

    When configuring your binder connections, you can use the values from an environment variable as explained on the dataflow cloudfoundry server docs.

    Part V. Binder Implementations

    36. Apache Kafka Binder

    36.1 Usage

    For using the Apache Kafka binder, you just need to add it to your Spring Cloud Stream application, using the following Maven coordinates:

    <dependency>
    +hello world 1458595080735

    36.1 Deploying Stream applications on CloudFoundry

    On CloudFoundry services are usually exposed via a special environment variable called VCAP_SERVICES.

    When configuring your binder connections, you can use the values from an environment variable as explained on the dataflow cloudfoundry server docs.

    Part VI. Binder Implementations

    37. Apache Kafka Binder

    37.1 Usage

    For using the Apache Kafka binder, you just need to add it to your Spring Cloud Stream application, using the following Maven coordinates:

    <dependency>
       <groupId>org.springframework.cloud</groupId>
       <artifactId>spring-cloud-stream-binder-kafka</artifactId>
     </dependency>

    Alternatively, you can also use the Spring Cloud Stream Kafka Starter.

    <dependency>
       <groupId>org.springframework.cloud</groupId>
       <artifactId>spring-cloud-starter-stream-kafka</artifactId>
    -</dependency>

    36.2 Apache Kafka Binder Overview

    A simplified diagram of how the Apache Kafka binder operates can be seen below.

    Figure 36.1. Kafka Binder

    kafka binder

    The Apache Kafka Binder implementation maps each destination to an Apache Kafka topic. +</dependency>

    37.2 Apache Kafka Binder Overview

    A simplified diagram of how the Apache Kafka binder operates can be seen below.

    Figure 37.1. Kafka Binder

    kafka binder

    The Apache Kafka Binder implementation maps each destination to an Apache Kafka topic. The consumer group maps directly to the same Apache Kafka concept. -Partitioning also maps directly to Apache Kafka partitions as well.

    36.3 Configuration Options

    This section contains the configuration options used by the Apache Kafka binder.

    For common configuration options and properties pertaining to binder, refer to the core documentation.

    36.3.1 Kafka Binder Properties

    spring.cloud.stream.kafka.binder.brokers

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

    Default: localhost.

    spring.cloud.stream.kafka.binder.defaultBrokerPort

    brokers allows hosts specified with or without port information (e.g., host1,host2:port2). +Partitioning also maps directly to Apache Kafka partitions as well.

    37.3 Configuration Options

    This section contains the configuration options used by the Apache Kafka binder.

    For common configuration options and properties pertaining to binder, refer to the core documentation.

    37.3.1 Kafka Binder Properties

    spring.cloud.stream.kafka.binder.brokers

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

    Default: localhost.

    spring.cloud.stream.kafka.binder.defaultBrokerPort

    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 to which the Kafka binder can connect.

    Default: localhost.

    spring.cloud.stream.kafka.binder.defaultZkPort

    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.configuration

    Key/Value map of client properties (both producers and consumer) passed to all clients created by the binder. Due to the fact that these properties will be used by both producers and consumers, usage should be restricted to common properties, especially security settings.

    Default: Empty map.

    spring.cloud.stream.kafka.binder.headers

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

    Default: empty.

    spring.cloud.stream.kafka.binder.healthTimeout

    The time to wait to get partition information in seconds; default 60. @@ -3462,7 +3659,7 @@ Of note, this setting is independent of the auto.topic.cre If set to false, the binder will rely on the partition size of the topic being already configured. If the partition count of the target topic is smaller than the expected value, the binder will fail to start.

    Default: false.

    spring.cloud.stream.kafka.binder.socketBufferSize

    Size (in bytes) of the socket buffer to be used by the Kafka consumers.

    Default: 2097152.

    spring.cloud.stream.kafka.binder.transaction.transactionIdPrefix

    Enable transactions in the binder; see transaction.id in the Kafka documentation and Transactions in the spring-kafka documentation. When transactions are enabled, individual producer properties are ignored and all producers use the spring.cloud.stream.kafka.binder.transaction.producer.* properties.

    Default null (no transactions)

    spring.cloud.stream.kafka.binder.transaction.producer.*

    Global producer properties for producers in a transactional binder. -See spring.cloud.stream.kafka.binder.transaction.transactionIdPrefix and Section 36.3.3, “Kafka Producer Properties” and the general producer properties supported by all binders.

    Default: See individual producer properties.

    36.3.2 Kafka Consumer Properties

    The following properties are available for Kafka consumers only and +See spring.cloud.stream.kafka.binder.transaction.transactionIdPrefix and Section 37.3.3, “Kafka Producer Properties” and the general producer properties supported by all binders.

    Default: See individual producer properties.

    37.3.2 Kafka Consumer Properties

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

    autoRebalanceEnabled

    When true, topic partitions will be automatically rebalanced between the members of a consumer group. When false, each consumer will be assigned a fixed set of partitions based on spring.cloud.stream.instanceCount and spring.cloud.stream.instanceIndex. This requires both spring.cloud.stream.instanceCount and spring.cloud.stream.instanceIndex properties to be set appropriately on each launched instance. @@ -3479,13 +3676,13 @@ If the consumer group is set explicitly for the consumer 'binding' (via error.<destination>.<group>. The DLQ topic name can be configurable via the property dlqName. This provides an alternative option to the more common Kafka replay scenario for the case when the number of errors is relatively small and replaying the entire original topic may be too cumbersome. -See Section 36.6, “Dead-Letter Topic Processing” processing for more information. +See Section 37.6, “Dead-Letter Topic Processing” processing for more information. Starting with version 2.0, messages sent to the DLQ topic are enhanced with the following headers: x-original-topic, x-exception-message and x-exception-stacktrace as byte[].

    Default: false.

    configuration

    Map with a key/value pair containing generic Kafka consumer properties.

    Default: Empty map.

    dlqName

    The name of the DLQ topic to receive the error messages.

    Default: null (If not specified, messages that result in errors will be forwarded to a topic named error.<destination>.<group>).

    dlqProducerProperties

    Using this, dlq specific producer properties can be set. All the properties available through kafka producer properties can be set through this property.

    Default: Default Kafka producer properties.

    standardHeaders

    Indicates which standard headers are populated by the inbound channel adapter. none, id, timestamp or both. Useful if using native deserialization and the first component to receive a message needs an id (such as an aggregator that is configured to use a JDBC message store).

    Default: none

    converterBeanName

    The name of a bean that implements RecordMessageConverter; used in the inbound channel adapter to replace the default MessagingMessageConverter.

    Default: null

    idleEventInterval

    The interval, in milliseconds between events indicating that no messages have recently been received. Use an ApplicationListener<ListenerContainerIdleEvent> to receive these events. -See the section called “Example: Pausing and Resuming the Consumer” for a usage example.

    Default: 30000

    36.3.3 Kafka Producer Properties

    The following properties are available for Kafka producers only and +See the section called “Example: Pausing and Resuming the Consumer” for a usage example.

    Default: 30000

    37.3.3 Kafka Producer Properties

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

    bufferSize

    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.

    Default: false.

    batchTimeout

    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.

    messageKeyExpression

    A SpEL expression evaluated against the outgoing message used to populate the key of the produced Kafka message. For example headers.key or payload.myKey.

    Default: none.

    headerPatterns

    A comma-delimited list of simple patterns to match spring-messaging headers to be mapped to the kafka Headers in the ProducerRecord. @@ -3496,7 +3693,7 @@ For example !foo,fo* will pass minPartitionCount for a binder and partitionCount for an application, as the larger value will be used. If a topic already exists with a smaller partition count and autoAddPartitions is disabled (the default), then the binder will fail to start. If a topic already exists with a smaller partition count and autoAddPartitions is enabled, new partitions will be added. -If a topic already exists with a larger number of partitions than the maximum of (minPartitionCount and partitionCount), the existing partition count will be used.

    36.3.4 Usage examples

    In this section, we illustrate the use of the above properties for specific scenarios.

    Example: Setting autoCommitOffset false and relying on manual acking.

    This example illustrates how one may manually acknowledge offsets in a consumer application.

    This example requires that spring.cloud.stream.kafka.bindings.input.consumer.autoCommitOffset is set to false. +If a topic already exists with a larger number of partitions than the maximum of (minPartitionCount and partitionCount), the existing partition count will be used.

    37.3.4 Usage examples

    In this section, we illustrate the use of the above properties for specific scenarios.

    Example: Setting autoCommitOffset false and relying on manual acking.

    This example illustrates how one may manually acknowledge offsets in a consumer application.

    This example requires that spring.cloud.stream.kafka.bindings.input.consumer.autoCommitOffset is set to false. Use the corresponding input channel name for your example.

    @SpringBootApplication
     @EnableBinding(Sink.class)
     public class ManuallyAcknowdledgingConsumer {
    @@ -3620,10 +3817,10 @@ If you use the default Kafka version, then ensure that you exclude the kafka bro
       </exclusions>
     </dependency>

    If you exclude the Apache Kafka server dependency and the topic is not present on the server, then the Apache Kafka broker will create the topic if auto topic creation is enabled on the server. Please keep in mind that if you are relying on this, then the Kafka server will use the default number of partitions and replication factors. -On the other hand, if auto topic creation is disabled on the server, then care must be taken before running the application to create the topic with the desired number of partitions.

    If you want to have full control over how partitions are allocated, then leave the default settings as they are, i.e. do not exclude the kafka broker jar and ensure that spring.cloud.stream.kafka.binder.autoCreateTopics is set to true, which is the default.

    36.4 Error Channels

    Starting with version 1.3, the binder unconditionally sends exceptions to an error channel for each consumer destination, and can be configured to send async producer send failures to an error channel too. -See the section called “Message Channel Binders and Error Channels” for more information.

    The payload of the ErrorMessage for a send failure is a KafkaSendFailureException with properties:

    • failedMessage - the spring-messaging Message<?> that failed to be sent.
    • record - the raw ProducerRecord that was created from the failedMessage

    There is no automatic handling of producer exceptions (such as sending to a Dead-Letter queue); you can consume these exceptions with your own Spring Integration flow.

    36.5 Kafka Metrics

    Kafka binder module exposes the following metrics:

    spring.cloud.stream.binder.kafka.someGroup.someTopic.lag - this metric indicates how many messages have not been yet consumed from given binder’s topic by given consumer group. +On the other hand, if auto topic creation is disabled on the server, then care must be taken before running the application to create the topic with the desired number of partitions.

    If you want to have full control over how partitions are allocated, then leave the default settings as they are, i.e. do not exclude the kafka broker jar and ensure that spring.cloud.stream.kafka.binder.autoCreateTopics is set to true, which is the default.

    37.4 Error Channels

    Starting with version 1.3, the binder unconditionally sends exceptions to an error channel for each consumer destination, and can be configured to send async producer send failures to an error channel too. +See the section called “Message Channel Binders and Error Channels” for more information.

    The payload of the ErrorMessage for a send failure is a KafkaSendFailureException with properties:

    • failedMessage - the spring-messaging Message<?> that failed to be sent.
    • record - the raw ProducerRecord that was created from the failedMessage

    There is no automatic handling of producer exceptions (such as sending to a Dead-Letter queue); you can consume these exceptions with your own Spring Integration flow.

    37.5 Kafka Metrics

    Kafka binder module exposes the following metrics:

    spring.cloud.stream.binder.kafka.someGroup.someTopic.lag - this metric indicates how many messages have not been yet consumed from given binder’s topic by given consumer group. For example if the value of the metric spring.cloud.stream.binder.kafka.myGroup.myTopic.lag is 1000, then consumer group myGroup has 1000 messages to waiting to be consumed from topic myTopic. -This metric is particularly useful to provide auto-scaling feedback to PaaS platform of your choice.

    36.6 Dead-Letter Topic Processing

    Because it can’t be anticipated how users would want to dispose of dead-lettered messages, the framework does not provide any standard mechanism to handle them. +This metric is particularly useful to provide auto-scaling feedback to PaaS platform of your choice.

    37.6 Dead-Letter Topic Processing

    Because it can’t be anticipated how users would want to dispose of dead-lettered messages, the framework does not provide any standard mechanism to handle them. If the reason for the dead-lettering is transient, you may wish to route the messages back to the original topic. However, if the problem is a permanent issue, that could cause an infinite loop. The following spring-boot application is an example of how to route those messages back to the original topic, but moves them to a third "parking lot" topic after three attempts. @@ -3710,7 +3907,7 @@ spring.cloud.stream.kafka.binder.headers=x-retries

    } }

    -

    36.7 Partitioning with the Kafka Binder

    Apache Kafka supports topic partitioning natively.

    Sometimes it is advantageous to send data to specific partitions, for example when you want to strictly order message processing - all messages for a particular customer should go to the same partition.

    The following illustrates how to configure the producer and consumer side:

    @SpringBootApplication
    +

    37.7 Partitioning with the Kafka Binder

    Apache Kafka supports topic partitioning natively.

    Sometimes it is advantageous to send data to specific partitions, for example when you want to strictly order message processing - all messages for a particular customer should go to the same partition.

    The following illustrates how to configure the producer and consumer side:

    @SpringBootApplication
     @EnableBinding(Source.class)
     public class KafkaPartitionProducerApplication {
     
    @@ -3777,7 +3974,7 @@ Kafka will allocate partitions across the instances.

              destination: partitioned.topic
               group: myGroup

    You can add instances as needed; Kafka will rebalance the partition allocations. -If the instance count (or instance count * concurrency) exceeds the number of partitions, some consumers will be idle.

    36.8 Kafka Streams Binding Capabilities of Spring Cloud Stream

    Spring Cloud Stream Kafka support also includes a binder specifically designed for Apache Kafka Streams binding. +If the instance count (or instance count * concurrency) exceeds the number of partitions, some consumers will be idle.

    37.8 Kafka Streams Binding Capabilities of Spring Cloud Stream

    Spring Cloud Stream Kafka support also includes a binder specifically designed for Apache Kafka Streams binding. Using this binder, applications can be written that leverage the Apache Kafka Streams API. For more information on Kafka Streams, see Kafka Streams API Developer Manual

    Kafka Streams support in Spring Cloud Stream is based on the foundations provided by the Spring Kafka project. For details on that support, see Kafaka Streams Support in Spring Kafka.

    Here are the maven coordinates for the Spring Cloud Stream Kafka Streams binder artifact.

    <dependency>
    @@ -3785,7 +3982,7 @@ For details on that support, see <artifactId>spring-cloud-stream-binder-kafka-streams</artifactId>
     </dependency>

    High level streams DSL provided through the Kafka Streams API can be used through Spring Cloud Stream support. Some minimal support for writing applications using the processor API is also available through the binder. -Kafka Streams applications using the Spring Cloud Stream support can be written using the processor model, i.e. messages read from an inbound topic and messages written to an outbound topic or using the sink style where it does not have an output binding.

    36.8.1 Usage example of high level streams DSL

    This application will listen from a Kafka topic and write the word count for each unique word that it sees in a 5 seconds time window.

    @SpringBootApplication
    +Kafka Streams applications using the Spring Cloud Stream support can be written using the processor model, i.e. messages read from an inbound topic and messages written to an outbound topic or using the sink style where it does not have an output binding.

    37.8.1 Usage example of high level streams DSL

    This application will listen from a Kafka topic and write the word count for each unique word that it sees in a 5 seconds time window.

    @SpringBootApplication
     @EnableBinding(KStreamProcessor.class)
     public class WordCountProcessorApplication {
     
    @@ -3805,7 +4002,7 @@ public class WordCountProcessorApplication {
     		SpringApplication.run(WordCountProcessorApplication.class, args);
     	}

    If you build it as a Spring Boot uber jar, you can run the above example in the following way:

    java -jar uber.jar  --spring.cloud.stream.bindings.input.destination=words --spring.cloud.stream.bindings.output.destination=counts

    This means that the application will listen from the incoming Kafka topic words and write to the output topic counts.

    Spring Cloud Stream will ensure that the messages from both the incoming and outgoing topics are bound as KStream objects. Applications can exclusively focus on the business aspects of the code, i.e. writing the logic required in the processor rather than setting up the streams specific configuration required by the Kafka Streams infrastructure. -All such infrastructure details are handled by the framework.

    36.8.2 Multiple Input bindings on the inbound

    Spring Cloud Stream Kafka Streams binder allows the users to write applications with multiple bindings. +All such infrastructure details are handled by the framework.

    37.8.2 Multiple Input bindings on the inbound

    Spring Cloud Stream Kafka Streams binder allows the users to write applications with multiple bindings. There are use cases in which you may want to have multiple incoming KStream objects or a combination of KStream and KTable objects. Both of these flavors are supported. Here are some examples.

    @EnableBinding(KStreamKTableBinding.class)
    @@ -3842,7 +4039,7 @@ interface KStreamKTableBinding extends KafkaStreamsProcessor {
     
         @Input("inputX")
         KTable<?, ?> inputTable();
    -}

    36.8.3 Support for branching in Kafka Streams API

    Kafka Streams allow outbound data to be split into multiple topics based on some predicates. +}

    37.8.3 Support for branching in Kafka Streams API

    Kafka Streams allow outbound data to be split into multiple topics based on some predicates. Spring Cloud Stream Kafka Streams binder provides support for this feature without losing the overall programming model exposed through StreamListener in the end user application. You write the application in the usual way as demonstrated above in the word count example. When using the branching feature, you are required to do a few things. @@ -3909,7 +4106,7 @@ spring.cloud.stream.bindings.output3: spring.cloud.stream.bindings.input: destination: words consumer: - headerMode: raw

    36.8.4 Message conversion in Spring Cloud Stream Kafka Streams applications

    Spring Cloud Stream Kafka Streams binder allows the usage of usual patterns for content type conversions as in other message channel based binder applications. + headerMode: raw

    37.8.4 Message conversion in Spring Cloud Stream Kafka Streams applications

    Spring Cloud Stream Kafka Streams binder allows the usage of usual patterns for content type conversions as in other message channel based binder applications. Many Kafka Streams operations - that are part of the actual application and not at the inbound and outbound - need to know the type of SerDe’s used to correctly transform key and value data. Therefore, it may be more natural to rely on the SerDe facilities provided by the Apache Kafka Streams library itself for inbound and outbound conversions rather than using the content type conversions offered by the framework. On the other hand, you might be already familiar with the content type conversion patterns in spring cloud stream and want to keep using them for inbound and outbound conversions. @@ -3986,12 +4183,12 @@ public KStream<?, WordCount> process(KStream<Object, String> input) ..... ..... }); -}

    36.8.5 Support for interactive queries

    As part of the public API of the binder, it now exposes a class called QueryableStoreRegistry. +}

    37.8.5 Support for interactive queries

    As part of the public API of the binder, it now exposes a class called QueryableStoreRegistry. You can access this as a Spring bean in your application. One easy way to get access to this bean from your application is to autowire the bean as below.

    @Autowired
     private QueryableStoreRegistry queryableStoreRegistry;

    Once you gain access to this bean, then you can find out the particular state store that you are interested in. Here is an example:

    ReadOnlyKeyValueStore<Object, Object> keyValueStore =
    -						queryableStoreRegistry.getQueryableStoreType("my-store", QueryableStoreTypes.keyValueStore());

    Then you can retrieve the data that you stored in this store during the execution of your application.

    36.8.6 Kafka Streams properties

    We covered all the relevant properties that you need when writing Kafka Streams applications using Spring Cloud Stream, scattered in the above sections, but here they are again.

    The following properties are available at the binder level and must be prefixed with spring.cloud.stream.kafka.binder..

    configuration
    Map with a key/value pair containing properties pertaining to Apache Kafka Streams API. + queryableStoreRegistry.getQueryableStoreType("my-store", QueryableStoreTypes.keyValueStore());

    Then you can retrieve the data that you stored in this store during the execution of your application.

    37.8.6 Kafka Streams properties

    We covered all the relevant properties that you need when writing Kafka Streams applications using Spring Cloud Stream, scattered in the above sections, but here they are again.

    The following properties are available at the binder level and must be prefixed with spring.cloud.stream.kafka.binder..

    configuration
    Map with a key/value pair containing properties pertaining to Apache Kafka Streams API. This property must be prefixed with spring.cloud.stream.kafka.streams.binder.. Following are some examples of using this property.
    spring.cloud.stream.kafka.streams.binder.configuration.default.key.serde=org.apache.kafka.common.serialization.Serdes$StringSerde
     spring.cloud.stream.kafka.streams.binder.configuration.default.value.serde=org.apache.kafka.common.serialization.Serdes$StringSerde
    @@ -4001,13 +4198,13 @@ You can override the application id for an individual Stre
     You have to ensure that you are using the same group name for all input bindings in the case of multiple inputs on the same methods.

    Default: default

    The following properties are available for Kafka Streams producers only and must be prefixed with spring.cloud.stream.kafka.streams.bindings.<binding name>.producer..

    keySerde

    key serde to use

    Default: none.

    valueSerde

    value serde to use

    Default: none.

    useNativeEncoding

    flag to enable native encoding

    Default: false.

    The following properties are available for Kafka Streams consumers only and must be prefixed with spring.cloud.stream.kafka.streams.bindings.<binding name>.consumer..

    keySerde

    key serde to use

    Default: none.

    valueSerde

    value serde to use

    Default: none.

    materializedAs

    state store to materialize when using incoming KTable types

    Default: none.

    useNativeDecoding

    flag to enable native decoding

    Default: false.

    dlqName

    DLQ topic name.

    Default: none.

    Other common properties used from core Spring Cloud Stream.

    spring.cloud.stream.bindings.<binding name>.destination
     spring.cloud.stream.bindings.<binding name>.group

    TimeWindow properties:

    Windowing is an important concept in stream processing applications. Following properties are available for configuring time windows.

    spring.cloud.stream.kafka.streams.timeWindow.length

    When this property is given, you can autowire a TimeWindows bean into the application. -The value is expressed in milliseconds.

    Default: none.

    spring.cloud.stream.kstream.timeWindow.advanceBy

    Value is given in milliseconds.

    Default: none.

    37. RabbitMQ Binder

    37.1 Usage

    For using the RabbitMQ binder, you just need to add it to your Spring Cloud Stream application, using the following Maven coordinates:

    <dependency>
    +The value is expressed in milliseconds.

    Default: none.

    spring.cloud.stream.kstream.timeWindow.advanceBy

    Value is given in milliseconds.

    Default: none.

    38. RabbitMQ Binder

    38.1 Usage

    For using the RabbitMQ binder, you just need to add it to your Spring Cloud Stream application, using the following Maven coordinates:

    <dependency>
       <groupId>org.springframework.cloud</groupId>
       <artifactId>spring-cloud-stream-binder-rabbit</artifactId>
     </dependency>

    Alternatively, you can also use the Spring Cloud Stream RabbitMQ Starter.

    <dependency>
       <groupId>org.springframework.cloud</groupId>
       <artifactId>spring-cloud-starter-stream-rabbit</artifactId>
    -</dependency>

    37.2 RabbitMQ Binder Overview

    A simplified diagram of how the RabbitMQ binder operates can be seen below.

    Figure 37.1. RabbitMQ Binder

    rabbit binder

    The RabbitMQ Binder implementation maps each destination to a TopicExchange. +</dependency>

    38.2 RabbitMQ Binder Overview

    A simplified diagram of how the RabbitMQ binder operates can be seen below.

    Figure 38.1. RabbitMQ Binder

    rabbit binder

    The RabbitMQ Binder implementation maps each destination to a TopicExchange. For each consumer group, a Queue will be bound to that TopicExchange. Each consumer instance have a corresponding RabbitMQ Consumer instance for its group’s Queue. For partitioned producers/consumers the queues are suffixed with the partition index and use the partition index as routing key.

    Using the autoBindDlq option, you can optionally configure the binder to create and configure dead-letter queues (DLQs) (and a dead-letter exchange DLX). @@ -4017,9 +4214,9 @@ If retry is disabled (maxAttempts = 1), you should In addition, republishToDlq causes the binder to publish a failed message to the DLQ (instead of rejecting it); this enables additional information to be added to the message in headers, such as the stack trace in the x-exception-stacktrace header. This option does not need retry enabled; you can republish a failed message after just one attempt. Starting with version 1.2, you can configure the delivery mode of republished messages; see property republishDeliveryMode.

    [Important]Important

    Setting requeueRejected to true will cause the message to be requeued and redelivered continually, which is likely not what you want unless the failure issue is transient. -In general, it’s better to enable retry within the binder by setting maxAttempts to greater than one, or set republishToDlq to true.

    See Section 37.3.1, “RabbitMQ Binder Properties” for more information about these properties.

    The framework does not provide any standard mechanism to consume dead-letter messages (or to re-route them back to the primary queue). -Some options are described in Section 37.6, “Dead-Letter Queue Processing”.

    [Note]Note

    When multiple RabbitMQ binders are used in a Spring Cloud Stream application, it is important to disable 'RabbitAutoConfiguration' to avoid the same configuration from RabbitAutoConfiguration being applied to the two binders.

    Starting with version 1.3, the RabbitMessageChannelBinder creates an internal ConnectionFactory copy for the non-transactional producers to avoid dead locks on consumers when shared, cached connections are blocked because of Memory Alarm on Broker.

    37.3 Configuration Options

    This section contains settings specific to the RabbitMQ Binder and bound channels.

    For general binding configuration options and properties, -please refer to the Spring Cloud Stream core documentation.

    37.3.1 RabbitMQ Binder Properties

    By default, the RabbitMQ binder uses Spring Boot’s ConnectionFactory, and it therefore supports all Spring Boot configuration options for RabbitMQ. +In general, it’s better to enable retry within the binder by setting maxAttempts to greater than one, or set republishToDlq to true.

    See Section 38.3.1, “RabbitMQ Binder Properties” for more information about these properties.

    The framework does not provide any standard mechanism to consume dead-letter messages (or to re-route them back to the primary queue). +Some options are described in Section 38.6, “Dead-Letter Queue Processing”.

    [Note]Note

    When multiple RabbitMQ binders are used in a Spring Cloud Stream application, it is important to disable 'RabbitAutoConfiguration' to avoid the same configuration from RabbitAutoConfiguration being applied to the two binders.

    Starting with version 1.3, the RabbitMessageChannelBinder creates an internal ConnectionFactory copy for the non-transactional producers to avoid dead locks on consumers when shared, cached connections are blocked because of Memory Alarm on Broker.

    38.3 Configuration Options

    This section contains settings specific to the RabbitMQ Binder and bound channels.

    For general binding configuration options and properties, +please refer to the Spring Cloud Stream core documentation.

    38.3.1 RabbitMQ Binder Properties

    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 Spring Boot options, the RabbitMQ binder supports the following properties:

    spring.cloud.stream.rabbit.binder.adminAddresses

    A comma-separated list of RabbitMQ management plugin URLs. Only used when nodes contains more than one entry. @@ -4030,7 +4227,7 @@ When more than one entry, used to locate the server address where a queue is loc Each entry in this list must have a corresponding entry in spring.rabbitmq.addresses. Only needed if you are using a RabbitMQ cluster and wish to consume from the node that hosts the queue. See Queue Affinity and the LocalizedQueueConnectionFactory for more information.

    Default: empty.

    spring.cloud.stream.rabbit.binder.compressionLevel

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

    Default: 1 (BEST_LEVEL).

    37.3.2 RabbitMQ Consumer Properties

    The following properties are available for Rabbit consumers only and +See java.util.zip.Deflater.

    Default: 1 (BEST_LEVEL).

    38.3.2 RabbitMQ Consumer Properties

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

    acknowledgeMode

    The acknowledge mode.

    Default: AUTO.

    autoBindDlq

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

    Default: false.

    bindingRoutingKey

    The routing key with which to bind the queue to the exchange (if bindQueue is true). for partitioned destinations -<instanceIndex> will be appended.

    Default: #.

    bindQueue

    Whether to bind the queue to the destination exchange; set to false if you have set up your own infrastructure and have previously created/bound the queue.

    Default: true.

    deadLetterQueueName

    name of the DLQ

    Default: prefix+destination.dlq

    deadLetterExchange

    a DLX to assign to the queue; if autoBindDlq is true

    Default: 'prefix+DLX'

    deadLetterRoutingKey

    a dead letter routing key to assign to the queue; if autoBindDlq is true

    Default: destination

    declareExchange

    Whether to declare the exchange for the destination.

    Default: true.

    delayedExchange

    Whether to declare the exchange as a Delayed Message Exchange - requires the delayed message exchange plugin on the broker. The x-delayed-type argument is set to the exchangeType.

    Default: false.

    dlqDeadLetterExchange

    if a DLQ is declared, a DLX to assign to that queue

    Default: none

    dlqDeadLetterRoutingKey

    if a DLQ is declared, a dead letter routing key to assign to that queue; default none

    Default: none

    dlqExpires

    how long before an unused dead letter queue is deleted (ms)

    Default: no expiration

    dlqLazy

    Declare the dead letter queue with the x-queue-mode=lazy argument. @@ -4044,7 +4241,7 @@ Defaults to false so that the container keeps tryin Only relevant if missingQueuesFatal is true; otherwise the container keeps retrying indefinitely.

    Default
    3
    queueNameGroupOnly

    When true, consume from a queue with a name equal to the group; otherwise the queue name is destination.group. This is useful, for example, when using Spring Cloud Stream to consume from an existing RabbitMQ queue.

    Default: false.

    recoveryInterval

    The interval between connection recovery attempts, in milliseconds.

    Default: 5000.

    requeueRejected

    Whether delivery failures should be requeued when retry is disabled or republishToDlq is false.

    Default: false.

    republishDeliveryMode

    When republishToDlq is true, specify the delivery mode of the republished message.

    Default: DeliveryMode.PERSISTENT

    republishToDlq

    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 binder will republish failed messages to the DLQ with additional headers, including the exception message and stack trace from the cause of the final failure.

    Default: false

    transacted

    Whether to use transacted channels.

    Default: false.

    ttl

    default time to live to apply to the queue when declared (ms)

    Default: no limit

    txSize

    The number of deliveries between acks.

    Default: 1.

    37.3.3 Rabbit Producer Properties

    The following properties are available for Rabbit producers only and +If set to true, the binder will republish failed messages to the DLQ with additional headers, including the exception message and stack trace from the cause of the final failure.

    Default: false

    transacted

    Whether to use transacted channels.

    Default: false.

    ttl

    default time to live to apply to the queue when declared (ms)

    Default: no limit

    txSize

    The number of deliveries between acks.

    Default: 1.

    38.3.3 Rabbit Producer Properties

    The following properties are available for Rabbit producers only and 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.

    batchingEnabled

    Whether to enable message batching by producers.

    Default: false.

    batchSize

    The number of messages to buffer when batching is enabled.

    Default: 100.

    batchBufferLimit
    Default: 10000.
    batchTimeout
    Default: 5000.
    bindingRoutingKey

    The routing key with which to bind the queue to the exchange (if bindQueue is true). Only applies to non-partitioned destinations. Only applies if requiredGroups are provided and then only to those groups.

    Default: #.

    bindQueue

    Whether to bind the queue to the destination exchange; set to false if you have set up your own infrastructure and have previously created/bound the queue. @@ -4074,12 +4271,12 @@ This is useful, for example, when using Spring Cloud Stream to consume from an e Only applies if requiredGroups are provided and then only to those groups.

    Default: false.

    routingKeyExpression

    A SpEL expression to determine the routing key to use when publishing messages. For a fixed routing key, use a literal expression, e.g. routingKeyExpression='my.routingKey' in a properties file, or routingKeyExpression: '''my.routingKey''' in a YAML file.

    Default: destination or destination-<partition> for partitioned destinations.

    transacted

    Whether to use transacted channels.

    Default: false.

    ttl

    default time to live to apply to the queue when declared (ms) Only applies if requiredGroups are provided and then only to those groups.

    Default: no limit

    [Note]Note

    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 (prior to 0.11), that do not natively support headers).

    37.4 Retry With the RabbitMQ Binder

    37.4.1 Overview

    When retry is enabled within the binder, the listener container thread is suspended for any back off periods that are configured. +Spring Cloud Stream supports them as part of an extended internal protocol used for any type of transport (including transports, such as Kafka (prior to 0.11), that do not natively support headers).

    38.4 Retry With the RabbitMQ Binder

    38.4.1 Overview

    When retry is enabled within the binder, the listener container thread is suspended for any back off periods that are configured. This might be important when strict ordering is required with a single consumer but for other use cases it prevents other messages from being processed on that thread. An alternative to using binder retry is to set up dead lettering with time to live on the dead-letter queue (DLQ), as well as dead-letter configuration on the DLQ itself. -See Section 37.3.1, “RabbitMQ Binder Properties” for more information about the properties discussed here. +See Section 38.3.1, “RabbitMQ Binder Properties” for more information about the properties discussed here. Example configuration to enable this feature:

    • Set autoBindDlq to true - the binder will create a DLQ; you can optionally specify a name in deadLetterQueueName
    • Set dlqTtl to the back off time you want to wait between redeliveries
    • Set the dlqDeadLetterExchange to the default exchange - expired messages from the DLQ will be routed to the original queue since the default deadLetterRoutingKey is the queue name (destination.group)

    To force a message to be dead-lettered, either throw an AmqpRejectAndDontRequeueException, or set requeueRejected to true and throw any exception.

    The loop will continue without end, which is fine for transient problems but you may want to give up after some number of attempts. -Fortunately, RabbitMQ provides the x-death header which allows you to determine how many cycles have occurred.

    To acknowledge a message after giving up, throw an ImmediateAcknowledgeAmqpException.

    37.4.2 Putting it All Together

    ---
    +Fortunately, RabbitMQ provides the x-death header which allows you to determine how many cycles have occurred.

    To acknowledge a message after giving up, throw an ImmediateAcknowledgeAmqpException.

    38.4.2 Putting it All Together

    ---
     spring.cloud.stream.bindings.input.destination=myDestination
     spring.cloud.stream.bindings.input.group=consumerGroup
     #disable binder retries
    @@ -4110,14 +4307,14 @@ After 5 seconds, the message expires and is routed to the original queue using t
         }
     
     }

    -

    Notice that the count property in the x-death header is a Long.

    37.5 Error Channels

    Starting with version 1.3, the binder unconditionally sends exceptions to an error channel for each consumer destination, and can be configured to send async producer send failures to an error channel too. -See the section called “Message Channel Binders and Error Channels” for more information.

    With rabbitmq, there are two types of send failures:

    The latter is rare; quoting the RabbitMQ documentation "[A nack] will only be delivered if an internal error occurs in the Erlang process responsible for a queue.".

    As well as enabling producer error channels as described in the section called “Message Channel Binders and Error Channels”, the RabbitMQ binder will only send messages to the channels if the connection factory is appropriately configured:

    • ccf.setPublisherConfirms(true);
    • ccf.setPublisherReturns(true);

    When using spring boot configuration for the connection factory, set properties:

    • spring.rabbitmq.publisher-confirms
    • spring.rabbitmq.publisher-returns

    The payload of the ErrorMessage for a returned message is a ReturnedAmqpMessageException with properties:

    • failedMessage - the spring-messaging Message<?> that failed to be sent.
    • amqpMessage - the raw spring-amqp Message
    • replyCode - an integer value indicating the reason for the failure (e.g. 312 - No route)
    • replyText - a text value indicating the reason for the failure e.g. NO_ROUTE.
    • exchange - the exchange to which the message was published.
    • routingKey - the routing key used when the message was published.

    For negatively acknowledged confirms, the payload is a NackedAmqpMessageException with properties:

    • failedMessage - the spring-messaging Message<?> that failed to be sent.
    • nackReason - a reason (if available; you may need to examine the broker logs for more information).

    There is no automatic handling of these exceptions (such as sending to a Dead-Letter queue); you can consume these exceptions with your own Spring Integration flow.

    37.6 Dead-Letter Queue Processing

    Because it can’t be anticipated how users would want to dispose of dead-lettered messages, the framework does not provide any standard mechanism to handle them. +

    Notice that the count property in the x-death header is a Long.

    38.5 Error Channels

    Starting with version 1.3, the binder unconditionally sends exceptions to an error channel for each consumer destination, and can be configured to send async producer send failures to an error channel too. +See the section called “Message Channel Binders and Error Channels” for more information.

    With rabbitmq, there are two types of send failures:

    The latter is rare; quoting the RabbitMQ documentation "[A nack] will only be delivered if an internal error occurs in the Erlang process responsible for a queue.".

    As well as enabling producer error channels as described in the section called “Message Channel Binders and Error Channels”, the RabbitMQ binder will only send messages to the channels if the connection factory is appropriately configured:

    • ccf.setPublisherConfirms(true);
    • ccf.setPublisherReturns(true);

    When using spring boot configuration for the connection factory, set properties:

    • spring.rabbitmq.publisher-confirms
    • spring.rabbitmq.publisher-returns

    The payload of the ErrorMessage for a returned message is a ReturnedAmqpMessageException with properties:

    • failedMessage - the spring-messaging Message<?> that failed to be sent.
    • amqpMessage - the raw spring-amqp Message
    • replyCode - an integer value indicating the reason for the failure (e.g. 312 - No route)
    • replyText - a text value indicating the reason for the failure e.g. NO_ROUTE.
    • exchange - the exchange to which the message was published.
    • routingKey - the routing key used when the message was published.

    For negatively acknowledged confirms, the payload is a NackedAmqpMessageException with properties:

    • failedMessage - the spring-messaging Message<?> that failed to be sent.
    • nackReason - a reason (if available; you may need to examine the broker logs for more information).

    There is no automatic handling of these exceptions (such as sending to a Dead-Letter queue); you can consume these exceptions with your own Spring Integration flow.

    38.6 Dead-Letter Queue Processing

    Because it can’t be anticipated how users would want to dispose of dead-lettered messages, the framework does not provide any standard mechanism to handle them. If the reason for the dead-lettering is transient, you may wish to route the messages back to the original queue. However, if the problem is a permanent issue, that could cause an infinite loop. The following spring-boot application is an example of how to route those messages back to the original queue, but moves them to a third "parking lot" queue after three attempts. The second example utilizes the RabbitMQ Delayed Message Exchange to introduce a delay to the requeued message. In this example, the delay increases for each attempt. -These examples use a @RabbitListener to receive messages from the DLQ, you could also use RabbitTemplate.receive() in a batch process.

    The examples assume the original destination is so8400in and the consumer group is so8400.

    37.6.1 Non-Partitioned Destinations

    The first two examples are when the destination is not partitioned.

    @SpringBootApplication
    +These examples use a @RabbitListener to receive messages from the DLQ, you could also use RabbitTemplate.receive() in a batch process.

    The examples assume the original destination is so8400in and the consumer group is so8400.

    38.6.1 Non-Partitioned Destinations

    The first two examples are when the destination is not partitioned.

    @SpringBootApplication
     public class ReRouteDlqApplication {
     
         private static final String ORIGINAL_QUEUE = "so8400in.so8400";
    @@ -4215,7 +4412,7 @@ These examples use a @RabbitListener to receive mes
             return new Queue(PARKING_LOT);
         }
     
    -}

    37.6.2 Partitioned Destinations

    With partitioned destinations, there is one DLQ for all partitions and we determine the original queue from the headers.

    republishToDlq=false

    When republishToDlq is false, RabbitMQ publishes the message to the DLX/DLQ with an x-death header containing information about the original destination.

    @SpringBootApplication
    +}

    38.6.2 Partitioned Destinations

    With partitioned destinations, there is one DLQ for all partitions and we determine the original queue from the headers.

    republishToDlq=false

    When republishToDlq is false, RabbitMQ publishes the message to the DLX/DLQ with an x-death header containing information about the original destination.

    @SpringBootApplication
     public class ReRouteDlqApplication {
     
     	private static final String ORIGINAL_QUEUE = "so8400in.so8400";
    @@ -4311,7 +4508,7 @@ These examples use a @RabbitListener to receive mes
     		return new Queue(PARKING_LOT);
     	}
     
    -}

    37.7 Partitioning with the RabbitMQ Binder

    RabbitMQ does not support partitioning natively.

    Sometimes it is advantageous to send data to specific partitions, for example when you want to strictly order message processing - all messages for a particular customer should go to the same partition.

    The RabbitMessageChannelBinder provides partitioning by binding a queue for each partition to the destination exchange.

    The following illustrates how to configure the producer and consumer side:

    Producer.  +}

    38.7 Partitioning with the RabbitMQ Binder

    RabbitMQ does not support partitioning natively.

    Sometimes it is advantageous to send data to specific partitions, for example when you want to strictly order message processing - all messages for a particular customer should go to the same partition.

    The RabbitMessageChannelBinder provides partitioning by binding a queue for each partition to the destination exchange.

    The following illustrates how to configure the producer and consumer side:

    Producer. 

    @SpringBootApplication
     @EnableBinding(Source.class)
     public class RabbitPartitionProducerApplication {
    @@ -4386,14 +4583,14 @@ Otherwise, any messages sent to a partition will be lost until the corresponding
                     instance-index: 0

    [Important]Important

    The RabbitMessageChannelBinder does not support dynamic scaling; there must be at least one consumer per partition. The consumer’s instanceIndex is used to indicate which partition will be consumed. -On platforms such as Cloud Foundry there can only be one instance with an instanceIndex.

    Part VI. Spring Cloud Bus

    Spring Cloud Bus links nodes of a distributed system with a lightweight message broker. This can then be used to broadcast state changes (e.g. configuration changes) or other management instructions. A key idea is that the Bus is like a distributed Actuator for a Spring Boot application that is scaled out, but it can also be used as a communication channel between apps. Starters are provided for an AMQP broker as the transport or for Kafka, but the same basic feature set (and some more depending on the transport) is on the roadmap for other transports.

    [Note]Note

    Spring Cloud is released under the non-restrictive Apache 2.0 license. If you would like to contribute to this section of the documentation or if you find an error, please find the source code and issue trackers in the project at github.

    38. 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 or spring-cloud-starter-bus-kafka to your dependency management and Spring Cloud takes care of the rest. Make sure the broker (RabbitMQ or Kafka) is available and configured: 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. for Rabbit

    application.yml.  +On platforms such as Cloud Foundry there can only be one instance with an instanceIndex.

    Part VII. Spring Cloud Bus

    Spring Cloud Bus links nodes of a distributed system with a lightweight message broker. This can then be used to broadcast state changes (e.g. configuration changes) or other management instructions. A key idea is that the Bus is like a distributed Actuator for a Spring Boot application that is scaled out, but it can also be used as a communication channel between apps. Starters are provided for an AMQP broker as the transport or for Kafka, but the same basic feature set (and some more depending on the transport) is on the roadmap for other transports.

    [Note]Note

    Spring Cloud is released under the non-restrictive Apache 2.0 license. If you would like to contribute to this section of the documentation or if you find an error, please find the source code and issue trackers in the project at github.

    39. 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 or spring-cloud-starter-bus-kafka to your dependency management and Spring Cloud takes care of the rest. Make sure the broker (RabbitMQ or Kafka) is available and configured: 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. for Rabbit

    application.yml. 

    spring:
       rabbitmq:
         host: mybroker.com
         port: 5672
         username: user
         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 may be added in the future (ie. only service X nodes in data center Y, etc…​). There are also some http endpoints under the /bus/* actuator namespace. There are currently two implemented. The first, /bus/env, sends key/value pairs to update each node’s Spring Environment. The second, /bus/refresh, will reload each application’s configuration, just as if they had all been pinged on their /refresh endpoint.

    [Note]Note

    The Bus starters cover Rabbit and Kafka, because those are the two most common implementations, but Spring Cloud Stream is quite flexible and binder will work combined with spring-cloud-bus.

    39. Addressing an Instance

    Each instance of the application has a service ID, whose value can be set using spring.cloud.bus.id, and whose value is expected to be a colon-separated list of identifiers, in order of least specific to most specific. The default value is constructed from the environment as a combination of the spring.application.name and server.port (or spring.application.index if set). The default value of the ID is constructed in the form app:index:id where:

    • app is the vcap.application.name if it exists, or spring.application.name
    • index is the vcap.application.instance_index if it exists, or else spring.application.index, or else local.server.port (or server.port or 0).
    • id is the vcap.application.instance_id if it exists, or else a random value.

    The HTTP endpoints accept a "destination" parameter, e.g. "/bus/refresh?destination=customers:9000", where the destination is a service 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.

    40. 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 rest of the service ID.

    41. Service 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 service ID againts the current service ID. If multiple instances of a service have the same 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 ID. Cloud Foundry supplies an index to differentiate. To ensure that the ID is unique outside Cloud Foundry, set spring.application.index to something unique for each instance of a service.

    42. Customizing the Message Broker

    Spring Cloud Bus uses +

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

    [Note]Note

    The Bus starters cover Rabbit and Kafka, because those are the two most common implementations, but Spring Cloud Stream is quite flexible and binder will work combined with spring-cloud-bus.

    40. Addressing an Instance

    Each instance of the application has a service ID, whose value can be set using spring.cloud.bus.id, and whose value is expected to be a colon-separated list of identifiers, in order of least specific to most specific. The default value is constructed from the environment as a combination of the spring.application.name and server.port (or spring.application.index if set). The default value of the ID is constructed in the form app:index:id where:

    • app is the vcap.application.name if it exists, or spring.application.name
    • index is the vcap.application.instance_index if it exists, or else spring.application.index, or else local.server.port (or server.port or 0).
    • id is the vcap.application.instance_id if it exists, or else a random value.

    The HTTP endpoints accept a "destination" parameter, e.g. "/bus/refresh?destination=customers:9000", where the destination is a service 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.

    41. 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 rest of the service ID.

    42. Service 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 service ID againts the current service ID. If multiple instances of a service have the same 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 ID. Cloud Foundry supplies an index to differentiate. To ensure that the ID is unique outside Cloud Foundry, set spring.application.index to something unique for each instance of a service.

    43. Customizing the Message Broker

    Spring Cloud Bus uses 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 @@ -4407,7 +4604,7 @@ 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.

    43. Tracing Bus Events

    Bus events (subclasses of RemoteApplicationEvent) can be traced by +consult the Spring Cloud Stream documentation.

    44. 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 @@ -4447,13 +4644,13 @@ for the AckRemoteApplicationEvent and TraceRepository and mine the data from there.

    [Note]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.

    44. Broadcasting Your Own Events

    The Bus can carry any event of type RemoteApplicationEvent, but the +queries on the data. Or forward it to a specialized tracing service.

    45. 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 it needs to be in a subpackage of org.springframework.cloud.bus.event.

    To customise the event name you can use @JsonTypeName on your custom class or rely on the default strategy which is to use the simple name of the class. Note that both the producer and the consumer will need access to the class -definition.

    44.1 Registering events in custom packages

    If you cannot or don’t want to use a subpackage of org.springframework.cloud.bus.event +definition.

    45.1 Registering events in custom packages

    If you cannot or don’t want to use a subpackage of org.springframework.cloud.bus.event for your custom events, you must specify which packages to scan for events of type RemoteApplicationEvent using @RemoteApplicationEventScan. Packages specified with @RemoteApplicationEventScan include subpackages.

    For example, if you have a custom event called FooEvent:

    package com.acme;
    @@ -4480,7 +4677,7 @@ package of BusConfiguration.

    You can also exp }

    All examples of @RemoteApplicationEventScan above are equivalent, in that the com.acme package will be registered by explicitly specifying the packages on @RemoteApplicationEventScan. Note, you can specify multiple base -packages to scan.

    Part VII. Spring Cloud Sleuth

    Adrian Cole, Spencer Gibb, Marcin Grzejszczak, Dave Syer

    1.3.5.BUILD-SNAPSHOT

    45. Introduction

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

    45.1 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 +packages to scan.

    Part VIII. Spring Cloud Sleuth

    Adrian Cole, Spencer Gibb, Marcin Grzejszczak, Dave Syer

    1.3.5.BUILD-SNAPSHOT

    46. Introduction

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

    46.1 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 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 @@ -4499,7 +4696,7 @@ response from the server side. If one subtracts the cs timestamp from this times 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
     Span Id = D
     Client Sent

    That means that the current span has Trace-Id set to X, Span-Id set to D. Also, the - Client Sent event took place.

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

    Parent child relationship

    45.2 Purpose

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

    45.2.1 Distributed tracing with Zipkin

    Altogether there are 7 spans . If you go to traces in Zipkin you will see this number in the second trace:

    Traces

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

    Traces Info propagation
    [Note]Note

    When picking a particular trace you will see merged spans. That means that if there were 2 spans sent to + Client Sent event took place.

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

    Parent child relationship

    46.2 Purpose

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

    46.2.1 Distributed tracing with Zipkin

    Altogether there are 7 spans . If you go to traces in Zipkin you will see this number in the second trace:

    Traces

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

    Traces Info propagation
    [Note]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.

    Why is there a difference between the 7 and 4 spans in this case?

    • 2 spans come from http:/start span. It has the Server Received (SR) and Server Sent (SS) annotations.
    • 2 spans come from the RPC call from service1 to service2 to the http:/foo endpoint. The Client Sent (CS) and Client Received (CR) events took place on service1 side. Server Received (SR) and Server Sent (SS) events took place @@ -4509,16 +4706,16 @@ on the service3 side. Physically there are 2 spans and Client Received (CR) events took place on service2 side. Server Received (SR) and Server Sent (SS) events took place on the service4 side. Physically there are 2 spans but they form 1 logical span related to an RPC call.

    So if we count the physical spans we have 1 from http:/start, 2 from service1 calling service2, 2 form service2 calling service3 and 2 from service2 calling service4. Altogether 7 spans.

    Logically we see the information of Total Spans: 4 because we have 1 span related to the incoming request -to service1 and 3 spans related to RPC calls.

    45.2.2 Visualizing errors

    Zipkin allows you to visualize errors in your trace. When an exception was thrown and wasn’t caught then we’re +to service1 and 3 spans related to RPC calls.

    46.2.2 Visualizing errors

    Zipkin allows you to visualize errors in your trace. When an exception was thrown and wasn’t caught then we’re setting proper tags on the span which Zipkin can properly colorize. You could see in the list of traces one - trace that was in red color. That’s because there was an exception thrown.

    If you click that trace then you’ll see a similar picture

    Error Traces

    Then if you click on one of the spans you’ll see the following

    Error Traces Info propagation

    As you can see you can easily see the reason for an error and the whole stacktrace related to it.

    45.2.3 Distributed tracing with Brave

    Starting with version 2.0.0, Spring Cloud Sleuth uses + trace that was in red color. That’s because there was an exception thrown.

    If you click that trace then you’ll see a similar picture

    Error Traces

    Then if you click on one of the spans you’ll see the following

    Error Traces Info propagation

    As you can see you can easily see the reason for an error and the whole stacktrace related to it.

    46.2.3 Distributed tracing with Brave

    Starting with version 2.0.0, Spring Cloud Sleuth uses Brave as the tracing library. That means that Sleuth no longer takes care of storing the context but it delegates that work to Brave.

    Due to the fact that Sleuth had different naming / tagging conventions than Brave, we’ve decided to follow the Brave’s conventions from now on. However, if you want to use the legacy Sleuth approaches, it’s enough to set the spring.sleuth.http.legacy.enabled property -to true.

    45.2.4 Live examples

    Figure 45.1. Click Pivotal Web Services icon to see it live!

    Zipkin deployed on Pivotal Web Services

    Click here to see it live!

    The dependency graph in Zipkin would look like this:

    Dependencies

    Figure 45.2. Click Pivotal Web Services icon to see it live!

    Zipkin deployed on Pivotal Web Services

    Click here to see it live!

    45.2.5 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
    +to true.

    46.2.4 Live examples

    Figure 46.1. Click Pivotal Web Services icon to see it live!

    Zipkin deployed on Pivotal Web Services

    Click here to see it live!

    The dependency graph in Zipkin would look like this:

    Dependencies

    Figure 46.2. Click Pivotal Web Services icon to see it live!

    Zipkin deployed on Pivotal Web Services

    Click here to see it live!

    46.2.5 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
     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]
    @@ -4613,7 +4810,7 @@ we’re passing the dependencies in the groupId:artifa
     		<!--<appender-ref ref="flatfile"/>-->
     	</root>
     </configuration>
    [Note]Note

    If you’re using a custom logback-spring.xml then you have to pass the spring.application.name in -bootstrap instead of application property file. Otherwise your custom logback file won’t read the property properly.

    45.2.6 Propagating Span Context

    The span context is the state that must get propagated to any child Spans across process boundaries. +bootstrap instead of application property file. Otherwise your custom logback file won’t read the property properly.

    46.2.6 Propagating Span Context

    The span context is the state that must get propagated to any child Spans across process boundaries. Part of the Span Context is the Baggage. The trace and span IDs are a required part of the span context. Baggage is an optional part.

    Baggage is a set of key:value pairs stored in the span context. Baggage travels together with the trace and is attached to every span. Spring Cloud Sleuth will understand that a header is baggage related if the HTTP @@ -4628,8 +4825,8 @@ baggage and will not even receive that information.

    Tags are attached to a can search by tag to find the trace, where there exists a span having the searched tag value.

    If you want to be able to lookup a span based on baggage, you should add corresponding entry as a tag in the root span.

    [Important]Important

    Remember that the span needs to be in scope!

    initialSpan.tag("foo",
     		ExtraFieldPropagation.get(initialSpan.context(), "foo"));
     initialSpan.tag("UPPER_CASE",
    -		ExtraFieldPropagation.get(initialSpan.context(), "UPPER_CASE"));

    45.3 Adding to the project

    [Important]Important

    To ensure that your application name is properly displayed in Zipkin - set the spring.application.name property in bootstrap.yml.

    45.3.1 Only Sleuth (log correlation)

    If you want to profit only from Spring Cloud Sleuth without the Zipkin integration just add + ExtraFieldPropagation.get(initialSpan.context(), "UPPER_CASE"));

    46.3 Adding to the project

    [Important]Important

    To ensure that your application name is properly displayed in Zipkin + set the spring.application.name property in bootstrap.yml.

    46.3.1 Only Sleuth (log correlation)

    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.

    Maven. 

    <dependencyManagement> 1
           <dependencies>
    @@ -4659,7 +4856,7 @@ dependencies { "org.springframework.cloud:spring-cloud-starter-sleuth"
     }

    1

    In order not to pick versions by yourself it’s much better if you add the dependency management via -the Spring BOM

    2

    Add the dependency to spring-cloud-starter-sleuth

    45.3.2 Sleuth with Zipkin via HTTP

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

    Maven.  +the Spring BOM

    2

    Add the dependency to spring-cloud-starter-sleuth

    46.3.2 Sleuth with Zipkin via HTTP

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

    Maven. 

    <dependencyManagement> 1
           <dependencies>
               <dependency>
    @@ -4688,7 +4885,7 @@ dependencies { "org.springframework.cloud:spring-cloud-starter-zipkin"
     }

    1

    In order not to pick versions by yourself it’s much better if you add the dependency management via -the Spring BOM

    2

    Add the dependency to spring-cloud-starter-zipkin

    45.3.3 Sleuth with Zipkin via RabbitMQ or Kafka

    If you want to use RabbitMQ or Kafka instead of http, add the spring-rabbit or spring-kafka +the Spring BOM

    2

    Add the dependency to spring-cloud-starter-zipkin

    46.3.3 Sleuth with Zipkin via RabbitMQ or Kafka

    If you want to use RabbitMQ or Kafka instead of http, add the spring-rabbit or spring-kafka dependencies. The default destination name is zipkin.

    Note: spring-cloud-sleuth-stream is deprecated and incompatible with these destinations

    If you want Sleuth over RabbitMQ add the spring-cloud-starter-zipkin and spring-rabbit dependencies.

    Maven. 

    <dependencyManagement> 1
    @@ -4724,7 +4921,7 @@ dependencies {
         compile "org.springframework.amqp:spring-rabbit" 3
     }

    1

    In order not to pick versions by yourself it’s much better if you add the dependency management via -the Spring BOM

    2

    Add the dependency to spring-cloud-starter-zipkin - that way all dependent dependencies will be downloaded

    3

    To automatically configure rabbit, simply add the spring-rabbit dependency

    46. Additional resources

    Marcin Grzejszczak talking about Spring Cloud Sleuth and Zipkin

    click here to see the video

    47. 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] ...
      +the Spring BOM

      2

      Add the dependency to spring-cloud-starter-zipkin - that way all dependent dependencies will be downloaded

      3

      To automatically configure rabbit, simply add the spring-rabbit dependency

    47. Additional resources

    Marcin Grzejszczak talking about Spring Cloud Sleuth and Zipkin

    click here to see the video

    48. 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 @@ -4741,14 +4938,14 @@ Configure the location of the service using spring.zipkin. above. Other logging systems have to configure their own formatter to get the same result. The default is logging.pattern.level set to %5p [${spring.zipkin.service.name:${spring.application.name:-}},%X{X-B3-TraceId:-},%X{X-B3-SpanId:-},%X{X-Span-Export:-}] (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.

      47.1 Introduction to Brave

      [Important]Important

      Starting with version 2.0.0 Spring Cloud Sleuth uses + This means that if you’re not using SLF4J this pattern WILL NOT be automatically applied.

      48.1 Introduction to Brave

      [Important]Important

      Starting with version 2.0.0 Spring Cloud Sleuth uses Brave as the tracing library. For your convenience we’re embedding part of the Brave’s docs here.

      Brave is a library used to capture and report latency information about distributed operations to Zipkin. Most users won’t use Brave directly, rather libraries or frameworks than employ Brave on their behalf.

      This module includes tracer creates and joins spans that model the latency of potentially distributed work. It also includes libraries to propagate the trace context over network boundaries, for example, via -http headers.

      47.1.1 Tracing

      Most importantly, you need a brave.Tracer, configured to [report to Zipkin] +http headers.

      48.1.1 Tracing

      Most importantly, you need a brave.Tracer, configured to [report to Zipkin] (https://github.com/openzipkin/zipkin-reporter-java).

      Here’s an example setup that sends trace data (spans) to Zipkin over http (as opposed to Kafka).

      class MyClass {
       
      @@ -4765,12 +4962,12 @@ http (as opposed to Kafka).

      [Important]Important

      If your span contains a name greater than 50 chars, then that name will be truncated to 50 chars. Your names have to be explicit and concrete. Big names lead to -latency issues and sometimes even thrown exceptions.

      47.1.2 Tracing

      The tracer creates and joins spans that model the latency of potentially +latency issues and sometimes even thrown exceptions.

      48.1.2 Tracing

      The tracer creates and joins spans that model the latency of potentially distributed work. It can employ sampling to reduce overhead in process or to reduce the amount of data sent to Zipkin.

      Spans returned by a tracer report data to Zipkin when finished, or do nothing if unsampled. After starting a span, you can annotate events of interest or add tags containing details or lookup keys.

      Spans have a context which includes trace identifiers that place it at -the correct spot in the tree representing the distributed operation.

      47.1.3 Local Tracing

      When tracing local code, just run it inside a span.

      Span span = tracer.newTrace().name("encode").start();
      +the correct spot in the tree representing the distributed operation.

      48.1.3 Local Tracing

      When tracing local code, just run it inside a span.

      Span span = tracer.newTrace().name("encode").start();
       try {
         doSomethingExpensive();
       } finally {
      @@ -4782,7 +4979,7 @@ you will be a part of an existing trace. When this is the case, call
         doSomethingExpensive();
       } finally {
         span.finish();
      -}

      47.1.4 Customizing spans

      Once you have a span, you can add tags to it, which can be used as lookup +}

      48.1.4 Customizing spans

      Once you have a span, you can add tags to it, which can be used as lookup keys or details. For example, you might add a tag with your runtime version.

      span.tag("clnt/finagle.version", "6.36.0");

      When exposing the ability to customize spans to third parties, prefer brave.SpanCustomizer as opposed to brave.Span. The former is simpler to @@ -4791,7 +4988,7 @@ understand and test, and doesn’t tempt users with span lifecycle hooks.

      Since brave.Span implements brave.SpanCustomizer, it is just as easy for you to pass to users.

      Ex.

      for (MyTraceCallback callback : userCallbacks) {
         callback.request(request, span);
      -}

      47.1.5 Implicitly looking up the current span

      Sometimes you won’t know if a trace is in progress or not, and you don’t +}

      48.1.5 Implicitly looking up the current span

      Sometimes you won’t know if a trace is in progress or not, and you don’t want users to do null checks. brave.CurrentSpanCustomizer adds to any span that’s in progress or drops data accordingly.

      Ex.

      // user code can then inject this without a chance of it being null.
       @Autowire SpanCustomizer span;
      @@ -4799,7 +4996,7 @@ span that’s in progress or drops data accordingly.

      Ex.

      void userCode() {
         span.annotate("tx.started");
         ...
      -}

      47.1.6 RPC tracing

      Check for instrumentation written here +}

      48.1.6 RPC tracing

      Check for instrumentation written here and Zipkin’s list before rolling your own RPC instrumentation!

      RPC tracing is often done automatically by interceptors. Under the scenes, they add tags and events that relate to their role in an RPC operation.

      Here’s an example of a client span:

      // before you send a request, add metadata that describes the operation
      @@ -4847,12 +5044,12 @@ oneWayReceive.start().flush();
       
       // you should not modify this span anymore as it is complete. However,
       // you can create children to represent follow-up work.
      -next = tracer.newSpan(oneWayReceive.context()).name("step2").start();

      Note The above propagation logic is a simplified version of our [http handlers](https://github.com/openzipkin/sleuth/tree/master/instrumentation/http#http-server).

      There’s a working example of a one-way span [here](src/test/java/sleuth/features/async/OneWaySpanTest.java).

    48. Sampling

    Sampling may be employed to reduce the data collected and reported out +next = tracer.newSpan(oneWayReceive.context()).name("step2").start();

    Note The above propagation logic is a simplified version of our [http handlers](https://github.com/openzipkin/sleuth/tree/master/instrumentation/http#http-server).

    There’s a working example of a one-way span [here](src/test/java/sleuth/features/async/OneWaySpanTest.java).

    49. Sampling

    Sampling may be employed to reduce the data collected and reported out of process. When a span isn’t sampled, it adds no overhead (noop).

    Sampling is an up-front decision, meaning that the decision to report data is made at the first operation in a trace, and that decision is propagated downstream.

    By default, there’s a global sampler that applies a single rate to all traced operations. Tracer.Builder.sampler is how you indicate this, -and it defaults to trace every request.

    48.1 Declarative sampling

    Some need to sample based on the type or annotations of a java method.

    Most users will use a framework interceptor which automates this sort of +and it defaults to trace every request.

    49.1 Declarative sampling

    Some need to sample based on the type or annotations of a java method.

    Most users will use a framework interceptor which automates this sort of policy. Here’s how they might work internally.

    // derives a sample rate from an annotation on a java method
     DeclarativeSampler<Traced> sampler = DeclarativeSampler.create(Traced::sampleRate);
     
    @@ -4864,7 +5061,7 @@ DeclarativeSampler<Traced> sampler = DeclarativeSampler.create(Traced::sam
       } finally {
         span.finish();
       }
    -}

    48.2 Custom sampling

    You may want to apply different policies depending on what the operation +}

    49.2 Custom sampling

    You may want to apply different policies depending on what the operation is. For example, you might not want to trace requests to static resources such as images, or you might want to trace all requests to a new api.

    Most users will use a framework interceptor which automates this sort of policy. Here’s how they might work internally.

    Span newTrace(Request input) {
    @@ -4875,7 +5072,7 @@ policy. Here’s how they might work internally.

    return tracer.newTrace(flags);
    -}

    Note: the above is the basis for the built-in http sampler

    48.3 Sampling in Spring Cloud Sleuth

    Spring Cloud Sleuth by default sets all spans to non-exportable. +}

    Note: the above is the basis for the built-in http sampler

    49.3 Sampling in Spring Cloud Sleuth

    Spring Cloud Sleuth by default sets all spans to non-exportable. That means that 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 @@ -4889,7 +5086,7 @@ value needs to be a double from 0.0 to return Sampler.ALWAYS_SAMPLE; }

    [Tip]Tip

    You can set the HTTP header X-B3-Flags to 1 or when doing messaging you can set spanFlags header to 1. Then the current span will be forced to be exportable -regardless of the sampling decision.

    49. Propagation

    Propagation is needed to ensure activity originating from the same root +regardless of the sampling decision.

    50. Propagation

    Propagation is needed to ensure activity originating from the same root are collected together in the same trace. The most common propagation approach is to copy a trace context from a client sending an RPC request to a server receiving it.

    For example, when an downstream Http call is made, its trace context is @@ -4918,7 +5115,7 @@ injector.inject(span.context(), request);

    Here’s what server-side extracted = tracing.propagation().extractor(Request::getHeader); // when a server receives a request, it joins or starts a new trace -span = tracer.nextSpan(extracted, request);

    49.1 Propagating extra fields

    Sometimes you need to propagate extra fields, such as a request ID or an alternate trace context. +span = tracer.nextSpan(extracted, request);

    50.1 Propagating extra fields

    Sometimes you need to propagate extra fields, such as a request ID or an alternate trace context. For example, if you are in a Cloud Foundry environment, you might want to pass the request ID:

    // when you initialize the builder, define the extra field you want to propagate
     tracingBuilder.propagationFactory(
       ExtraFieldPropagation.newFactory(B3Propagation.FACTORY, "x-vcap-request-id")
    @@ -4929,7 +5126,7 @@ requestId = ExtraFieldPropagation.get(tracingBuilder.propagationFactory(
       ExtraFieldPropagation.newFactory(B3Propagation.FACTORY, "x-amzn-trace-id")
    -);

    49.1.1 Prefixed fields

    You can also prefix fields, if they follow a common pattern. For example, the following will +);

    50.1.1 Prefixed fields

    You can also prefix fields, if they follow a common pattern. For example, the following will propagate the field "x-vcap-request-id" as-is, but send the fields "country-code" and "user-id" on the wire as "x-baggage-country-code" and "x-baggage-user-id" respectively.

    Setup your tracing instance with allowed fields:

    tracingBuilder.propagationFactory(
       ExtraFieldPropagation.newFactoryBuilder(B3Propagation.FACTORY)
    @@ -4943,11 +5140,11 @@ Brave it’s required to pass the list of baggage keys.
     There are two properties to achieve this. Via the spring.sleuth.baggage-keys you set keys
     that will get prefixed with baggage- for http calls and baggage_ for messaging. You can also pass
     a list of prefixed keys that will be whitelisted without any prefix via
    -spring.sleuth.propagation-keys property.

    49.1.2 Extracting a propagated context

    The TraceContext.Extractor<C> reads trace identifiers and sampling status +spring.sleuth.propagation-keys property.

    50.1.2 Extracting a propagated context

    The TraceContext.Extractor<C> reads trace identifiers and sampling status from an incoming request or message. The carrier is usually a request object or headers.

    This utility is used in standard instrumentation like [HttpServerHandler](../instrumentation/http/src/main/java/sleuth/http/HttpServerHandler.java), but can also be used for custom RPC or messaging code.

    TraceContextOrSamplingFlags is usually only used with Tracer.nextSpan(extracted), unless you are -sharing span IDs between a client and a server.

    49.1.3 Sharing span IDs between client and server

    A normal instrumentation pattern is creating a span representing the server +sharing span IDs between a client and a server.

    50.1.3 Sharing span IDs between client and server

    A normal instrumentation pattern is creating a span representing the server side of an RPC. Extractor.extract might return a complete trace context when applied to an incoming client request. Tracer.joinSpan attempts to continue the this trace, using the same span ID if supported, or creating a child span @@ -4976,7 +5173,7 @@ always provisioned and the incoming context determines the parent ID.

    Here └───────────────────┘

    Note: Some span reporters do not support sharing span IDs. For example, if you set Tracing.Builder.spanReporter(amazonXrayOrGoogleStackdrive), disable join via Tracing.Builder.supportsJoin(false). This will force a new child span on -Tracer.joinSpan().

    49.1.4 Implementing Propagation

    TraceContext.Extractor<C> is implemented by a Propagation.Factory plugin. Internally, this code +Tracer.joinSpan().

    50.1.4 Implementing Propagation

    TraceContext.Extractor<C> is implemented by a Propagation.Factory plugin. Internally, this code will create the union type TraceContextOrSamplingFlags with one of the following: * TraceContext if trace and span IDs were present. * TraceIdContext if a trace ID was present, but not span IDs. @@ -4984,16 +5181,16 @@ will create the union type TraceContextOrSamplingFlagsTraceContext was extracted, add the extra data as TraceContext.extra() -* Otherwise, add it as TraceContextOrSamplingFlags.extra(), which Tracer.nextSpan handles.

    50. Current Tracing Component

    Brave supports a "current tracing component" concept which should only +* Otherwise, add it as TraceContextOrSamplingFlags.extra(), which Tracer.nextSpan handles.

    51. Current Tracing Component

    Brave supports a "current tracing component" concept which should only be used when you have no other means to get a reference. This was made for JDBC connections, as they often initialize prior to the tracing component.

    The most recent tracing component instantiated is available via Tracing.current(). You there’s also a shortcut to get only the tracer via Tracing.currentTracer(). If you use either of these methods, do -noot cache the result. Instead, look them up each time you need them.

    51. Current Span

    Brave supports a "current span" concept which represents the in-flight +noot cache the result. Instead, look them up each time you need them.

    52. Current Span

    Brave supports a "current span" concept which represents the in-flight operation. Tracer.currentSpan() can be used to add custom tags to a span and Tracer.nextSpan() can be used to create a child of whatever -is in-flight.

    51.1 Setting a span in scope manually

    When writing new instrumentation, it is important to place a span you +is in-flight.

    52.1 Setting a span in scope manually

    When writing new instrumentation, it is important to place a span you created in scope as the current span. Not only does this allow users to access it with Tracer.currentSpan(), but it also allows customizations like SLF4J MDC to see the current trace IDs.

    Tracer.withSpanInScope(Span) facilitates this and is most conveniently @@ -5007,7 +5204,7 @@ span in scope like this.

    withSpanInScope.

    try (SpanInScope cleared = tracer.withSpanInScope(null)) {
       startBackgroundThread();
    -}

    52. Instrumentation

    Spring Cloud Sleuth instruments all your Spring application +}

    53. 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 @@ -5019,10 +5216,10 @@ request headers by configuring spring.sleuth.keys.http.hea list of header names).

    [Note]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).

    53. Span lifecycle

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

    • 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 sampled then it will be eligible for collection to e.g. Zipkin.
    • 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
    [Tip]Tip

    Spring Cloud Sleuth creates the instance of Tracer for you. In order to use it, -all you need is to just autowire it.

    53.1 Creating and finishing spans

    You can manually create spans by using the Tracer.

    // Start a span. If there was a span present in this thread it will become
    +something).

    54. Span lifecycle

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

    • 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 sampled then it will be eligible for collection to e.g. Zipkin.
    • 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
    [Tip]Tip

    Spring Cloud Sleuth creates the instance of Tracer for you. In order to use it, +all you need is to just autowire it.

    54.1 Creating and finishing spans

    You can manually create spans by using the Tracer.

    // Start a span. If there was a span present in this thread it will become
     // the `newSpan`'s parent.
     Span newSpan = this.tracer.nextSpan().name("calculateTax");
     try (Tracer.SpanInScope ws = this.tracer.withSpanInScope(newSpan.start())) {
    @@ -5039,7 +5236,7 @@ Span 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]Important

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

    [Important]Important

    If your span contains a name greater than 50 chars, then that name will be truncated to 50 chars. Your names have to be explicit and concrete. Big names lead to -latency issues and sometimes even thrown exceptions.

    53.2 Continuing spans

    Sometimes you don’t want to create a new span but you want to continue one. Example of such a +latency issues and sometimes even thrown exceptions.

    54.2 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.

    To continue a span you can use brave.Tracer.

    // let's assume that we're in a thread Y and we've received
     // the `initialSpan` from thread X
    @@ -5055,7 +5252,7 @@ Span continuedSpan = // Once done remember to flush the span. That means that
     	// it will get reported but the span itself is not yet finished
     	continuedSpan.flush();
    -}

    53.3 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. +}

    54.3 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. In Brave, whenever you call nextSpan(), it’s creating one in reference to the span being currently in scope. It’s enough to just put @@ -5079,9 +5276,9 @@ Span newSpan = null; newSpan.finish(); } }

    [Important]Important

    After having created such a span remember to finish it, otherwise it will not get -reported to e.g. Zipkin

    54. Naming spans

    Picking a span name is not a trivial task. Span name should depict an operation name. The name should +reported to e.g. Zipkin

    55. 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:

    • controller-method-name when received by a Controller with a method name conrollerMethodName
    • 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.

    54.1 @SpanName annotation

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

    @SpanName("calculateTax")
    +artificial like:

    • controller-method-name when received by a Controller with a method name conrollerMethodName
    • 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.

    55.1 @SpanName annotation

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

    @SpanName("calculateTax")
     class TaxCountingRunnable implements Runnable {
     
     	@Override public void run() {
    @@ -5091,7 +5288,7 @@ artificial like:

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

    The span will be named calculateTax.

    54.2 toString() method

    It’s pretty rare to create separate classes for Runnable or Callable. Typically one creates an anonymous +future.get();

    The span will be named calculateTax.

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

    Runnable runnable = new TraceRunnable(tracer, spanNamer, errorParser, new Runnable() {
     	@Override public void run() {
    @@ -5104,12 +5301,12 @@ we’re checking if the class has a custom implementation of the // ... some additional logic ...
    -future.get();

    will lead in creating a span named calculateTax.

    55. Managing spans with annotations

    55.1 Rationale

    The main arguments for this features are

    • api-agnostic means to collaborate with a span

      • use of annotations allows users to add to a span with no library dependency on a span api. +future.get();

        will lead in creating a span named calculateTax.

    56. Managing spans with annotations

    56.1 Rationale

    The main arguments for this features are

    • api-agnostic means to collaborate with a span

      • use of annotations allows users to add to a span with no library dependency on a span api. This allows Sleuth to change its core api less impact to user code.
    • reduced surface area for basic span operations.

      • without this feature one has to use the span api, which has lifecycle commands that could be used incorrectly. By only exposing scope, tag and log functionality, users can collaborate without accidentally breaking span lifecycle.
    • collaboration with runtime generated code

      • with libraries such as Spring Data / Feign the implementations of interfaces are generated at runtime thus span wrapping of objects was tedious. Now you can provide annotations - over interfaces and arguments of those interfaces

    55.2 Creating new spans

    If you really don’t want to take care of creating local spans manually you can profit from the + over interfaces and arguments of those interfaces

    56.2 Creating new spans

    If you really don’t want to take care of creating local spans manually you can profit from the @NewSpan annotation. Also we give you the @SpanTag annotation to add tags in an automated fashion.

    Let’s look at some examples of usage.

    @NewSpan
     void testMethod();

    Annotating the method without any parameter will lead to a creation of a new span whose name @@ -5127,7 +5324,7 @@ the tag key will be testTag and the tag value will public void testMethod3() { }

    You can place the @NewSpan annotation on both the class and an interface. If you override the interface’s method and provide a different value of the @NewSpan annotation then the most -concrete one wins (in this case customNameOnTestMethod3 will be set).

    55.3 Continuing spans

    If you want to just add tags and annotations to an existing span it’s enough +concrete one wins (in this case customNameOnTestMethod3 will be set).

    56.3 Continuing spans

    If you want to just add tags and annotations to an existing span it’s enough to use the @ContinueSpan annotation as presented below. Note that in contrast with the @NewSpan annotation you can also add logs via the log parameter:

    // method declaration
     @ContinueSpan(log = "testMethod11")
    @@ -5135,21 +5332,21 @@ with the @NewSpan annotation you can also add logs
     
     // method execution
     this.testBean.testMethod11("test");
    -this.testBean.testMethod13();

    That way the span will get continued and:

    • logs with name testMethod11.before and testMethod11.after will be created
    • if an exception will be thrown a log testMethod11.afterFailure will also be created
    • tag with key testTag11 and value test will be created

    55.4 More advanced tag setting

    There are 3 different ways to add tags to a span. All of them are controlled by the SpanTag annotation. +this.testBean.testMethod13();

    That way the span will get continued and:

    • logs with name testMethod11.before and testMethod11.after will be created
    • if an exception will be thrown a log testMethod11.afterFailure will also be created
    • tag with key testTag11 and value test will be created

    56.4 More advanced tag setting

    There are 3 different ways to add tags to a span. All of them are controlled by the SpanTag annotation. Precedence is:

    • try with the bean of TagValueResolver type and provided name
    • if one hasn’t provided the bean name, try to evaluate an expression. We’re searching for a TagValueExpressionResolver bean. -The default implementation uses SPEL expression resolution.
    • if one hasn’t provided any expression to evaluate just return a toString() value of the parameter

    55.4.1 Custom extractor

    The value of the tag for following method will be computed by an implementation of TagValueResolver interface. +The default implementation uses SPEL expression resolution.

  • if one hasn’t provided any expression to evaluate just return a toString() value of the parameter
  • 56.4.1 Custom extractor

    The value of the tag for following method will be computed by an implementation of TagValueResolver interface. Its class name has to be passed as the value of the resolver attribute.

    Having such an annotated method:

    @NewSpan
     public void getAnnotationForTagValueResolver(@SpanTag(key = "test", resolver = TagValueResolver.class) String test) {
     }

    and such a TagValueResolver bean implementation

    @Bean(name = "myCustomTagValueResolver")
     public TagValueResolver tagValueResolver() {
     	return parameter -> "Value from myCustomTagValueResolver";
    -}

    Will lead to setting of a tag value equal to Value from myCustomTagValueResolver.

    55.4.2 Resolving expressions for value

    Having such an annotated method:

    @NewSpan
    +}

    Will lead to setting of a tag value equal to Value from myCustomTagValueResolver.

    56.4.2 Resolving expressions for value

    Having such an annotated method:

    @NewSpan
     public void getAnnotationForTagValueExpression(@SpanTag(key = "test", expression = "length() + ' characters'") String test) {
     }

    and no custom implementation of a TagValueExpressionResolver will lead to evaluation of the SPEL expression and a tag with value 4 characters will be set on the span. If you want to use some other expression resolution mechanism you can create your own implementation -of the bean.

    55.4.3 Using toString method

    Having such an annotated method:

    @NewSpan
    +of the bean.

    56.4.3 Using toString method

    Having such an annotated method:

    @NewSpan
     public void getAnnotationForArgumentToString(@SpanTag("test") Long param) {
    -}

    if executed with a value of 15 will lead to setting of a tag with a String value of "15".

    56. Customizations

    56.1 Spring Integration

    56.2 HTTP

    56.3 TraceFilter

    You can also modify the behaviour of the TraceFilter - the component that is responsible +}

    if executed with a value of 15 will lead to setting of a tag with a String value of "15".

    57. Customizations

    57.1 Spring Integration

    57.2 HTTP

    57.3 TraceFilter

    You can also modify the behaviour of the TraceFilter - the component that is responsible for processing the input HTTP request and adding tags basing on the HTTP response. You can customize the tags, or modify the response headers by registering your own instance of the TraceFilter bean.

    In the following example we will register the TraceFilter bean and we will add the ZIPKIN-TRACE-ID response header containing the current Span’s trace id. Also we will @@ -5175,11 +5372,11 @@ add to the Span a tag with key custom and a value < currentSpan.tag("custom", "tag"); chain.doFilter(request, response); } -}

    56.4 Custom service name

    By default Sleuth assumes that when you send a span to Zipkin, you want the span’s service name +}

    57.4 Custom service name

    By default Sleuth assumes that when you send a span to Zipkin, you want the span’s service name to be equal to spring.application.name value. That’s not always the case though. There are situations in which you want to explicitly provide a different service name for all spans coming from your application. To achieve that it’s enough to just pass the following property - to your application to override that value (example for foo service name):

    spring.zipkin.service.name: foo

    56.5 Customization of reported spans

    Before reporting spans to e.g. Zipkin you can be interested in modifying that span in some way. + to your application to override that value (example for foo service name):

    spring.zipkin.service.name: foo

    57.5 Customization of reported spans

    Before reporting spans to e.g. Zipkin you can be interested in modifying that span in some way. You can achieve that by using the SpanAdjuster interface.

    In Sleuth we’re generating spans with a fixed name. Some users want to modify the name depending on values of tags. Implementation of the SpanAdjuster interface can be used to alter that name. Example:

    Example. If you register two beans of SpanAdjuster type:

    @Bean SpanAdjuster adjusterOne() {
     	return span -> span.toBuilder().name("foo").build();
    @@ -5187,25 +5384,25 @@ of tags. Implementation of the SpanAdjuster interfa
     
     @Bean SpanAdjuster adjusterTwo() {
     	return span -> span.toBuilder().name(span.name() + " bar").build();
    -}

    This will lead in changing the name of the reported span to foo bar, just before it gets reported (e.g. to Zipkin).

    56.6 Host locator

    [Important]Important

    This section is about defining host from service discovery. It’s NOT +}

    This will lead in changing the name of the reported span to foo bar, just before it gets reported (e.g. to Zipkin).

    57.6 Host locator

    [Important]Important

    This section is about defining host from service discovery. It’s NOT about finding Zipkin in service discovery.

    In order to define the host that is corresponding to a particular span we need to resolve the host name and port. The default approach is to take it from server properties. If those for some reason are not set then we’re trying to retrieve the host name from the network interfaces.

    If you have the discovery client enabled and prefer to retrieve the host address from the registered instance in a service registry then you have to set the property (it’s applicable for both HTTP and -Stream based span reporting).

    spring.zipkin.locator.discovery.enabled: true

    57. Sending spans to Zipkin

    By default if you add spring-cloud-starter-zipkin as a dependency to your project, +Stream based span reporting).

    spring.zipkin.locator.discovery.enabled: true

    58. Sending spans to Zipkin

    By default if you add spring-cloud-starter-zipkin as a dependency to your project, when the span is closed, it will be sent to Zipkin over HTTP. The communication is asynchronous. You can configure the URL by setting the spring.zipkin.baseUrl property as follows:

    spring.zipkin.baseUrl: http://192.168.99.100:9411/

    If you want to find Zipkin via service discovery it’s enough to pass the Zipkin’s service id inside the URL (example for zipkinserver service id)

    spring.zipkin.baseUrl: http://zipkinserver/

    If you have web, rabbit or kafka together on the classpath, you might need to pick the means by which you would like to send spans to zipkin. To do that just set either web, rabbit or kafka to the spring.zipkin.sender.type property. -Example for web:

    spring.zipkin.sender.type: web

    58. Zipkin Stream Span Consumer

    [Important]Important

    The suggested approach is to use the Zipkin’s +Example for web:

    spring.zipkin.sender.type: web

    59. Zipkin Stream Span Consumer

    [Important]Important

    The suggested approach is to use the Zipkin’s native support for message based span sending. Starting from Edgware Zipkin Stream server is deprecated and in Finchley it got removed.

    Please refer to the Dalston Documentaion -on how to create a Stream Zipkin server.

    59. Integrations

    59.1 OpenTracing

    Spring Cloud Sleuth is OpenTracing compatible. If you have +on how to create a Stream Zipkin server.

    60. Integrations

    60.1 OpenTracing

    Spring Cloud Sleuth is OpenTracing compatible. If you have OpenTracing on the classpath we will automatically register the OpenTracing -Tracer bean. If you wish to disable this just set spring.sleuth.opentracing.enabled to false

    59.2 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() {
    +Tracer bean. If you wish to disable this just set spring.sleuth.opentracing.enabled to false

    60.2 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() {
     	@Override
     	public void run() {
     		// do some work
    @@ -5237,10 +5434,10 @@ Callable<String> traceCallable = "calculateTax");
     // Wrapping `Callable` with `Tracing`. That way the current span will be available
     // in the thread of `Callable`
    -Callable<String> traceCallableFromTracer = tracing.currentTraceContext().wrap(callable);

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

    59.3 Hystrix

    59.3.1 Custom Concurrency Strategy

    We’re registering a custom HystrixConcurrencyStrategy +Callable<String> traceCallableFromTracer = tracing.currentTraceContext().wrap(callable);

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

    60.3 Hystrix

    60.3.1 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.

    59.3.2 Manual Command setting

    Assuming that you have the following HystrixCommand:

    HystrixCommand<String> hystrixCommand = new HystrixCommand<String>(setter) {
    +on before the Hystrix command was called. To disable the custom Hystrix Concurrency Strategy set the spring.sleuth.hystrix.strategy.enabled to false.

    60.3.2 Manual Command setting

    Assuming that you have the following HystrixCommand:

    HystrixCommand<String> hystrixCommand = new HystrixCommand<String>(setter) {
     	@Override
     	protected String run() throws Exception {
     		return someLogic();
    @@ -5251,29 +5448,29 @@ on before the Hystrix command was called. To disable the custom Hystrix Concurre
     	public String doRun() throws Exception {
     		return someLogic();
     	}
    -};

    59.4 RxJava

    We’re registering a custom RxJavaSchedulersHook +};

    60.4 RxJava

    We’re registering a custom 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.

    You can define a list of regular expressions for thread names, for which you don’t want a Span to be created. Just provide a comma separated list -of regular expressions in the spring.sleuth.rxjava.schedulers.ignoredthreads property.

    59.5 HTTP integration

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

    59.5.1 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 +of regular expressions in the spring.sleuth.rxjava.schedulers.ignoredthreads property.

    60.5 HTTP integration

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

    60.5.1 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. If you want to reuse the Sleuth’s default skip patterns and just append your own, pass those patterns via - the spring.sleuth.web.additionalSkipPattern.

    59.5.2 HandlerInterceptor

    Since we want the span names to be precise we’re using a TraceHandlerInterceptor that either wraps an + the spring.sleuth.web.additionalSkipPattern.

    60.5.2 HandlerInterceptor

    Since we want the span names to be precise we’re using a TraceHandlerInterceptor that either wraps an existing HandlerInterceptor or is added directly to the list of existing HandlerInterceptors. The TraceHandlerInterceptor adds a special request attribute to the given HttpServletRequest. If the the TraceFilter doesn’t see this attribute set it will create a "fallback" span which is an additional span created on the server side so that the trace is presented properly in the UI. Seeing that most likely - signifies that there is a missing instrumentation. In that case please file an issue in Spring Cloud Sleuth.

    59.5.3 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.

    59.5.4 WebFlux support

    Via the TraceWebFilter all sampled incoming requests result in creation of a Span. That Span’s name is http: + the path to which + signifies that there is a missing instrumentation. In that case please file an issue in Spring Cloud Sleuth.

    60.5.3 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.

    60.5.4 WebFlux support

    Via the TraceWebFilter 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. If you want to reuse the Sleuth’s default skip patterns and just append your own, pass those patterns via - the spring.sleuth.web.additionalSkipPattern.

    59.6 HTTP client integration

    59.6.1 Synchronous Rest Template

    We’re injecting a RestTemplate interceptor that ensures that all the tracing information is passed to the requests. Each time a + the spring.sleuth.web.additionalSkipPattern.

    60.6 HTTP client integration

    60.6.1 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.

    [Important]Important

    You have to register RestTemplate as a bean so that the interceptors will get injected. -If you create a RestTemplate instance with a new keyword then the instrumentation WILL NOT work.

    59.6.2 Asynchronous Rest Template

    [Important]Important

    Starting with Sleuth 2.0.0 we no longer register +If you create a RestTemplate instance with a new keyword then the instrumentation WILL NOT work.

    60.6.2 Asynchronous Rest Template

    [Important]Important

    Starting with Sleuth 2.0.0 we no longer register a bean of AsyncRestTemplate type. It’s up to you to create such a bean. Then we will instrument it.

    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 @@ -5298,25 +5495,25 @@ can see an example of how to set up such a custom AsyncRes //CUSTOMIZE HERE return factory; } -}

    59.6.3 WebClient

    We inject a ExchangeFilterFunction implementation that creates a span and via on success and on +}

    60.6.3 WebClient

    We inject a ExchangeFilterFunction implementation that creates a span and via on success and on error callbacks takes care of closing client side spans.

    [Important]Important

    You have to register WebClient as a bean so that the tracing instrumention gets applied. -If you create a WebClient instance with a new keyword then the instrumentation WILL NOT work.

    59.6.4 Traverson

    If you’re using the Traverson library +If you create a WebClient instance with a new keyword then the instrumentation WILL NOT work.

    60.6.4 Traverson

    If you’re using the Traverson library it’s enough for you to inject a RestTemplate as a bean into your Traverson object. Since RestTemplate is already intercepted, you will get full support of tracing in your client. Below you can find a pseudo code of how to do that:

    @Autowired RestTemplate restTemplate;
     
     Traverson traverson = new Traverson(URI.create("http://some/address"),
         MediaType.APPLICATION_JSON, MediaType.APPLICATION_JSON_UTF8).setRestOperations(restTemplate);
    -// use Traverson

    59.7 Feign

    By default Spring Cloud Sleuth provides integration with feign via the TraceFeignClientAutoConfiguration. You can disable it entirely +// use Traverson

    60.7 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.

    59.8 Asynchronous communication

    59.8.1 @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:

    • if the method is annotated with @SpanName then the value of the annotation will be the Span’s name
    • if the method is not annotated with @SpanName 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

    59.8.2 @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 +however will be still there.

    60.8 Asynchronous communication

    60.8.1 @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:

    • if the method is annotated with @SpanName then the value of the annotation will be the Span’s name
    • if the method is not annotated with @SpanName 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

    60.8.2 @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.

    [Tip]Tip

    If you are using spring-cloud-sleuth-stream and spring-cloud-netflix-hystrix-stream together, Span will be created for each Hystrix metrics and sent to Zipkin. This may be annoying. You can prevent this by setting -spring.sleuth.scheduled.skipPattern=org.springframework.cloud.netflix.hystrix.stream.HystrixStreamTask

    59.8.3 Executor, ExecutorService and ScheduledExecutorService

    We’re providing LazyTraceExecutor, TraceableExecutorService and TraceableScheduledExecutorService. Those implementations +spring.sleuth.scheduled.skipPattern=org.springframework.cloud.netflix.hystrix.stream.HystrixStreamTask

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

    CompletableFuture<Long> completableFuture = CompletableFuture.supplyAsync(() -> {
     	// perform some logic
     	return 1_000_000L;
    @@ -5343,18 +5540,18 @@ can see an example of how to set up such a custom Executor
     		executor.initialize();
     		return new LazyTraceExecutor(this.beanFactory, executor);
     	}
    -}

    59.9 Messaging

    Spring Cloud Sleuth integrates with Spring Integration. It creates spans for publish and +}

    60.9 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.

    You can provide the spring.sleuth.integration.patterns pattern to explicitly provide the names of channels that you want to include for tracing. By default all channels are included.

    [Important]Important

    When using the Executor to build a Spring Integration IntegrationFlow remember to use the untraced version of the Executor. -Decorating Spring Integration Executor Channel with TraceableExecutorService will cause the spans to be improperly closed.

    59.10 Zuul

    We’re instrumenting the Zuul Ribbon integration by enriching the Ribbon requests with tracing information. -To disable Zuul support set the spring.sleuth.zuul.enabled property to false.

    60. Running examples

    You can find the running examples deployed in the Pivotal Web Services. Check them out in the following links:

    Part VIII. Spring Cloud Consul

    1.3.5.BUILD-SNAPSHOT

    This project provides Consul integrations for Spring Boot apps through autoconfiguration +Decorating Spring Integration Executor Channel with TraceableExecutorService will cause the spans to be improperly closed.

    60.10 Zuul

    We’re instrumenting the Zuul Ribbon integration by enriching the Ribbon requests with tracing information. +To disable Zuul support set the spring.sleuth.zuul.enabled property to false.

    61. Running examples

    You can find the running examples deployed in the Pivotal Web Services. Check them out in the following links:

    Part IX. Spring Cloud Consul

    1.3.5.BUILD-SNAPSHOT

    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 application and build large distributed systems with Consul based components. The 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.

    61. Install Consul

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

    62. 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

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

    63. 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.

    63.1 How to activate

    To activate Consul Service Discovery use the starter with group org.springframework.cloud and artifact id spring-cloud-starter-consul-discovery. See the Spring Cloud Project page for details on setting up your build system with the current Spring Cloud Release Train.

    63.2 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
    +(Hystrix) are provided by integration with Spring Cloud Netflix.

    62. Install Consul

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

    63. 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

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

    64. 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.

    64.1 How to activate

    To activate Consul Service Discovery use the starter with group org.springframework.cloud and artifact id spring-cloud-starter-consul-discovery. See the Spring Cloud Project page for details on setting up your build system with the current Spring Cloud Release Train.

    64.2 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
     @RestController
     public class Application {
     
    @@ -5373,26 +5570,26 @@ Intelligent Routing (Zuul) and Client Side Load Balancing (Ribbon), Circuit Brea
         consul:
           host: localhost
           port: 8500

    -

    [Caution]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.

    To disable the Consul Discovery Client you can set spring.cloud.consul.discovery.enabled to false.

    To disable the service registration you can set spring.cloud.consul.discovery.register to false.

    63.3 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.context-path=/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.  +

    [Caution]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.

    To disable the Consul Discovery Client you can set spring.cloud.consul.discovery.enabled to false.

    To disable the service registration you can set spring.cloud.consul.discovery.register to false.

    64.3 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.context-path=/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.context-path}/health
             healthCheckInterval: 15s

    -

    63.3.1 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.  +

    64.3.1 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:
             tags: foo=bar, baz

    -

    The above configuration will result in a map with foo→bar and baz→baz.

    63.3.2 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.  +

    The above configuration will result in a map with foo→bar and baz→baz.

    64.3.2 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}:${vcap.application.instance_id:${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 vcap.application.instance_id will be populated automatically in a Spring Boot application, so the random value will not be needed.

    63.4 Looking up services

    63.4.1 Using Ribbon

    Spring Cloud has support for Feign (a REST client builder) and also Spring RestTemplate +

    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 vcap.application.instance_id will be populated automatically in a Spring Boot application, so the random value will not be needed.

    64.4 Looking up services

    64.4.1 Using Ribbon

    Spring Cloud has support for Feign (a REST client builder) and also Spring RestTemplate for looking up services using the logical service names/ids instead of physical URLs. Both Feign and the discovery-aware RestTemplate utilize Ribbon for client-side load balancing.

    If you want to access service STORES using the RestTemplate simply declare:

    @LoadBalanced
     @Bean
     public RestTemplate loadbalancedRestTemplate() {
    @@ -5404,7 +5601,7 @@ public String getFirstProduct() {
        return this.restTemplate.getForObject("https://STORES/products/1", String.class);
     }

    If you have Consul clusters in multiple datacenters and you want to access a service in another datacenter a service name/id alone is not enough. In that case you use property spring.cloud.consul.discovery.datacenters.STORES=dc-west where STORES is the service name/id and dc-west is the datacenter -where the STORES service lives.

    63.4.2 Using the DiscoveryClient

    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
    +where the STORES service lives.

    64.4.2 Using the DiscoveryClient

    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() {
    @@ -5413,10 +5610,10 @@ public String serviceUrl() {
             return list.get(0).getUri();
         }
         return null;
    -}

    64. 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/
    +}

    65. 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/
     config/testApp/
     config/application,dev/
    -config/application/

    The most specific property source is at the top, with the least specific at the bottom. Properties in 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. Section 64.3, “Config Watch” will also automatically detect changes and reload the application context.

    64.1 How to activate

    To get started with Consul Configuration use the starter with group org.springframework.cloud and artifact id spring-cloud-starter-consul-config. See the Spring Cloud Project page for details on setting up your build system with the current Spring Cloud Release Train.

    This will enable auto-configuration that will setup Spring Cloud Consul Config.

    64.2 Customizing

    Consul Config may be customized using the following properties:

    bootstrap.yml.  +config/application/

    The most specific property source is at the top, with the least specific at the bottom. Properties in 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. Section 65.3, “Config Watch” will also automatically detect changes and reload the application context.

    65.1 How to activate

    To get started with Consul Configuration use the starter with group org.springframework.cloud and artifact id spring-cloud-starter-consul-config. See the Spring Cloud Project page for details on setting up your build system with the current Spring Cloud Release Train.

    This will enable auto-configuration that will setup Spring Cloud Consul Config.

    65.2 Customizing

    Consul Config may be customized using the following properties:

    bootstrap.yml. 

    spring:
       cloud:
         consul:
    @@ -5425,7 +5622,7 @@ config/application/

    The most specific property source is at the top, wit 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

    64.3 Config Watch

    The Consul Config Watch takes advantage of the ability of consul to watch a key prefix. The Config Watch makes a blocking Consul HTTP API call to determine if any relevant configuration data has changed for the current application. If there is new configuration data a Refresh Event is published. This is equivalent to calling the /refresh actuator endpoint.

    To change the frequency of when the Config Watch is called change spring.cloud.consul.config.watch.delay. The default value is 1000, which is in milliseconds.

    To disable the Config Watch set spring.cloud.consul.config.watch.enabled=false.

    64.4 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.  +

    • 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

    65.3 Config Watch

    The Consul Config Watch takes advantage of the ability of consul to watch a key prefix. The Config Watch makes a blocking Consul HTTP API call to determine if any relevant configuration data has changed for the current application. If there is new configuration data a Refresh Event is published. This is equivalent to calling the /refresh actuator endpoint.

    To change the frequency of when the Config Watch is called change spring.cloud.consul.config.watch.delay. The default value is 1000, which is in milliseconds.

    To disable the Config Watch set spring.cloud.consul.config.watch.enabled=false.

    65.4 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:
    @@ -5434,7 +5631,7 @@ config/application/

    The most specific property source is at the top, wit

    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.

    64.5 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.  +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.

    65.5 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:
    @@ -5448,7 +5645,7 @@ foo-production.yml
     foo.properties
     master.ref

    the following property sources would be created:

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

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

    64.6 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.

    65. Consul Retry

    If you expect that the consul agent may occasionally be unavailable when +config/application.yml

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

    65.6 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.

    66. 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 behaviour is to retry 6 times with an initial backoff interval of 1000ms and an @@ -5456,7 +5653,7 @@ 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]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.

    66. Spring Cloud Bus with Consul

    66.1 How to activate

    To get started with the Consul Bus use the starter with group org.springframework.cloud and artifact id spring-cloud-starter-consul-bus. See the Spring Cloud Project page for details on setting up your build system with the current Spring Cloud Release Train.

    See the Spring Cloud Bus documentation for the available actuator endpoints and howto send custom messages.

    67. 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.

    68. 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.  +Retry has a RetryInterceptorBuilder that makes it easy to create one.

    67. Spring Cloud Bus with Consul

    67.1 How to activate

    To get started with the Consul Bus use the starter with group org.springframework.cloud and artifact id spring-cloud-starter-consul-bus. See the Spring Cloud Project page for details on setting up your build system with the current Spring Cloud Release Train.

    See the Spring Cloud Bus documentation for the available actuator endpoints and howto send custom messages.

    68. 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.

    69. 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>
         <groupId>org.springframework.cloud</groupId>
         <artifactId>spring-cloud-netflix-turbine</artifactId>
    @@ -5480,13 +5677,13 @@ public class Turbine {
             SpringApplication.run(DemoturbinecommonsApplication.class, args);
         }
     }

    -

    Part IX. Spring Cloud Zookeeper

    This project provides Zookeeper integrations for Spring Boot apps through autoconfiguration +

    Part X. 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 application and build large distributed systems with Zookeeper based components. The 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.

    69. Install Zookeeper

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

    70. 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.

    70.1 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.

    [Note]Note

    You still need to include org.springframework.boot:spring-boot-starter-web for web functionality.

    70.2 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
    +(Hystrix) are provided by integration with Spring Cloud Netflix.

    70. Install Zookeeper

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

    71. 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.

    71.1 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.

    [Note]Note

    You still need to include org.springframework.boot:spring-boot-starter-web for web functionality.

    71.2 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
     @RestController
     public class Application {
     
    @@ -5504,7 +5701,7 @@ Intelligent Routing (Zuul) and Client Side Load Balancing (Ribbon), Circuit Brea
       cloud:
         zookeeper:
           connect-string: localhost:2181

    -

    [Caution]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.

    Having spring-cloud-starter-zookeeper-discovery on the classpath 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).

    If you would like to disable the Zookeeper Discovery Client you can set spring.cloud.zookeeper.discovery.enabled to false.

    70.3 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.

    @Autowired
    +

    [Caution]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.

    Having spring-cloud-starter-zookeeper-discovery on the classpath 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).

    If you would like to disable the Zookeeper Discovery Client you can set spring.cloud.zookeeper.discovery.enabled to false.

    71.3 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.

    @Autowired
     private DiscoveryClient discoveryClient;
     
     public String serviceUrl() {
    @@ -5513,7 +5710,7 @@ Intelligent Routing (Zuul) and Client Side Load Balancing (Ribbon), Circuit Brea
             return list.get(0).getUri().toString();
         }
         return null;
    -}

    71. Using Spring Cloud Zookeeper with Spring Cloud Netflix Components

    Spring Cloud Netflix supplies useful tools that work regardless of which DiscoveryClient implementation is used. Feign, Turbine, Ribbon and Zuul all work with Spring Cloud Zookeeper.

    71.1 Ribbon with Zookeeper

    Spring Cloud Zookeeper provides an implementation of Ribbon’s ServerList. When the spring-cloud-starter-zookeeper-discovery is used, Ribbon is auto-configured to use the ZookeeperServerList by default.

    72. Spring Cloud Zookeeper and Service Registry

    Spring Cloud Zookeeper implements the ServiceRegistry interface allowing developers to register arbitrary service in a programmatic way.

    The ServiceInstanceRegistration class offers a builder() method to create a Registration object that can be used by the ServiceRegistry.

    @Autowired
    +}

    72. Using Spring Cloud Zookeeper with Spring Cloud Netflix Components

    Spring Cloud Netflix supplies useful tools that work regardless of which DiscoveryClient implementation is used. Feign, Turbine, Ribbon and Zuul all work with Spring Cloud Zookeeper.

    72.1 Ribbon with Zookeeper

    Spring Cloud Zookeeper provides an implementation of Ribbon’s ServerList. When the spring-cloud-starter-zookeeper-discovery is used, Ribbon is auto-configured to use the ZookeeperServerList by default.

    73. Spring Cloud Zookeeper and Service Registry

    Spring Cloud Zookeeper implements the ServiceRegistry interface allowing developers to register arbitrary service in a programmatic way.

    The ServiceInstanceRegistration class offers a builder() method to create a Registration object that can be used by the ServiceRegistry.

    @Autowired
     private ZookeeperServiceRegistry serviceRegistry;
     
     public void registerThings() {
    @@ -5524,9 +5721,9 @@ Intelligent Routing (Zuul) and Client Side Load Balancing (Ribbon), Circuit Brea
                 .name("/a/b/c/d/anotherservice")
                 .build();
         this.serviceRegistry.register(registration);
    -}

    72.1 Instance Status

    Netflix Eureka supports having instances registered with the server that are OUT_OF_SERVICE and not returned as active service instances. This is very useful for behaviors such as blue/green deployments. The Curator Service Discovery recipe does not support this behavior. Taking advantage of the flexible payload has let Spring Cloud Zookeeper implement OUT_OF_SERVICE by updating some specific metadata and then filtering on that metadata in the Ribbon ZookeeperServerList. The ZookeeperServerList filters out all non-null instance statuses that do not equal UP. If the instance status field is empty, it is considered UP for backwards compatibility. To change the status of an instance POST OUT_OF_SERVICE to the ServiceRegistry instance status actuator endpoint.

    $ http POST http://localhost:8081/service-registry status=OUT_OF_SERVICE
    NOTE: The above example uses the `http` command from https://httpie.org

    73. Zookeeper Dependencies

    73.1 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 +}

    73.1 Instance Status

    Netflix Eureka supports having instances registered with the server that are OUT_OF_SERVICE and not returned as active service instances. This is very useful for behaviors such as blue/green deployments. The Curator Service Discovery recipe does not support this behavior. Taking advantage of the flexible payload has let Spring Cloud Zookeeper implement OUT_OF_SERVICE by updating some specific metadata and then filtering on that metadata in the Ribbon ZookeeperServerList. The ZookeeperServerList filters out all non-null instance statuses that do not equal UP. If the instance status field is empty, it is considered UP for backwards compatibility. To change the status of an instance POST OUT_OF_SERVICE to the ServiceRegistry instance status actuator endpoint.

    $ http POST http://localhost:8081/service-registry status=OUT_OF_SERVICE
    NOTE: The above example uses the `http` command from https://httpie.org

    74. Zookeeper Dependencies

    74.1 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.

    73.2 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).

    73.3 Setting up Zookeeper Dependencies

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

    application.yml.  +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.

    74.2 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).

    74.3 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:
    @@ -5548,36 +5745,36 @@ spring.cloud.zookeeper:
           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.

    73.3.1 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 +

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

    74.3.1 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();
    -}

    73.3.2 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.

    73.3.3 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

    73.3.4 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 +}

    74.3.2 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.

    74.3.3 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

    74.3.4 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

    and the following version:

    v1

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

    application/vnd.newsletter.v1+json

    73.3.5 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. +version yaml property. Let’s take a look at an example.

    Having the following contentTypeTemplate:

    application/vnd.newsletter.$version+json

    and the following version:

    v1

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

    application/vnd.newsletter.v1+json

    74.3.5 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.

    73.3.6 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.

    73.3.7 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.

    73.4 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 + - no-cache

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

    74.3.6 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.

    74.3.7 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.

    74.4 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.

    74. 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.

    74.1 How to activate

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

    74.2 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. +headers and content type with version set in Dependency configuration. Wihtout this setting of those two parameters will not be operational.

    75. 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.

    75.1 How to activate

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

    75.2 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.

    74.3 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 + whether your dependency has changed to CONNECTED or DISCONNECTED.

    75.3 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 overridden since the DefaultDependencyPresenceOnStartupVerifier is registered only when there is no bean of DependencyPresenceOnStartupVerifier.

    75. 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
    +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 overridden since the DefaultDependencyPresenceOnStartupVerifier is registered only when there is no bean of DependencyPresenceOnStartupVerifier.

    76. 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
     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.

    75.1 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.

    75.2 Customizing

    Zookeeper Config may be customized using the following properties:

    bootstrap.yml.  +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.

    76.1 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.

    76.2 Customizing

    Zookeeper Config may be customized using the following properties:

    bootstrap.yml. 

    spring:
       cloud:
         zookeeper:
    @@ -5586,7 +5783,7 @@ config/application

    The most specific property source is at the top, with root: configuration defaultContext: apps 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

    75.3 ACLs

    You can add authentication information for Zookeeper ACLs by calling the addAuthInfo method of a +

    • 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

    76.3 ACLs

    You can add authentication information for Zookeeper ACLs by calling the addAuthInfo method of a CuratorFramework bean. One way to accomplish this is by providing your own CuratorFramework bean:

    @BoostrapConfiguration
     public class CustomCuratorFrameworkConfig {
     
    @@ -5614,7 +5811,7 @@ comma-separated list set as the value of the property
     

    org.springframework.cloud.bootstrap.BootstrapConfiguration=\
     my.project.CustomCuratorFrameworkConfig,\
     my.project.DefaultCuratorFrameworkConfig

    -

    Unresolved directive in spring-cloud.adoc - include::../../../../cli/docs/src/main/asciidoc/spring-cloud-cli.adoc[]

    Part X. Spring Cloud Security

    Spring Cloud Security offers a set of primitives for building secure +

    Unresolved directive in spring-cloud.adoc - include::../../../../cli/docs/src/main/asciidoc/spring-cloud-cli.adoc[]

    Part XI. Spring Cloud Security

    Spring Cloud Security offers a set of primitives for building secure applications and services with minimum fuss. A declarative model which can be heavily configured externally (or centrally) lends itself to the implementation of large systems of co-operating, remote components, @@ -5622,7 +5819,7 @@ usually with a central indentity management service. It is also extremely easy to use in a service platform like Cloud Foundry. Building on Spring Boot and Spring Security OAuth2 we can quickly create systems that implement common patterns like single sign on, token relay and token -exchange.

    [Note]Note

    Spring Cloud is released under the non-restrictive Apache 2.0 license. If you would like to contribute to this section of the documentation or if you find an error, please find the source code and issue trackers in the project at github.

    76. Quickstart

    76.1 OAuth2 Single Sign On

    Here’s a Spring Cloud "Hello World" app with HTTP Basic +exchange.

    [Note]Note

    Spring Cloud is released under the non-restrictive Apache 2.0 license. If you would like to contribute to this section of the documentation or if you find an error, please find the source code and issue trackers in the project at github.

    77. Quickstart

    77.1 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')
     @Controller
    @@ -5672,7 +5869,7 @@ decide what the defaults should be, usually depending on the settings in
     the client registration that it holds.

    [Note]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).

    76.2 OAuth2 Protected Resource

    You want to protect an API resource with an OAuth2 token? Here’s a +sample here).

    77.2 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')
     @RestController
    @@ -5691,12 +5888,12 @@ simple example (paired with the client above):

    app.groovy.  resource: userInfoUri: https://api.github.com/user preferTokenInfo: false

    -

    77. More Detail

    77.1 Single Sign On

    [Note]Note

    All of the OAuth2 SSO and resource server features moved to Spring Boot +

    78. More Detail

    78.1 Single Sign On

    [Note]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.

    77.2 Token Relay

    A Token Relay is where an OAuth2 consumer acts as a Client and +Spring Boot user guide.

    78.2 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.

    77.2.1 Client Token Relay

    If your app is a user facing OAuth2 client (i.e. has declared +Server.

    78.2.1 Client Token Relay

    If your app is a user facing OAuth2 client (i.e. has declared @EnableOAuth2Sso or @EnableOAuth2Client) then it has an OAuth2ClientContext in request scope from Spring Boot. You can create your own OAuth2RestTemplate from this context and an @@ -5707,7 +5904,7 @@ Security and Spring Boot.)

    OAuth2ProtectedResourceDetails automatically if you are using client_credentials tokens. In that case you need to create your own ClientCredentialsResourceDetails and configure it with -@ConfigurationProperties("security.oauth2.client").

    77.2.2 Client Token Relay in Zuul Proxy

    If your app also has a +@ConfigurationProperties("security.oauth2.client").

    78.2.2 Client Token Relay in Zuul Proxy

    If your app also has a Spring Cloud Zuul embedded reverse proxy (using @EnableZuulProxy) then you can ask it to forward OAuth2 access tokens downstream to the services @@ -5730,7 +5927,7 @@ a ZuulFilter, which itself is activated because Zuu 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.

    77.2.3 Resource Server Token Relay

    If your app has @EnableResourceServer you might want to relay the +and puts it in a request header for the downstream requests.

    78.2.3 Resource Server Token Relay

    If your app has @EnableResourceServer you might want to relay the incoming token downstream to other services. If you use a RestTemplate to contact the downstream services then this is just a matter of how to create the template with the right context.

    If your service uses UserInfoTokenServices to authenticate incoming @@ -5772,7 +5969,7 @@ 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 OAuth2Context instead of autowiring the default one.

    Feign clients will also pick up an interceptor that uses the OAuth2ClientContext if it is available, so they should also do a -token relay anywhere where a RestTemplate would.

    78. Configuring Authentication Downstream of a Zuul Proxy

    You can control the authorization behaviour downstream of an +token relay anywhere where a RestTemplate would.

    79. 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:
       auth:
    @@ -5786,7 +5983,7 @@ 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.

    Part XI. Spring Cloud for Cloud Foundry

    Spring Cloud for Cloudfoundry makes it easy to run +ProxyAuthenticationProperties for full details.

    Part XII. Spring Cloud for Cloud Foundry

    Spring Cloud for Cloudfoundry makes it easy to run Spring Cloud apps in Cloud Foundry (the Platform as a Service). Cloud Foundry has the notion of a "service", which is @@ -5801,7 +5998,7 @@ implementation of Spring Cloud Commons DiscoveryClient@EnableDiscoveryClient and provide your credentials as spring.cloud.cloudfoundry.discovery.[username,password] (also *.url if you are not connecting to Pivotal Web Services) and then you can use the DiscoveryClient directly or via a LoadBalancerClient.

    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.

    79. Discovery

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

    app.groovy.  +the fact that it has to get an access token from Cloud Foundry.

    80. Discovery

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

    app.groovy. 

    @Grab('org.springframework.cloud:spring-cloud-cloudfoundry')
     @RestController
     @EnableDiscoveryClient
    @@ -5820,7 +6017,7 @@ the fact that it has to get an access token from Cloud Foundry.

    It will show its app name in the home page.

    The DiscoveryClient can lists all the apps in a space, according to the credentials it is authenticated with, where the space defaults to the one the client is running in (if any). If neither org nor space -are configured, they default per the user’s profile in Cloud Foundry.

    80. Single Sign On

    [Note]Note

    All of the OAuth2 SSO and resource server features moved to Spring Boot +are configured, they default per the user’s profile in Cloud Foundry.

    81. Single Sign On

    [Note]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 credentials to the Spring Boot features. If you have a CloudFoundry @@ -5828,12 +6025,12 @@ 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.

    Part XII. Spring Cloud Contract

    _Documentation Authors: Adam Dudczak, Mathias Düsterhöft, Marcin Grzejszczak, Dennis Kieselhorst, Jakub Kubryński, Karol Lassak, -Olga Maciaszek-Sharma, Mariusz Smykuła, Dave Syer, Jay Bryant

    1.3.5.BUILD-SNAPSHOT

    81. Spring Cloud Contract

    You need confidence when pushing new features to a new application or service in a +parameterized using spring.oauth2.sso.serviceId.

    Part XIII. Spring Cloud Contract

    _Documentation Authors: Adam Dudczak, Mathias Düsterhöft, Marcin Grzejszczak, Dennis Kieselhorst, Jakub Kubryński, Karol Lassak, +Olga Maciaszek-Sharma, Mariusz Smykuła, Dave Syer, Jay Bryant

    1.3.5.BUILD-SNAPSHOT

    82. Spring Cloud Contract

    You need confidence when pushing new features to a new application or service in a distributed system. This project provides support for Consumer Driven Contracts and service schemas in Spring applications (for both HTTP and message-based interactions), covering a range of options for writing tests, publishing them as assets, and asserting -that a contract is kept by producers and consumers.

    82. Spring Cloud Contract Verifier Introduction

    [Tip]Tip

    The Accurest project was initially started by Marcin Grzejszczak and Jakub Kubrynski +that a contract is kept by producers and consumers.

    83. Spring Cloud Contract Verifier Introduction

    [Tip]Tip

    The Accurest project was initially started by Marcin Grzejszczak and Jakub Kubrynski (codearte.io)

    Spring Cloud Contract Verifier enables Consumer Driven Contract (CDC) development of JVM-based applications. It moves TDD to the level of software architecture.

    Spring Cloud Contract Verifier ships with Contract Definition Language (CDL). Contract definitions are used to produce the following resources:

    • JSON stub definitions to be used by WireMock when doing integration testing on the @@ -5842,7 +6039,7 @@ produced by Spring Cloud Contract Verifier.
    • Messaging r Integration, Spring Cloud Stream, Spring AMQP, and Apache Camel. You can also set your own integrations.
    • Acceptance tests (in JUnit or Spock) are used to verify if server-side implementation of the API is compliant with the contract (server tests). A full test is generated by -Spring Cloud Contract Verifier.

    82.1 Why a Contract Verifier?

    Assume that we have a system consisting of multiple microservices:

    Microservices Architecture

    82.1.1 Testing issues

    If we wanted to test the application in top left corner to determine whether it can +Spring Cloud Contract Verifier.

    83.1 Why a Contract Verifier?

    Assume that we have a system consisting of multiple microservices:

    Microservices Architecture

    83.1.1 Testing issues

    If we wanted to test the application in top left corner to determine whether it can communicate with other services, we could do one of two things:

    • Deploy all microservices and perform end-to-end tests.
    • Mock other microservices in unit/integration tests.

    Both have their advantages but also a lot of disadvantages.

    Deploy all microservices and perform end to end tests

    Advantages:

    • Simulates production.
    • Tests real communication between services.

    Disadvantages:

    • To test one microservice, we have to deploy 6 microservices, a couple of databases, etc.
    • The environment where the tests run is locked for a single suite of tests (nobody else would be able to run the tests in the meantime).
    • They take a long time to run.
    • The feedback comes very late in the process.
    • They are extremely hard to debug.

    Mock other microservices in unit/integration tests

    Advantages:

    • They provide very fast feedback.
    • They have no infrastructure requirements.

    Disadvantages:

    • The implementor of the service creates stubs that might have nothing to do with @@ -5851,13 +6048,13 @@ created. The main idea is to give you very fast feedback, without the need to se whole world of microservices. If you work on stubs, then the only applications you need are those that your application directly uses.

      Stubbed Services

      Spring Cloud Contract Verifier gives you the certainty that the stubs that you use were created by the service that you’re calling. Also, if you can use them, it means that they -were tested against the producer’s side. In short, you can trust those stubs.

    82.2 Purposes

    The main purposes of Spring Cloud Contract Verifier with Stub Runner are:

    • To ensure that WireMock/Messaging stubs (used when developing the client) do exactly +were tested against the producer’s side. In short, you can trust those stubs.

    83.2 Purposes

    The main purposes of Spring Cloud Contract Verifier with Stub Runner are:

    • To ensure that WireMock/Messaging stubs (used when developing the client) do exactly what the actual server-side implementation does.
    • To promote ATDD method and Microservices architectural style.
    • To provide a way to publish changes in contracts that are immediately visible on both sides.
    • To generate boilerplate test code to be used on the server side.
    [Important]Important

    Spring Cloud Contract Verifier’s purpose is NOT to start writing business features in the contracts. Assume that we have a business use case of fraud check. If a user can be a fraud for 100 different reasons, we would assume that you would create 2 contracts, one for the positive case and one for the negative case. Contract tests are -used to test contracts between applications and not to simulate full behavior.

    82.3 How It Works

    This section explores how Spring Cloud Contract Verifier with Stub Runner works.

    82.3.1 Defining the contract

    As consumers of services, we need to define what exactly we want to achieve. We need to +used to test contracts between applications and not to simulate full behavior.

    83.3 How It Works

    This section explores how Spring Cloud Contract Verifier with Stub Runner works.

    83.3.1 Defining the contract

    As consumers of services, we need to define what exactly we want to achieve. We need to formulate our expectations. That is why we write contracts.

    Assume that you want to send a request containing the ID of a client company and the amount it wants to borrow from us. You also want to send it to the /fraudcheck url via the PUT method.

    Groovy DSL.  @@ -5971,7 +6168,7 @@ response: # (7) #(9) - and JSON body equal to # { "fraudCheckStatus": "FRAUD", "rejectionReason": "Amount too high" } #(10) - with header `Content-Type` equal to `application/json;charset=UTF-8`

    -

    82.3.2 Client Side

    Spring Cloud Contract generates stubs, which you can use during client-side testing. +

    83.3.2 Client Side

    Spring Cloud Contract generates stubs, which you can use during client-side testing. You get a running WireMock instance/Messaging route that simulates the service. You would like to feed that instance with a proper stub definition.

    At some point in time, you need to send a request to the Fraud Detection service.

    ResponseEntity<FraudServiceResponse> response =
     		restTemplate.exchange("http://localhost:" + port + "/fraudcheck", HttpMethod.PUT,
    @@ -5983,7 +6180,7 @@ You would like to feed that instance with a proper stub definition.

    At som @DirtiesContext public class LoanApplicationServiceTests {

    After that, during the tests, Spring Cloud Contract automatically finds the stubs (simulating the real service) in the Maven repository and exposes them on a configured -(or random) port.

    82.3.3 Server Side

    Since you are developing your stub, you need to be sure that it actually resembles your +(or random) port.

    83.3.3 Server Side

    Since you are developing your stub, you need to be sure that it actually resembles your concrete implementation. You cannot have a situation where your stub acts in one way and your application behaves in a different way, especially in production.

    To ensure that your application behaves the way you define in your stub, tests are generated from the stub you provide.

    The autogenerated test looks, more or less, like this:

    @Test
    @@ -6004,7 +6201,7 @@ generated from the stub you provide.

    The autogenerated test looks, more or DocumentContext parsedJson = JsonPath.parse(response.getBody().asString()); assertThatJson(parsedJson).field("['fraudCheckStatus']").matches("[A-Z]{5}"); assertThatJson(parsedJson).field("['rejection.reason']").isEqualTo("Amount too high"); -}

    82.4 Step-by-step Guide to Consumer Driven Contracts (CDC)

    Consider an example of Fraud Detection and the Loan Issuance process. The business +}

    83.4 Step-by-step Guide to Consumer Driven Contracts (CDC)

    Consider an example of Fraud Detection and the Loan Issuance process. The business scenario is such that we want to issue loans to people but do not want them to steal from us. The current implementation of our system grants loans to everybody.

    Assume that Loan Issuance is a client to the Fraud Detection server. In the current sprint, we must develop a new feature: if a client wants to borrow too much money, then @@ -6013,7 +6210,7 @@ Issuance has an artifact-id of http-client, and bot discuss changes while going through the process. CDC is all about communication.

    The server side code is available here and the client code here.

    [Tip]Tip

    In this case, the producer owns the contracts. Physically, all the contract are -in the producer’s repository.

    82.4.1 Technical note

    If using the SNAPSHOT / Milestone / Release Candidate versions please add the +in the producer’s repository.

    83.4.1 Technical note

    If using the SNAPSHOT / Milestone / Release Candidate versions please add the following section to your build:

    Maven. 

    <repositories>
     	<repository>
    @@ -6075,7 +6272,7 @@ following section to your build:

    Maven.  maven { url "http://repo.spring.io/milestone" } maven { url "http://repo.spring.io/release" } }

    -

    82.4.2 Consumer side (Loan Issuance)

    As a developer of the Loan Issuance service (a consumer of the Fraud Detection server), you might do the following steps:

    1. Start doing TDD by writing a test for your feature.
    2. Write the missing implementation.
    3. Clone the Fraud Detection service repository locally.
    4. Define the contract locally in the repo of Fraud Detection service.
    5. Add the Spring Cloud Contract Verifier plugin.
    6. Run the integration tests.
    7. File a pull request.
    8. Create an initial implementation.
    9. Take over the pull request.
    10. Write the missing implementation.
    11. Deploy your app.
    12. Work online.

    Start doing TDD by writing a test for your feature.

    @Test
    +

    83.4.2 Consumer side (Loan Issuance)

    As a developer of the Loan Issuance service (a consumer of the Fraud Detection server), you might do the following steps:

    1. Start doing TDD by writing a test for your feature.
    2. Write the missing implementation.
    3. Clone the Fraud Detection service repository locally.
    4. Define the contract locally in the repo of Fraud Detection service.
    5. Add the Spring Cloud Contract Verifier plugin.
    6. Run the integration tests.
    7. File a pull request.
    8. Create an initial implementation.
    9. Take over the pull request.
    10. Write the missing implementation.
    11. Deploy your app.
    12. Work online.

    Start doing TDD by writing a test for your feature.

    @Test
     public void shouldBeRejectedDueToAbnormalLoanAmount() {
     	// given:
     	LoanApplication application = new LoanApplication(new Client("1234567890"),
    @@ -6290,7 +6487,7 @@ with group id com.example, artifact id stubs classifier on port 8080.

    File a pull request.

    What you have done until now is an iterative process. You can play around with the contract, install it locally, and work on the consumer side until the contract works as you wish.

    Once you are satisfied with the results and the test passes, publish a pull request to -the server side. Currently, the consumer side work is done.

    82.4.3 Producer side (Fraud Detection server)

    As a developer of the Fraud Detection server (a server to the Loan Issuance service):

    Create an initial implementation.

    As a reminder, you can see the initial implementation here:

    @RequestMapping(value = "/fraudcheck", method = PUT)
    +the server side. Currently, the consumer side work is done.

    83.4.3 Producer side (Fraud Detection server)

    As a developer of the Fraud Detection server (a server to the Loan Issuance service):

    Create an initial implementation.

    As a reminder, you can see the initial implementation here:

    @RequestMapping(value = "/fraudcheck", method = PUT)
     public FraudCheckResult fraudCheck(@RequestBody FraudCheck fraudCheck) {
     return new FraudCheckResult(FraudCheckStatus.OK, NO_REASON);
     }

    Take over the pull request.

    $ git checkout -b contract-change-pr master
    @@ -6382,20 +6579,20 @@ Contract Verifier plugin adds the tests to the gene
     actually run those tests from your IDE.

    Deploy your app.

    Once you finish your work, you can deploy your change. First, merge the branch:

    $ git checkout master
     $ git merge --no-ff contract-change-pr
     $ git push origin master

    Your CI might run something like ./mvnw clean deploy, which would publish both the -application and the stub artifacts.

    82.4.4 Consumer Side (Loan Issuance) Final Step

    As a developer of the Loan Issuance service (a consumer of the Fraud Detection server):

    Merge branch to master.

    $ git checkout master
    +application and the stub artifacts.

    83.4.4 Consumer Side (Loan Issuance) Final Step

    As a developer of the Loan Issuance service (a consumer of the Fraud Detection server):

    Merge branch to master.

    $ git checkout master
     $ git merge --no-ff contract-change-pr

    Work online.

    Now you can disable the offline work for Spring Cloud Contract Stub Runner and indicate where the repository with your stubs is located. At this moment the stubs of the server side are automatically downloaded from Nexus/Artifactory. You can set the value of stubsMode to REMOTE. The following code shows an example of achieving the same thing by changing the properties.

    stubrunner:
       ids: 'com.example:http-server-dsl:+:stubs:8080'
    -  repositoryRoot: http://repo.spring.io/libs-snapshot

    That’s it!

    82.5 Dependencies

    The best way to add dependencies is to use the proper starter dependency.

    For stub-runner, use spring-cloud-starter-stub-runner. When you use a plugin, add -spring-cloud-starter-contract-verifier.

    82.6 Additional Links

    Here are some resources related to Spring Cloud Contract Verifier and Stub Runner. Note + repositoryRoot: http://repo.spring.io/libs-snapshot

    That’s it!

    83.5 Dependencies

    The best way to add dependencies is to use the proper starter dependency.

    For stub-runner, use spring-cloud-starter-stub-runner. When you use a plugin, add +spring-cloud-starter-contract-verifier.

    83.6 Additional Links

    Here are some resources related to Spring Cloud Contract Verifier and Stub Runner. Note that some may be outdated, because the Spring Cloud Contract Verifier project is under -constant development.

    82.6.1 Spring Cloud Contract video

    You can check out the video from the Warsaw JUG about Spring Cloud Contract:

    82.7 Samples

    You can find some samples at -samples.

    83. Spring Cloud Contract FAQ

    83.1 Why use Spring Cloud Contract Verifier and not X ?

    For the time being Spring Cloud Contract Verifier is a JVM based tool. So it could be your first pick when you’re already creating +constant development.

    83.6.1 Spring Cloud Contract video

    You can check out the video from the Warsaw JUG about Spring Cloud Contract:

    83.7 Samples

    You can find some samples at +samples.

    84. Spring Cloud Contract FAQ

    84.1 Why use Spring Cloud Contract Verifier and not X ?

    For the time being Spring Cloud Contract Verifier is a JVM based tool. So it could be your first pick when you’re already creating software for the JVM. This project has a lot of really interesting features but especially quite a few of them definitely make -Spring Cloud Contract Verifier stand out on the "market" of Consumer Driven Contract (CDC) tooling. Out of many the most interesting are:

    • Possibility to do CDC with messaging
    • Clear and easy to use, statically typed DSL
    • Possibility to copy paste your current JSON file to the contract and only edit its elements
    • Automatic generation of tests from the defined Contract
    • Stub Runner functionality - the stubs are automatically downloaded at runtime from Nexus / Artifactory
    • Spring Cloud integration - no discovery service is needed for integration tests

    83.2 I don’t want to write a contract in Groovy!

    No problem. You can write a contract in YAML!

    83.3 What is this value(consumer(), producer()) ?

    One of the biggest challenges related to stubs is their reusability. Only if they can be vastly used, will they serve their purpose. +Spring Cloud Contract Verifier stand out on the "market" of Consumer Driven Contract (CDC) tooling. Out of many the most interesting are:

    • Possibility to do CDC with messaging
    • Clear and easy to use, statically typed DSL
    • Possibility to copy paste your current JSON file to the contract and only edit its elements
    • Automatic generation of tests from the defined Contract
    • Stub Runner functionality - the stubs are automatically downloaded at runtime from Nexus / Artifactory
    • Spring Cloud integration - no discovery service is needed for integration tests

    84.2 I don’t want to write a contract in Groovy!

    No problem. You can write a contract in YAML!

    84.3 What is this value(consumer(), producer()) ?

    One of the biggest challenges related to stubs is their reusability. Only if they can be vastly used, will they serve their purpose. What typically makes that difficult are the hard-coded values of request / response elements. For example dates or ids. Imagine the following JSON request

    {
         "time" : "2016-10-10 20:10:15",
    @@ -6461,19 +6658,19 @@ for time and UUID are simplified and most likely invalid but we want to keep thi
     					])
     			}
     }
    [Important]Important

    Please read the Groovy docs related to JSON to understand how to -properly structure the request / response bodies.

    83.4 How to do Stubs versioning?

    83.4.1 API Versioning

    Let’s try to answer a question what versioning really means. If you’re referring to the API version then there are +properly structure the request / response bodies.

    84.4 How to do Stubs versioning?

    84.4.1 API Versioning

    Let’s try to answer a question what versioning really means. If you’re referring to the API version then there are different approaches.

    • use Hypermedia, links and do not version your API by any means
    • pass versions through headers / urls

    I will not try to answer a question which approach is better. Whatever suit your needs and allows you to generate business value should be picked.

    Let’s assume that you do version your API. In that case you should provide as many contracts as many versions you support. -You can create a subfolder for every version or append it to th contract name - whatever suits you more.

    83.4.2 JAR versioning

    If by versioning you mean the version of the JAR that contains the stubs then there are essentially two main approaches.

    Let’s assume that you’re doing Continuous Delivery / Deployment which means that you’re generating a new version of +You can create a subfolder for every version or append it to th contract name - whatever suits you more.

    84.4.2 JAR versioning

    If by versioning you mean the version of the JAR that contains the stubs then there are essentially two main approaches.

    Let’s assume that you’re doing Continuous Delivery / Deployment which means that you’re generating a new version of the jar each time you go through the pipeline and that jar can go to production at any time. For example your jar version looks like this (it got built on the 20.10.2016 at 20:15:21) :

    1.0.0.20161020-201521-RELEASE

    In that case your generated stub jar will look like this.

    1.0.0.20161020-201521-RELEASE-stubs.jar

    In this case you should inside your application.yml or @AutoConfigureStubRunner when referencing stubs provide the latest version of the stubs. You can do that by passing the + sign. Example

    @AutoConfigureStubRunner(ids = {"com.example:http-server-dsl:+:stubs:8080"})

    If the versioning however is fixed (e.g. 1.0.4.RELEASE or 2.1.1) then you have to set the concrete value of the jar -version. Example for 2.1.1.

    @AutoConfigureStubRunner(ids = {"com.example:http-server-dsl:2.1.1:stubs:8080"})

    83.4.3 Dev or prod stubs

    You can manipulate the classifier to run the tests against current development version of the stubs of other services +version. Example for 2.1.1.

    @AutoConfigureStubRunner(ids = {"com.example:http-server-dsl:2.1.1:stubs:8080"})

    84.4.3 Dev or prod stubs

    You can manipulate the classifier to run the tests against current development version of the stubs of other services or the ones that were deployed to production. If you alter your build to deploy the stubs with the prod-stubs classifier - once you reach production deployment then you can run tests in one case with dev stubs and one with prod stubs.

    Example of tests using development version of stubs

    @AutoConfigureStubRunner(ids = {"com.example:http-server-dsl:+:stubs:8080"})

    Example of tests using production version of stubs

    @AutoConfigureStubRunner(ids = {"com.example:http-server-dsl:+:prod-stubs:8080"})

    You can pass those values also via properties from your deployment pipeline.

    83.5 Common repo with contracts

    Another way of storing contracts other than having them with the producer is keeping them in a common place. + once you reach production deployment then you can run tests in one case with dev stubs and one with prod stubs.

    Example of tests using development version of stubs

    @AutoConfigureStubRunner(ids = {"com.example:http-server-dsl:+:stubs:8080"})

    Example of tests using production version of stubs

    @AutoConfigureStubRunner(ids = {"com.example:http-server-dsl:+:prod-stubs:8080"})

    You can pass those values also via properties from your deployment pipeline.

    84.5 Common repo with contracts

    Another way of storing contracts other than having them with the producer is keeping them in a common place. It can be related to security issues where the consumers can’t clone the producer’s code. Also if you keep contracts in a single place then you, as a producer, will know how many consumers you have and which -consumer will you break with your local changes.

    83.5.1 Repo structure

    Let’s assume that we have a producer with coordinates com.example:server and 3 consumers: client1, +consumer will you break with your local changes.

    84.5.1 Repo structure

    Let’s assume that we have a producer with coordinates com.example:server and 3 consumers: client1, client2, client3. Then in the repository with common contracts you would have the following setup (which you can checkout here:

    ├── com
     │   └── example
    @@ -6664,11 +6861,11 @@ Those poms are necessary for the consumer side to run mvn
     			</excludes>
     		</fileSet>
     	</fileSets>
    -</assembly>

    83.5.2 Workflow

    The workflow would look similar to the one presented in the Step by step guide to CDC. The only difference +</assembly>

    84.5.2 Workflow

    The workflow would look similar to the one presented in the Step by step guide to CDC. The only difference is that the producer doesn’t own the contracts anymore. So the consumer and the producer have to work on - common contracts in a common repository.

    83.5.3 Consumer

    When the consumer wants to work on the contracts offline, instead of cloning the producer code, the + common contracts in a common repository.

    84.5.3 Consumer

    When the consumer wants to work on the contracts offline, instead of cloning the producer code, the consumer team clones the common repository, goes to the required producer’s folder (e.g. com/example/server) -and runs mvn clean install -DskipTests to install locally the stubs converted from the contracts.

    [Tip]Tip

    You need to have Maven installed locally

    83.5.4 Producer

    As a producer it’s enough to alter the Spring Cloud Contract Verifier to provide the URL and the dependency +and runs mvn clean install -DskipTests to install locally the stubs converted from the contracts.

    [Tip]Tip

    You need to have Maven installed locally

    84.5.4 Producer

    As a producer it’s enough to alter the Spring Cloud Contract Verifier to provide the URL and the dependency of the JAR containing the contracts:

    <plugin>
     	<groupId>org.springframework.cloud</groupId>
     	<artifactId>spring-cloud-contract-maven-plugin</artifactId>
    @@ -6684,7 +6881,7 @@ of the JAR containing the contracts:

    http://link/to/your/nexus/or/artifactory/or/sth. It will be then unpacked in a local temporary folder
     and contracts present under the com/example/server will be picked as the ones used to generate the
     tests and the stubs. Due to this convention the producer team will know which consumer teams will be broken
    -when some incompatible changes are done.

    The rest of the flow looks the same.

    83.5.5 How can I define messaging contracts per topic not per producer?

    To avoid messaging contracts duplication in the common repo, when few producers writing messages to one topic, +when some incompatible changes are done.

    The rest of the flow looks the same.

    84.5.5 How can I define messaging contracts per topic not per producer?

    To avoid messaging contracts duplication in the common repo, when few producers writing messages to one topic, we could create the structure when the rest contracts would be placed in a folder per producer and messaging contracts in the folder per topic.

    For Maven Project

    To make it possible to work on the producer side we could do the following things (all via Maven plugins):

    • Add common repo dependency to your classpath:
    <dependency>
        <groupId>com.example</groupId>
    @@ -6789,20 +6986,20 @@ deleteUnwantedContracts.dependsOn("deleteUnwantedContracts")
    • Configure plugin by specifying the directory containing contracts using contractsDslDir property
    contracts {
     
         contractsDslDir = new File("${buildDir}/unpackedContracts")
    -}

    83.6 Can I have multiple base classes for tests?

    Yes! Check out the Different base classes for contracts sections -of either Gradle or Maven plugins.

    83.7 How can I debug the request/response being sent by the generated tests client?

    The generated tests all boil down to RestAssured in some form or fashion which relies on Apache HttpClient. HttpClient has a facility called wire logging which logs the entire request and response to HttpClient. Spring Boot has a logging common application property for doing this sort of thing, just add this to your application properties

    logging.level.org.apache.http.wire=DEBUG

    83.7.1 How can I debug the mapping/request/response being sent by WireMock?

    Starting from version 1.2.0 we turn on WireMock logging to +}

    84.6 Can I have multiple base classes for tests?

    Yes! Check out the Different base classes for contracts sections +of either Gradle or Maven plugins.

    84.7 How can I debug the request/response being sent by the generated tests client?

    The generated tests all boil down to RestAssured in some form or fashion which relies on Apache HttpClient. HttpClient has a facility called wire logging which logs the entire request and response to HttpClient. Spring Boot has a logging common application property for doing this sort of thing, just add this to your application properties

    logging.level.org.apache.http.wire=DEBUG

    84.7.1 How can I debug the mapping/request/response being sent by WireMock?

    Starting from version 1.2.0 we turn on WireMock logging to info and the WireMock notifier to being verbose. Now you will exactly know what request was received by WireMock server and which -matching response definition was picked.

    To turn off this feature just bump WireMock logging to ERROR

    logging.level.com.github.tomakehurst.wiremock=ERROR

    83.7.2 How can I see what got registered in the HTTP server stub?

    You can use the mappingsOutputFolder property on @AutoConfigureStubRunner or StubRunnerRule +matching response definition was picked.

    To turn off this feature just bump WireMock logging to ERROR

    logging.level.com.github.tomakehurst.wiremock=ERROR

    84.7.2 How can I see what got registered in the HTTP server stub?

    You can use the mappingsOutputFolder property on @AutoConfigureStubRunner or StubRunnerRule to dump all mappings per artifact id. Also the port at which the given stub server was -started will be attached.

    83.7.3 Can I reference the request from the response?

    Yes! With version 1.1.0 we’ve added such a possibility. On the HTTP stub server side we’re providing support -for this for WireMock. In case of other HTTP server stubs you’ll have to implement the approach yourself.

    83.7.4 Can I reference text from file?

    Yes! With version 1.2.0 we’ve added such a possibility. It’s enough to call file(…​) method in the +started will be attached.

    84.7.3 Can I reference the request from the response?

    Yes! With version 1.1.0 we’ve added such a possibility. On the HTTP stub server side we’re providing support +for this for WireMock. In case of other HTTP server stubs you’ll have to implement the approach yourself.

    84.7.4 Can I reference text from file?

    Yes! With version 1.2.0 we’ve added such a possibility. It’s enough to call file(…​) method in the DSL and provide a path relative to where the contract lays. -If you’re using YAML just use the bodyFromFile property.

    85. Spring Cloud Contract Verifier Setup

    You can set up Spring Cloud Contract Verifier in the following ways:

    85.1 Gradle Project

    To learn how to set up the Gradle project for Spring Cloud Contract Verifier, read the +following sections:

    85.1.1 Prerequisites

    In order to use Spring Cloud Contract Verifier with WireMock, you muse use either a Gradle or a Maven plugin.

    [Warning]Warning

    If you want to use Spock in your projects, you must add separately the spock-core and spock-spring modules. Check Spock -docs for more information

    84.1.2 Add Gradle Plugin with Dependencies

    To add a Gradle plugin with dependencies, use code similar to this:

    buildscript {
    +docs for more information

    85.1.2 Add Gradle Plugin with Dependencies

    To add a Gradle plugin with dependencies, use code similar to this:

    buildscript {
     	repositories {
     		mavenCentral()
     	}
    @@ -6827,7 +7024,7 @@ dependencies {
     	testCompile 'org.spockframework:spock-core:1.0-groovy-2.4'
     	testCompile 'org.spockframework:spock-spring:1.0-groovy-2.4'
     	testCompile 'org.springframework.cloud:spring-cloud-starter-contract-verifier'
    -}

    84.1.3 Gradle and Rest Assured 2.0

    By default, Rest Assured 3.x is added to the classpath. However, to use Rest Assured 2.x +}

    85.1.3 Gradle and Rest Assured 2.0

    By default, Rest Assured 3.x is added to the classpath. However, to use Rest Assured 2.x you can add it to the plugins classpath, as shown here:

    buildscript {
     	repositories {
     		mavenCentral()
    @@ -6846,7 +7043,7 @@ depenendencies {
         testCompile "com.jayway.restassured:rest-assured:2.5.0"
         testCompile "com.jayway.restassured:spring-mock-mvc:2.5.0"
     }

    That way, the plugin automatically sees that Rest Assured 2.x is present on the classpath -and modifies the imports accordingly.

    84.1.4 Snapshot Versions for Gradle

    Add the additional snapshot repository to your build.gradle to use snapshot versions, +and modifies the imports accordingly.

    85.1.4 Snapshot Versions for Gradle

    Add the additional snapshot repository to your build.gradle to use snapshot versions, which are automatically uploaded after every successful build, as shown here:

    buildscript {
     	repositories {
     		mavenCentral()
    @@ -6855,16 +7052,16 @@ which are automatically uploaded after every successful build, as shown here:

    "http://repo.spring.io/milestone" } maven { url "http://repo.spring.io/release" } } -}

    84.1.5 Add stubs

    By default, Spring Cloud Contract Verifier is looking for stubs in the +}

    85.1.5 Add stubs

    By default, Spring Cloud Contract Verifier is looking for stubs in the src/test/resources/contracts directory.

    The directory containing stub definitions is treated as a class name, and each stub definition is treated as a single test. Spring Cloud Contract Verifier assumes that it contains at least one level of directories that are to be used as the test class name. If more than one level of nested directories is present, all except the last one is used as the package name. For example, with following structure:

    src/test/resources/contracts/myservice/shouldCreateUser.groovy
     src/test/resources/contracts/myservice/shouldReturnUser.groovy

    Spring Cloud Contract Verifier creates a test class named defaultBasePackage.MyService -with two methods:

    • shouldCreateUser()
    • shouldReturnUser()

    84.1.6 Run the Plugin

    The plugin registers itself to be invoked before a check task. If you want it to be +with two methods:

    • shouldCreateUser()
    • shouldReturnUser()

    85.1.6 Run the Plugin

    The plugin registers itself to be invoked before a check task. If you want it to be part of your build process, you need to do nothing more. If you just want to generate -tests, invoke the generateContractTests task.

    84.1.7 Default Setup

    The default Gradle Plugin setup creates the following Gradle part of the build (in +tests, invoke the generateContractTests task.

    85.1.7 Default Setup

    The default Gradle Plugin setup creates the following Gradle part of the build (in pseudocode):

    contracts {
         targetFramework = 'JUNIT'
         testMode = 'MockMvc'
    @@ -6908,12 +7105,12 @@ publishing {
                 artifact verifierStubsJar
             }
         }
    -}

    84.1.8 Configure Plugin

    To change the default configuration, add a contracts snippet to your Gradle config, as +}

    85.1.8 Configure Plugin

    To change the default configuration, add a contracts snippet to your Gradle config, as shown here:

    contracts {
     	testMode = 'MockMvc'
     	baseClassForTests = 'org.mycompany.tests'
     	generatedTestSourcesDir = project.file('src/generatedContract')
    -}

    84.1.9 Configuration Options

    • testMode: Defines the mode for acceptance tests. By default, the mode is MockMvc, +}

    85.1.9 Configuration Options

    • testMode: Defines the mode for acceptance tests. By default, the mode is MockMvc, which is based on Spring’s MockMvc. It can also be changed to JaxRsClient or to Explicit for real HTTP calls.
    • imports: Creates an array with imports that should be included in generated tests (for example ['org.myorg.Matchers']). By default, it creates an empty array.
    • staticImports: Creates an array with static imports that should be included in @@ -6942,7 +7139,7 @@ closure to set it up. * contractsMode: Specifies the mode of downloading contracts (whether the JAR is available offline, remotely etc.) * contractsSnapshotCheckSkip: If set to true will not assert whether the -downloaded stubs / contract JAR was downloaded from a remote location or a local one

    84.1.10 Single Base Class for All Tests

    When using Spring Cloud Contract Verifier in default MockMvc, you need to create a base +downloaded stubs / contract JAR was downloaded from a remote location or a local one

    85.1.10 Single Base Class for All Tests

    When using Spring Cloud Contract Verifier in default MockMvc, you need to create a base specification for all generated acceptance tests. In this class, you need to point to an endpoint, which should be verified.

    abstract class BaseMockMvcSpec extends Specification {
     
    @@ -6961,7 +7158,7 @@ endpoint, which should be verified.

    If you use Explicit mode, you can use a base class to initialize the whole tested app as you might see in regular integration tests. If you use the JAXRSCLIENT mode, this base class should also contain a protected WebTarget webTarget field. Right now, the -only option to test the JAX-RS API is to start a web server.

    84.1.11 Different Base Classes for Contracts

    If your base classes differ between contracts, you can tell the Spring Cloud Contract +only option to test the JAX-RS API is to start a web server.

    85.1.11 Different Base Classes for Contracts

    If your base classes differ between contracts, you can tell the Spring Cloud Contract plugin which class should get extended by the autogenerated tests. You have two options:

    • Follow a convention by providing the packageWithBaseClasses
    • Provide explicit mapping via baseClassMappings

    By Convention

    The convention is such that if you have a contract under (for example) src/test/resources/contract/foo/bar/baz/ and set the value of the packageWithBaseClasses property to com.example.base, then Spring Cloud Contract @@ -6980,7 +7177,7 @@ baseClassMappings { - src/test/resources/contract/foo/

    By providing the baseClassForTests, we have a fallback in case mapping did not succeed. (You could also provide the packageWithBaseClasses as a fallback.) That way, the tests generated from src/test/resources/contract/com/ contracts extend the -com.example.ComBase, whereas the rest of the tests extend com.example.FooBase.

    84.1.12 Invoking Generated Tests

    To ensure that the provider side is compliant with defined contracts, you need to invoke:

    ./gradlew generateContractTests test

    84.1.13 Spring Cloud Contract Verifier on the Consumer Side

    In a consuming service, you need to configure the Spring Cloud Contract Verifier plugin +com.example.ComBase, whereas the rest of the tests extend com.example.FooBase.

    85.1.12 Invoking Generated Tests

    To ensure that the provider side is compliant with defined contracts, you need to invoke:

    ./gradlew generateContractTests test

    85.1.13 Spring Cloud Contract Verifier on the Consumer Side

    In a consuming service, you need to configure the Spring Cloud Contract Verifier plugin in exactly the same way as in case of provider. If you do not want to use Stub Runner then you need to copy contracts stored in src/test/resources/contracts and generate WireMock JSON stubs using:

    ./gradlew generateClientStubs
    [Note]Note

    The stubsOutputDir option has to be set for stub generation to work.

    When present, JSON stubs can be used in automated tests of consuming a service.

    @ContextConfiguration(loader == SpringApplicationContextLoader, classes == Application)
    @@ -7004,8 +7201,8 @@ WireMock JSON stubs using:

    ./gradlew generateClie
     	loanApplication.rejectionReason == null
      }
     }

    LoanApplication makes a call to FraudDetection service. This request is handled by a -WireMock server configured with stubs generated by Spring Cloud Contract Verifier.

    85.2 Maven Project

    To learn how to set up the Maven project for Spring Cloud Contract Verifier, read the +following sections:

    85.2.1 Add maven plugin

    Add the Spring Cloud Contract BOM in a fashion similar to this:

    <dependencyManagement>
     	<dependencies>
     		<dependency>
     			<groupId>org.springframework.cloud</groupId>
    @@ -7025,7 +7222,7 @@ following sections:

      </configuration> </plugin>

    You can read more in the Spring -Cloud Contract Maven Plugin Documentation.

    84.2.2 Maven and Rest Assured 2.0

    By default, Rest Assured 3.x is added to the classpath. However, you can use Rest +Cloud Contract Maven Plugin Documentation.

    85.2.2 Maven and Rest Assured 2.0

    By default, Rest Assured 3.x is added to the classpath. However, you can use Rest Assured 2.x by adding it to the plugins classpath, as shown here:

    <plugin>
         <groupId>org.springframework.cloud</groupId>
         <artifactId>spring-cloud-contract-maven-plugin</artifactId>
    @@ -7071,7 +7268,7 @@ Assured 2.x by adding it to the plugins classpath, as shown here:

    That way, the plugin automatically sees that Rest Assured 3.x is present on the classpath -and modifies the imports accordingly.

    84.2.3 Snapshot versions for Maven

    For Snapshot and Milestone versions, you have to add the following section to your +and modifies the imports accordingly.

    85.2.3 Snapshot versions for Maven

    For Snapshot and Milestone versions, you have to add the following section to your pom.xml, as shown here:

    <repositories>
     	<repository>
     		<id>spring-snapshots</id>
    @@ -7123,16 +7320,16 @@ and modifies the imports accordingly.

    <enabled>false</enabled> </snapshots> </pluginRepository> -</pluginRepositories>

    84.2.4 Add stubs

    By default, Spring Cloud Contract Verifier is looking for stubs in the +</pluginRepositories>

    85.2.4 Add stubs

    By default, Spring Cloud Contract Verifier is looking for stubs in the src/test/resources/contracts directory. The directory containing stub definitions is treated as a class name, and each stub definition is treated as a single test. We assume that it contains at least one directory to be used as test class name. If there is more than one level of nested directories, all except the last one is used as package name. For example, with following structure:

    src/test/resources/contracts/myservice/shouldCreateUser.groovy
     src/test/resources/contracts/myservice/shouldReturnUser.groovy

    Spring Cloud Contract Verifier creates a test class named defaultBasePackage.MyService -with two methods

    • shouldCreateUser()
    • shouldReturnUser()

    84.2.5 Run plugin

    The plugin goal generateTests is assigned to be invoked in the phase called +with two methods

    • shouldCreateUser()
    • shouldReturnUser()

    85.2.5 Run plugin

    The plugin goal generateTests is assigned to be invoked in the phase called generate-test-sources. If you want it to be part of your build process, you need not do -anything. If you just want to generate tests, invoke the generateTests goal.

    84.2.6 Configure plugin

    To change the default configuration, just add a configuration section to the plugin +anything. If you just want to generate tests, invoke the generateTests goal.

    85.2.6 Configure plugin

    To change the default configuration, just add a configuration section to the plugin definition or the execution definition, as shown here:

    <plugin>
         <groupId>org.springframework.cloud</groupId>
         <artifactId>spring-cloud-contract-maven-plugin</artifactId>
    @@ -7149,7 +7346,7 @@ definition or the execution definition, as shown he
             <basePackageForTests>org.springframework.cloud.verifier.twitter.place</basePackageForTests>
             <baseClassForTests>org.springframework.cloud.verifier.twitter.place.BaseMockMvcSpec</baseClassForTests>
         </configuration>
    -</plugin>

    84.2.7 Configuration Options

    • testMode: Defines the mode for acceptance tests. By default, the mode is MockMvc, +</plugin>

    85.2.7 Configuration Options

    • testMode: Defines the mode for acceptance tests. By default, the mode is MockMvc, which is based on Spring’s MockMvc. It can also be changed to JaxRsClient or to Explicit for real HTTP calls.
    • basePackageForTests: Specifies the base package for all generated tests. If not set, the value is picked from baseClassForTests’s package and from `packageWithBaseClasses. @@ -7176,7 +7373,7 @@ the following options:

        groupid/artifactid where gropuid is slash separated.
      • contractsMode: Picks the mode in which stubs will be found and registered
      • contractsSnapshotCheckSkip: If true then will not assert whether a stub / contract JAR was downloaded from local or remote location
      • contractsRepositoryUrl: URL to a repo with the artifacts that have contracts. If it is not provided, use the current Maven ones.
      • contractsRepositoryUsername: The user name to be used to connect to the repo with contracts.
      • contractsRepositoryPassword: The password to be used to connect to the repo with contracts.
      • contractsRepositoryProxyHost: The proxy host to be used to connect to the repo with contracts.
      • contractsRepositoryProxyPort: The proxy port to be used to connect to the repo with contracts.

      We cache only non-snapshot, explicitly provided versions (for example -+ or 1.0.0.BUILD-SNAPSHOT won’t get cached). By default, this feature is turned on.

    84.2.8 Single Base Class for All Tests

    When using Spring Cloud Contract Verifier in default MockMvc, you need to create a base ++ or 1.0.0.BUILD-SNAPSHOT won’t get cached). By default, this feature is turned on.

    85.2.8 Single Base Class for All Tests

    When using Spring Cloud Contract Verifier in default MockMvc, you need to create a base specification for all generated acceptance tests. In this class, you need to point to an endpoint, which should be verified.

    package org.mycompany.tests
     
    @@ -7191,7 +7388,7 @@ endpoint, which should be verified.

    If you use Explicit mode, you can use a base class to initialize the whole tested app similarly, as you might find in regular integration tests. If you use the JAXRSCLIENT mode, this base class should also contain a protected WebTarget webTarget field. Right -now, the only option to test the JAX-RS API is to start a web server.

    84.2.9 Different base classes for contracts

    If your base classes differ between contracts, you can tell the Spring Cloud Contract +now, the only option to test the JAX-RS API is to start a web server.

    85.2.9 Different base classes for contracts

    If your base classes differ between contracts, you can tell the Spring Cloud Contract plugin which class should get extended by the autogenerated tests. You have two options:

    • Follow a convention by providing the packageWithBaseClasses
    • provide explicit mapping via baseClassMappings

    By Convention

    The convention is such that if you have a contract under (for example) src/test/resources/contract/foo/bar/baz/ and set the value of the packageWithBaseClasses property to com.example.base, then Spring Cloud Contract @@ -7224,7 +7421,7 @@ name of the base class for the matched contract. You have to provide a list call * src/test/resources/contract/foo/

    By providing the baseClassForTests, we have a fallback in case mapping did not succeed. (You can also provide the packageWithBaseClasses as a fallback.) That way, the tests generated from src/test/resources/contract/com/ contracts extend the -com.example.ComBase, whereas the rest of the tests extend com.example.FooBase.

    84.2.10 Invoking generated tests

    The Spring Cloud Contract Maven Plugin generates verification code in a directory called +com.example.ComBase, whereas the rest of the tests extend com.example.FooBase.

    85.2.10 Invoking generated tests

    The Spring Cloud Contract Maven Plugin generates verification code in a directory called /generated-test-sources/contractVerifier and attaches this directory to testCompile goal.

    For Groovy Spock code, use the following:

    <plugin>
     	<groupId>org.codehaus.gmavenplus</groupId>
    @@ -7254,7 +7451,7 @@ goal.

    For Groovy Spock code, use the following:

    </testSources>
     	</configuration>
     </plugin>

    To ensure that provider side is compliant with defined contracts, you need to invoke -mvn generateTest test.

    84.2.11 Maven Plugin and STS

    If you see the following exception while using STS:

    STS Exception

    When you click on the error marker you should see something like this:

     plugin:1.1.0.M1:convert:default-convert:process-test-resources) org.apache.maven.plugin.PluginExecutionException: Execution default-convert of goal org.springframework.cloud:spring-
    +mvn generateTest test.

    85.2.11 Maven Plugin and STS

    If you see the following exception while using STS:

    STS Exception

    When you click on the error marker you should see something like this:

     plugin:1.1.0.M1:convert:default-convert:process-test-resources) org.apache.maven.plugin.PluginExecutionException: Execution default-convert of goal org.springframework.cloud:spring-
      cloud-contract-maven-plugin:1.1.0.M1:convert failed. at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:145) at
      org.eclipse.m2e.core.internal.embedder.MavenImpl.execute(MavenImpl.java:331) at org.eclipse.m2e.core.internal.embedder.MavenImpl$11.call(MavenImpl.java:1362) at
     ...
    @@ -7291,7 +7488,7 @@ goal.

    For Groovy Spock code, use the following:

    </plugin>
             </plugins>
         </pluginManagement>
    -</build>

    84.3 Stubs and Transitive Dependencies

    The Maven and Gradle plugin that add the tasks that create the stubs jar for you. One +</build>

    85.3 Stubs and Transitive Dependencies

    The Maven and Gradle plugin that add the tasks that create the stubs jar for you. One problem that arises is that, when reusing the stubs, you can mistakenly import all of that stub’s dependencies. When building a Maven artifact, even though you have a couple of different jars, all of them share one pom:

    ├── github-webhook-0.0.1.BUILD-20160903.075506-1-stubs.jar
    @@ -7308,7 +7505,7 @@ when you include the github-webhook stubs in anothe
     dependency gets downloaded by Stub Runner) then, since all of the dependencies are
     optional, they will not get downloaded.

    Create a separate artifactid for the stubs

    If you create a separate artifactid, then you can set it up in whatever way you wish. For example, you might decide to have no dependencies at all.

    Exclude dependencies on the consumer side

    As a consumer, if you add the stub dependency to your classpath, you can explicitly -exclude the unwanted dependencies.

    84.4 CI Server setup

    When fetching stubs / contracts in a CI, shared environment, what might happen is that +exclude the unwanted dependencies.

    85.4 CI Server setup

    When fetching stubs / contracts in a CI, shared environment, what might happen is that both the producer and the consumer reuse the same local Maven repository. Due to this, the framework, responsible for downloading a stub JAR from remote location, can’t decide which JAR should be picked, local or remote one. That caused @@ -7316,7 +7513,7 @@ the "The artifact was found in the local repository but yo stated that it should be downloaded from a remote one" exception and failed the build.

    For such cases we’re introducing the property and plugin setup mechanism:

    • via stubrunner.snapshot-check-skip system property
    • via STUBRUNNER_SNAPSHOT_CHECK_SKIP environment variable

    if either of these values is set to true, then the stub downloader will not verify the origin of the downloaded JAR.

    For the plugins you need to set the contractsSnapshotSkipCheck property -to true.

    84.5 Scenarios

    You can handle scenarios with Spring Cloud Contract Verifier. All you need to do is to +to true.

    85.5 Scenarios

    You can handle scenarios with Spring Cloud Contract Verifier. All you need to do is to stick to the proper naming convention while creating your contracts. The convention requires including an order number followed by an underscore. This will work regardles of whether you’re working with YAML or Groovy. Example:

    my_contracts_dir\
    @@ -7325,10 +7522,10 @@ requires including an order number followed by an underscore. This will work reg
         2_showCart.groovy
         3_logout.groovy

    Such a tree causes Spring Cloud Contract Verifier to generate WireMock’s scenario with a name of scenario1 and the three following steps:

    1. login marked as Started pointing to…​
    2. showCart marked as Step1 pointing to…​
    3. logout marked as Step2 which will close the scenario.

    More details about WireMock scenarios can be found at -http://wiremock.org/stateful-behaviour.html

    Spring Cloud Contract Verifier also generates tests with a guaranteed order of execution.

    84.6 Docker Project

    We’re publishing a springcloud/spring-cloud-contract Docker image +http://wiremock.org/stateful-behaviour.html

    Spring Cloud Contract Verifier also generates tests with a guaranteed order of execution.

    85.6 Docker Project

    We’re publishing a springcloud/spring-cloud-contract Docker image that contains a project that will generate tests and execute them in EXPLICIT mode against a running application.

    [Tip]Tip

    The EXPLICIT mode means that the tests generated from contracts will send -real requests and not the mocked ones.

    84.6.1 Short intro to Maven, JARs and Binary storage

    Since the Docker image can be used by non JVM projects, it’s good to +real requests and not the mocked ones.

    85.6.1 Short intro to Maven, JARs and Binary storage

    Since the Docker image can be used by non JVM projects, it’s good to explain the basic terms behind Spring Cloud Contract packaging defaults.

    Part of the following definitions were taken from the Maven Glossary

    • Project: Maven thinks in terms of projects. Everything that you will build are projects. Those projects follow a well defined “Project Object Model”. Projects can depend on other projects, @@ -7355,7 +7552,7 @@ like them to be available for others to download / reference or reuse. In case of the JVM world those artifacts would be JARs, for Ruby these are gems and for Docker those would be Docker images. You can store those artifacts in a manager. Examples of such managers can be Artifactory -or Nexus.

    84.6.2 How it works

    The image searches for contracts under the /contracts folder. +or Nexus.

    85.6.2 How it works

    The image searches for contracts under the /contracts folder. The output from running the tests will be available under /spring-cloud-contract/build folder (it’s useful for debugging purposes).

    It’s enough for you to mount your contracts, pass the environment variables @@ -7363,8 +7560,8 @@ purposes).

    It’s enough for you to mount your contracts, pass the env your running application, to the Artifact manager instance etc.

    • PROJECT_GROUP - your project’s group id. Defaults to com.example.
    • PROJECT_VERSION - your project’s version. Defaults to 0.0.1-SNAPSHOT
    • PROJECT_NAME - artifact id. Defaults to example
    • REPO_WITH_BINARIES_URL - URL of your Artifact Manager. Defaults to http://localhost:8081/artifactory/libs-release-local which is the default URL of Artifactory running locally
    • REPO_WITH_BINARIES_USERNAME - (optional) username when the Artifact Manager is secured
    • REPO_WITH_BINARIES_PASSWORD - (optional) password when the Artifact Manager is secured
    • PUBLISH_ARTIFACTS - if set to true then will publish artifact to binary storage. Defaults to true.

    These environment variables are used when tests are executed:

    • APPLICATION_BASE_URL - url against which tests should be executed. Remember that it has to be accessible from the Docker container (e.g. localhost -will not work)
    • APPLICATION_USERNAME - (optional) username for basic authentication to your application
    • APPLICATION_PASSWORD - (optional) password for basic authentication to your application

    84.6.3 Example of usage

    Let’s take a look at a simple MVC application

    $ git clone https://github.com/spring-cloud-samples/spring-cloud-contract-nodejs
    -$ cd bookstore

    The contracts are available under /contracts folder.

    84.6.4 Server side (nodejs)

    Since we want to run tests, we could just execute:

    $ npm test

    however, for learning purposes, let’s split it into pieces:

    # Stop docker infra (nodejs, artifactory)
    +will not work)
  • APPLICATION_USERNAME - (optional) username for basic authentication to your application
  • APPLICATION_PASSWORD - (optional) password for basic authentication to your application
  • 85.6.3 Example of usage

    Let’s take a look at a simple MVC application

    $ git clone https://github.com/spring-cloud-samples/spring-cloud-contract-nodejs
    +$ cd bookstore

    The contracts are available under /contracts folder.

    85.6.4 Server side (nodejs)

    Since we want to run tests, we could just execute:

    $ npm test

    however, for learning purposes, let’s split it into pieces:

    # Stop docker infra (nodejs, artifactory)
     $ ./stop_infra.sh
     # Start docker infra (nodejs, artifactory)
     $ ./setup_infra.sh
    @@ -7396,9 +7593,9 @@ stateful situation

      • the contracts will be taken from /contracts folder.
      • the output of the test execution is available under node_modules/spring-cloud-contract/output.
  • the stubs will be uploaded to Artifactory. You can check them out under http://localhost:8081/artifactory/libs-release-local/com/example/bookstore/0.0.1.RELEASE/ . -The stubs will be here http://localhost:8081/artifactory/libs-release-local/com/example/bookstore/0.0.1.RELEASE/bookstore-0.0.1.RELEASE-stubs.jar.
  • To see how the client side looks like check out the Section 86.9, “Stub Runner Docker” section.

    85. Spring Cloud Contract Verifier Messaging

    Spring Cloud Contract Verifier lets you verify applications that uses messaging as a +The stubs will be here http://localhost:8081/artifactory/libs-release-local/com/example/bookstore/0.0.1.RELEASE/bookstore-0.0.1.RELEASE-stubs.jar.

    To see how the client side looks like check out the Section 87.9, “Stub Runner Docker” section.

    86. Spring Cloud Contract Verifier Messaging

    Spring Cloud Contract Verifier lets you verify applications that uses messaging as a means of communication. All of the integrations shown in this document work with Spring, -but you can also create one of your own and use that.

    85.1 Integrations

    You can use one of the following four integration configurations:

    • Apache Camel
    • Spring Integration
    • Spring Cloud Stream
    • Spring AMQP

    Since we use Spring Boot, if you have added one of these libraries to the classpath, all +but you can also create one of your own and use that.

    86.1 Integrations

    You can use one of the following four integration configurations:

    • Apache Camel
    • Spring Integration
    • Spring Cloud Stream
    • Spring AMQP

    Since we use Spring Boot, if you have added one of these libraries to the classpath, all the messaging configuration is automatically set up.

    [Important]Important

    Remember to put @AutoConfigureMessageVerifier on the base class of your generated tests. Otherwise, messaging part of Spring Cloud Contract Verifier does not work.

    [Important]Important

    If you want to use Spring Cloud Stream, remember to add a dependency on @@ -7410,7 +7607,7 @@ work.

    </dependency>

    Gradle. 

    testCompile "org.springframework.cloud:spring-cloud-stream-test-support"

    -

    85.2 Manual Integration Testing

    The main interface used by the tests is +

    86.2 Manual Integration Testing

    The main interface used by the tests is org.springframework.cloud.contract.verifier.messaging.MessageVerifier. It defines how to send and receive messages. You can create your own implementation to achieve the same goal.

    In a test, you can inject a ContractVerifierMessageExchange to send and receive @@ -7424,14 +7621,14 @@ Here’s an example:

    private MessageVerifier verifier;
       ...
     }
    [Note]Note

    If your tests require stubs as well, then @AutoConfigureStubRunner includes the -messaging configuration, so you only need the one annotation.

    85.3 Publisher-Side Test Generation

    Having the input or outputMessage sections in your DSL results in creation of tests +messaging configuration, so you only need the one annotation.

    86.3 Publisher-Side Test Generation

    Having the input or outputMessage sections in your DSL results in creation of tests on the publisher’s side. By default, JUnit tests are created. However, there is also a possibility to create Spock tests.

    There are 3 main scenarios that we should take into consideration:

    • Scenario 1: There is no input message that produces an output message. The output message is triggered by a component inside the application (for example, scheduler).
    • Scenario 2: The input message triggers an output message.
    • Scenario 3: The input message is consumed and there is no output message.
    [Important]Important

    The destination passed to messageFrom or sentTo can have different meanings for different messaging implementations. For Stream and Integration it is first resolved as a destination of a channel. Then, if there is no such destination it is resolved as a channel name. For Camel, that’s a certain component (for example, -jms).

    85.3.1 Scenario 1: No Input Message

    Here is an example for Camel. For the given contract:

    Groovy DSL.  +jms).

    86.3.1 Scenario 1: No Input Message

    Here is an example for Camel. For the given contract:

    Groovy DSL. 

    def contractDsl = Contract.make {
     	label 'some_label'
     	input {
    @@ -7484,7 +7681,7 @@ outputMessage:
       DocumentContext parsedJson = JsonPath.parse(contractVerifierObjectMapper.writeValueAsString(response.payload))
       assertThatJson(parsedJson).field("bookName").isEqualTo("foo")
     
    -'''

    85.3.2 Scenario 2: Output Triggered by Input

    Here is an example for Camel. For the given contract:

    Groovy DSL.  +'''

    86.3.2 Scenario 2: Output Triggered by Input

    Here is an example for Camel. For the given contract:

    Groovy DSL. 

    def contractDsl = Contract.make {
     	label 'some_label'
     	input {
    @@ -7555,7 +7752,7 @@ then:
     and:
        DocumentContext parsedJson = JsonPath.parse(contractVerifierObjectMapper.writeValueAsString(response.payload))
        assertThatJson(parsedJson).field("bookName").isEqualTo("foo")
    -"""

    85.3.3 Scenario 3: No Output Message

    Here is an example for Camel. For the given contract:

    Groovy DSL.  +"""

    86.3.3 Scenario 3: No Output Message

    Here is an example for Camel. For the given contract:

    Groovy DSL. 

    def contractDsl = Contract.make {
     	label 'some_label'
     	input {
    @@ -7603,7 +7800,7 @@ when:
     then:
     	 noExceptionThrown()
     	 bookWasDeleted()
    -'''

    85.4 Consumer Stub Generation

    Unlike the HTTP part, in messaging, we need to publish the Groovy DSL inside the JAR with +'''

    86.4 Consumer Stub Generation

    Unlike the HTTP part, in messaging, we need to publish the Groovy DSL inside the JAR with a stub. Then it is parsed on the consumer side and proper stubbed routes are created.

    For more information, see the Stub Runner Messaging sections.

    Maven.  @@ -7655,11 +7852,11 @@ publishing { } } }

    -

    86. Spring Cloud Contract Stub Runner

    One of the issues that you might encounter while using Spring Cloud Contract Verifier is +

    87. Spring Cloud Contract Stub Runner

    One of the issues that you might encounter while using Spring Cloud Contract Verifier is passing the generated WireMock JSON stubs from the server side to the client side (or to various clients). The same takes place in terms of client-side generation for messaging.

    Copying the JSON files and setting the client side for messaging manually is out of the question. That is why we introduced Spring Cloud Contract Stub Runner. It can -automatically download and run the stubs for you.

    86.1 Snapshot versions

    Add the additional snapshot repository to your build.gradle file to use snapshot +automatically download and run the stubs for you.

    87.1 Snapshot versions

    Add the additional snapshot repository to your build.gradle file to use snapshot versions, which are automatically uploaded after every successful build:

    Maven. 

    <repositories>
     	<repository>
    @@ -7722,7 +7919,7 @@ versions, which are automatically uploaded after every successful build:

    "http://repo.spring.io/milestone" } maven { url "http://repo.spring.io/release" } }

    -

    86.2 Publishing Stubs as JARs

    The easiest approach would be to centralize the way stubs are kept. For example, you can +

    87.2 Publishing Stubs as JARs

    The easiest approach would be to centralize the way stubs are kept. For example, you can keep them as jars in a Maven repository.

    [Tip]Tip

    For both Maven and Gradle, the setup comes ready to work. However, you can customize it if you want to.

    Maven. 

    <!-- First disable the default jar setup in the properties section -->
    @@ -7810,9 +8007,9 @@ publishing {
     		}
     	}
     }

    -

    86.3 Stub Runner Core

    Runs stubs for service collaborators. Treating stubs as contracts of services allows to use stub-runner as an implementation of +

    87.3 Stub Runner Core

    Runs stubs for service collaborators. Treating stubs as contracts of services allows to use stub-runner as an implementation of Consumer Driven Contracts.

    Stub Runner allows you to automatically download the stubs of the provided dependencies (or pick those from the classpath), start WireMock servers for them and feed them with proper stub definitions. -For messaging, special stub routes are defined.

    86.3.1 Retrieving stubs

    You can pick the following options of acquiring stubs

    • Aether based solution that downloads JARs with stubs from Artifactory / Nexus
    • Classpath scanning solution that searches classpath via pattern to retrieve stubs
    • Write your own implementation of the org.springframework.cloud.contract.stubrunner.StubDownloaderBuilder for full customization

    The latter example is described in the Custom Stub Runner section.

    Stub downloading

    You can control the stub downloading via the stubsMode switch. It picks value from the +For messaging, special stub routes are defined.

    87.3.1 Retrieving stubs

    You can pick the following options of acquiring stubs

    • Aether based solution that downloads JARs with stubs from Artifactory / Nexus
    • Classpath scanning solution that searches classpath via pattern to retrieve stubs
    • Write your own implementation of the org.springframework.cloud.contract.stubrunner.StubDownloaderBuilder for full customization

    The latter example is described in the Custom Stub Runner section.

    Stub downloading

    You can control the stub downloading via the stubsMode switch. It picks value from the StubRunnerProperties.StubsMode enum. You can use the following options

    • StubRunnerProperties.StubsMode.CLASSPATH (default value) - will pick stubs from the classpath
    • StubRunnerProperties.StubsMode.LOCAL - will pick stubs from a local storage (e.g. .m2)
    • StubRunnerProperties.StubsMode.REMOTE - will pick stubs from a remote location

    Example:

    @AutoConfigureStubRunner(repositoryRoot="http://foo.bar", ids = "com.example:beer-api-producer:+:stubs:8095", stubsMode = StubRunnerProperties.StubsMode.LOCAL)

    Classpath scanning

    If you set the stubsMode property to StubRunnerProperties.StubsMode.CLASSPATH (or set nothing since CLASSPATH is the default value) then classpath will get scanned. Let’s look at the following example:

    @AutoConfigureStubRunner(ids = {
    @@ -7871,7 +8068,7 @@ structure in your stubs jar.

    └──
                     │       └── contract2.groovy
                     └── mappings
                         └── mapping.json

    By maintaining this structure classpath gets scanned and you can profit from the messaging / -HTTP stubs without the need to download artifacts.

    86.3.2 Running stubs

    Limitations

    [Important]Important

    There might be a problem with StubRunner shutting down ports between tests. You might +HTTP stubs without the need to download artifacts.

    87.3.2 Running stubs

    Limitations

    [Important]Important

    There might be a problem with StubRunner shutting down ports between tests. You might have a situation in which you get port conflicts. As long as you use the same context across tests everything works fine. But when the context are different (e.g. different stubs or different profiles) then you have to either use @DirtiesContext to shut down the stub servers, or else run them on @@ -7938,7 +8135,7 @@ mappings available for the given server:

    ["uuid" : "f9152eb9-bf77-4c38-8289-90be7d10d0d7"
     },
     ...
    -]

    Messaging Stubs

    Depending on the provided Stub Runner dependency and the DSL the messaging routes are automatically set up.

    86.4 Stub Runner JUnit Rule

    Stub Runner comes with a JUnit rule thanks to which you can very easily download and run stubs for given group and artifact id:

    @ClassRule public static StubRunnerRule rule = new StubRunnerRule()
    +]

    Messaging Stubs

    Depending on the provided Stub Runner dependency and the DSL the messaging routes are automatically set up.

    87.4 Stub Runner JUnit Rule

    Stub Runner comes with a JUnit rule thanks to which you can very easily download and run stubs for given group and artifact id:

    @ClassRule public static StubRunnerRule rule = new StubRunnerRule()
     		.repoRoot(repoRoot())
     		.downloadStub("org.springframework.cloud.contract.verifier.stubs", "loanIssuance")
     		.downloadStub("org.springframework.cloud.contract.verifier.stubs:fraudDetectionServer");

    After that rule gets executed Stub Runner connects to your Maven repository and for the given list of dependencies tries to:

    • download them
    • cache them locally
    • unzip them to a temporary folder
    • start a WireMock server for each Maven dependency on a random port from the provided range of ports / provided port
    • feed the WireMock server with all JSON files that are valid WireMock definitions
    • can also send messages (remember to pass an implementation of MessageVerifier interface)

    Stub Runner uses Eclipse Aether mechanism to download the Maven dependencies. @@ -8022,14 +8219,14 @@ def 'should outp then(httpGet(rule.findStubUrl("fraudDetectionServer").toString() + "/name")).isEqualTo("fraudDetectionServer"); }

    Check the Common properties for JUnit and Spring for more information on how to apply global configuration of Stub Runner.

    [Important]Important

    To use the JUnit rule together with messaging you have to provide an implementation of the MessageVerifier interface to the rule builder (e.g. rule.messageVerifier(new MyMessageVerifier())). -If you don’t do this then whenever you try to send a message an exception will be thrown.

    86.4.1 Maven settings

    The stub downloader honors Maven settings for a different local repository folder. -Authentication details for repositories and profiles are currently not taken into account, so you need to specify it using the properties mentioned above.

    86.4.2 Providing fixed ports

    You can also run your stubs on fixed ports. You can do it in two different ways. One is to pass it in the properties, and the other via fluent API of -JUnit rule.

    86.4.3 Fluent API

    When using the StubRunnerRule you can add a stub to download and then pass the port for the last downloaded stub.

    @ClassRule public static StubRunnerRule rule = new StubRunnerRule()
    +If you don’t do this then whenever you try to send a message an exception will be thrown.

    87.4.1 Maven settings

    The stub downloader honors Maven settings for a different local repository folder. +Authentication details for repositories and profiles are currently not taken into account, so you need to specify it using the properties mentioned above.

    87.4.2 Providing fixed ports

    You can also run your stubs on fixed ports. You can do it in two different ways. One is to pass it in the properties, and the other via fluent API of +JUnit rule.

    87.4.3 Fluent API

    When using the StubRunnerRule you can add a stub to download and then pass the port for the last downloaded stub.

    @ClassRule public static StubRunnerRule rule = new StubRunnerRule()
     		.repoRoot(repoRoot())
     		.downloadStub("org.springframework.cloud.contract.verifier.stubs", "loanIssuance")
     		.withPort(12345)
     		.downloadStub("org.springframework.cloud.contract.verifier.stubs:fraudDetectionServer:12346");

    You can see that for this example the following test is valid:

    then(rule.findStubUrl("loanIssuance")).isEqualTo(URI.create("http://localhost:12345").toURL());
    -then(rule.findStubUrl("fraudDetectionServer")).isEqualTo(URI.create("http://localhost:12346").toURL());

    86.4.4 Stub Runner with Spring

    Sets up Spring configuration of the Stub Runner project.

    By providing a list of stubs inside your configuration file the Stub Runner automatically downloads +then(rule.findStubUrl("fraudDetectionServer")).isEqualTo(URI.create("http://localhost:12346").toURL());

    87.4.4 Stub Runner with Spring

    Sets up Spring configuration of the Stub Runner project.

    By providing a list of stubs inside your configuration file the Stub Runner automatically downloads and registers in WireMock the selected stubs.

    If you want to find the URL of your stubbed dependency you can autowire the StubFinder interface and use its methods as presented below:

    @ContextConfiguration(classes = Config, loader = SpringBootContextLoader)
     @SpringBootTest(properties = [" stubrunner.cloud.enabled=false",
    @@ -8120,7 +8317,7 @@ Below you can find an example of achieving the same result by setting values on
     		stubsMode = StubRunnerProperties.StubsMode.REMOTE,
     		repositoryRoot = "classpath:m2repo/repository/")

    Stub Runner Spring registers environment variables in the following manner for every registered WireMock server. Example for Stub Runner ids - com.example:foo, com.example:bar.

    • stubrunner.runningstubs.foo.port
    • stubrunner.runningstubs.bar.port

    Which you can reference in your code.

    86.5 Stub Runner Spring Cloud

    Stub Runner can integrate with Spring Cloud.

    For real life examples you can check the

    86.5.1 Stubbing Service Discovery

    The most important feature of Stub Runner Spring Cloud is the fact that it’s stubbing

    • DiscoveryClient
    • Ribbon ServerList

    that means that regardless of the fact whether you’re using Zookeeper, Consul, Eureka or anything else, you don’t need that in your tests. + com.example:foo, com.example:bar.

    • stubrunner.runningstubs.foo.port
    • stubrunner.runningstubs.bar.port

    Which you can reference in your code.

    87.5 Stub Runner Spring Cloud

    Stub Runner can integrate with Spring Cloud.

    For real life examples you can check the

    87.5.1 Stubbing Service Discovery

    The most important feature of Stub Runner Spring Cloud is the fact that it’s stubbing

    • DiscoveryClient
    • Ribbon ServerList

    that means that regardless of the fact whether you’re using Zookeeper, Consul, Eureka or anything else, you don’t need that in your tests. We’re starting WireMock instances of your dependencies and we’re telling your application whenever you’re using Feign, load balanced RestTemplate or DiscoveryClient directly, to call those stubbed servers instead of calling the real Service Discovery tool.

    For example this test will pass

    def 'should make service discovery work'() {
     	expect: 'WireMocks are running'
    @@ -8139,15 +8336,15 @@ via a static block like presented below (example for Eureka)

    static {
             System.setProperty("eureka.client.enabled", "false");
             System.setProperty("spring.cloud.config.failFast", "false");
    -    }

    86.5.2 Additional Configuration

    You can match the artifactId of the stub with the name of your app by using the stubrunner.idsToServiceIds: map. + }

    87.5.2 Additional Configuration

    You can match the artifactId of the stub with the name of your app by using the stubrunner.idsToServiceIds: map. You can disable Stub Runner Ribbon support by providing: stubrunner.cloud.ribbon.enabled equal to false You can disable Stub Runner support by providing: stubrunner.cloud.enabled equal to false

    [Tip]Tip

    By default all service discovery will be stubbed. That means that regardless of the fact if you have an existing DiscoveryClient its results will be ignored. However, if you want to reuse it, just set stubrunner.cloud.delegate.enabled to true and then your existing DiscoveryClient results will be - merged with the stubbed ones.

    86.6 Stub Runner Boot Application

    Spring Cloud Contract Stub Runner Boot is a Spring Boot application that exposes REST endpoints to + merged with the stubbed ones.

    87.6 Stub Runner Boot Application

    Spring Cloud Contract Stub Runner Boot is a Spring Boot application that exposes REST endpoints to trigger the messaging labels and to access started WireMock servers.

    One of the use-cases is to run some smoke (end to end) tests on a deployed application. You can check out the Spring Cloud Pipelines -project for more information.

    86.6.1 How to use it?

    Stub Runner Server

    Just add the

    compile "org.springframework.cloud:spring-cloud-starter-stub-runner"

    Annotate a class with @EnableStubRunnerServer, build a fat-jar and you’re ready to go!

    For the properties check the Stub Runner Spring section.

    Stub Runner Server Fat Jar

    You can download a standalone JAR from Maven (for example, for version 1.2.3.RELEASE), as follows:

    $ wget -O stub-runner.jar 'https://search.maven.org/remote_content?g=org.springframework.cloud&a=spring-cloud-contract-stub-runner-boot&v=1.2.3.RELEASE'
    +project for more information.

    87.6.1 How to use it?

    Stub Runner Server

    Just add the

    compile "org.springframework.cloud:spring-cloud-starter-stub-runner"

    Annotate a class with @EnableStubRunnerServer, build a fat-jar and you’re ready to go!

    For the properties check the Stub Runner Spring section.

    Stub Runner Server Fat Jar

    You can download a standalone JAR from Maven (for example, for version 1.2.3.RELEASE), as follows:

    $ wget -O stub-runner.jar 'https://search.maven.org/remote_content?g=org.springframework.cloud&a=spring-cloud-contract-stub-runner-boot&v=1.2.3.RELEASE'
     $ java -jar stub-runner.jar --stubrunner.ids=... --stubrunner.repositoryRoot=...

    Spring Cloud CLI

    Starting from 1.4.0.RELEASE version of the Spring Cloud CLI project you can start Stub Runner Boot by executing spring cloud stubrunner.

    In order to pass the configuration just create a stubrunner.yml file in the current working directory or a subdirectory called config or in ~/.spring-cloud. The file could look like this @@ -8157,7 +8354,7 @@ or a subdirectory called config or in spring cloud stubrunner from your terminal window to start -the Stub Runner server. It will be available at port 8750.

    86.6.2 Endpoints

    HTTP

    • GET /stubs - returns a list of all running stubs in ivy:integer notation
    • GET /stubs/{ivy} - returns a port for the given ivy notation (when calling the endpoint ivy can also be artifactId only)

    Messaging

    For Messaging

    • GET /triggers - returns a list of all running labels in ivy : [ label1, label2 …​] notation
    • POST /triggers/{label} - executes a trigger with label
    • POST /triggers/{ivy}/{label} - executes a trigger with label for the given ivy notation (when calling the endpoint ivy can also be artifactId only)

    86.6.3 Example

    @ContextConfiguration(classes = StubRunnerBoot, loader = SpringBootContextLoader)
    +the Stub Runner server. It will be available at port 8750.

    87.6.2 Endpoints

    HTTP

    • GET /stubs - returns a list of all running stubs in ivy:integer notation
    • GET /stubs/{ivy} - returns a port for the given ivy notation (when calling the endpoint ivy can also be artifactId only)

    Messaging

    For Messaging

    • GET /triggers - returns a list of all running labels in ivy : [ label1, label2 …​] notation
    • POST /triggers/{label} - executes a trigger with label
    • POST /triggers/{ivy}/{label} - executes a trigger with label for the given ivy notation (when calling the endpoint ivy can also be artifactId only)

    87.6.3 Example

    @ContextConfiguration(classes = StubRunnerBoot, loader = SpringBootContextLoader)
     @SpringBootTest(properties = "spring.cloud.zookeeper.enabled=false")
     @ActiveProfiles("test")
     class StubRunnerBootSpec extends Specification {
    @@ -8243,7 +8440,7 @@ the Stub Runner server. It will be available at port 8750<
     			e.message.contains("org.springframework.cloud.contract.verifier.stubs:bootService:0.0.1-SNAPSHOT:stubs=")
     	}
     
    -}

    86.6.4 Stub Runner Boot with Service Discovery

    One of the possibilities of using Stub Runner Boot is to use it as a feed of stubs for "smoke-tests". What does it mean? +}

    87.6.4 Stub Runner Boot with Service Discovery

    One of the possibilities of using Stub Runner Boot is to use it as a feed of stubs for "smoke-tests". What does it mean? Let’s assume that you don’t want to deploy 50 microservice to a test environment in order to check if your application is working fine. You’ve already executed a suite of tests during the build process but you would also like to ensure that the packaging of your application is fine. What you can do @@ -8276,7 +8473,7 @@ and we want to have the stub runner feature turned on @Aut (4) - we provide a list of artifactId to serviceId mapping

    That way your deployed application can send requests to started WireMock servers via the service discovery. Most likely points 1-3 could be set by default in application.yml cause they are not likely to change. That way you can provide only the list of stubs to download whenever you start -the Stub Runner Boot.

    86.7 Stubs Per Consumer

    There are cases in which 2 consumers of the same endpoint want to have 2 different responses.

    [Tip]Tip

    This approach also allows you to immediately know which consumer is using which part of your API. +the Stub Runner Boot.

    87.7 Stubs Per Consumer

    There are cases in which 2 consumers of the same endpoint want to have 2 different responses.

    [Tip]Tip

    This approach also allows you to immediately know which consumer is using which part of your API. You can remove part of a response that your API produces and you can see which of your autogenerated tests fails. If none fails then you can safely delete that part of the response cause nobody is using it.

    Let’s look at the following example for contract defined for the producer called producer. There are 2 consumers: foo-consumer and bar-consumer.

    Consumer foo-service

    request {
    @@ -8331,25 +8528,25 @@ Or set the test as follows:

    foo-consumer in its name (i.e. those from the
     src/test/resources/contracts/foo-consumer/some/contracts/…​ folder) will be allowed to be referenced.

    You can check out issue 224 for more -information about the reasons behind this change.

    86.8 Common

    This section briefly describes common properties, including:

    86.8.1 Common Properties for JUnit and Spring

    You can set repetitive properties by using system properties or Spring configuration +information about the reasons behind this change.

    87.8 Common

    This section briefly describes common properties, including:

    87.8.1 Common Properties for JUnit and Spring

    You can set repetitive properties by using system properties or Spring configuration properties. Here are their names with their default values:

    Property nameDefault valueDescription

    stubrunner.minPort

    10000

    Minimum value of a port for a started WireMock with stubs.

    stubrunner.maxPort

    15000

    Maximum value of a port for a started WireMock with stubs.

    stubrunner.repositoryRoot

     

    Maven repo URL. If blank, then call the local maven repo.

    stubrunner.classifier

    stubs

    Default classifier for the stub artifacts.

    stubrunner.stubsMode

    CLASSPATH

    The way you want to fetch and register the stubs

    stubrunner.ids

     

    Array of Ivy notation stubs to download.

    stubrunner.username

     

    Optional username to access the tool that stores the JARs with stubs.

    stubrunner.password

     

    Optional password to access the tool that stores the JARs with stubs.

    stubrunner.stubsPerConsumer

    false

    Set to true if you want to use different stubs for each consumer instead of registering all stubs for every consumer.

    stubrunner.consumerName

     

    If you want to use a stub for each consumer and want to -override the consumer name just change this value.

    86.8.2 Stub Runner Stubs IDs

    You can provide the stubs to download via the stubrunner.ids system property. They +override the consumer name just change this value.

    87.8.2 Stub Runner Stubs IDs

    You can provide the stubs to download via the stubrunner.ids system property. They follow this pattern:

    groupId:artifactId:version:classifier:port

    Note that version, classifier and port are optional.

    • If you do not provide the port, a random one will be picked.
    • If you do not provide the classifier, the default is used. (Note that you can pass an empty classifier this way: groupId:artifactId:version:).
    • If you do not provide the version, then the + will be passed and the latest one is downloaded.

    port means the port of the WireMock server.

    [Important]Important

    Starting with version 1.0.4, you can provide a range of versions that you would like the Stub Runner to take into consideration. You can read more about the Aether versioning -ranges here.

    86.9 Stub Runner Docker

    We’re publishing a spring-cloud/spring-cloud-contract-stub-runner Docker image +ranges here.

    87.9 Stub Runner Docker

    We’re publishing a spring-cloud/spring-cloud-contract-stub-runner Docker image that will start the standalone version of Stub Runner.

    If you want to learn more about the basics of Maven, artifact ids, -group ids, classifiers and Artifact Managers, just click here Section 84.6, “Docker Project”.

    86.9.1 How to use it

    Just execute the docker image. You can pass any of the Section 86.8.1, “Common Properties for JUnit and Spring” +group ids, classifiers and Artifact Managers, just click here Section 85.6, “Docker Project”.

    87.9.1 How to use it

    Just execute the docker image. You can pass any of the Section 87.8.1, “Common Properties for JUnit and Spring” as environment variables. The convention is that all the letters should be upper case. The camel case notation should and the dot (.) should be separated via underscore (_). E.g. the stubrunner.repositoryRoot property should be represented - as a STUBRUNNER_REPOSITORY_ROOT environment variable.

    86.9.2 Example of client side usage in a non JVM project

    We’d like to use the stubs created in this Section 84.6.4, “Server side (nodejs)” step. + as a STUBRUNNER_REPOSITORY_ROOT environment variable.

    87.9.2 Example of client side usage in a non JVM project

    We’d like to use the stubs created in this Section 85.6.4, “Server side (nodejs)” step. Let’s assume that we want to run the stubs on port 9876. The NodeJS code is available here:

    $ git clone https://github.com/spring-cloud-samples/spring-cloud-contract-nodejs
     $ cd bookstore

    Let’s run the Stub Runner Boot application with the stubs.

    # Provide the Spring Cloud Contract Docker version
    @@ -8367,11 +8564,11 @@ that the stubs are setup properly.

    "Content-Type:application/json" -X POST --data '{ "title" : "Title", "genre" : "Genre", "description" : "Description", "author" : "Author", "publisher" : "Publisher", "pages" : 100, "image_url" : "https://d213dhlpdb53mu.cloudfront.net/assets/pivotal-square-logo-41418bd391196c3022f3cd9f3959b3f6d7764c47873d858583384e759c7db435.svg", "buy_url" : "https://pivotal.io" }' http://localhost:9876/api/books
     # Now time for the second request
     $ curl -X GET http://localhost:9876/api/books
    -# You will receive contents of the JSON

    87. Stub Runner for Messaging

    Stub Runner can run the published stubs in memory. It can integrate with the following +# You will receive contents of the JSON

    88. Stub Runner for Messaging

    Stub Runner can run the published stubs in memory. It can integrate with the following frameworks:

    • Spring Integration
    • Spring Cloud Stream
    • Spring AMQP

    It also provides entry points to integrate with any other solution on the market.

    [Important]Important

    If you have multiple frameworks on the classpath Stub Runner will need to define which one should be used. Let’s assume that you have both AMQP, Spring Cloud Stream and Spring Integration on the classpath. Then you need to set stubrunner.stream.enabled=false and stubrunner.integration.enabled=false. -That way the only remaining framework is Spring AMQP.

    87.1 Stub triggering

    To trigger a message, use the StubTrigger interface:

    package org.springframework.cloud.contract.stubrunner;
    +That way the only remaining framework is Spring AMQP.

    88.1 Stub triggering

    To trigger a message, use the StubTrigger interface:

    package org.springframework.cloud.contract.stubrunner;
     
     import java.util.Collection;
     import java.util.Map;
    @@ -8412,10 +8609,10 @@ That way the only remaining framework is Spring AMQP.

    Map<String, Collection<String>> labels(); }

    For convenience, the StubFinder interface extends StubTrigger, so you only need one -or the other in your tests.

    StubTrigger gives you the following options to trigger a message:

    87.1.1 Trigger by Label

    stubFinder.trigger('return_book_1')

    87.1.2 Trigger by Group and Artifact Ids

    stubFinder.trigger('org.springframework.cloud.contract.verifier.stubs:streamService', 'return_book_1')

    87.1.3 Trigger by Artifact Ids

    stubFinder.trigger('streamService', 'return_book_1')

    87.1.4 Trigger All Messages

    stubFinder.trigger()

    87.2 Stub Runner Integration

    Spring Cloud Contract Verifier Stub Runner’s messaging module gives you an easy way to +or the other in your tests.

    StubTrigger gives you the following options to trigger a message:

    88.1.1 Trigger by Label

    stubFinder.trigger('return_book_1')

    88.1.2 Trigger by Group and Artifact Ids

    stubFinder.trigger('org.springframework.cloud.contract.verifier.stubs:streamService', 'return_book_1')

    88.1.3 Trigger by Artifact Ids

    stubFinder.trigger('streamService', 'return_book_1')

    88.1.4 Trigger All Messages

    stubFinder.trigger()

    88.2 Stub Runner Integration

    Spring Cloud Contract Verifier Stub Runner’s messaging module gives you an easy way to integrate with Spring Integration. For the provided artifacts, it automatically downloads -the stubs and registers the required routes.

    87.2.1 Adding the Runner to the Project

    You can have both Spring Integration and Spring Cloud Contract Stub Runner on the -classpath. Remember to annotate your test class with @AutoConfigureStubRunner.

    87.2.2 Disabling the functionality

    If you need to disable this functionality, set the +the stubs and registers the required routes.

    88.2.1 Adding the Runner to the Project

    You can have both Spring Integration and Spring Cloud Contract Stub Runner on the +classpath. Remember to annotate your test class with @AutoConfigureStubRunner.

    88.2.2 Disabling the functionality

    If you need to disable this functionality, set the stubrunner.integration.enabled=false property.

    Assume that you have the following Maven repository with deployed stubs for the integrationService application:

    └── .m2
         └── repository
    @@ -8491,7 +8688,7 @@ assertJsons(receivedMessage.payload)
     receivedMessage.headers.get('BOOK-NAME') == 'foo'

    Scenario 2 (output triggered by input)

    Since the route is set for you, you can send a message to the output destination:

    messaging.send(new BookReturned('foo'), [sample: 'header'], 'input')

    To listen to the output of the message sent to output:

    Message<?> receivedMessage = messaging.receive('outputTest')

    The received message passes the following assertions:

    receivedMessage != null
     assertJsons(receivedMessage.payload)
    -receivedMessage.headers.get('BOOK-NAME') == 'foo'

    Scenario 3 (input with no output)

    Since the route is set for you, you can send a message to the input destination:

    messaging.send(new BookReturned('foo'), [sample: 'header'], 'delete')

    87.3 Stub Runner Stream

    Spring Cloud Contract Verifier Stub Runner’s messaging module gives you an easy way to +receivedMessage.headers.get('BOOK-NAME') == 'foo'

    Scenario 3 (input with no output)

    Since the route is set for you, you can send a message to the input destination:

    messaging.send(new BookReturned('foo'), [sample: 'header'], 'delete')

    88.3 Stub Runner Stream

    Spring Cloud Contract Verifier Stub Runner’s messaging module gives you an easy way to integrate with Spring Stream. For the provided artifacts, it automatically downloads the stubs and registers the required routes.

    [Warning]Warning

    If Stub Runner’s integration with Stream the messageFrom or sentTo Strings are resolved first as a destination of a channel and no such destination exists, the @@ -8504,8 +8701,8 @@ destination is resolved as a channel name.

    </dependency>

    Gradle. 

    testCompile "org.springframework.cloud:spring-cloud-stream-test-support"

    -

    87.3.1 Adding the Runner to the Project

    You can have both Spring Cloud Stream and Spring Cloud Contract Stub Runner on the -classpath. Remember to annotate your test class with @AutoConfigureStubRunner.

    87.3.2 Disabling the functionality

    If you need to disable this functionality, set the stubrunner.stream.enabled=false +

    88.3.1 Adding the Runner to the Project

    You can have both Spring Cloud Stream and Spring Cloud Contract Stub Runner on the +classpath. Remember to annotate your test class with @AutoConfigureStubRunner.

    88.3.2 Disabling the functionality

    If you need to disable this functionality, set the stubrunner.stream.enabled=false property.

    Assume that you have the following Maven repository with a deployed stubs for the streamService application:

    └── .m2
         └── repository
    @@ -8572,7 +8769,7 @@ receivedMessage.headers.get(destination:

    messaging.send(new BookReturned('foo'), [sample: 'header'], 'bookStorage')

    To listen to the output of the message sent to returnBook:

    Message<?> receivedMessage = messaging.receive('returnBook')

    The received message passes the following assertions:

    receivedMessage != null
     assertJsons(receivedMessage.payload)
     receivedMessage.headers.get('BOOK-NAME') == 'foo'

    Scenario 3 (input with no output)

    Since the route is set for you, you can send a message to the output -destination:

    messaging.send(new BookReturned('foo'), [sample: 'header'], 'delete')

    87.4 Stub Runner Spring AMQP

    Spring Cloud Contract Verifier Stub Runner’s messaging module provides an easy way to +destination:

    messaging.send(new BookReturned('foo'), [sample: 'header'], 'delete')

    88.4 Stub Runner Spring AMQP

    Spring Cloud Contract Verifier Stub Runner’s messaging module provides an easy way to integrate with Spring AMQP’s Rabbit Template. For the provided artifacts, it automatically downloads the stubs and registers the required routes.

    The integration tries to work standalone (that is, without interaction with a running RabbitMQ message broker). It expects a RabbitTemplate on the application context and @@ -8584,7 +8781,7 @@ queues. Bindings connect an exchange to a queue. If message contracts are trigge Spring AMQP stub runner integration looks for bindings on the application context that match this exchange. Then it collects the queues from the Spring exchanges and tries to find message listeners bound to these queues. The message is triggered for all matching -message listeners.

    87.4.1 Adding the Runner to the Project

    You can have both Spring AMQP and Spring Cloud Contract Stub Runner on the classpath and +message listeners.

    88.4.1 Adding the Runner to the Project

    You can have both Spring AMQP and Spring Cloud Contract Stub Runner on the classpath and set the property stubrunner.amqp.enabled=true. Remember to annotate your test class with @AutoConfigureStubRunner.

    [Important]Important

    If you already have Stream and Integration on the classpath, you need to disable them explicitly by setting the stubrunner.stream.enabled=false and @@ -8657,7 +8854,7 @@ definition is matched and invoked with the contract message.

    ConnectionFactory.

    To disable the mocked ConnectionFactory, set the following property: stubrunner.amqp.mockConnection=false

    stubrunner:
       amqp:
    -    mockConnection: false

    88. Contract DSL

    Spring Cloud Contract supports out of the box 2 types of DSL. One written in + mockConnection: false

    89. Contract DSL

    Spring Cloud Contract supports out of the box 2 types of DSL. One written in Groovy and one written in YAML.

    If you decide to write the contract in Groovy, do not be alarmed if you have not used Groovy before. Knowledge of the language is not really needed, as the Contract DSL uses only a tiny subset of it (only literals, method calls and closures). Also, the DSL is statically @@ -8751,13 +8948,13 @@ response: regex: bar - key: foo3 command: andMeToo($it)

    [Tip]Tip

    You can compile contracts to stubs mapping using standalone maven command: -mvn org.springframework.cloud:spring-cloud-contract-maven-plugin:convert

    88.1 Limitations

    [Warning]Warning

    Spring Cloud Contract Verifier does not properly support XML. Please use JSON or +mvn org.springframework.cloud:spring-cloud-contract-maven-plugin:convert

    89.1 Limitations

    [Warning]Warning

    Spring Cloud Contract Verifier does not properly support XML. Please use JSON or help us implement this feature.

    [Warning]Warning

    The support for verifying the size of JSON arrays is experimental. If you want to turn it on, please set the value of the following system property to true: spring.cloud.contract.verifier.assert.size. By default, this feature is set to false. You can also provide the assertJsonSize property in the plugin configuration.

    [Warning]Warning

    Because JSON structure can have any form, it can be impossible to parse it properly when using the Groovy DSL and the value(consumer(…​), producer(…​)) notation in GString. That -is why you should use the Groovy Map notation.

    88.2 Common Top-Level elements

    The following sections describe the most common top-level elements:

    88.2.1 Description

    You can add a description to your contract. The description is arbitrary text. The +is why you should use the Groovy Map notation.

    89.2 Common Top-Level elements

    The following sections describe the most common top-level elements:

    89.2.1 Description

    You can add a description to your contract. The description is arbitrary text. The following code shows an example:

    Groovy DSL. 

    		org.springframework.cloud.contract.spec.Contract.make {
     			description('''
    @@ -8815,7 +9012,7 @@ response:
             regex: bar
           - key: foo3
             command: andMeToo($it)

    -

    88.2.2 Name

    You can provide a name for your contract. Assume that you provided the following name: +

    89.2.2 Name

    You can provide a name for your contract. Assume that you provided the following name: should register a user. If you do so, the name of the autogenerated test is validate_should_register_a_user. Also, the name of the stub in a WireMock stub is should_register_a_user.json.

    [Important]Important

    You must ensure that the name does not contain any characters that make the @@ -8827,14 +9024,14 @@ override each other.

    Groovy DSL.  }

    YAML. 

    name: some name

    -

    88.2.3 Ignoring Contracts

    If you want to ignore a contract, you can either set a value of ignored contracts in the +

    89.2.3 Ignoring Contracts

    If you want to ignore a contract, you can either set a value of ignored contracts in the plugin configuration or set the ignored property on the contract itself:

    Groovy DSL. 

    org.springframework.cloud.contract.spec.Contract.make {
     	ignored()
     }

    YAML. 

    ignored: true

    -

    88.2.4 Passing Values from Files

    Starting with version 1.2.0, you can pass values from files. Assume that you have the +

    89.2.4 Passing Values from Files

    Starting with version 1.2.0, you can pass values from files. Assume that you have the following resources in our project.

    └── src
         └── test
             └── resources
    @@ -8871,7 +9068,7 @@ response:
       bodyFromFile: response.json

    Further assume that the JSON files is as follows:

    request.json

    { "status" : "REQUEST" }

    response.json

    { "status" : "RESPONSE" }

    When test or stub generation takes place, the contents of the file is passed to the body of a request or a response. The name of the file needs to be a file with location -relative to the folder in which the contract lays.

    88.2.5 HTTP Top-Level Elements

    The following methods can be called in the top-level closure of a contract definition. +relative to the folder in which the contract lays.

    89.2.5 HTTP Top-Level Elements

    The following methods can be called in the top-level closure of a contract definition. request and response are mandatory. priority is optional.

    Groovy DSL. 

    org.springframework.cloud.contract.spec.Contract.make {
     	// Definition of HTTP request part of the contract
    @@ -8901,7 +9098,7 @@ response:
     ...

    [Important]Important

    If you want to make your contract have a higher value of priority you need to pass a lower number to the priority tag / method. E.g. priority with -value 5 has higher priority than priority with value 10.

    88.3 Request

    The HTTP protocol requires only method and url to be specified in a request. The +value 5 has higher priority than priority with value 10.

    89.3 Request

    The HTTP protocol requires only method and url to be specified in a request. The same information is mandatory in request definition of the Contract.

    Groovy DSL. 

    org.springframework.cloud.contract.spec.Contract.make {
     	request {
    @@ -9166,7 +9363,7 @@ parametrization of either fileName or "transformers" : [ "response-template", "foo-transformer" ]
       }
     }
    -	'''

    88.4 Response

    The response must contain an HTTP status code and may contain other information. The + '''

    89.4 Response

    The response must contain an HTTP status code and may contain other information. The following code shows an example:

    Groovy DSL. 

    org.springframework.cloud.contract.spec.Contract.make {
     	request {
    @@ -9183,12 +9380,12 @@ following code shows an example:

    Groovy DSL.  ... status: 200

    Besides status, the response may contain headers and a body, both of which are -specified the same way as in the request (see the previous paragraph).

    88.5 Dynamic properties

    The contract can contain some dynamic properties: timestamps, IDs, and so on. You do not +specified the same way as in the request (see the previous paragraph).

    89.5 Dynamic properties

    The contract can contain some dynamic properties: timestamps, IDs, and so on. You do not want to force the consumers to stub their clocks to always return the same value of time so that it gets matched by the stub.

    For Groovy DSL you can provide the dynamic parts in your contracts in two ways: pass them directly in the body or set them in separate sections called -testMatchers and stubMatchers.

    For YAML you can only use the matchers section.

    88.5.1 Dynamic properties inside the body

    [Important]Important

    This section is valid only for Groovy DSL. Check out the -Section 88.5.7, “Dynamic Properties in the Matchers Sections” section for YAML examples of a similar feature.

    You can set the properties inside the body either with the value method or, if you use +testMatchers and stubMatchers.

    For YAML you can only use the matchers section.

    89.5.1 Dynamic properties inside the body

    [Important]Important

    This section is valid only for Groovy DSL. Check out the +Section 89.5.7, “Dynamic Properties in the Matchers Sections” section for YAML examples of a similar feature.

    You can set the properties inside the body either with the value method or, if you use the Groovy map notation, with $(). The following example shows how to set dynamic properties with the value method:

    value(consumer(...), producer(...))
     value(c(...), p(...))
    @@ -9197,8 +9394,8 @@ value(client(...), server(...))

    The following example shows how to set d $(c(...), p(...)) $(stub(...), test(...)) $(client(...), server(...))

    Both approaches work equally well. stub and client methods are aliases over the consumer -method. Subsequent sections take a closer look at what you can do with those values.

    88.5.2 Regular expressions

    [Important]Important

    This section is valid only for Groovy DSL. Check out the -Section 88.5.7, “Dynamic Properties in the Matchers Sections” section for YAML examples of a similar feature.

    You can use regular expressions to write your requests in Contract DSL. Doing so is +method. Subsequent sections take a closer look at what you can do with those values.

    89.5.2 Regular expressions

    [Important]Important

    This section is valid only for Groovy DSL. Check out the +Section 89.5.7, “Dynamic Properties in the Matchers Sections” section for YAML examples of a similar feature.

    You can use regular expressions to write your requests in Contract DSL. Doing so is particularly useful when you want to indicate that a given response should be provided for requests that follow a given pattern. Also, you can use regular expressions when you need to use patterns and not exact values both for your test and your server side tests.

    The following example shows how to use regular expressions to write a request:

    org.springframework.cloud.contract.spec.Contract.make {
    @@ -9344,8 +9541,8 @@ Pattern nonBlank() {
     				message: "User not found by email = [${value(producer(regex(email())), consumer('not.existing@user.com'))}]"
     		)
     	}
    -}

    88.5.3 Passing Optional Parameters

    [Important]Important

    This section is valid only for Groovy DSL. Check out the -Section 88.5.7, “Dynamic Properties in the Matchers Sections” section for YAML examples of a similar feature.

    It is possible to provide optional parameters in your contract. However, you can provide +}

    89.5.3 Passing Optional Parameters

    [Important]Important

    This section is valid only for Groovy DSL. Check out the +Section 89.5.7, “Dynamic Properties in the Matchers Sections” section for YAML examples of a similar feature.

    It is possible to provide optional parameters in your contract. However, you can provide optional parameters only for the following:

    • STUB side of the Request
    • TEST side of the Response

    The following example shows how to provide optional parameters:

    org.springframework.cloud.contract.spec.Contract.make {
     	priority 1
     	request {
    @@ -9410,8 +9607,8 @@ expression that must be present 0 or more times.

    If you use Spock for, the }, "priority" : 1 } -'''

    88.5.4 Executing Custom Methods on the Server Side

    [Important]Important

    This section is valid only for Groovy DSL. Check out the -Section 88.5.7, “Dynamic Properties in the Matchers Sections” section for YAML examples of a similar feature.

    You can define a method call that executes on the server side during the test. Such a +'''

    89.5.4 Executing Custom Methods on the Server Side

    [Important]Important

    This section is valid only for Groovy DSL. Check out the +Section 89.5.7, “Dynamic Properties in the Matchers Sections” section for YAML examples of a similar feature.

    You can define a method call that executes on the server side during the test. Such a method can be added to the class defined as "baseClassForTests" in the configuration. The following code shows an example of the contract portion of the test case:

    org.springframework.cloud.contract.spec.Contract.make {
     	request {
    @@ -9474,7 +9671,7 @@ It should resemble the following code:

    "/something");
     
     // then:
    - assertThat(response.statusCode()).isEqualTo(200);

    88.5.5 Referencing the Request from the Response

    The best situation is to provide fixed values, but sometimes you need to reference a + assertThat(response.statusCode()).isEqualTo(200);

    89.5.5 Referencing the Request from the Response

    The best situation is to provide fixed values, but sometimes you need to reference a request in your response.

    If you’re writing contracts using Groovy DSL, you can use the fromRequest() method, which lets you reference a bunch of elements from the HTTP request. You can use the following options:

    • fromRequest().url(): Returns the request URL and query parameters.
    • fromRequest().query(String key): Returns the first query parameter with a given name.
    • fromRequest().query(String key, int index): Returns the nth query parameter with a @@ -9622,7 +9819,7 @@ in sending the following response body:

      }
      [Important]Important

      This feature works only with WireMock having a version greater than or equal to 2.5.1. The Spring Cloud Contract Verifier uses WireMock’s response-template response transformer. It uses Handlebars to convert the Mustache {{{ }}} templates into -proper values. Additionally, it registers two helper functions:

      • escapejsonbody: Escapes the request body in a format that can be embedded in a JSON.
      • jsonpath: For a given parameter, find an object in the request body.

    88.5.6 Registering Your Own WireMock Extension

    WireMock lets you register custom extensions. By default, Spring Cloud Contract registers +proper values. Additionally, it registers two helper functions:

    • escapejsonbody: Escapes the request body in a format that can be embedded in a JSON.
    • jsonpath: For a given parameter, find an object in the request body.

    89.5.6 Registering Your Own WireMock Extension

    WireMock lets you register custom extensions. By default, Spring Cloud Contract registers the transformer, which lets you reference a request from a response. If you want to provide your own extensions, you can register an implementation of the org.springframework.cloud.contract.verifier.dsl.wiremock.WireMockExtensions interface. @@ -9654,7 +9851,7 @@ org.springframework.cloud.contract.stubrunner.provider.wiremock.TestWireMockExte } }

    [Important]Important

    Remember to override the applyGlobally() method and set it to false if you -want the transformation to be applied only for a mapping that explicitly requires it.

    88.5.7 Dynamic Properties in the Matchers Sections

    If you work with Pact, the following discussion may seem familiar. +want the transformation to be applied only for a mapping that explicitly requires it.

    89.5.7 Dynamic Properties in the Matchers Sections

    If you work with Pact, the following discussion may seem familiar. Quite a few users are used to having a separation between the body and setting the dynamic parts of a contract.

    You can use two separate sections:

    • stubMatchers, which lets you define the dynamic values that should end up in a stub. You can set it in the request or inputMessage part of your contract.
    • testMatchers, which is present in the response or outputMessage side of the @@ -10059,7 +10256,7 @@ and: assertThat(parsedJson.read("\$.events[0].eventId", String.class)).matches("^([a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12})\$") assertThat(parsedJson.read("\$.events[0].status", String.class)).matches(".+")

      As you can see, the assertion is malformed. Only the first element of the array got asserted. In order to fix this, you should apply the assertion to the whole $.events -collection and assert it with the byCommand(…​) method.

    88.6 JAX-RS Support

    The Spring Cloud Contract Verifier supports the JAX-RS 2 Client API. The base class needs +collection and assert it with the byCommand(…​) method.

    89.6 JAX-RS Support

    The Spring Cloud Contract Verifier supports the JAX-RS 2 Client API. The base class needs to define protected WebTarget webTarget and server initialization. The only option for testing JAX-RS API is to start a web server. Also, a request with a body needs to have a content type set. Otherwise, the default of application/octet-stream gets used.

    In order to use JAX-RS mode, use the following settings:

    testMode == 'JAXRSCLIENT'

    The following example shows a generated test API:

    '''
    @@ -10084,7 +10281,7 @@ content type set. Otherwise, the default of application/oc
      // and:
       DocumentContext parsedJson = JsonPath.parse(responseAsString);
       assertThatJson(parsedJson).field("['property1']").isEqualTo("a");
    -'''

    88.7 Async Support

    If you’re using asynchronous communication on the server side (your controllers are +'''

    89.7 Async Support

    If you’re using asynchronous communication on the server side (your controllers are returning Callable, DeferredResult, and so on), then, inside your contract, you must provide a sync() method in the response section. The following code shows an example:

    Groovy DSL. 

    org.springframework.cloud.contract.spec.Contract.make {
    @@ -10101,7 +10298,7 @@ provide a sync() method in the response:
         async: true

    -

    88.8 Working with Context Paths

    Spring Cloud Contract supports context paths.

    [Important]Important

    The only change needed to fully support context paths is the switch on the +

    89.8 Working with Context Paths

    Spring Cloud Contract supports context paths.

    [Important]Important

    The only change needed to fully support context paths is the switch on the PRODUCER side. Also, the autogenerated tests must use EXPLICIT mode. The consumer side remains untouched. In order for the generated test to pass, you must use EXPLICIT mode.

    Maven.  @@ -10145,8 +10342,8 @@ socket.

    Consider the following contract:

    or
     	}
     }

    If you do it this way:

    • All of your requests in the autogenerated tests are sent to the real endpoint with your context path included (for example, /my-context-path/url).
    • Your contracts reflect that you have a context path. Your generated stubs also have -that information (for example, in the stubs, you have to call /my-context-path/url).

    88.9 Messaging Top-Level Elements

    The DSL for messaging looks a little bit different than the one that focuses on HTTP. The -following sections explain the differences:

    88.9.1 Output Triggered by a Method

    The output message can be triggered by calling a method (such as a Scheduler when a was +that information (for example, in the stubs, you have to call /my-context-path/url).

    89.9 Messaging Top-Level Elements

    The DSL for messaging looks a little bit different than the one that focuses on HTTP. The +following sections explain the differences:

    89.9.1 Output Triggered by a Method

    The output message can be triggered by calling a method (such as a Scheduler when a was started and a message was sent), as shown in the following example:

    Groovy DSL. 

    def dsl = Contract.make {
     	// Human readable description
    @@ -10191,7 +10388,7 @@ outputMessage:
     

    In the previous example case, the output message is sent to output if a method called bookReturnedTriggered is executed. On the message publisher’s side, we generate a test that calls that method to trigger the message. On the consumer side, you can use -the some_label to trigger the message.

    88.9.2 Output Triggered by a Message

    The output message can be triggered by receiving a message, as shown in the following +the some_label to trigger the message.

    89.9.2 Output Triggered by a Message

    The output message can be triggered by receiving a message, as shown in the following example:

    Groovy DSL. 

    def dsl = Contract.make {
     	description 'Some Description'
    @@ -10247,7 +10444,7 @@ outputMessage:
     received on the input destination. On the message publisher’s side, the engine
     generates a test that sends the input message to the defined destination. On the
     consumer side, you can either send a message to the input destination or use a label
    -(some_label in the example) to trigger the message.

    88.9.3 Consumer/Producer

    [Important]Important

    This section is valid only for Groovy DSL.

    In HTTP, you have a notion of client/stub and `server/test notation. You can also +(some_label in the example) to trigger the message.

    89.9.3 Consumer/Producer

    [Important]Important

    This section is valid only for Groovy DSL.

    In HTTP, you have a notion of client/stub and `server/test notation. You can also use those paradigms in messaging. In addition, Spring Cloud Contract Verifier also provides the consumer and producer methods, as presented in the following example (note that you can use either $ or value methods to provide consumer and producer @@ -10268,10 +10465,10 @@ parts):

    Contract.make {
     				bookName: 'foo'
     		])
     	}
    -}

    88.9.4 Common

    In the input or outputMessage section you can call assertThat with the name +}

    89.9.4 Common

    In the input or outputMessage section you can call assertThat with the name of a method (e.g. assertThatMessageIsOnTheQueue()) that you have defined in the base class or in a static import. Spring Cloud Contract will execute that method -in the generated test.

    88.10 Multiple Contracts in One File

    You can define multiple contracts in one file. Such a contract might resemble the +in the generated test.

    89.10 Multiple Contracts in One File

    You can define multiple contracts in one file. Such a contract might resemble the following example:

    Groovy DSL. 

    import org.springframework.cloud.contract.spec.Contract
     
    @@ -10360,10 +10557,10 @@ index of the contract in the list.

    The generated stubs is shown in the fol 1_WithList.json

    As you can see, the first file got the name parameter from the contract. The second got the name of the contract file (WithList.groovy) prefixed with the index (in this case, the contract had an index of 1 in the list of contracts in the file).

    [Tip]Tip

    As you can see, it iss much better if you name your contracts because doing so makes -your tests far more meaningful.

    89. Customization

    [Important]Important

    This section is valid only for Groovy DSL

    You can customize the Spring Cloud Contract Verifier by extending the DSL, as shown in -the remainder of this section.

    89.1 Extending the DSL

    You can provide your own functions to the DSL. The key requirement for this feature is to +your tests far more meaningful.

    90. Customization

    [Important]Important

    This section is valid only for Groovy DSL

    You can customize the Spring Cloud Contract Verifier by extending the DSL, as shown in +the remainder of this section.

    90.1 Extending the DSL

    You can provide your own functions to the DSL. The key requirement for this feature is to maintain the static compatibility. Later in this document, you can see examples of:

    • Creating a JAR with reusable classes.
    • Referencing of these classes in the DSLs.

    You can find the full example -here.

    89.1.1 Common JAR

    The following examples show three classes that can be reused in the DSLs.

    PatternUtils contains functions used by both the consumer and the producer.

    package com.example;
    +here.

    90.1.1 Common JAR

    The following examples show three classes that can be reused in the DSLs.

    PatternUtils contains functions used by both the consumer and the producer.

    package com.example;
     
     import java.util.regex.Pattern;
     
    @@ -10494,8 +10691,8 @@ maintain the static compatibility. Later in this document, you can see examples
     		return new ServerDslProperty( PatternUtils.ok(), "OK");
     	}
     }
    -//end::impl[]

    89.1.2 Adding the Dependency to the Project

    In order for the plugins and IDE to be able to reference the common JAR classes, you need -to pass the dependency to your project.

    89.1.3 Test the Dependency in the Project’s Dependencies

    First, add the common jar dependency as a test dependency. Because your contracts files +//end::impl[]

    90.1.2 Adding the Dependency to the Project

    In order for the plugins and IDE to be able to reference the common JAR classes, you need +to pass the dependency to your project.

    90.1.3 Test the Dependency in the Project’s Dependencies

    First, add the common jar dependency as a test dependency. Because your contracts files are available on the test resources path, the common jar classes automatically become visible in your Groovy files. The following examples show how to test the dependency:

    Maven. 

    <dependency>
    @@ -10506,7 +10703,7 @@ visible in your Groovy files. The following examples show how to test the depend
     </dependency>

    Gradle. 

    testCompile("com.example:beer-common:0.0.1-SNAPSHOT")

    -

    89.1.4 Test a Dependency in the Plugin’s Dependencies

    Now, you must add the dependency for the plugin to reuse at runtime, as shown in the +

    90.1.4 Test a Dependency in the Plugin’s Dependencies

    Now, you must add the dependency for the plugin to reuse at runtime, as shown in the following example:

    Maven. 

    <plugin>
     	<groupId>org.springframework.cloud</groupId>
    @@ -10533,7 +10730,7 @@ following example:

    Maven.  </plugin>

    Gradle. 

    classpath "com.example:beer-common:0.0.1-SNAPSHOT"

    -

    89.1.5 Referencing classes in DSLs

    You can now reference your classes in your DSL, as shown in the following example:

    package contracts.beer.rest
    +

    90.1.5 Referencing classes in DSLs

    You can now reference your classes in your DSL, as shown in the following example:

    package contracts.beer.rest
     
     import com.example.ConsumerUtils
     import com.example.ProducerUtils
    @@ -10574,12 +10771,12 @@ then:
     			contentType(applicationJson())
     		}
     	}
    -}

    90. Using the Pluggable Architecture

    You may encounter cases where you have your contracts have been defined in other formats, +}

    91. Using the Pluggable Architecture

    You may encounter cases where you have your contracts have been defined in other formats, such as YAML, RAML or PACT. In those cases, you still want to benefit from the automatic generation of tests and stubs. You can add your own implementation for generating both tests and stubs. Also, you can customize the way tests are generated (for example, you can generate tests for other languages) and the way stubs are generated (for example, you -can generate stubs for other HTTP server implementations).

    90.1 Custom Contract Converter

    The ContractConverter interface lets you register your own implementation of a contract +can generate stubs for other HTTP server implementations).

    91.1 Custom Contract Converter

    The ContractConverter interface lets you register your own implementation of a contract structure converter. The following code listing shows the ContractConverter interface:

    package org.springframework.cloud.contract.spec
     
     /**
    @@ -10621,9 +10818,9 @@ structure converter. The following code listing shows the 
     conversion. Also, you must define how to perform that conversion in both directions.

    [Important]Important

    Once you create your implementation, you must create a /META-INF/spring.factories file in which you provide the fully qualified name of your implementation.

    The following example shows a typical spring.factories file:

    org.springframework.cloud.contract.spec.ContractConverter=\
    -org.springframework.cloud.contract.verifier.converter.YamlContractConverter

    90.1.1 Pact Converter

    Spring Cloud Contract includes support for Pact representation of +org.springframework.cloud.contract.verifier.converter.YamlContractConverter

    91.1.1 Pact Converter

    Spring Cloud Contract includes support for Pact representation of contracts. Instead of using the Groovy DSL, you can use Pact files. In this section, we -present how to add Pact support for your project.

    90.1.2 Pact Contract

    Consider following example of a Pact contract, which is a file under the +present how to add Pact support for your project.

    91.1.2 Pact Contract

    Consider following example of a Pact contract, which is a file under the src/test/resources/contracts folder.

    {
       "provider": {
         "name": "Provider"
    @@ -10677,7 +10874,7 @@ present how to add Pact support for your project.

    "version": "2.4.18" } } -}

    The remainder of this section about using Pact refers to the preceding file.

    90.1.3 Pact for Producers

    On the producer side, you mustadd two additional dependencies to your plugin +}

    The remainder of this section about using Pact refers to the preceding file.

    91.1.3 Pact for Producers

    On the producer side, you mustadd two additional dependencies to your plugin configuration. One is the Spring Cloud Contract Pact support, and the other represents the current Pact version that you use.

    Maven. 

    <plugin>
    @@ -10747,7 +10944,7 @@ test might be as follows:

    "Content-Type" : "application/vnd.fraud.v1+json;charset=UTF-8"
         }
       }
    -}

    90.1.4 Pact for Consumers

    On the producer side, you must add two additional dependencies to your project +}

    91.1.4 Pact for Consumers

    On the producer side, you must add two additional dependencies to your project dependencies. One is the Spring Cloud Contract Pact support, and the other represents the current Pact version that you use.

    Maven. 

    <dependency>
    @@ -10764,7 +10961,7 @@ current Pact version that you use.

    Maven. 

    Gradle. 

    testCompile "org.springframework.cloud:spring-cloud-contract-spec-pact"
     testCompile 'au.com.dius:pact-jvm-model:2.4.18'

    -

    90.2 Using the Custom Test Generator

    If you want to generate tests for languages other than Java or you are not happy with the +

    91.2 Using the Custom Test Generator

    If you want to generate tests for languages other than Java or you are not happy with the way the verifier builds Java tests, you can register your own implementation.

    The SingleTestGenerator interface lets you register your own implementation. The following code listing shows the SingleTestGenerator interface:

    package org.springframework.cloud.contract.verifier.builder
     
    @@ -10799,7 +10996,7 @@ following code listing shows the SingleTestGenerator

    Again, you must provide a spring.factories file, such as the one shown in the following example:

    org.springframework.cloud.contract.verifier.builder.SingleTestGenerator=/
    -com.example.MyGenerator

    90.3 Using the Custom Stub Generator

    If you want to generate stubs for stub servers other than WireMock, you can plug in your +com.example.MyGenerator

    91.3 Using the Custom Stub Generator

    If you want to generate stubs for stub servers other than WireMock, you can plug in your own implementation of the StubGenerator interface. The following code listing shows the StubGenerator interface:

    package org.springframework.cloud.contract.verifier.converter
     
    @@ -10841,7 +11038,7 @@ own implementation of the StubGenerator interface.
     example:

    # Stub converters
     org.springframework.cloud.contract.verifier.converter.StubGenerator=\
     org.springframework.cloud.contract.verifier.wiremock.DslToWireMockClientConverter

    The default implementation is the WireMock stub generation.

    [Tip]Tip

    You can provide multiple stub generator implementations. For example, from a single -DSL, you can produce both WireMock stubs and Pact files.

    90.4 Using the Custom Stub Runner

    If you decide to use a custom stub generation, you also need a custom way of running +DSL, you can produce both WireMock stubs and Pact files.

    91.4 Using the Custom Stub Runner

    If you decide to use a custom stub generation, you also need a custom way of running stubs with your different stub provider.

    Assume that you use Moco to build your stubs and that you have written a stub generator and placed your stubs in a JAR file.

    In order for Stub Runner to know how to run your stubs, you have to define a custom HTTP Stub server implementation, which might resemble the following example:

    package org.springframework.cloud.contract.stubrunner.provider.moco
    @@ -10924,7 +11121,7 @@ HTTP Stub server implementation, which might resemble the following example:

    }

    Then, you can register it in your spring.factories file, as shown in the following example:

    org.springframework.cloud.contract.stubrunner.HttpServerStub=\
     org.springframework.cloud.contract.stubrunner.provider.moco.MocoHttpServerStub

    Now you can run stubs with Moco.

    [Important]Important

    If you do not provide any implementation, then the default (WireMock) -implementation is used. If you provide more than one, the first one on the list is used.

    90.5 Using the Custom Stub Downloader

    You can customize the way your stubs are downloaded by creating an implementation of the +implementation is used. If you provide more than one, the first one on the list is used.

    91.5 Using the Custom Stub Downloader

    You can customize the way your stubs are downloaded by creating an implementation of the StubDownloaderBuilder interface, as shown in the following example:

    package com.example;
     
     class CustomStubDownloaderBuilder implements StubDownloaderBuilder {
    @@ -10950,7 +11147,7 @@ org.springframework.cloud.contract.stubrunner.StubDownloaderBuilder=\
     com.example.CustomStubDownloaderBuilder

    Now you can pick a folder with the source of your stubs.

    [Important]Important

    If you do not provide any implementation, then the default is used (scan classpath). If you provide the stubsMode = StubRunnerProperties.StubsMode.LOCAL or , stubsMode = StubRunnerProperties.StubsMode.REMOTE then the Aether implementation will be used -If you provide more than one, then the first one on the list is used.

    91. Spring Cloud Contract WireMock

    The Spring Cloud Contract WireMock modules let you use WireMock in a +If you provide more than one, then the first one on the list is used.

    92. Spring Cloud Contract WireMock

    The Spring Cloud Contract WireMock modules let you use WireMock in a Spring Boot application. Check out the samples for more details.

    If you have a Spring Boot application that uses Tomcat as an embedded server (which is @@ -10980,7 +11177,7 @@ your test. The following code shows an example:

    <
     server port can be bound in the test application context with the "wiremock.server.port"
     property. Using @AutoConfigureWireMock adds a bean of type WiremockConfiguration to
     your test application context, where it will be cached in between methods and classes
    -having the same context, the same as for Spring integration tests.

    91.1 Registering Stubs Automatically

    If you use @AutoConfigureWireMock, it registers WireMock JSON stubs from the file +having the same context, the same as for Spring integration tests.

    92.1 Registering Stubs Automatically

    If you use @AutoConfigureWireMock, it registers WireMock JSON stubs from the file system or classpath (by default, from file:src/test/resources/mappings). You can customize the locations using the stubs attribute in the annotation, which can be an Ant-style resource pattern or a directory. In the case of a directory, */.json is @@ -10999,7 +11196,7 @@ public class WiremockImportApplicationTests { }

    [Note]Note

    Actually, WireMock always loads mappings from src/test/resources/mappings as well as the custom locations in the stubs attribute. To change this behavior, you can -also specify a files root as described in the next section of this document.

    91.2 Using Files to Specify the Stub Bodies

    WireMock can read response bodies from files on the classpath or the file system. In that +also specify a files root as described in the next section of this document.

    92.2 Using Files to Specify the Stub Bodies

    WireMock can read response bodies from files on the classpath or the file system. In that case, you can see in the JSON DSL that the response has a bodyFileName instead of a (literal) body. The files are resolved relative to a root directory (by default, src/test/resources/__files). To customize this location you can set the files @@ -11010,7 +11207,7 @@ supported. A list of values can be given, in which case WireMock resolves the fi that exists when it needs to find a response body.

    [Note]Note

    When you configure the files root, it also affects the automatic loading of stubs, because they come from the root location in a subdirectory called "mappings". The value of files has no -effect on the stubs loaded explicitly from the stubs attribute.

    91.3 Alternative: Using JUnit Rules

    For a more conventional WireMock experience, you can use JUnit @Rules to start and stop +effect on the stubs loaded explicitly from the stubs attribute.

    92.3 Alternative: Using JUnit Rules

    For a more conventional WireMock experience, you can use JUnit @Rules to start and stop the server. To do so, use the WireMockSpring convenience class to obtain an Options instance, as shown in the following example:

    @RunWith(SpringRunner.class)
     @SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
    @@ -11036,7 +11233,7 @@ instance, as shown in the following example:

    
     	}
     
     }

    The @ClassRule means that the server shuts down after all the methods in this class -have been run.

    91.4 Relaxed SSL Validation for Rest Template

    WireMock lets you stub a "secure" server with an "https" URL protocol. If your +have been run.

    92.4 Relaxed SSL Validation for Rest Template

    WireMock lets you stub a "secure" server with an "https" URL protocol. If your application wants to contact that stub server in an integration test, it will find that the SSL certificates are not valid (the usual problem with self-installed certificates). The best option is often to re-configure the client to use "http". If that’s not an @@ -11062,7 +11259,7 @@ annotation or the stub runner. If you use the JUnit @Rule< classpath and it is selected by the RestTemplateBuilder and configured to ignore SSL errors. If you use the default java.net client, you do not need the annotation (but it won’t do any harm). There is no support currently for other clients, but it may be added -in future releases.

    91.5 WireMock and Spring MVC Mocks

    Spring Cloud Contract provides a convenience class that can load JSON WireMock stubs into +in future releases.

    92.5 WireMock and Spring MVC Mocks

    Spring Cloud Contract provides a convenience class that can load JSON WireMock stubs into a Spring MockRestServiceServer. The following code shows an example:

    @RunWith(SpringRunner.class)
     @SpringBootTest(webEnvironment = WebEnvironment.NONE)
     public class WiremockForDocsMockServerApplicationTests {
    @@ -11093,7 +11290,7 @@ pattern. The JSON format is the normal WireMock format, which you can read about
     WireMock website.

    Currently, the Spring Cloud Contract Verifier supports Tomcat, Jetty, and Undertow as Spring Boot embedded servers, and Wiremock itself has "native" support for a particular version of Jetty (currently 9.2). To use the native Jetty, you need to add the native -Wiremock dependencies and exclude the Spring Boot container (if there is one).

    91.6 Customization of WireMock configuration

    You can register a bean of org.springframework.cloud.contract.wiremock.WireMockConfigurationCustomizer type +Wiremock dependencies and exclude the Spring Boot container (if there is one).

    92.6 Customization of WireMock configuration

    You can register a bean of org.springframework.cloud.contract.wiremock.WireMockConfigurationCustomizer type in order to customize the WireMock configuration (e.g. add custom transformers). Example:

    		@Bean WireMockConfigurationCustomizer optionsCustomizer() {
     			return new WireMockConfigurationCustomizer() {
    @@ -11101,7 +11298,7 @@ Example:

    		// perform your customization here
     				}
     			};
    -		}

    91.7 Generating Stubs using REST Docs

    Spring REST Docs can be used to generate + }

    92.7 Generating Stubs using REST Docs

    Spring REST Docs can be used to generate documentation (for example in Asciidoctor format) for an HTTP API with Spring MockMvc or WebTestClient or Rest Assured. At the same time that you generate documentation for your API, you can also @@ -11205,7 +11402,7 @@ available on the classpath (by stubs as JARs, for example). After that, you can create a stub using WireMock in a number of different ways, including by using @AutoConfigureWireMock(stubs="classpath:resource.json"), as described earlier in this -document.

    91.8 Generating Contracts by Using REST Docs

    You can also generate Spring Cloud Contract DSL files and documentation with Spring REST +document.

    92.8 Generating Contracts by Using REST Docs

    You can also generate Spring Cloud Contract DSL files and documentation with Spring REST Docs. If you do so in combination with Spring Cloud WireMock, you get both the contracts and the stubs.

    Why would you want to use this feature? Some people in the community asked questions about a situation in which they would like to move to DSL-based contract definition, @@ -11255,8 +11452,8 @@ Contract.make { } } }

    The generated document (formatted in Asciidoc in this case) contains a formatted -contract. The location of this file would be index/dsl-contract.adoc.

    92. Migrations

    This section covers migrating from one version of Spring Cloud Contract Verifier to the -next version. It covers the following versions upgrade paths:

    92.1 1.0.x → 1.1.x

    This section covers upgrading from version 1.0 to version 1.1.

    92.1.1 New structure of generated stubs

    In 1.1.x we have introduced a change to the structure of generated stubs. If you have +contract. The location of this file would be index/dsl-contract.adoc.

    93. Migrations

    This section covers migrating from one version of Spring Cloud Contract Verifier to the +next version. It covers the following versions upgrade paths:

    93.1 1.0.x → 1.1.x

    This section covers upgrading from version 1.0 to version 1.1.

    93.1.1 New structure of generated stubs

    In 1.1.x we have introduced a change to the structure of generated stubs. If you have been using the @AutoConfigureWireMock notation to use the stubs from the classpath, it no longer works. The following example shows how the @AutoConfigureWireMock notation used to work:

    @AutoConfigureWireMock(stubs = "classpath:/customer-stubs/mappings", port = 8084)

    You must either change the location of the stubs to: @@ -11334,21 +11531,21 @@ structure presented in the previous snippet.

    Maven.&nbs from "${project.buildDir}/resources/main/customer-stubs/META-INF/${project.group}/${project.name}/${project.version}" into "${project.buildDir}/resources/main/customer-stubs" }

    -

    92.2 1.1.x → 1.2.x

    This section covers upgrading from version 1.1 to version 1.2.

    92.2.1 Custom HttpServerStub

    HttpServerStub includes a method that was not in version 1.1. The method is +

    93.2 1.1.x → 1.2.x

    This section covers upgrading from version 1.1 to version 1.2.

    93.2.1 Custom HttpServerStub

    HttpServerStub includes a method that was not in version 1.1. The method is String registeredMappings() If you have classes that implement HttpServerStub, you now have to implement the registeredMappings() method. It should return a String representing all mappings available in a single HttpServerStub.

    See issue 355 for more -detail.

    92.2.2 New packages for generated tests

    The flow for setting the generated tests package name will look like this:

    • Set basePackageForTests
    • If basePackageForTests was not set, pick the package from baseClassForTests
    • If baseClassForTests was not set, pick packageWithBaseClasses
    • If nothing got set, pick the default value: +detail.

    93.2.2 New packages for generated tests

    The flow for setting the generated tests package name will look like this:

    • Set basePackageForTests
    • If basePackageForTests was not set, pick the package from baseClassForTests
    • If baseClassForTests was not set, pick packageWithBaseClasses
    • If nothing got set, pick the default value: org.springframework.cloud.contract.verifier.tests

    See issue 260 for more -detail.

    92.2.3 New Methods in TemplateProcessor

    In order to add support for fromRequest.path, the following methods had to be added to the +detail.

    93.2.3 New Methods in TemplateProcessor

    In order to add support for fromRequest.path, the following methods had to be added to the TemplateProcessor interface:

    • path()
    • path(int index)

    See issue 388 for more -detail.

    92.2.4 RestAssured 3.0

    Rest Assured, used in the generated test classes, got bumped to 3.0. If +detail.

    93.2.4 RestAssured 3.0

    Rest Assured, used in the generated test classes, got bumped to 3.0. If you manually set versions of Spring Cloud Contract and the release train you might see the following exception:

    Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.1:testCompile (default-testCompile) on project some-project: Compilation failure: Compilation failure:
     [ERROR] /some/path/SomeClass.java:[4,39] package com.jayway.restassured.response does not exist

    This exception will occur due to the fact that the tests got generated with an old version of plugin and at test execution time you have an incompatible -version of the release train (and vice versa).

    Done via issue 267

    92.3 1.2.x → 2.0.x

    92.3.1 No Camel support

    We will add back Apache Camel support only after this issue -gets fixed

    93. Links

    The following links may be helpful when working with Spring Cloud Contract Verifier:

    93.3 1.2.x → 2.0.x

    93.3.1 No Camel support

    We will add back Apache Camel support only after this issue +gets fixed

    Part XIII. Spring Cloud Vault

    © 2016-2018 The original authors.

    [Note]Note

    Copies of this document may be made for your own use and for distribution to others, provided that you do not charge any fee for such copies and further provided that each copy contains this Copyright Notice, whether distributed in print or electronically.

    Spring Cloud Vault Config provides client-side support for externalized configuration in a distributed system. With HashiCorp’s Vault you have a central place to manage external secret properties for applications across all environments. Vault can manage static and dynamic secrets such as username/password for remote applications/resources and provide credentials for external services such as MySQL, PostgreSQL, Apache Cassandra, MongoDB, Consul, AWS and more.

    94. Quick Start

    Prerequisites

    To get started with Vault and this guide you need a +Marcin Grzejszczak

    Part XIV. Spring Cloud Vault

    © 2016-2018 The original authors.

    [Note]Note

    Copies of this document may be made for your own use and for distribution to others, provided that you do not charge any fee for such copies and further provided that each copy contains this Copyright Notice, whether distributed in print or electronically.

    Spring Cloud Vault Config provides client-side support for externalized configuration in a distributed system. With HashiCorp’s Vault you have a central place to manage external secret properties for applications across all environments. Vault can manage static and dynamic secrets such as username/password for remote applications/resources and provide credentials for external services such as MySQL, PostgreSQL, Apache Cassandra, MongoDB, Consul, AWS and more.

    95. Quick Start

    Prerequisites

    To get started with Vault and this guide you need a *NIX-like operating systems that provides:

    • wget, openssl and unzip
    • at least Java 7 and a properly configured JAVA_HOME environment variable

    Install Vault

    $ src/test/bash/install_vault.sh

    Create SSL certificates for Vault

    $ src/test/bash/create_certificates.sh
    [Note]Note

    create_certificates.sh creates certificates in work/ca and a JKS truststore work/keystore.jks. If you want to run Spring Cloud Vault using this quickstart guide you need to configure the truststore the spring.cloud.vault.ssl.trust-store property to file:work/keystore.jks.

    Start Vault server

    $ src/test/bash/local_run_vault.sh

    Vault is started listening on 0.0.0.0:8200 using the inmem storage and https. Vault is sealed and not initialized when starting up.

    [Note]Note

    If you want to run tests, leave Vault uninitialized. The tests will @@ -11390,9 +11587,9 @@ backend is enabled which accesses secret config settings via JSON endpoints.

    SpringApplication (i.e. what is normally "application" in a regular Spring Boot app), "profile" is an active profile (or comma-separated list of properties). Properties retrieved from Vault will be used "as-is" -without further prefixing of the property names.

    95. Client Side Usage

    To use these features in an application, just build it as a Spring +without further prefixing of the property names.

    96. Client Side Usage

    To use these features in an application, just build it as a Spring Boot application that depends on spring-cloud-vault-config (e.g. see -the test cases). Example Maven configuration:

    Example 95.1. pom.xml

    <parent>
    +the test cases). Example Maven configuration:

    Example 96.1. pom.xml

    <parent>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-parent</artifactId>
         <version>1.5.4.RELEASE</version>
    @@ -11437,7 +11634,7 @@ the test cases). Example Maven configuration:

    8200 if it is running. To modify the startup behavior you can change the location of the Vault server using bootstrap.properties (like application.properties but for -the bootstrap phase of an application context), e.g.

    Example 95.2. bootstrap.yml

    spring.cloud.vault:
    +the bootstrap phase of an application context), e.g.

    Example 96.2. bootstrap.yml

    spring.cloud.vault:
         host: localhost
         port: 8200
         scheme: https
    @@ -11453,24 +11650,24 @@ additional configuration like
     SSL and
     authentication.

    If the application imports the spring-boot-starter-actuator project, the status of the vault server will be available via the /health endpoint.

    The vault health indicator can be enabled or disabled through the -property health.vault.enabled (default true).

    95.1 Authentication

    Vault requires an authentication mechanism to authorize client requests.

    Spring Cloud Vault supports multiple authentication mechanisms to authenticate applications with Vault.

    For a quickstart, use the root token printed by the Vault initialization.

    Example 95.3. bootstrap.yml

    spring.cloud.vault:
    -    token: 19aefa97-cccc-bbbb-aaaa-225940e63d76

    [Warning]Warning

    Consider carefully your security requirements. Static token authentication is fine if you want quickly get started with Vault, but a static token is not protected any further. Any disclosure to unintended parties allows Vault use with the associated token roles.

    96. Authentication methods

    Different organizations have different requirements for security +property health.vault.enabled (default true).

    96.1 Authentication

    Vault requires an authentication mechanism to authorize client requests.

    Spring Cloud Vault supports multiple authentication mechanisms to authenticate applications with Vault.

    For a quickstart, use the root token printed by the Vault initialization.

    Example 96.3. bootstrap.yml

    spring.cloud.vault:
    +    token: 19aefa97-cccc-bbbb-aaaa-225940e63d76

    [Warning]Warning

    Consider carefully your security requirements. Static token authentication is fine if you want quickly get started with Vault, but a static token is not protected any further. Any disclosure to unintended parties allows Vault use with the associated token roles.

    97. Authentication methods

    Different organizations have different requirements for security and authentication. Vault reflects that need by shipping multiple authentication -methods. Spring Cloud Vault supports token and AppId authentication.

    96.1 Token authentication

    Tokens are the core method for authentication within Vault. +methods. Spring Cloud Vault supports token and AppId authentication.

    97.1 Token authentication

    Tokens are the core method for authentication within Vault. Token authentication requires a static token to be provided using the Bootstrap Application Context.

    [Note]Note

    Token authentication is the default authentication method. If a token is disclosed an unintended party gains access to Vault and -can access secrets for the intended client.

    Example 96.1. bootstrap.yml

    spring.cloud.vault:
    +can access secrets for the intended client.

    Example 97.1. bootstrap.yml

    spring.cloud.vault:
         authentication: TOKEN
         token: 00000000-0000-0000-0000-000000000000

    • authentication setting this value to TOKEN selects the Token -authentication method
    • token sets the static token to use

    See also: Vault Documentation: Tokens

    96.2 AppId authentication

    Vault supports AppId +authentication method

  • token sets the static token to use
  • See also: Vault Documentation: Tokens

    97.2 AppId authentication

    Vault supports AppId authentication that consists of two hard to guess tokens. The AppId defaults to spring.application.name that is statically configured. The second token is the UserId which is a part determined by the application, usually related to the runtime environment. IP address, Mac address or a Docker container name are good examples. Spring Cloud Vault Config supports IP address, Mac address and static UserId’s (e.g. supplied via System properties). -The IP and Mac address are represented as Hex-encoded SHA256 hash.

    IP address-based UserId’s use the local host’s IP address.

    Example 96.2. bootstrap.yml using SHA256 IP-Address UserId’s

    spring.cloud.vault:
    +The IP and Mac address are represented as Hex-encoded SHA256 hash.

    IP address-based UserId’s use the local host’s IP address.

    Example 97.2. bootstrap.yml using SHA256 IP-Address UserId’s

    spring.cloud.vault:
         authentication: APPID
         app-id:
             user-id: IP_ADDRESS

    • authentication setting this value to APPID selects the AppId @@ -11480,42 +11677,42 @@ so make sure to include the -n flag.

      < localhost-bound device. The configuration also allows specifying a network-interface hint to pick the right device. The value of network-interface is optional and can be either an interface -name or interface index (0-based).

      Example 96.3. bootstrap.yml using SHA256 Mac-Address UserId’s

      spring.cloud.vault:
      +name or interface index (0-based).

      Example 97.3. bootstrap.yml using SHA256 Mac-Address UserId’s

      spring.cloud.vault:
           authentication: APPID
           app-id:
               user-id: MAC_ADDRESS
               network-interface: eth0

      • network-interface sets network interface to obtain the physical address

      The corresponding command to generate the IP address UserId from a command line is:

      $ echo -n 0AFEDE1234AC | sha256sum
      [Note]Note

      The Mac address is specified uppercase and without colons. Including the line break of echo leads to a different hash value -so make sure to include the -n flag.

      96.2.1 Custom UserId

      The UserId generation is an open mechanism. You can set +so make sure to include the -n flag.

      97.2.1 Custom UserId

      The UserId generation is an open mechanism. You can set spring.cloud.vault.app-id.user-id to any string and the configured value will be used as static UserId.

      A more advanced approach lets you set spring.cloud.vault.app-id.user-id to a classname. This class must be on your classpath and must implement the org.springframework.cloud.vault.AppIdUserIdMechanism interface and the createUserId method. Spring Cloud Vault will obtain the UserId by calling createUserId each time it authenticates using AppId to -obtain a token.

      Example 96.4. bootstrap.yml

      spring.cloud.vault:
      +obtain a token.

      Example 97.4. bootstrap.yml

      spring.cloud.vault:
           authentication: APPID
           app-id:
      -        user-id: com.examlple.MyUserIdMechanism

      Example 96.5. MyUserIdMechanism.java

      public class MyUserIdMechanism implements AppIdUserIdMechanism {
      +        user-id: com.examlple.MyUserIdMechanism

      Example 97.5. MyUserIdMechanism.java

      public class MyUserIdMechanism implements AppIdUserIdMechanism {
       
         @Override
         public String createUserId() {
           String userId = ...
           return userId;
         }
      -}

      See also: Vault Documentation: Using the App ID auth backend

      96.3 AppRole authentication

      AppRole is intended for machine -authentication, like the deprecated (since Vault 0.6.1) Section 96.2, “AppId authentication”. +}


      See also: Vault Documentation: Using the App ID auth backend

    97.3 AppRole authentication

    AppRole is intended for machine +authentication, like the deprecated (since Vault 0.6.1) Section 97.2, “AppId authentication”. AppRole authentication consists of two hard to guess (secret) tokens: RoleId and SecretId.

    Spring Vault supports various AppRole scenarios (push/pull mode and wrapped).

    RoleId and optionally SecretId must be provided by configuration, -Spring Vault will not look up these or create a custom SecretId.

    Example 96.6. bootstrap.yml with AppRole authentication properties

    spring.cloud.vault:
    +Spring Vault will not look up these or create a custom SecretId.

    Example 97.6. bootstrap.yml with AppRole authentication properties

    spring.cloud.vault:
         authentication: APPROLE
         app-role:
    -        role-id: bde2076b-cccb-3cf0-d57e-bca7b1e83a52

    The following scenarios are supported along the required configuration details:

    Table 96.1. Configuration

    Method

    RoleId

    SecretId

    RoleName

    Token

    Provided RoleId/SecretId

    Provided

    Provided

      

    Provided RoleId without SecretId

    Provided

       

    Provided RoleId, Pull SecretId

    Provided

    Provided

    Provided

    Provided

    Pull RoleId, provided SecretId

     

    Provided

    Provided

    Provided

    Full Pull Mode

      

    Provided

    Provided

    Wrapped

       

    Provided

    Wrapped RoleId, provided SecretId

    Provided

      

    Provided

    Provided RoleId, wrapped SecretId

     

    Provided

     

    Provided


    Table 96.2. Pull/Push/Wrapped Matrix

    RoleId

    SecretId

    Supported

    Provided

    Provided

    Provided

    Pull

    Provided

    Wrapped

    Provided

    Absent

    Pull

    Provided

    Pull

    Pull

    Pull

    Wrapped

    Pull

    Absent

    Wrapped

    Provided

    Wrapped

    Pull

    Wrapped

    Wrapped

    Wrapped

    Absent


    [Note]Note

    You can use still all combinations of push/pull/wrapped modes by providing a configured AppRoleAuthentication bean within the boostrap context. Spring Cloud Vault cannot derive all possible AppRole combinations from the configuration properties.

    Example 96.7. bootstrap.yml with all AppRole authentication properties

    spring.cloud.vault:
    +        role-id: bde2076b-cccb-3cf0-d57e-bca7b1e83a52

    The following scenarios are supported along the required configuration details:

    Table 97.1. Configuration

    Method

    RoleId

    SecretId

    RoleName

    Token

    Provided RoleId/SecretId

    Provided

    Provided

      

    Provided RoleId without SecretId

    Provided

       

    Provided RoleId, Pull SecretId

    Provided

    Provided

    Provided

    Provided

    Pull RoleId, provided SecretId

     

    Provided

    Provided

    Provided

    Full Pull Mode

      

    Provided

    Provided

    Wrapped

       

    Provided

    Wrapped RoleId, provided SecretId

    Provided

      

    Provided

    Provided RoleId, wrapped SecretId

     

    Provided

     

    Provided


    Table 97.2. Pull/Push/Wrapped Matrix

    RoleId

    SecretId

    Supported

    Provided

    Provided

    Provided

    Pull

    Provided

    Wrapped

    Provided

    Absent

    Pull

    Provided

    Pull

    Pull

    Pull

    Wrapped

    Pull

    Absent

    Wrapped

    Provided

    Wrapped

    Pull

    Wrapped

    Wrapped

    Wrapped

    Absent


    [Note]Note

    You can use still all combinations of push/pull/wrapped modes by providing a configured AppRoleAuthentication bean within the boostrap context. Spring Cloud Vault cannot derive all possible AppRole combinations from the configuration properties.

    Example 97.7. bootstrap.yml with all AppRole authentication properties

    spring.cloud.vault:
         authentication: APPROLE
         app-role:
             role-id: bde2076b-cccb-3cf0-d57e-bca7b1e83a52
             secret-id: 1696536f-1976-73b1-b241-0b4213908d39
             role: my-role
    -        app-role-path: approle

    • role-id sets the RoleId.
    • secret-id sets the SecretId. SecretId can be omitted if AppRole is configured without requiring SecretId (See bind_secret_id).
    • role: sets the AppRole name for pull mode.
    • app-role-path sets the path of the approle authentication mount to use.

    See also: Vault Documentation: Using the AppRole auth backend

    96.4 AWS-EC2 authentication

    The aws-ec2 + app-role-path: approle


    • role-id sets the RoleId.
    • secret-id sets the SecretId. SecretId can be omitted if AppRole is configured without requiring SecretId (See bind_secret_id).
    • role: sets the AppRole name for pull mode.
    • app-role-path sets the path of the approle authentication mount to use.

    See also: Vault Documentation: Using the AppRole auth backend

    97.4 AWS-EC2 authentication

    The aws-ec2 auth backend provides a secure introduction mechanism for AWS EC2 instances, allowing automated retrieval of a Vault token. Unlike most Vault authentication backends, this backend @@ -11523,7 +11720,7 @@ does not require first-deploying, or provisioning security-sensitive credentials (tokens, username/password, client certificates, etc.). Instead, it treats AWS as a Trusted Third Party and uses the cryptographically signed dynamic metadata information that uniquely -represents each EC2 instance.

    Example 96.8. bootstrap.yml using AWS-EC2 Authentication

    spring.cloud.vault:
    +represents each EC2 instance.

    Example 97.8. bootstrap.yml using AWS-EC2 Authentication

    spring.cloud.vault:
         authentication: AWS_EC2

    AWS-EC2 authentication enables nonce by default to follow the Trust On First Use (TOFU) principle. Any unintended party that gains access to the PKCS#7 identity metadata can authenticate @@ -11534,17 +11731,17 @@ party does not have the nonce and can raise an alert in Vault for further investigation.

    The nonce is kept in memory and is lost during application restart. You can configure a static nonce with spring.cloud.vault.aws-ec2.nonce.

    AWS-EC2 authentication roles are optional and default to the AMI. You can configure the authentication role by setting the -spring.cloud.vault.aws-ec2.role property.

    Example 96.9. bootstrap.yml with configured role

    spring.cloud.vault:
    +spring.cloud.vault.aws-ec2.role property.

    Example 97.9. bootstrap.yml with configured role

    spring.cloud.vault:
         authentication: AWS_EC2
         aws-ec2:
    -        role: application-server

    Example 96.10. bootstrap.yml with all AWS EC2 authentication properties

    spring.cloud.vault:
    +        role: application-server

    Example 97.10. bootstrap.yml with all AWS EC2 authentication properties

    spring.cloud.vault:
         authentication: AWS_EC2
         aws-ec2:
             role: application-server
             aws-ec2-path: aws-ec2
             identity-document: http://...
             nonce: my-static-nonce

    • authentication setting this value to AWS_EC2 selects the AWS EC2 -authentication method
    • role sets the name of the role against which the login is being attempted.
    • aws-ec2-path sets the path of the AWS EC2 mount to use
    • identity-document sets URL of the PKCS#7 AWS EC2 identity document
    • nonce used for AWS-EC2 authentication. An empty nonce defaults to nonce generation

    See also: Vault Documentation: Using the aws auth backend

    96.5 AWS-IAM authentication

    The aws backend provides a secure +authentication method

  • role sets the name of the role against which the login is being attempted.
  • aws-ec2-path sets the path of the AWS EC2 mount to use
  • identity-document sets URL of the PKCS#7 AWS EC2 identity document
  • nonce used for AWS-EC2 authentication. An empty nonce defaults to nonce generation
  • See also: Vault Documentation: Using the aws auth backend

    97.5 AWS-IAM authentication

    The aws backend provides a secure authentication mechanism for AWS IAM roles, allowing the automatic authentication with vault based on the current IAM role of the running application. Unlike most Vault authentication backends, this backend @@ -11558,39 +11755,39 @@ will use the IAM role assigned to the ECS task of the running container. If you are running your application naked on top of an EC2 instance then the IAM role used will be the one assigned to the EC2 instance.

    When using the AWS-IAM authentication you must create a role in Vault and assign it to your IAM role. An empty role defaults to -the friendly name the current IAM role.

    Example 96.11. bootstrap.yml with required AWS-IAM Authentication properties

    spring.cloud.vault:
    -    authentication: AWS_IAM

    Example 96.12. bootstrap.yml with all AWS-IAM Authentication properties

    spring.cloud.vault:
    +the friendly name the current IAM role.

    Example 97.11. bootstrap.yml with required AWS-IAM Authentication properties

    spring.cloud.vault:
    +    authentication: AWS_IAM

    Example 97.12. bootstrap.yml with all AWS-IAM Authentication properties

    spring.cloud.vault:
         authentication: AWS_IAM
         aws-iam:
             role: my-dev-role
             aws-path: aws
             server-id: some.server.name

    • role sets the name of the role against which the login is being attempted. This should be bound to your IAM role. If one is not supplied then the friendly name of the current IAM user will be used as the vault role.
    • aws-path sets the path of the AWS mount to use
    • server-id sets the value to use for the X-Vault-AWS-IAM-Server-ID header preventing certain types of replay attacks.

    AWS-IAM requires the AWS Java SDK dependency (com.amazonaws:aws-java-sdk-core) -as the authentication implementation uses AWS SDK types for credentials and request signing.

    See also: Vault Documentation: Using the aws auth backend

    96.6 TLS certificate authentication

    The cert auth backend allows authentication using SSL/TLS client -certificates that are either signed by a CA or self-signed.

    To enable cert authentication you need to:

    1. Use SSL, see Chapter 102, Vault Client SSL configuration
    2. Configure a Java Keystore that contains the client -certificate and the private key
    3. Set the spring.cloud.vault.authentication to CERT

    Example 96.13. bootstrap.yml

    spring.cloud.vault:
    +as the authentication implementation uses AWS SDK types for credentials and request signing.

    See also: Vault Documentation: Using the aws auth backend

    97.6 TLS certificate authentication

    The cert auth backend allows authentication using SSL/TLS client +certificates that are either signed by a CA or self-signed.

    To enable cert authentication you need to:

    1. Use SSL, see Chapter 103, Vault Client SSL configuration
    2. Configure a Java Keystore that contains the client +certificate and the private key
    3. Set the spring.cloud.vault.authentication to CERT

    Example 97.13. bootstrap.yml

    spring.cloud.vault:
         authentication: CERT
         ssl:
             key-store: classpath:keystore.jks
             key-store-password: changeit
    -        cert-auth-path: cert

    See also: Vault Documentation: Using the Cert auth backend

    96.7 Cubbyhole authentication

    Cubbyhole authentication uses Vault primitives to provide a secured authentication + cert-auth-path: cert


    See also: Vault Documentation: Using the Cert auth backend

    97.7 Cubbyhole authentication

    Cubbyhole authentication uses Vault primitives to provide a secured authentication workflow. Cubbyhole authentication uses tokens as primary login method. An ephemeral token is used to obtain a second, login VaultToken from Vault’s Cubbyhole secret backend. The login token is usually longer-lived and used to interact with Vault. The login token will be retrieved from a wrapped -response stored at /cubbyhole/response.

    Creating a wrapped token

    [Note]Note

    Response Wrapping for token creation requires Vault 0.6.0 or higher.

    Example 96.14. Creating and storing tokens

    $ vault token-create -wrap-ttl="10m"
    +response stored at /cubbyhole/response.

    Creating a wrapped token

    [Note]Note

    Response Wrapping for token creation requires Vault 0.6.0 or higher.

    Example 97.14. Creating and storing tokens

    $ vault token-create -wrap-ttl="10m"
     Key                            Value
     ---                            -----
     wrapping_token:                397ccb93-ff6c-b17b-9389-380b01ca2645
     wrapping_token_ttl:            0h10m0s
     wrapping_token_creation_time:  2016-09-18 20:29:48.652957077 +0200 CEST
    -wrapped_accessor:              46b6aebb-187f-932a-26d7-4f3d86a68319

    Example 96.15. bootstrap.yml

    spring.cloud.vault:
    +wrapped_accessor:              46b6aebb-187f-932a-26d7-4f3d86a68319

    Example 97.15. bootstrap.yml

    spring.cloud.vault:
         authentication: CUBBYHOLE
    -    token: 397ccb93-ff6c-b17b-9389-380b01ca2645

    See also:

    96.8 Kubernetes authentication

    Kubernetes authentication mechanism (since Vault 0.8.3) allows to authenticate with Vault using a Kubernetes Service Account Token. -The authentication is role based and the role is bound to a service account name and a namespace.

    A file containing a JWT token for a pod’s service account is automatically mounted at /var/run/secrets/kubernetes.io/serviceaccount/token.

    Example 96.16. bootstrap.yml with all Kubernetes authentication properties

    spring.cloud.vault:
    +    token: 397ccb93-ff6c-b17b-9389-380b01ca2645

    See also:

    97.8 Kubernetes authentication

    Kubernetes authentication mechanism (since Vault 0.8.3) allows to authenticate with Vault using a Kubernetes Service Account Token. +The authentication is role based and the role is bound to a service account name and a namespace.

    A file containing a JWT token for a pod’s service account is automatically mounted at /var/run/secrets/kubernetes.io/serviceaccount/token.

    Example 97.16. bootstrap.yml with all Kubernetes authentication properties

    spring.cloud.vault:
         authentication: KUBERNETES
         kubernetes:
             role: my-dev-role
    -        service-account-token-file: /var/run/secrets/kubernetes.io/serviceaccount/token

    • role sets the Role.
    • service-account-token-file sets the location of the file containing the Kubernetes Service Account Token. Defaults to /var/run/secrets/kubernetes.io/serviceaccount/token.

    See also:

    97. Secret Backends

    97.1 Generic Backend

    Spring Cloud Vault supports at the basic level the generic secret + service-account-token-file: /var/run/secrets/kubernetes.io/serviceaccount/token


    • role sets the Role.
    • service-account-token-file sets the location of the file containing the Kubernetes Service Account Token. Defaults to /var/run/secrets/kubernetes.io/serviceaccount/token.

    See also:

    98. Secret Backends

    98.1 Generic Backend

    Spring Cloud Vault supports at the basic level the generic secret backend. The generic secret backend allows storage of arbitrary values as key-value store. A single context can store one or many key-value tuples. Contexts can be organized hierarchically. @@ -11610,9 +11807,9 @@ No active profiles will skip accessing contexts with a profile name.

    Prope default-context: application application-name: my-app

    • enabled setting this value to false disables the secret backend config usage
    • backend sets the path of the secret mount to use
    • default-context sets the context name used by all applications
    • application-name overrides the application name for use in the generic backend
    • profile-separator separates the profile name from the context in -property sources with profiles

    See also: Vault Documentation: Using the generic secret backend

    97.2 Consul

    Spring Cloud Vault can obtain credentials for HashiCorp Consul. +property sources with profiles

    See also: Vault Documentation: Using the generic secret backend

    98.2 Consul

    Spring Cloud Vault can obtain credentials for HashiCorp Consul. The Consul integration requires the spring-cloud-vault-config-consul -dependency.

    Example 97.1. pom.xml

    <dependencies>
    +dependency.

    Example 98.1. pom.xml

    <dependencies>
         <dependency>
             <groupId>org.springframework.cloud</groupId>
             <artifactId>spring-cloud-vault-config-consul</artifactId>
    @@ -11628,8 +11825,8 @@ the property name by setting spring.cloud.vault.consul.tok
             enabled: true
             role: readonly
             backend: consul
    -        token-property: spring.cloud.consul.token
    • enabled setting this value to true enables the Consul backend config usage
    • role sets the role name of the Consul role definition
    • backend sets the path of the Consul mount to use
    • token-property sets the property name in which the Consul ACL token is stored

    See also: Vault Documentation: Setting up Consul with Vault

    97.3 RabbitMQ

    Spring Cloud Vault can obtain credentials for RabbitMQ.

    The RabbitMQ integration requires the spring-cloud-vault-config-rabbitmq -dependency.

    Example 97.2. pom.xml

    <dependencies>
    +        token-property: spring.cloud.consul.token
    • enabled setting this value to true enables the Consul backend config usage
    • role sets the role name of the Consul role definition
    • backend sets the path of the Consul mount to use
    • token-property sets the property name in which the Consul ACL token is stored

    See also: Vault Documentation: Setting up Consul with Vault

    98.3 RabbitMQ

    Spring Cloud Vault can obtain credentials for RabbitMQ.

    The RabbitMQ integration requires the spring-cloud-vault-config-rabbitmq +dependency.

    Example 98.2. pom.xml

    <dependencies>
         <dependency>
             <groupId>org.springframework.cloud</groupId>
             <artifactId>spring-cloud-vault-config-rabbitmq</artifactId>
    @@ -11647,8 +11844,8 @@ by setting spring.cloud.vault.rabbitmq.username-property        role: readonly
             backend: rabbitmq
             username-property: spring.rabbitmq.username
    -        password-property: spring.rabbitmq.password
    • enabled setting this value to true enables the RabbitMQ backend config usage
    • role sets the role name of the RabbitMQ role definition
    • backend sets the path of the RabbitMQ mount to use
    • username-property sets the property name in which the RabbitMQ username is stored
    • password-property sets the property name in which the RabbitMQ password is stored

    See also: Vault Documentation: Setting up RabbitMQ with Vault

    97.4 AWS

    Spring Cloud Vault can obtain credentials for AWS.

    The AWS integration requires the spring-cloud-vault-config-aws -dependency.

    Example 97.3. pom.xml

    <dependencies>
    +        password-property: spring.rabbitmq.password
    • enabled setting this value to true enables the RabbitMQ backend config usage
    • role sets the role name of the RabbitMQ role definition
    • backend sets the path of the RabbitMQ mount to use
    • username-property sets the property name in which the RabbitMQ username is stored
    • password-property sets the property name in which the RabbitMQ password is stored

    See also: Vault Documentation: Setting up RabbitMQ with Vault

    98.4 AWS

    Spring Cloud Vault can obtain credentials for AWS.

    The AWS integration requires the spring-cloud-vault-config-aws +dependency.

    Example 98.3. pom.xml

    <dependencies>
         <dependency>
             <groupId>org.springframework.cloud</groupId>
             <artifactId>spring-cloud-vault-config-aws</artifactId>
    @@ -11666,16 +11863,16 @@ by setting spring.cloud.vault.aws.access-key-property        role: readonly
             backend: aws
             access-key-property: cloud.aws.credentials.accessKey
    -        secret-key-property: cloud.aws.credentials.secretKey
    • enabled setting this value to true enables the AWS backend config usage
    • role sets the role name of the AWS role definition
    • backend sets the path of the AWS mount to use
    • access-key-property sets the property name in which the AWS access key is stored
    • secret-key-property sets the property name in which the AWS secret key is stored

    See also: Vault Documentation: Setting up AWS with Vault

    98. Database backends

    Vault supports several database secret backends to generate database + secret-key-property: cloud.aws.credentials.secretKey

    • enabled setting this value to true enables the AWS backend config usage
    • role sets the role name of the AWS role definition
    • backend sets the path of the AWS mount to use
    • access-key-property sets the property name in which the AWS access key is stored
    • secret-key-property sets the property name in which the AWS secret key is stored

    See also: Vault Documentation: Setting up AWS with Vault

    99. Database backends

    Vault supports several database secret backends to generate database credentials dynamically based on configured roles. This means services that need to access a database no longer need to configure credentials: they can request them from Vault, and use Vault’s leasing -mechanism to more easily roll keys.

    Spring Cloud Vault integrates with these backends:

    Using a database secret backend requires to enable the +mechanism to more easily roll keys.

    Spring Cloud Vault integrates with these backends:

    Using a database secret backend requires to enable the backend in the configuration and the spring-cloud-vault-config-databases dependency.

    Vault ships since 0.7.1 with a dedicated database secret backend that allows database integration via plugins. You can use that specific backend by using the generic database backend. Make sure to specify the appropriate -backend path, e.g. spring.cloud.vault.mysql.role.backend=database.

    Example 98.1. pom.xml

    <dependencies>
    +backend path, e.g. spring.cloud.vault.mysql.role.backend=database.

    Example 99.1. pom.xml

    <dependencies>
         <dependency>
             <groupId>org.springframework.cloud</groupId>
             <artifactId>spring-cloud-vault-config-databases</artifactId>
    @@ -11683,7 +11880,7 @@ backend path, e.g. spring.cloud.vault.mysql.role.backend=d
         </dependency>
     </dependencies>

    [Note]Note

    Enabling multiple JDBC-compliant databases will generate credentials and store them by default in the same property keys hence property names for -JDBC secrets need to be configured separately.

    98.1 Database

    Spring Cloud Vault can obtain credentials for any database listed at +JDBC secrets need to be configured separately.

    99.1 Database

    Spring Cloud Vault can obtain credentials for any database listed at https://www.vaultproject.io/api/secret/databases/index.html. The integration can be enabled by setting spring.cloud.vault.database.enabled=true (default false) and @@ -11700,7 +11897,7 @@ You can configure the property names by setting role: readonly backend: database username-property: spring.datasource.username - password-property: spring.datasource.username

    • enabled setting this value to true enables the Database backend config usage
    • role sets the role name of the Database role definition
    • backend sets the path of the Database mount to use
    • username-property sets the property name in which the Database username is stored
    • password-property sets the property name in which the Database password is stored

    See also: Vault Documentation: Database Secrets backend

    98.2 Apache Cassandra

    [Note]Note

    The cassandra backend has been deprecated in Vault 0.7.1 and + password-property: spring.datasource.username

    • enabled setting this value to true enables the Database backend config usage
    • role sets the role name of the Database role definition
    • backend sets the path of the Database mount to use
    • username-property sets the property name in which the Database username is stored
    • password-property sets the property name in which the Database password is stored

    See also: Vault Documentation: Database Secrets backend

    99.2 Apache Cassandra

    [Note]Note

    The cassandra backend has been deprecated in Vault 0.7.1 and it is recommended to use the database backend and mount it as cassandra.

    Spring Cloud Vault can obtain credentials for Apache Cassandra. The integration can be enabled by setting spring.cloud.vault.cassandra.enabled=true (default false) and @@ -11715,7 +11912,7 @@ You can configure the property names by setting role: readonly backend: cassandra username-property: spring.data.cassandra.username - password-property: spring.data.cassandra.username

    • enabled setting this value to true enables the Cassandra backend config usage
    • role sets the role name of the Cassandra role definition
    • backend sets the path of the Cassandra mount to use
    • username-property sets the property name in which the Cassandra username is stored
    • password-property sets the property name in which the Cassandra password is stored

    See also: Vault Documentation: Setting up Apache Cassandra with Vault

    98.3 MongoDB

    [Note]Note

    The mongodb backend has been deprecated in Vault 0.7.1 and + password-property: spring.data.cassandra.username

    • enabled setting this value to true enables the Cassandra backend config usage
    • role sets the role name of the Cassandra role definition
    • backend sets the path of the Cassandra mount to use
    • username-property sets the property name in which the Cassandra username is stored
    • password-property sets the property name in which the Cassandra password is stored

    See also: Vault Documentation: Setting up Apache Cassandra with Vault

    99.3 MongoDB

    [Note]Note

    The mongodb backend has been deprecated in Vault 0.7.1 and it is recommended to use the database backend and mount it as mongodb.

    Spring Cloud Vault can obtain credentials for MongoDB. The integration can be enabled by setting spring.cloud.vault.mongodb.enabled=true (default false) and @@ -11730,7 +11927,7 @@ You can configure the property names by setting role: readonly backend: mongodb username-property: spring.data.mongodb.username - password-property: spring.data.mongodb.password

    • enabled setting this value to true enables the MongodB backend config usage
    • role sets the role name of the MongoDB role definition
    • backend sets the path of the MongoDB mount to use
    • username-property sets the property name in which the MongoDB username is stored
    • password-property sets the property name in which the MongoDB password is stored

    See also: Vault Documentation: Setting up MongoDB with Vault

    98.4 MySQL

    [Note]Note

    The mysql backend has been deprecated in Vault 0.7.1 and + password-property: spring.data.mongodb.password

    • enabled setting this value to true enables the MongodB backend config usage
    • role sets the role name of the MongoDB role definition
    • backend sets the path of the MongoDB mount to use
    • username-property sets the property name in which the MongoDB username is stored
    • password-property sets the property name in which the MongoDB password is stored

    See also: Vault Documentation: Setting up MongoDB with Vault

    99.4 MySQL

    [Note]Note

    The mysql backend has been deprecated in Vault 0.7.1 and it is recommended to use the database backend and mount it as mysql. Configuration for spring.cloud.vault.mysql will be removed in a future version.

    Spring Cloud Vault can obtain credentials for MySQL. The integration can be enabled by setting @@ -11746,7 +11943,7 @@ You can configure the property names by setting role: readonly backend: mysql username-property: spring.datasource.username - password-property: spring.datasource.username

    • enabled setting this value to true enables the MySQL backend config usage
    • role sets the role name of the MySQL role definition
    • backend sets the path of the MySQL mount to use
    • username-property sets the property name in which the MySQL username is stored
    • password-property sets the property name in which the MySQL password is stored

    See also: Vault Documentation: Setting up MySQL with Vault

    98.5 PostgreSQL

    [Note]Note

    The postgresql backend has been deprecated in Vault 0.7.1 and + password-property: spring.datasource.username

    • enabled setting this value to true enables the MySQL backend config usage
    • role sets the role name of the MySQL role definition
    • backend sets the path of the MySQL mount to use
    • username-property sets the property name in which the MySQL username is stored
    • password-property sets the property name in which the MySQL password is stored

    See also: Vault Documentation: Setting up MySQL with Vault

    99.5 PostgreSQL

    [Note]Note

    The postgresql backend has been deprecated in Vault 0.7.1 and it is recommended to use the database backend and mount it as postgresql. Configuration for spring.cloud.vault.postgresql will be removed in a future version.

    Spring Cloud Vault can obtain credentials for PostgreSQL. The integration can be enabled by setting @@ -11762,7 +11959,7 @@ You can configure the property names by setting role: readonly backend: postgresql username-property: spring.datasource.username - password-property: spring.datasource.username

    • enabled setting this value to true enables the PostgreSQL backend config usage
    • role sets the role name of the PostgreSQL role definition
    • backend sets the path of the PostgreSQL mount to use
    • username-property sets the property name in which the PostgreSQL username is stored
    • password-property sets the property name in which the PostgreSQL password is stored

    See also: Vault Documentation: Setting up PostgreSQL with Vault

    99. Configure PropertySourceLocator behavior

    Spring Cloud Vault uses property-based configuration to create PropertySources + password-property: spring.datasource.username

    • enabled setting this value to true enables the PostgreSQL backend config usage
    • role sets the role name of the PostgreSQL role definition
    • backend sets the path of the PostgreSQL mount to use
    • username-property sets the property name in which the PostgreSQL username is stored
    • password-property sets the property name in which the PostgreSQL password is stored

    See also: Vault Documentation: Setting up PostgreSQL with Vault

    100. Configure PropertySourceLocator behavior

    Spring Cloud Vault uses property-based configuration to create PropertySources for generic and discovered secret backends.

    Discovered backends provide VaultSecretBackendDescriptor beans to describe the configuration state to use secret backend as PropertySource. A SecretBackendMetadataFactory is required to create a SecretBackendMetadata object which contains path, name and property transformation @@ -11781,7 +11978,7 @@ at least one VaultConfigurer bean. You can however } }

    [Note]Note

    All customization is required to happen in the bootstrap context. Add your configuration classes to META-INF/spring.factories at org.springframework.cloud.bootstrap.BootstrapConfiguration -in your application.

    100. Service Registry Configuration

    You can use a DiscoveryClient (such as from Spring Cloud Consul) to locate +in your application.

    101. Service Registry Configuration

    You can use a DiscoveryClient (such as from Spring Cloud Consul) to locate a Vault server by setting spring.cloud.vault.discovery.enabled=true (default false). The net result of that is that your apps need a bootstrap.yml (or an environment variable) with the appropriate discovery configuration. @@ -11795,12 +11992,12 @@ need to provide a scheme metadata entry to be set e If no scheme is configured and the service is not exposed as secure service, then configuration defaults to spring.cloud.vault.scheme which is https when it’s not set.

    spring.cloud.vault.discovery:
         enabled: true
    -    service-id: my-vault-service

    101. Vault Client Fail Fast

    In some cases, it may be desirable to fail startup of a service if + service-id: my-vault-service

    102. Vault Client Fail Fast

    In some cases, it may be desirable to fail startup of a service if it cannot connect to the Vault Server. If this is the desired behavior, set the bootstrap configuration property spring.cloud.vault.fail-fast=true and the client will halt with an Exception.

    spring.cloud.vault:
    -    fail-fast: true

    102. Vault Client SSL configuration

    SSL can be configured declaratively by setting various properties. + fail-fast: true

    103. Vault Client SSL configuration

    SSL can be configured declaratively by setting various properties. You can set either javax.net.ssl.trustStore to configure JVM-wide SSL settings or spring.cloud.vault.ssl.trust-store to set SSL settings only for Spring Cloud Vault Config.

    spring.cloud.vault:
    @@ -11810,7 +12007,7 @@ to set SSL settings only for Spring Cloud Vault Config.

    trust-store-password sets the trust-store password

    Please note that configuring spring.cloud.vault.ssl.* can be only applied when either Apache Http Components or the OkHttp client -is on your class-path.

    103. Lease lifecycle management (renewal and revocation)

    With every secret, Vault creates a lease: +is on your class-path.

    104. Lease lifecycle management (renewal and revocation)

    With every secret, Vault creates a lease: metadata containing information such as a time duration, renewability, and more.

    Vault promises that the data will be valid for the given duration, or Time To Live (TTL). Once the lease is expired, Vault can @@ -11829,7 +12026,346 @@ to false. This is not recommended as leases can exp Spring Cloud Vault cannot longer access Vault or services using generated credentials and valid credentials remain active after application shutdown.

    spring.cloud.vault:
    -    config.lifecycle.enabled: true

    See also: Vault Documentation: Lease, Renew, and Revoke

    Part XIV. 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 + config.lifecycle.enabled: true

    See also: Vault Documentation: Lease, Renew, and Revoke

    Part XV. Spring Cloud Gateway

    1.3.5.BUILD-SNAPSHOT

    This project provides an API Gateway built on top of the Spring Ecosystem, including: Spring 5, Spring Boot 2 and Project Reactor. Spring Cloud Gateway aims to provide a simple, yet effective way to route to APIs and provide cross cutting concerns to them such as: security, monitoring/metrics, and resiliency.

    105. How to Include Spring Cloud Gateway

    To include Spring Cloud Gateway in your project use the starter with group org.springframework.cloud +and artifact id spring-cloud-starter-gateway. See the Spring Cloud Project page +for details on setting up your build system with the current Spring Cloud Release Train.

    If you include the starter, but, for some reason, you do not want the gateway to be enabled, set spring.cloud.gateway.enabled=false.

    106. Glossary

    • Route: Route the basic building block of the gateway. It is defined by an ID, a destination URI, a collection of predicates and a collection of filters. A route is matched if aggregate predicate is true.
    • Predicate: This is a Java 8 Function Predicate. The input type is a Spring Framework ServerWebExchange. This allows developers to match on anything from the HTTP request, such as headers or parameters.
    • Filter: These are instances Spring Framework GatewayFilter constructed in with a specific factory. Here, requests and responses can be modified before or after sending the downstream request.

    107. How It Works

    Spring Cloud Gateway Diagram

    Clients make requests to Spring Cloud Gateway. If the Gateway Handler Mapping determines that a request matches a Route, it is sent to the Gateway Web Handler. This handler runs sends the request through a filter chain that is specific to the request. The reason the filters are divided by the dotted line, is that filters may execute logic before the proxy request is sent or after. All "pre" filter logic is executed, then the proxy request is made. After the proxy request is made, the "post" filter logic is executed.

    [Note]Note

    URIs defined in routes without a port will get a default port set to 80 and 443 for HTTP and HTTPS URIs respectively.

    108. Route Predicate Factories

    Spring Cloud Gateway matches routes as part of the Spring WebFlux HandlerMapping infrastructure. Spring Cloud Gateway includes many built-in Route Predicate Factories. All of these predicates match on different attributes of the HTTP request. Multiple Route Predicate Factories can be combined and are combined via logical and.

    108.1 After Route Predicate Factory

    The After Route Predicate Factory takes one parameter, a datetime. This predicate matches requests that happen after the current datetime.

    application.yml.  +

    spring:
    +  cloud:
    +    gateway:
    +      routes:
    +      - id: after_route
    +        uri: http://example.org
    +        predicates:
    +        - After=2017-01-20T17:42:47.789-07:00[America/Denver]

    +

    This route matches any request after Jan 20, 2017 17:42 Mountain Time (Denver).

    108.2 Before Route Predicate Factory

    The Before Route Predicate Factory takes one parameter, a datetime. This predicate matches requests that happen before the current datetime.

    application.yml.  +

    spring:
    +  cloud:
    +    gateway:
    +      routes:
    +      - id: before_route
    +        uri: http://example.org
    +        predicates:
    +        - Before=2017-01-20T17:42:47.789-07:00[America/Denver]

    +

    This route matches any request before Jan 20, 2017 17:42 Mountain Time (Denver).

    108.3 Between Route Predicate Factory

    The Between Route Predicate Factory takes two parameters, datetime1 and datetime2. This predicate matches requests that happen after datetime1 and before datetime2. The datetime2 parameter must be after datetime1.

    application.yml.  +

    spring:
    +  cloud:
    +    gateway:
    +      routes:
    +      - id: between_route
    +        uri: http://example.org
    +        predicates:
    +        - Betweeen=2017-01-20T17:42:47.789-07:00[America/Denver], 2017-01-21T17:42:47.789-07:00[America/Denver]

    +

    This route matches any request after Jan 20, 2017 17:42 Mountain Time (Denver) and before Jan 21, 2017 17:42 Mountain Time (Denver). This could be useful for maintenance windows.

    108.4 Cookie Route Predicate Factory

    The Cookie Route Predicate Factory takes two parameters, the cookie name and a regular expression. This predicate matches cookies that have the given name and the value matches the regular expression.

    application.yml.  +

    spring:
    +  cloud:
    +    gateway:
    +      routes:
    +      - id: cookie_route
    +        uri: http://example.org
    +        predicates:
    +        - Cookie=chocolate, ch.p

    +

    This route matches the request has a cookie named chocolate who’s value matches the ch.p regular expression.

    108.5 Header Route Predicate Factory

    The Header Route Predicate Factory takes two parameters, the header name and a regular expression. This predicate matches with a header that has the given name and the value matches the regular expression.

    application.yml.  +

    spring:
    +  cloud:
    +    gateway:
    +      routes:
    +      - id: header_route
    +        uri: http://example.org
    +        predicates:
    +        - Header=X-Request-Id, \d+

    +

    This route matches if the request has a header named X-Request-Id whos value matches the \d+ regular expression (has a value of one or more digits).

    108.6 Host Route Predicate Factory

    The Host Route Predicate Factory takes one parameter: the host name pattern. The pattern is an Ant style pattern with . as the separator. This predicates matches the Host header that matches the pattern.

    application.yml.  +

    spring:
    +  cloud:
    +    gateway:
    +      routes:
    +      - id: host_route
    +        uri: http://example.org
    +        predicates:
    +        - Host=**.somehost.org

    +

    This route would match if the request has a Host header has the value www.somehost.org or beta.somehost.org.

    108.7 Method Route Predicate Factory

    The Method Route Predicate Factory takes one parameter: the HTTP method to match.

    application.yml.  +

    spring:
    +  cloud:
    +    gateway:
    +      routes:
    +      - id: method_route
    +        uri: http://example.org
    +        predicates:
    +        - Method=GET

    +

    This route would match if the request method was a GET.

    108.8 Path Route Predicate Factory

    The Path Route Predicate Factory takes one parameter: a Spring PathMatcher pattern.

    application.yml.  +

    spring:
    +  cloud:
    +    gateway:
    +      routes:
    +      - id: host_route
    +        uri: http://example.org
    +        predicates:
    +        - Path=/foo/{segment}

    +

    This route would match if the request path was, for example: /foo/1 or /foo/bar.

    This predicate extracts the URI template variables (like segment defined in the example above) as a map of names and values and places it in the ServerWebExchange.getAttributes() with a key defined in PathRoutePredicate.URL_PREDICATE_VARS_ATTR. Those values are then available for use by GatewayFilter Factories

    108.9 Query Route Predicate Factory

    The Query Route Predicate Factory takes two parameters: a required param and an optional regexp.

    application.yml.  +

    spring:
    +  cloud:
    +    gateway:
    +      routes:
    +      - id: query_route
    +        uri: http://example.org
    +        predicates:
    +        - Query=baz

    +

    This route would match if the request contained a baz query parameter.

    application.yml.  +

    spring:
    +  cloud:
    +    gateway:
    +      routes:
    +      - id: query_route
    +        uri: http://example.org
    +        predicates:
    +        - Query=foo, ba.

    +

    This route would match if the request contained a foo query parameter whose value matched the ba. regexp, so bar and baz would match.

    108.10 RemoteAddr Route Predicate Factory

    The RemoteAddr Route Predicate Factory takes a list (min size 1) of CIDR-notation (IPv4 or IPv6) strings, e.g. 192.168.0.1/16 (where 192.168.0.1 is an IP address and 16 is a subnet mask.

    application.yml.  +

    spring:
    +  cloud:
    +    gateway:
    +      routes:
    +      - id: remoteaddr_route
    +        uri: http://example.org
    +        predicates:
    +        - RemoteAddr=192.168.1.1/24

    +

    This route would match if the remote address of the request was, for example, 192.168.1.10.

    109. GatewayFilter Factories

    Route filters allow the modification of the incoming HTTP request or outgoing HTTP response in some manner. Route filters are scoped to a particular route. Spring Cloud Gateway includes many built-in GatewayFilter Factories.

    109.1 AddRequestHeader GatewayFilter Factory

    The AddRequestHeader GatewayFilter Factory takes a name and value parameter.

    application.yml.  +

    spring:
    +  cloud:
    +    gateway:
    +      routes:
    +      - id: add_request_header_route
    +        uri: http://example.org
    +        filters:
    +        - AddRequestHeader=X-Request-Foo, Bar

    +

    This will add X-Request-Foo:Bar header to the downstream request’s headers for all matching requests.

    109.2 AddRequestParameter GatewayFilter Factory

    The AddRequestParameter GatewayFilter Factory takes a name and value parameter.

    application.yml.  +

    spring:
    +  cloud:
    +    gateway:
    +      routes:
    +      - id: add_request_parameter_route
    +        uri: http://example.org
    +        filters:
    +        - AddRequestParameter=foo, bar

    +

    This will add foo=bar to the downstream request’s query string for all matching requests.

    109.3 AddResponseHeader GatewayFilter Factory

    The AddResponseHeader GatewayFilter Factory takes a name and value parameter.

    application.yml.  +

    spring:
    +  cloud:
    +    gateway:
    +      routes:
    +      - id: add_request_header_route
    +        uri: http://example.org
    +        filters:
    +        - AddResponseHeader=X-Response-Foo, Bar

    +

    This will add X-Response-Foo:Bar header to the downstream response’s headers for all matching requests.

    109.4 Hystrix GatewayFilter Factory

    The Hystrix GatewayFilter Factory takes a single name parameters, which is the name of the HystrixCommand. (More options might be added in future releases).

    application.yml.  +

    spring:
    +  cloud:
    +    gateway:
    +      routes:
    +      - id: hytstrix_route
    +        uri: http://example.org
    +        filters:
    +        - Hystrix=myCommandName

    +

    This wraps the remaining filters in a HystrixCommand with command name myCommandName.

    The Hystrix filter takes an optional fallbackUri parameter. Currently, only forward: schemed URIs are supported. If the fallback is called, the request will be forwarded to the controller matched by the URI.

    application.yml.  +

    spring:
    +  cloud:
    +    gateway:
    +      routes:
    +      - id: hytstrix_route
    +        uri: http://example.org
    +        filters:
    +        - name: Hystrix
    +          args:
    +            name: fallbackcmd
    +            fallbackUri: forward:/fallbackcontroller
    +
    +This will forward to the `/fallbackcontroller` when the Hystrix fallback is called.

    +

    109.5 PrefixPath GatewayFilter Factory

    The PrefixPath GatewayFilter Factory takes a single prefix parameter.

    application.yml.  +

    spring:
    +  cloud:
    +    gateway:
    +      routes:
    +      - id: prefixpath_route
    +        uri: http://example.org
    +        filters:
    +        - PrefixPath=/mypath

    +

    This will prefix /mypath to the path of all matching requests. So a request to /hello, would be sent to /mypath/hello.

    109.6 PreserveHostHeader GatewayFilter Factory

    The PreserveHostHeader GatewayFilter Factory has not parameters. This filter, sets a request attribute that the routing filter will inspect to determine if the original host header should be sent, rather than the host header determined by the http client.

    application.yml.  +

    spring:
    +  cloud:
    +    gateway:
    +      routes:
    +      - id: preserve_host_route
    +        uri: http://example.org
    +        filters:
    +        - PreserveHostHeader

    +

    This will prefix /mypath to the path of all matching requests. So a request to /hello, would be sent to /mypath/hello.

    109.7 RequestRateLimiter GatewayFilter Factory

    The RequestRateLimiter GatewayFilter Factory takes three parameters: replenishRate, burstCapacity & keyResolverName.

    replenishRate is how many requests per second do you want a user to be allowed to do.

    burstCapacity TODO: document burst capacity

    keyResolver is a bean that implements the KeyResolver interface. In configuration, reference the bean by name using SpEL. #{@myKeyResolver} is a SpEL expression referencing a bean with the name myKeyResolver.

    KeyResolver.java.  +

    public interface KeyResolver {
    +	Mono<String> resolve(ServerWebExchange exchange);
    +}

    +

    The KeyResolver interface allows pluggable strategies to derive the key for limiting requests. In future milestones, there will be some KeyResolver implementations.

    The redis implementation is based off of work done at Stripe. It requires the use of the spring-boot-starter-data-redis-reactive Spring Boot starter.

    application.yml.  +

    spring:
    +  cloud:
    +    gateway:
    +      routes:
    +      - id: requestratelimiter_route
    +        uri: http://example.org
    +        filters:
    +        - RequestRateLimiter=10, 20, #{@userKeyResolver}

    +

    Config.java.  +

    @Bean
    +KeyResolver userKeyResolver() {
    +    return exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst("user"));
    +}

    +

    This defines a request rate limit of 10 per user. The KeyResolver is a simple one that gets the user request parameter (note: this is not recommended for production).

    109.8 RedirectTo GatewayFilter Factory

    The RedirectTo GatewayFilter Factory takes a status and a url parameter. The status should be a 300 series redirect http code, such as 301. The url should be a valid url. This will be the value of the Location header.

    application.yml.  +

    spring:
    +  cloud:
    +    gateway:
    +      routes:
    +      - id: prefixpath_route
    +        uri: http://example.org
    +        filters:
    +        - RedirectTo=302, http://acme.org

    +

    This will send a status 302 with a Location:http://acme.org header to perform a redirect.

    109.9 RemoveNonProxyHeaders GatewayFilter Factory

    The RemoveNonProxyHeaders GatewayFilter Factory removes headers from forwarded requests. The default list of headers that is removed comes from the IETF.

    The default removed headers are:

    • Connection
    • Keep-Alive
    • Proxy-Authenticate
    • Proxy-Authorization
    • TE
    • Trailer
    • Transfer-Encoding
    • Upgrade

    To change this, set the spring.cloud.gateway.filter.remove-non-proxy-headers.headers property to the list of header names to remove.

    109.10 RemoveRequestHeader GatewayFilter Factory

    The RemoveRequestHeader GatewayFilter Factory takes a name parameter. It is the name of the header to be removed.

    application.yml.  +

    spring:
    +  cloud:
    +    gateway:
    +      routes:
    +      - id: removerequestheader_route
    +        uri: http://example.org
    +        filters:
    +        - RemoveRequestHeader=X-Request-Foo

    +

    This will remove the X-Request-Foo header before it is sent downstream.

    109.11 RemoveResponseHeader GatewayFilter Factory

    The RemoveResponseHeader GatewayFilter Factory takes a name parameter. It is the name of the header to be removed.

    application.yml.  +

    spring:
    +  cloud:
    +    gateway:
    +      routes:
    +      - id: removeresponseheader_route
    +        uri: http://example.org
    +        filters:
    +        - RemoveResponseHeader=X-Response-Foo

    +

    This will remove the X-Response-Foo header from the response before it is returned to the gateway client.

    109.12 RewritePath GatewayFilter Factory

    The RewritePath GatewayFilter Factory takes a path regexp parameter and a replacement parameter. This uses Java regular expressions for a flexible way to rewrite the request path.

    application.yml.  +

    spring:
    +  cloud:
    +    gateway:
    +      routes:
    +      - id: rewritepath_route
    +        uri: http://example.org
    +        predicates:
    +        - Path=/foo/**
    +        filters:
    +        - RewritePath=/foo/(?<segment>.*), /$\{segment}

    +

    For a request path of /foo/bar, this will set the path to /bar before making the downstream request. Notice the $\ which is replaced with $ because of the YAML spec.

    109.13 SaveSession GatewayFilter Factory

    The SaveSession GatewayFilter Factory forces a WebSession::save operation before forwarding the call downstream. This is of particular use when +using something like Spring Session with a lazy data store and need to ensure the session state has been saved before making the forwarded call.

    application.yml.  +

    spring:
    +  cloud:
    +    gateway:
    +      routes:
    +      - id: save_session
    +        uri: http://example.org
    +        predicates:
    +        - Path=/foo/**
    +        filters:
    +        - SaveSession

    +

    If you are integrating Spring Security with Spring Session, and want to ensure security details have been forwarded to the remote process, this is critical.

    109.14 SecureHeaders GatewayFilter Factory

    The SecureHeaders GatewayFilter Factory adds a number of headers to the response at the reccomendation from this blog post.

    The following headers are added (allong with default values):

    • X-Xss-Protection:1; mode=block
    • Strict-Transport-Security:max-age=631138519
    • X-Frame-Options:DENY
    • X-Content-Type-Options:nosniff
    • Referrer-Policy:no-referrer
    • Content-Security-Policy:default-src 'self' https:; font-src 'self' https: data:; img-src 'self' https: data:; object-src 'none'; script-src https:; style-src 'self' https: 'unsafe-inline'
    • X-Download-Options:noopen
    • X-Permitted-Cross-Domain-Policies:none

    To change the default values set the appropriate property in the spring.cloud.gateway.filter.secure-headers namespace:

    Property to change:

    • xss-protection-header
    • strict-transport-security
    • frame-options
    • content-type-options
    • referrer-policy
    • content-security-policy
    • download-options
    • permitted-cross-domain-policies

    109.15 SetPath GatewayFilter Factory

    The SetPath GatewayFilter Factory takes a path template parameter. It offers a simple way to manipulate the request path by allowing templated segments of the path. This uses the uri templates from Spring Framework. Multiple matching segments are allowed.

    application.yml.  +

    spring:
    +  cloud:
    +    gateway:
    +      routes:
    +      - id: setpath_route
    +        uri: http://example.org
    +        predicates:
    +        - Path=/foo/{segment}
    +        filters:
    +        - SetPath=/{segment}

    +

    For a request path of /foo/bar, this will set the path to /bar before making the downstream request.

    109.16 SetResponseHeader GatewayFilter Factory

    The SetResponseHeader GatewayFilter Factory takes name and value parameters.

    application.yml.  +

    spring:
    +  cloud:
    +    gateway:
    +      routes:
    +      - id: setresponseheader_route
    +        uri: http://example.org
    +        filters:
    +        - SetResponseHeader=X-Response-Foo, Bar

    +

    This GatewayFilter replaces all headers with the given name, rather than adding. So if the downstream server responded with a X-Response-Foo:1234, this would be replaced with X-Response-Foo:Bar, which is what the gateway client would receive.

    109.17 SetStatus GatewayFilter Factory

    The SetStatus GatewayFilter Factory takes a single status parameter. It must be a valid Spring HttpStatus. It may be the integer value 404 or the string representation of the enumeration NOT_FOUND.

    application.yml.  +

    spring:
    +  cloud:
    +    gateway:
    +      routes:
    +      - id: setstatusstring_route
    +        uri: http://example.org
    +        filters:
    +        - SetStatus=BAD_REQUEST
    +      - id: setstatusint_route
    +        uri: http://example.org
    +        filters:
    +        - SetStatus=401

    +

    In either case, the HTTP status of the response will be set to 401.

    109.18 StripPrefix GatewayFilter Factory

    The StripPrefix GatewayFilter Factory takes one paramter, parts. The parts parameter indicated the number of parts in the path to strip from the request before sending it downstream.

    application.yml.  +

    spring:
    +  cloud:
    +    gateway:
    +      routes:
    +      - id: nameRoot
    +        uri: http://nameservice
    +        predicates:
    +        - Path=/name/**
    +        filters:
    +        - StripPrefix=2

    +

    When a request is made through the gateway to /name/bar/foo the request made to nameservice will look like http://nameservice/foo.

    110. Global Filters

    The GlobalFilter interface has the same signature as GatewayFilter. These are special filters that are conditionally applied to all routes. (This interface and usage are subject to change in future milestones).

    110.1 Combined Global Filter and GatewayFilter Ordering

    TODO: document ordering

    110.2 Forward Routing Filter

    The ForwardRoutingFilter looks for a URI in the exchange attribute ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR. If the url has a forward scheme (ie forward:///localendpoint), it will use the Spring DispatcherHandler to handler the request. The unmodified original url is appended to the list in the ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR attribute.

    110.3 LoadBalancerClient Filter

    The LoadBalancerClientFilter looks for a URI in the exchange attribute ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR. If the url has a lb scheme (ie lb://myservice), it will use the Spring Cloud LoadBalancerClient to resolve the name (myservice in the previous example) to an actual host and port and replace the URI in the same attribute. The unmodified original url is appended to the list in the ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR attribute. The filter will also look in the ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR attribute to see if it equals lb and then the same rules apply.

    110.4 Netty Routing Filter

    The Netty Routing Filter runs if the url located in the ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR exchange attribute has a http or https scheme. It uses the Netty HttpClient to make the downstream proxy request. The response is put in the ServerWebExchangeUtils.CLIENT_RESPONSE_ATTR exchange attribute for use in a later filter. (There is an experimental WebClientHttpRoutingFilter that performs the same function, but does not require netty)

    110.5 Netty Write Response Filter

    The NettyWriteResponseFilter runs if there is a Netty HttpClientResponse in the ServerWebExchangeUtils.CLIENT_RESPONSE_ATTR exchange attribute. It is run after all other filters have completed and writes the proxy response back to the gateway client response. (There is an experimental WebClientWriteResponseFilter that performs the same function, but does not require netty)

    110.6 RouteToRequestUrl Filter

    The RouteToRequestUrlFilter runs if there is a Route object in the ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR exchange attribute. It creates a new URI, based off of the request URI, but updated with the URI attribute of the Route object. The new URI is placed in the ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR exchange attribute`.

    If the URI has a scheme prefix, such as lb:ws://serviceid, the lb scheme is stripped from the URI and placed in the ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR for use later in the filter chain.

    110.7 Websocket Routing Filter

    The Websocket Routing Filter runs if the url located in the ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR exchange attribute has a ws or wss scheme. It uses the Spring Web Socket infrastructure to forward the Websocket request downstream.

    Websockets may be load-balanced by prefixing the URI with lb, such as lb:ws://serviceid.

    111. Configuration

    Configuration for Spring Cloud Gateway is driven by a collection of `RouteDefinitionLocator`s.

    RouteDefinitionLocator.java.  +

    public interface RouteDefinitionLocator {
    +	Flux<RouteDefinition> getRouteDefinitions();
    +}

    +

    By default, a PropertiesRouteDefinitionLocator loads properties using Spring Boot’s @ConfigurationProperties mechanism.

    The configuration examples above all use a shortcut notation that uses positional arguments rather than named ones. The two examples below are equivalent:

    application.yml.  +

    spring:
    +  cloud:
    +    gateway:
    +      routes:
    +      - id: setstatus_route
    +        uri: http://example.org
    +        filters:
    +        - name: SetStatus
    +          args:
    +            status: 401
    +      - id: setstatusshortcut_route
    +        uri: http://example.org
    +        filters:
    +        - SetStatus=401

    +

    For some usages of the gateway, properties will be adequate, but some production use cases will benefit from loading configuration from an external source, such as a database. Future milestone versions will have RouteDefinitionLocator implementations based off of Spring Data Repositories such as: Redis, MongoDB and Cassandra.

    111.1 Fluent Java Routes API

    To allow for simple configuration in Java, there is a fluent API defined in the Routes class.

    GatewaySampleApplication.java.  +

    // static imports from GatewayFilters and RoutePredicates
    +@Bean
    +public RouteLocator customRouteLocator(ThrottleGatewayFilterFactory throttle) {
    +    return Routes.locator()
    +            .route("test")
    +                .predicate(host("**.abc.org").and(path("/image/png")))
    +                .addResponseHeader("X-TestHeader", "foobar")
    +                .uri("http://httpbin.org:80")
    +            .route("test2")
    +                .predicate(path("/image/webp"))
    +                .add(addResponseHeader("X-AnotherHeader", "baz"))
    +                .uri("http://httpbin.org:80")
    +            .route("test3")
    +                .order(-1)
    +                .predicate(host("**.throttle.org").and(path("/get")))
    +                .add(throttle.apply(tuple().of("capacity", 1,
    +                     "refillTokens", 1,
    +                     "refillPeriod", 10,
    +                     "refillUnit", "SECONDS")))
    +                .uri("http://httpbin.org:80")
    +            .build();
    +}

    +

    This style also allows for more custom predicate assertions. The predicates defined by RouteDefinitionLocator beans are combined using logical and. By using the fluent Java API, you can use the and(), or() and negate() operators on the Predicate class.

    111.2 DiscoveryClient Route Definition Locator

    The Gateway can be configured to create routes based on services registered with a DiscoveryClient compatible service registry.

    To enable this, set spring.cloud.gateway.discovery.locator.enabled=true and make sure a DiscoveryClient implementation is on the classpath and enabled (such as Netflix Eureka, Consul or Zookeeper).

    112. Actuator API

    TODO: document the /gateway actuator endpoint

    113. Developer Guide

    TODO: overview of writing custom integrations

    113.1 Writing Custom Route Predicate Factories

    TODO: document writing Custom Route Predicate Factories

    113.2 Writing Custom GatewayFilter Factories

    TODO: document writing Custom GatewayFilter Factories

    113.3 Writing Custom Global Filters

    TODO: document writing Custom Global Filters

    113.4 Writing Custom Route Locators and Writers

    TODO: document writing Custom Route Locators and Writers

    114. Building a Simple Gateway Using Spring MVC

    Spring Cloud Gateway provides a utility object called ProxyExchange which you can use inside a regular Spring MVC handler as a method parameter. It supports basic downstream HTTP exchanges via methods that mirror the HTTP verbs, or forwarding to a local handler via the forward() method.

    Example (proxying a request to "/test" downstream to a remote server):

    @RestController
    +@SpringBootApplication
    +public class GatewaySampleApplication {
    +
    +	@Value("${remote.home}")
    +	private URI home;
    +
    +	@GetMapping("/test")
    +	public ResponseEntity<?> proxy(ProxyExchange<Object> proxy) throws Exception {
    +		return proxy.uri(home.toString() + "/image/png").get();
    +	}
    +
    +}

    There are convenience methods on the ProxyExchange to enable the handler method to discover and enhance the URI path of the incoming request. For example you might want to extract the trailing elements of a path to pass them downstream:

    @GetMapping("/proxy/path/**")
    +public ResponseEntity<?> proxyPath(ProxyExchange<?> proxy) throws Exception {
    +  String path = proxy.path("/proxy/path/");
    +  return proxy.uri(home.toString() + "/foos/" + path).get();
    +}

    All the features of Spring MVC are available to Gateway handler methods. So you can inject request headers and query parameters, for instance, and you can constrain the incoming requests with declarations in the mapping annotation. See the documentation for @RequestMapping in Spring MVC for more details of those features.

    Headers can be added to the downstream response using the header() methods on ProxyExchange.

    You can also manipulate response headers (and anything else you like in the response) by adding a mapper to the get() etc. method. The mapper is a Function that takes the incoming ResponseEntity and converts it to an outgoing one.

    First class support is provided for "sensitive" headers ("cookie" and "authorization" by default) which are not passed downstream, and for "proxy" headers (x-forwarded-*).

    Part XVI. 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 diff --git a/Finchley.M7/spring-cloud.xml b/Finchley.M7/spring-cloud.xml index 657d3504..de25b81f 100644 --- a/Finchley.M7/spring-cloud.xml +++ b/Finchley.M7/spring-cloud.xml @@ -4218,6 +4218,394 @@ can result in resource management issues. + +Spring Cloud OpenFeign + +1.3.5.BUILD-SNAPSHOT +This project provides OpenFeign integrations for Spring Boot apps through autoconfiguration +and binding to the Spring Environment and other Spring programming model idioms. + + +Declarative REST Client: Feign +Feign is a declarative web service client. It makes writing web service clients easier. To use Feign create an interface and annotate it. It has pluggable annotation support including Feign annotations and JAX-RS annotations. Feign also supports pluggable encoders and decoders. Spring Cloud adds support for Spring MVC annotations and for using the same HttpMessageConverters used by default in Spring Web. Spring Cloud integrates Ribbon and Eureka to provide a load balanced http client when using Feign. +

    +How to Include Feign +To include Feign in your project use the starter with group org.springframework.cloud +and artifact id spring-cloud-starter-openfeign. See the Spring Cloud Project page +for details on setting up your build system with the current Spring Cloud Release Train. +Example spring boot app +@SpringBootApplication +@EnableFeignClients +public class Application { + + public static void main(String[] args) { + SpringApplication.run(Application.class, args); + } + +} + +StoreClient.java + +@FeignClient("stores") +public interface StoreClient { + @RequestMapping(method = RequestMethod.GET, value = "/stores") + List<Store> getStores(); + + @RequestMapping(method = RequestMethod.POST, value = "/stores/{storeId}", consumes = "application/json") + Store update(@PathVariable("storeId") Long storeId, Store store); +} + + +In the @FeignClient annotation the String value ("stores" above) is +an arbitrary client name, which is used to create a Ribbon load +balancer (see below for details of Ribbon +support). You can also specify a URL using the url attribute +(absolute value or just a hostname). The name of the bean in the +application context is the fully qualified name of the interface. +To specify your own alias value you can use the qualifier value +of the @FeignClient annotation. +The Ribbon client above will want to discover the physical addresses +for the "stores" service. If your application is a Eureka client then +it will resolve the service in the Eureka service registry. If you +don’t want to use Eureka, you can simply configure a list of servers +in your external configuration (see +above for example). +
    +
    +Overriding Feign Defaults +A central concept in Spring Cloud’s Feign support is that of the named client. Each feign client is part of an ensemble of components that work together to contact a remote server on demand, and the ensemble has a name that you give it as an application developer using the @FeignClient annotation. Spring Cloud creates a new ensemble as an +ApplicationContext on demand for each named client using FeignClientsConfiguration. This contains (amongst other things) an feign.Decoder, a feign.Encoder, and a feign.Contract. +Spring Cloud lets you take full control of the feign client by declaring additional configuration (on top of the FeignClientsConfiguration) using @FeignClient. Example: +@FeignClient(name = "stores", configuration = FooConfiguration.class) +public interface StoreClient { + //.. +} +In this case the client is composed from the components already in FeignClientsConfiguration together with any in FooConfiguration (where the latter will override the former). + +FooConfiguration does not need to be annotated with @Configuration. However, if it is, then take care to exclude it from any @ComponentScan that would otherwise include this configuration as it will become the default source for feign.Decoder, feign.Encoder, feign.Contract, etc., when specified. This can be avoided by putting it in a separate, non-overlapping package from any @ComponentScan or @SpringBootApplication, or it can be explicitly excluded in @ComponentScan. + + +The serviceId attribute is now deprecated in favor of the name attribute. + + +Previously, using the url attribute, did not require the name attribute. Using name is now required. + +Placeholders are supported in the name and url attributes. +@FeignClient(name = "${feign.name}", url = "${feign.url}") +public interface StoreClient { + //.. +} +Spring Cloud Netflix provides the following beans by default for feign (BeanType beanName: ClassName): + + +Decoder feignDecoder: ResponseEntityDecoder (which wraps a SpringDecoder) + + +Encoder feignEncoder: SpringEncoder + + +Logger feignLogger: Slf4jLogger + + +Contract feignContract: SpringMvcContract + + +Feign.Builder feignBuilder: HystrixFeign.Builder + + +Client feignClient: if Ribbon is enabled it is a LoadBalancerFeignClient, otherwise the default feign client is used. + + +The OkHttpClient and ApacheHttpClient feign clients can be used by setting feign.okhttp.enabled or feign.httpclient.enabled to true, respectively, and having them on the classpath. +You can customize the HTTP client used by providing a bean of either ClosableHttpClient when using Apache or OkHttpClient whe using OK HTTP. +Spring Cloud Netflix does not provide the following beans by default for feign, but still looks up beans of these types from the application context to create the feign client: + + +Logger.Level + + +Retryer + + +ErrorDecoder + + +Request.Options + + +Collection<RequestInterceptor> + + +SetterFactory + + +Creating a bean of one of those type and placing it in a @FeignClient configuration (such as FooConfiguration above) allows you to override each one of the beans described. Example: +@Configuration +public class FooConfiguration { + @Bean + public Contract feignContract() { + return new feign.Contract.Default(); + } + + @Bean + public BasicAuthRequestInterceptor basicAuthRequestInterceptor() { + return new BasicAuthRequestInterceptor("user", "password"); + } +} +This replaces the SpringMvcContract with feign.Contract.Default and adds a RequestInterceptor to the collection of RequestInterceptor. +@FeignClient also can be configured using configuration properties. +application.yml +feign: + client: + config: + feignName: + connectTimeout: 5000 + readTimeout: 5000 + loggerLevel: full + errorDecoder: com.example.SimpleErrorDecoder + retryer: com.example.SimpleRetryer + requestInterceptors: + - com.example.FooRequestInterceptor + - com.example.BarRequestInterceptor + decode404: false + encoder: com.example.SimpleEncoder + decoder: com.example.SimpleDecoder + contract: com.example.SimpleContract +Default configurations can be specified in the @EnableFeignClients attribute defaultConfiguration in a similar manner as described above. The difference is that this configuration will apply to all feign clients. +If you prefer using configuration properties to configured all @FeignClient, you can create configuration properties with default feign name. +application.yml +feign: + client: + config: + default: + connectTimeout: 5000 + readTimeout: 5000 + loggerLevel: basic +If we create both @Configuration bean and configuration properties, configuration properties will win. +It will override @Configuration values. But if you want to change the priority to @Configuration, +you can change feign.client.default-to-properties to false. + +If you need to use ThreadLocal bound variables in your RequestInterceptor`s you will need to either set the +thread isolation strategy for Hystrix to `SEMAPHORE or disable Hystrix in Feign. + +application.yml +# To disable Hystrix in Feign +feign: + hystrix: + enabled: false + +# To set thread isolation to SEMAPHORE +hystrix: + command: + default: + execution: + isolation: + strategy: SEMAPHORE +
    +
    +Creating Feign Clients Manually +In some cases it might be necessary to customize your Feign Clients in a way that is not +possible using the methods above. In this case you can create Clients using the +Feign Builder API. Below is an example +which creates two Feign Clients with the same interface but configures each one with +a separate request interceptor. +@Import(FeignClientsConfiguration.class) +class FooController { + + private FooClient fooClient; + + private FooClient adminClient; + + @Autowired + public FooController( + Decoder decoder, Encoder encoder, Client client, Contract contract) { + this.fooClient = Feign.builder().client(client) + .encoder(encoder) + .decoder(decoder) + .contract(contract) + .requestInterceptor(new BasicAuthRequestInterceptor("user", "user")) + .target(FooClient.class, "http://PROD-SVC"); + this.adminClient = Feign.builder().client(client) + .encoder(encoder) + .decoder(decoder) + .contract(contract) + .requestInterceptor(new BasicAuthRequestInterceptor("admin", "admin")) + .target(FooClient.class, "http://PROD-SVC"); + } +} + +In the above example FeignClientsConfiguration.class is the default configuration +provided by Spring Cloud Netflix. + + +PROD-SVC is the name of the service the Clients will be making requests to. + + +The Feign Contract object defines what annotations and values are valid on interfaces. The +autowired Contract bean provides supports for SpringMVC annotations, instead of +the default Feign native annotations. + +
    +
    +Feign Hystrix Support +If Hystrix is on the classpath and feign.hystrix.enabled=true, Feign will wrap all methods with a circuit breaker. Returning a com.netflix.hystrix.HystrixCommand is also available. This lets you use reactive patterns (with a call to .toObservable() or .observe() or asynchronous use (with a call to .queue()). +To disable Hystrix support on a per-client basis create a vanilla Feign.Builder with the "prototype" scope, e.g.: +@Configuration +public class FooConfiguration { + @Bean + @Scope("prototype") + public Feign.Builder feignBuilder() { + return Feign.builder(); + } +} + +Prior to the Spring Cloud Dalston release, if Hystrix was on the classpath Feign would have wrapped +all methods in a circuit breaker by default. This default behavior was changed in Spring Cloud Dalston in +favor for an opt-in approach. + +
    +
    +Feign Hystrix Fallbacks +Hystrix supports the notion of a fallback: a default code path that is executed when they circuit is open or there is an error. To enable fallbacks for a given @FeignClient set the fallback attribute to the class name that implements the fallback. You also need to declare your implementation as a Spring bean. +@FeignClient(name = "hello", fallback = HystrixClientFallback.class) +protected interface HystrixClient { + @RequestMapping(method = RequestMethod.GET, value = "/hello") + Hello iFailSometimes(); +} + +static class HystrixClientFallback implements HystrixClient { + @Override + public Hello iFailSometimes() { + return new Hello("fallback"); + } +} +If one needs access to the cause that made the fallback trigger, one can use the fallbackFactory attribute inside @FeignClient. +@FeignClient(name = "hello", fallbackFactory = HystrixClientFallbackFactory.class) +protected interface HystrixClient { + @RequestMapping(method = RequestMethod.GET, value = "/hello") + Hello iFailSometimes(); +} + +@Component +static class HystrixClientFallbackFactory implements FallbackFactory<HystrixClient> { + @Override + public HystrixClient create(Throwable cause) { + return new HystrixClient() { + @Override + public Hello iFailSometimes() { + return new Hello("fallback; reason was: " + cause.getMessage()); + } + }; + } +} + +There is a limitation with the implementation of fallbacks in Feign and how Hystrix fallbacks work. Fallbacks are currently not supported for methods that return com.netflix.hystrix.HystrixCommand and rx.Observable. + +
    +
    +Feign and <literal>@Primary</literal> +When using Feign with Hystrix fallbacks, there are multiple beans in the ApplicationContext of the same type. This will cause @Autowired to not work because there isn’t exactly one bean, or one marked as primary. To work around this, Spring Cloud Netflix marks all Feign instances as @Primary, so Spring Framework will know which bean to inject. In some cases, this may not be desirable. To turn off this behavior set the primary attribute of @FeignClient to false. +@FeignClient(name = "hello", primary = false) +public interface HelloClient { + // methods here +} +
    +
    +Feign Inheritance Support +Feign supports boilerplate apis via single-inheritance interfaces. +This allows grouping common operations into convenient base interfaces. + +UserService.java + +public interface UserService { + + @RequestMapping(method = RequestMethod.GET, value ="/users/{id}") + User getUser(@PathVariable("id") long id); +} + + + +UserResource.java + +@RestController +public class UserResource implements UserService { + +} + + + +UserClient.java + +package project.user; + +@FeignClient("users") +public interface UserClient extends UserService { + +} + + + +It is generally not advisable to share an interface between a +server and a client. It introduces tight coupling, and also actually +doesn’t work with Spring MVC in its current form (method parameter +mapping is not inherited). + +
    +
    +Feign request/response compression +You may consider enabling the request or response GZIP compression for your +Feign requests. You can do this by enabling one of the properties: +feign.compression.request.enabled=true +feign.compression.response.enabled=true +Feign request compression gives you settings similar to what you may set for your web server: +feign.compression.request.enabled=true +feign.compression.request.mime-types=text/xml,application/xml,application/json +feign.compression.request.min-request-size=2048 +These properties allow you to be selective about the compressed media types and minimum request threshold length. +
    +
    +Feign logging +A logger is created for each Feign client created. By default the name of the logger is the full class name of the interface used to create the Feign client. Feign logging only responds to the DEBUG level. + +application.yml + +logging.level.project.user.UserClient: DEBUG + + +The Logger.Level object that you may configure per client, tells Feign how much to log. Choices are: + + +NONE, No logging (DEFAULT). + + +BASIC, Log only the request method and URL and the response status code and execution time. + + +HEADERS, Log the basic information along with request and response headers. + + +FULL, Log the headers, body, and metadata for both requests and responses. + + +For example, the following would set the Logger.Level to FULL: +@Configuration +public class FooConfiguration { + @Bean + Logger.Level feignLoggerLevel() { + return Logger.Level.FULL; + } +} + OtherClass.someMethod(myprop.get()); + } +} +stripped). The proxy uses Ribbon to locate an instance to forward to +via discovery, and all requests are executed in a +<<hystrix-fallbacks-for-routes, hystrix command>>, so +failures will show up in Hystrix metrics, and once the circuit is open +the proxy will not try to contact the service. +
    + + Spring Cloud Stream @@ -22241,6 +22629,842 @@ after application shutdown. See also: Vault Documentation: Lease, Renew, and Revoke + +Spring Cloud Gateway + +1.3.5.BUILD-SNAPSHOT +This project provides an API Gateway built on top of the Spring Ecosystem, including: Spring 5, Spring Boot 2 and Project Reactor. Spring Cloud Gateway aims to provide a simple, yet effective way to route to APIs and provide cross cutting concerns to them such as: security, monitoring/metrics, and resiliency. + + +How to Include Spring Cloud Gateway +To include Spring Cloud Gateway in your project use the starter with group org.springframework.cloud +and artifact id spring-cloud-starter-gateway. See the Spring Cloud Project page +for details on setting up your build system with the current Spring Cloud Release Train. +If you include the starter, but, for some reason, you do not want the gateway to be enabled, set spring.cloud.gateway.enabled=false. + + +Glossary + + +Route: Route the basic building block of the gateway. It is defined by an ID, a destination URI, a collection of predicates and a collection of filters. A route is matched if aggregate predicate is true. + + +Predicate: This is a Java 8 Function Predicate. The input type is a Spring Framework ServerWebExchange. This allows developers to match on anything from the HTTP request, such as headers or parameters. + + +Filter: These are instances Spring Framework GatewayFilter constructed in with a specific factory. Here, requests and responses can be modified before or after sending the downstream request. + + + + +How It Works + + + + + +Spring Cloud Gateway Diagram + + +Clients make requests to Spring Cloud Gateway. If the Gateway Handler Mapping determines that a request matches a Route, it is sent to the Gateway Web Handler. This handler runs sends the request through a filter chain that is specific to the request. The reason the filters are divided by the dotted line, is that filters may execute logic before the proxy request is sent or after. All "pre" filter logic is executed, then the proxy request is made. After the proxy request is made, the "post" filter logic is executed. + +URIs defined in routes without a port will get a default port set to 80 and 443 for HTTP and HTTPS URIs respectively. + + + +Route Predicate Factories +Spring Cloud Gateway matches routes as part of the Spring WebFlux HandlerMapping infrastructure. Spring Cloud Gateway includes many built-in Route Predicate Factories. All of these predicates match on different attributes of the HTTP request. Multiple Route Predicate Factories can be combined and are combined via logical and. +
    +After Route Predicate Factory +The After Route Predicate Factory takes one parameter, a datetime. This predicate matches requests that happen after the current datetime. + +application.yml + +spring: + cloud: + gateway: + routes: + - id: after_route + uri: http://example.org + predicates: + - After=2017-01-20T17:42:47.789-07:00[America/Denver] + + +This route matches any request after Jan 20, 2017 17:42 Mountain Time (Denver). +
    +
    +Before Route Predicate Factory +The Before Route Predicate Factory takes one parameter, a datetime. This predicate matches requests that happen before the current datetime. + +application.yml + +spring: + cloud: + gateway: + routes: + - id: before_route + uri: http://example.org + predicates: + - Before=2017-01-20T17:42:47.789-07:00[America/Denver] + + +This route matches any request before Jan 20, 2017 17:42 Mountain Time (Denver). +
    +
    +Between Route Predicate Factory +The Between Route Predicate Factory takes two parameters, datetime1 and datetime2. This predicate matches requests that happen after datetime1 and before datetime2. The datetime2 parameter must be after datetime1. + +application.yml + +spring: + cloud: + gateway: + routes: + - id: between_route + uri: http://example.org + predicates: + - Betweeen=2017-01-20T17:42:47.789-07:00[America/Denver], 2017-01-21T17:42:47.789-07:00[America/Denver] + + +This route matches any request after Jan 20, 2017 17:42 Mountain Time (Denver) and before Jan 21, 2017 17:42 Mountain Time (Denver). This could be useful for maintenance windows. +
    +
    +Cookie Route Predicate Factory +The Cookie Route Predicate Factory takes two parameters, the cookie name and a regular expression. This predicate matches cookies that have the given name and the value matches the regular expression. + +application.yml + +spring: + cloud: + gateway: + routes: + - id: cookie_route + uri: http://example.org + predicates: + - Cookie=chocolate, ch.p + + +This route matches the request has a cookie named chocolate who’s value matches the ch.p regular expression. +
    +
    +Header Route Predicate Factory +The Header Route Predicate Factory takes two parameters, the header name and a regular expression. This predicate matches with a header that has the given name and the value matches the regular expression. + +application.yml + +spring: + cloud: + gateway: + routes: + - id: header_route + uri: http://example.org + predicates: + - Header=X-Request-Id, \d+ + + +This route matches if the request has a header named X-Request-Id whos value matches the \d+ regular expression (has a value of one or more digits). +
    +
    +Host Route Predicate Factory +The Host Route Predicate Factory takes one parameter: the host name pattern. The pattern is an Ant style pattern with . as the separator. This predicates matches the Host header that matches the pattern. + +application.yml + +spring: + cloud: + gateway: + routes: + - id: host_route + uri: http://example.org + predicates: + - Host=**.somehost.org + + +This route would match if the request has a Host header has the value www.somehost.org or beta.somehost.org. +
    +
    +Method Route Predicate Factory +The Method Route Predicate Factory takes one parameter: the HTTP method to match. + +application.yml + +spring: + cloud: + gateway: + routes: + - id: method_route + uri: http://example.org + predicates: + - Method=GET + + +This route would match if the request method was a GET. +
    +
    +Path Route Predicate Factory +The Path Route Predicate Factory takes one parameter: a Spring PathMatcher pattern. + +application.yml + +spring: + cloud: + gateway: + routes: + - id: host_route + uri: http://example.org + predicates: + - Path=/foo/{segment} + + +This route would match if the request path was, for example: /foo/1 or /foo/bar. +This predicate extracts the URI template variables (like segment defined in the example above) as a map of names and values and places it in the ServerWebExchange.getAttributes() with a key defined in PathRoutePredicate.URL_PREDICATE_VARS_ATTR. Those values are then available for use by GatewayFilter Factories +
    +
    +Query Route Predicate Factory +The Query Route Predicate Factory takes two parameters: a required param and an optional regexp. + +application.yml + +spring: + cloud: + gateway: + routes: + - id: query_route + uri: http://example.org + predicates: + - Query=baz + + +This route would match if the request contained a baz query parameter. + +application.yml + +spring: + cloud: + gateway: + routes: + - id: query_route + uri: http://example.org + predicates: + - Query=foo, ba. + + +This route would match if the request contained a foo query parameter whose value matched the ba. regexp, so bar and baz would match. +
    +
    +RemoteAddr Route Predicate Factory +The RemoteAddr Route Predicate Factory takes a list (min size 1) of CIDR-notation (IPv4 or IPv6) strings, e.g. 192.168.0.1/16 (where 192.168.0.1 is an IP address and 16 is a subnet mask. + +application.yml + +spring: + cloud: + gateway: + routes: + - id: remoteaddr_route + uri: http://example.org + predicates: + - RemoteAddr=192.168.1.1/24 + + +This route would match if the remote address of the request was, for example, 192.168.1.10. +
    +
    + +GatewayFilter Factories +Route filters allow the modification of the incoming HTTP request or outgoing HTTP response in some manner. Route filters are scoped to a particular route. Spring Cloud Gateway includes many built-in GatewayFilter Factories. +
    +AddRequestHeader GatewayFilter Factory +The AddRequestHeader GatewayFilter Factory takes a name and value parameter. + +application.yml + +spring: + cloud: + gateway: + routes: + - id: add_request_header_route + uri: http://example.org + filters: + - AddRequestHeader=X-Request-Foo, Bar + + +This will add X-Request-Foo:Bar header to the downstream request’s headers for all matching requests. +
    +
    +AddRequestParameter GatewayFilter Factory +The AddRequestParameter GatewayFilter Factory takes a name and value parameter. + +application.yml + +spring: + cloud: + gateway: + routes: + - id: add_request_parameter_route + uri: http://example.org + filters: + - AddRequestParameter=foo, bar + + +This will add foo=bar to the downstream request’s query string for all matching requests. +
    +
    +AddResponseHeader GatewayFilter Factory +The AddResponseHeader GatewayFilter Factory takes a name and value parameter. + +application.yml + +spring: + cloud: + gateway: + routes: + - id: add_request_header_route + uri: http://example.org + filters: + - AddResponseHeader=X-Response-Foo, Bar + + +This will add X-Response-Foo:Bar header to the downstream response’s headers for all matching requests. +
    +
    +Hystrix GatewayFilter Factory +The Hystrix GatewayFilter Factory takes a single name parameters, which is the name of the HystrixCommand. (More options might be added in future releases). + +application.yml + +spring: + cloud: + gateway: + routes: + - id: hytstrix_route + uri: http://example.org + filters: + - Hystrix=myCommandName + + +This wraps the remaining filters in a HystrixCommand with command name myCommandName. +The Hystrix filter takes an optional fallbackUri parameter. Currently, only forward: schemed URIs are supported. If the fallback is called, the request will be forwarded to the controller matched by the URI. + +application.yml + +spring: + cloud: + gateway: + routes: + - id: hytstrix_route + uri: http://example.org + filters: + - name: Hystrix + args: + name: fallbackcmd + fallbackUri: forward:/fallbackcontroller + +This will forward to the `/fallbackcontroller` when the Hystrix fallback is called. + + +
    +
    +PrefixPath GatewayFilter Factory +The PrefixPath GatewayFilter Factory takes a single prefix parameter. + +application.yml + +spring: + cloud: + gateway: + routes: + - id: prefixpath_route + uri: http://example.org + filters: + - PrefixPath=/mypath + + +This will prefix /mypath to the path of all matching requests. So a request to /hello, would be sent to /mypath/hello. +
    +
    +PreserveHostHeader GatewayFilter Factory +The PreserveHostHeader GatewayFilter Factory has not parameters. This filter, sets a request attribute that the routing filter will inspect to determine if the original host header should be sent, rather than the host header determined by the http client. + +application.yml + +spring: + cloud: + gateway: + routes: + - id: preserve_host_route + uri: http://example.org + filters: + - PreserveHostHeader + + +This will prefix /mypath to the path of all matching requests. So a request to /hello, would be sent to /mypath/hello. +
    +
    +RequestRateLimiter GatewayFilter Factory +The RequestRateLimiter GatewayFilter Factory takes three parameters: replenishRate, burstCapacity & keyResolverName. +replenishRate is how many requests per second do you want a user to be allowed to do. +burstCapacity TODO: document burst capacity +keyResolver is a bean that implements the KeyResolver interface. In configuration, reference the bean by name using SpEL. #{@myKeyResolver} is a SpEL expression referencing a bean with the name myKeyResolver. + +KeyResolver.java + +public interface KeyResolver { + Mono<String> resolve(ServerWebExchange exchange); +} + + +The KeyResolver interface allows pluggable strategies to derive the key for limiting requests. In future milestones, there will be some KeyResolver implementations. +The redis implementation is based off of work done at Stripe. It requires the use of the spring-boot-starter-data-redis-reactive Spring Boot starter. + +application.yml + +spring: + cloud: + gateway: + routes: + - id: requestratelimiter_route + uri: http://example.org + filters: + - RequestRateLimiter=10, 20, #{@userKeyResolver} + + + +Config.java + +@Bean +KeyResolver userKeyResolver() { + return exchange -> Mono.just(exchange.getRequest().getQueryParams().getFirst("user")); +} + + +This defines a request rate limit of 10 per user. The KeyResolver is a simple one that gets the user request parameter (note: this is not recommended for production). +
    +
    +RedirectTo GatewayFilter Factory +The RedirectTo GatewayFilter Factory takes a status and a url parameter. The status should be a 300 series redirect http code, such as 301. The url should be a valid url. This will be the value of the Location header. + +application.yml + +spring: + cloud: + gateway: + routes: + - id: prefixpath_route + uri: http://example.org + filters: + - RedirectTo=302, http://acme.org + + +This will send a status 302 with a Location:http://acme.org header to perform a redirect. +
    +
    +RemoveNonProxyHeaders GatewayFilter Factory +The RemoveNonProxyHeaders GatewayFilter Factory removes headers from forwarded requests. The default list of headers that is removed comes from the IETF. + +The default removed headers are: + +Connection + + +Keep-Alive + + +Proxy-Authenticate + + +Proxy-Authorization + + +TE + + +Trailer + + +Transfer-Encoding + + +Upgrade + + +To change this, set the spring.cloud.gateway.filter.remove-non-proxy-headers.headers property to the list of header names to remove. +
    +
    +RemoveRequestHeader GatewayFilter Factory +The RemoveRequestHeader GatewayFilter Factory takes a name parameter. It is the name of the header to be removed. + +application.yml + +spring: + cloud: + gateway: + routes: + - id: removerequestheader_route + uri: http://example.org + filters: + - RemoveRequestHeader=X-Request-Foo + + +This will remove the X-Request-Foo header before it is sent downstream. +
    +
    +RemoveResponseHeader GatewayFilter Factory +The RemoveResponseHeader GatewayFilter Factory takes a name parameter. It is the name of the header to be removed. + +application.yml + +spring: + cloud: + gateway: + routes: + - id: removeresponseheader_route + uri: http://example.org + filters: + - RemoveResponseHeader=X-Response-Foo + + +This will remove the X-Response-Foo header from the response before it is returned to the gateway client. +
    +
    +RewritePath GatewayFilter Factory +The RewritePath GatewayFilter Factory takes a path regexp parameter and a replacement parameter. This uses Java regular expressions for a flexible way to rewrite the request path. + +application.yml + +spring: + cloud: + gateway: + routes: + - id: rewritepath_route + uri: http://example.org + predicates: + - Path=/foo/** + filters: + - RewritePath=/foo/(?<segment>.*), /$\{segment} + + +For a request path of /foo/bar, this will set the path to /bar before making the downstream request. Notice the $\ which is replaced with $ because of the YAML spec. +
    +
    +SaveSession GatewayFilter Factory +The SaveSession GatewayFilter Factory forces a WebSession::save operation before forwarding the call downstream. This is of particular use when +using something like Spring Session with a lazy data store and need to ensure the session state has been saved before making the forwarded call. + +application.yml + +spring: + cloud: + gateway: + routes: + - id: save_session + uri: http://example.org + predicates: + - Path=/foo/** + filters: + - SaveSession + + +If you are integrating Spring Security with Spring Session, and want to ensure security details have been forwarded to the remote process, this is critical. +
    +
    +SecureHeaders GatewayFilter Factory +The SecureHeaders GatewayFilter Factory adds a number of headers to the response at the reccomendation from this blog post. + +The following headers are added (allong with default values): + +X-Xss-Protection:1; mode=block + + +Strict-Transport-Security:max-age=631138519 + + +X-Frame-Options:DENY + + +X-Content-Type-Options:nosniff + + +Referrer-Policy:no-referrer + + +Content-Security-Policy:default-src 'self' https:; font-src 'self' https: data:; img-src 'self' https: data:; object-src 'none'; script-src https:; style-src 'self' https: 'unsafe-inline' + + +X-Download-Options:noopen + + +X-Permitted-Cross-Domain-Policies:none + + +To change the default values set the appropriate property in the spring.cloud.gateway.filter.secure-headers namespace: + +Property to change: + +xss-protection-header + + +strict-transport-security + + +frame-options + + +content-type-options + + +referrer-policy + + +content-security-policy + + +download-options + + +permitted-cross-domain-policies + + +
    +
    +SetPath GatewayFilter Factory +The SetPath GatewayFilter Factory takes a path template parameter. It offers a simple way to manipulate the request path by allowing templated segments of the path. This uses the uri templates from Spring Framework. Multiple matching segments are allowed. + +application.yml + +spring: + cloud: + gateway: + routes: + - id: setpath_route + uri: http://example.org + predicates: + - Path=/foo/{segment} + filters: + - SetPath=/{segment} + + +For a request path of /foo/bar, this will set the path to /bar before making the downstream request. +
    +
    +SetResponseHeader GatewayFilter Factory +The SetResponseHeader GatewayFilter Factory takes name and value parameters. + +application.yml + +spring: + cloud: + gateway: + routes: + - id: setresponseheader_route + uri: http://example.org + filters: + - SetResponseHeader=X-Response-Foo, Bar + + +This GatewayFilter replaces all headers with the given name, rather than adding. So if the downstream server responded with a X-Response-Foo:1234, this would be replaced with X-Response-Foo:Bar, which is what the gateway client would receive. +
    +
    +SetStatus GatewayFilter Factory +The SetStatus GatewayFilter Factory takes a single status parameter. It must be a valid Spring HttpStatus. It may be the integer value 404 or the string representation of the enumeration NOT_FOUND. + +application.yml + +spring: + cloud: + gateway: + routes: + - id: setstatusstring_route + uri: http://example.org + filters: + - SetStatus=BAD_REQUEST + - id: setstatusint_route + uri: http://example.org + filters: + - SetStatus=401 + + +In either case, the HTTP status of the response will be set to 401. +
    +
    +StripPrefix GatewayFilter Factory +The StripPrefix GatewayFilter Factory takes one paramter, parts. The parts parameter indicated the number of parts in the path to strip from the request before sending it downstream. + +application.yml + +spring: + cloud: + gateway: + routes: + - id: nameRoot + uri: http://nameservice + predicates: + - Path=/name/** + filters: + - StripPrefix=2 + + +When a request is made through the gateway to /name/bar/foo the request made to nameservice will look like http://nameservice/foo. +
    +
    + +Global Filters +The GlobalFilter interface has the same signature as GatewayFilter. These are special filters that are conditionally applied to all routes. (This interface and usage are subject to change in future milestones). +
    +Combined Global Filter and GatewayFilter Ordering +TODO: document ordering +
    +
    +Forward Routing Filter +The ForwardRoutingFilter looks for a URI in the exchange attribute ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR. If the url has a forward scheme (ie forward:///localendpoint), it will use the Spring DispatcherHandler to handler the request. The unmodified original url is appended to the list in the ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR attribute. +
    +
    +LoadBalancerClient Filter +The LoadBalancerClientFilter looks for a URI in the exchange attribute ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR. If the url has a lb scheme (ie lb://myservice), it will use the Spring Cloud LoadBalancerClient to resolve the name (myservice in the previous example) to an actual host and port and replace the URI in the same attribute. The unmodified original url is appended to the list in the ServerWebExchangeUtils.GATEWAY_ORIGINAL_REQUEST_URL_ATTR attribute. The filter will also look in the ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR attribute to see if it equals lb and then the same rules apply. +
    +
    +Netty Routing Filter +The Netty Routing Filter runs if the url located in the ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR exchange attribute has a http or https scheme. It uses the Netty HttpClient to make the downstream proxy request. The response is put in the ServerWebExchangeUtils.CLIENT_RESPONSE_ATTR exchange attribute for use in a later filter. (There is an experimental WebClientHttpRoutingFilter that performs the same function, but does not require netty) +
    +
    +Netty Write Response Filter +The NettyWriteResponseFilter runs if there is a Netty HttpClientResponse in the ServerWebExchangeUtils.CLIENT_RESPONSE_ATTR exchange attribute. It is run after all other filters have completed and writes the proxy response back to the gateway client response. (There is an experimental WebClientWriteResponseFilter that performs the same function, but does not require netty) +
    +
    +RouteToRequestUrl Filter +The RouteToRequestUrlFilter runs if there is a Route object in the ServerWebExchangeUtils.GATEWAY_ROUTE_ATTR exchange attribute. It creates a new URI, based off of the request URI, but updated with the URI attribute of the Route object. The new URI is placed in the ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR exchange attribute`. +If the URI has a scheme prefix, such as lb:ws://serviceid, the lb scheme is stripped from the URI and placed in the ServerWebExchangeUtils.GATEWAY_SCHEME_PREFIX_ATTR for use later in the filter chain. +
    +
    +Websocket Routing Filter +The Websocket Routing Filter runs if the url located in the ServerWebExchangeUtils.GATEWAY_REQUEST_URL_ATTR exchange attribute has a ws or wss scheme. It uses the Spring Web Socket infrastructure to forward the Websocket request downstream. +Websockets may be load-balanced by prefixing the URI with lb, such as lb:ws://serviceid. +
    +
    + +Configuration +Configuration for Spring Cloud Gateway is driven by a collection of `RouteDefinitionLocator`s. + +RouteDefinitionLocator.java + +public interface RouteDefinitionLocator { + Flux<RouteDefinition> getRouteDefinitions(); +} + + +By default, a PropertiesRouteDefinitionLocator loads properties using Spring Boot’s @ConfigurationProperties mechanism. +The configuration examples above all use a shortcut notation that uses positional arguments rather than named ones. The two examples below are equivalent: + +application.yml + +spring: + cloud: + gateway: + routes: + - id: setstatus_route + uri: http://example.org + filters: + - name: SetStatus + args: + status: 401 + - id: setstatusshortcut_route + uri: http://example.org + filters: + - SetStatus=401 + + +For some usages of the gateway, properties will be adequate, but some production use cases will benefit from loading configuration from an external source, such as a database. Future milestone versions will have RouteDefinitionLocator implementations based off of Spring Data Repositories such as: Redis, MongoDB and Cassandra. +
    +Fluent Java Routes API +To allow for simple configuration in Java, there is a fluent API defined in the Routes class. + +GatewaySampleApplication.java + +// static imports from GatewayFilters and RoutePredicates +@Bean +public RouteLocator customRouteLocator(ThrottleGatewayFilterFactory throttle) { + return Routes.locator() + .route("test") + .predicate(host("**.abc.org").and(path("/image/png"))) + .addResponseHeader("X-TestHeader", "foobar") + .uri("http://httpbin.org:80") + .route("test2") + .predicate(path("/image/webp")) + .add(addResponseHeader("X-AnotherHeader", "baz")) + .uri("http://httpbin.org:80") + .route("test3") + .order(-1) + .predicate(host("**.throttle.org").and(path("/get"))) + .add(throttle.apply(tuple().of("capacity", 1, + "refillTokens", 1, + "refillPeriod", 10, + "refillUnit", "SECONDS"))) + .uri("http://httpbin.org:80") + .build(); +} + + +This style also allows for more custom predicate assertions. The predicates defined by RouteDefinitionLocator beans are combined using logical and. By using the fluent Java API, you can use the and(), or() and negate() operators on the Predicate class. +
    +
    +DiscoveryClient Route Definition Locator +The Gateway can be configured to create routes based on services registered with a DiscoveryClient compatible service registry. +To enable this, set spring.cloud.gateway.discovery.locator.enabled=true and make sure a DiscoveryClient implementation is on the classpath and enabled (such as Netflix Eureka, Consul or Zookeeper). +
    +
    + +Actuator API +TODO: document the /gateway actuator endpoint + + +Developer Guide +TODO: overview of writing custom integrations +
    +Writing Custom Route Predicate Factories +TODO: document writing Custom Route Predicate Factories +
    +
    +Writing Custom GatewayFilter Factories +TODO: document writing Custom GatewayFilter Factories +
    +
    +Writing Custom Global Filters +TODO: document writing Custom Global Filters +
    +
    +Writing Custom Route Locators and Writers +TODO: document writing Custom Route Locators and Writers +
    +
    + +Building a Simple Gateway Using Spring MVC +Spring Cloud Gateway provides a utility object called ProxyExchange which you can use inside a regular Spring MVC handler as a method parameter. It supports basic downstream HTTP exchanges via methods that mirror the HTTP verbs, or forwarding to a local handler via the forward() method. +Example (proxying a request to "/test" downstream to a remote server): +@RestController +@SpringBootApplication +public class GatewaySampleApplication { + + @Value("${remote.home}") + private URI home; + + @GetMapping("/test") + public ResponseEntity<?> proxy(ProxyExchange<Object> proxy) throws Exception { + return proxy.uri(home.toString() + "/image/png").get(); + } + +} +There are convenience methods on the ProxyExchange to enable the handler method to discover and enhance the URI path of the incoming request. For example you might want to extract the trailing elements of a path to pass them downstream: +@GetMapping("/proxy/path/**") +public ResponseEntity<?> proxyPath(ProxyExchange<?> proxy) throws Exception { + String path = proxy.path("/proxy/path/"); + return proxy.uri(home.toString() + "/foos/" + path).get(); +} +All the features of Spring MVC are available to Gateway handler methods. So you can inject request headers and query parameters, for instance, and you can constrain the incoming requests with declarations in the mapping annotation. See the documentation for @RequestMapping in Spring MVC for more details of those features. +Headers can be added to the downstream response using the header() methods on ProxyExchange. +You can also manipulate response headers (and anything else you like in the response) by adding a mapper to the get() etc. method. The mapper is a Function that takes the incoming ResponseEntity and converts it to an outgoing one. +First class support is provided for "sensitive" headers ("cookie" and "authorization" by default) which are not passed downstream, and for "proxy" headers (x-forwarded-*). + +
    Appendix: Compendium of Configuration Properties