Easier Async configuration (#251)

added possibility to provide in an easy way custom client request factories

fixes #236
This commit is contained in:
Marcin Grzejszczak
2016-04-15 12:03:01 +02:00
parent cf34acef63
commit 8f8b9893f0
2 changed files with 47 additions and 9 deletions

View File

@@ -439,8 +439,13 @@ just set `spring.sleuth.web.client.enabled` to `false`.
==== Asynchronous Rest Template
Custom instrumentation is set to create and close Spans upon sending and receiving requests. To block the `AsyncRestTemplate`
features set `spring.sleuth.web.async.client.enabled` to `false`.
Custom instrumentation is set to create and close Spans upon sending and receiving requests. You can customize the `ClientHttpRequestFactory`
and the `AsyncClientHttpRequestFactory` by registering your beans. Remember to use tracing compatible implementations (e.g. don't forget to
wrap `ThreadPoolTaskScheduler` in a `TraceAsyncListenableTaskExecutor`).
To block the `AsyncRestTemplate` features set `spring.sleuth.web.async.client.enabled` to `false`.
To disable creation of the default `TraceAsyncClientHttpRequestFactoryWrapper` set `spring.sleuth.web.async.client.factory.enabled`
to `false`. If you don't want to create `AsyncRestClient` at all set `spring.sleuth.web.async.client.template.enabled` to `false`.
=== Feign

View File

@@ -16,6 +16,7 @@
package org.springframework.cloud.sleuth.instrument.web.client;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
@@ -27,8 +28,13 @@ import org.springframework.cloud.sleuth.Tracer;
import org.springframework.cloud.sleuth.autoconfig.TraceAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.task.AsyncListenableTaskExecutor;
import org.springframework.http.HttpRequest;
import org.springframework.http.client.AsyncClientHttpRequestFactory;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
import org.springframework.web.client.AsyncRestTemplate;
/**
@@ -46,18 +52,45 @@ import org.springframework.web.client.AsyncRestTemplate;
@AutoConfigureAfter(TraceAutoConfiguration.class)
public class TraceWebAsyncClientAutoConfiguration {
@Autowired Tracer tracer;
@Autowired SpanInjector<HttpRequest> spanInjector;
@Autowired(required = false) ClientHttpRequestFactory clientHttpRequestFactory;
@Autowired(required = false) AsyncClientHttpRequestFactory asyncClientHttpRequestFactory;
@Bean
@ConditionalOnMissingBean
public AsyncClientHttpRequestFactory asyncClientHttpRequestFactory(Tracer tracer,
SpanInjector<HttpRequest> spanInjector) {
return new TraceAsyncClientHttpRequestFactoryWrapper(tracer, spanInjector);
@Primary
@ConditionalOnProperty(value = "spring.sleuth.web.async.client.factory.enabled", matchIfMissing = true)
public TraceAsyncClientHttpRequestFactoryWrapper traceAsyncClientHttpRequestFactory() {
ClientHttpRequestFactory clientFactory = this.clientHttpRequestFactory;
AsyncClientHttpRequestFactory asyncClientFactory = this.asyncClientHttpRequestFactory;
if (clientFactory == null) {
clientFactory = defaultClientHttpRequestFactory(this.tracer);
}
if (asyncClientFactory == null) {
asyncClientFactory = clientFactory instanceof AsyncClientHttpRequestFactory ?
(AsyncClientHttpRequestFactory) clientFactory : defaultClientHttpRequestFactory(this.tracer);
}
return new TraceAsyncClientHttpRequestFactoryWrapper(this.tracer, this.spanInjector,
asyncClientFactory, clientFactory);
}
private SimpleClientHttpRequestFactory defaultClientHttpRequestFactory(Tracer tracer) {
SimpleClientHttpRequestFactory simpleClientHttpRequestFactory = new SimpleClientHttpRequestFactory();
simpleClientHttpRequestFactory.setTaskExecutor(asyncListenableTaskExecutor(tracer));
return simpleClientHttpRequestFactory;
}
private AsyncListenableTaskExecutor asyncListenableTaskExecutor(Tracer tracer) {
ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler();
threadPoolTaskScheduler.initialize();
return new TraceAsyncListenableTaskExecutor(threadPoolTaskScheduler, tracer);
}
@Bean
@ConditionalOnMissingBean
public AsyncRestTemplate asyncRestTemplate(AsyncClientHttpRequestFactory asyncClientHttpRequestFactory,
Tracer tracer) {
return new TraceAsyncRestTemplate(asyncClientHttpRequestFactory, tracer);
@ConditionalOnProperty(value = "spring.sleuth.web.async.client.template.enabled", matchIfMissing = true)
public AsyncRestTemplate traceAsyncRestTemplate() {
return new TraceAsyncRestTemplate(traceAsyncClientHttpRequestFactory(), this.tracer);
}
}