Remove @Bean RestTemplate

(If users need one they can add it themselves)

Fixes gh-239
This commit is contained in:
Dave Syer
2016-03-31 13:31:34 +01:00
parent 84f4d3720c
commit 00b67a87d5
10 changed files with 122 additions and 67 deletions

View File

@@ -38,8 +38,9 @@ import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.web.client.RestTemplate;
/**
* {@link org.springframework.boot.autoconfigure.EnableAutoConfiguration Auto-configuration}
* enables span information propagation when using {@link RestTemplate}
* {@link org.springframework.boot.autoconfigure.EnableAutoConfiguration
* Auto-configuration} enables span information propagation when using
* {@link RestTemplate}
*
* @author Marcin Grzejszczak
* @since 1.0.0
@@ -58,12 +59,6 @@ public class TraceWebClientAutoConfiguration {
return new TraceRestTemplateInterceptor(tracer, spanInjector);
}
@Bean
@ConditionalOnMissingBean
public RestTemplate restTemplate() {
return new RestTemplate();
}
@Bean
public SpanInjector<HttpRequest> httpRequestSpanInjector() {
return new HttpRequestInjector();
@@ -82,7 +77,8 @@ public class TraceWebClientAutoConfiguration {
public void init() {
if (this.restTemplates != null) {
for (RestTemplate restTemplate : this.restTemplates) {
List<ClientHttpRequestInterceptor> interceptors = new ArrayList<ClientHttpRequestInterceptor>(restTemplate.getInterceptors());
List<ClientHttpRequestInterceptor> interceptors = new ArrayList<ClientHttpRequestInterceptor>(
restTemplate.getInterceptors());
interceptors.add(this.traceRestTemplateInterceptor);
restTemplate.setInterceptors(interceptors);
}

View File

@@ -1,5 +1,17 @@
package org.springframework.cloud.sleuth.instrument.web;
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
import static com.github.tomakehurst.wiremock.client.WireMock.get;
import static com.github.tomakehurst.wiremock.client.WireMock.getRequestedFor;
import static com.github.tomakehurst.wiremock.client.WireMock.matching;
import static com.github.tomakehurst.wiremock.client.WireMock.urlMatching;
import static java.util.concurrent.TimeUnit.SECONDS;
import static junitparams.JUnitParamsRunner.$;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.asyncDispatch;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.request;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
@@ -14,6 +26,7 @@ import org.springframework.cloud.sleuth.Span;
import org.springframework.cloud.sleuth.instrument.DefaultTestAutoConfiguration;
import org.springframework.cloud.sleuth.instrument.web.common.AbstractMvcWiremockIntegrationTest;
import org.springframework.cloud.sleuth.instrument.web.common.HttpMockServer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;
import org.springframework.http.MediaType;
import org.springframework.scheduling.annotation.EnableAsync;
@@ -31,38 +44,33 @@ import org.springframework.web.context.request.async.WebAsyncTask;
import junitparams.JUnitParamsRunner;
import junitparams.Parameters;
import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
import static com.github.tomakehurst.wiremock.client.WireMock.get;
import static com.github.tomakehurst.wiremock.client.WireMock.getRequestedFor;
import static com.github.tomakehurst.wiremock.client.WireMock.matching;
import static com.github.tomakehurst.wiremock.client.WireMock.urlMatching;
import static java.util.concurrent.TimeUnit.SECONDS;
import static junitparams.JUnitParamsRunner.$;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.asyncDispatch;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.request;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@SpringApplicationConfiguration(classes = {RestTemplateTraceAspectIntegrationTests.CorrelationIdAspectTestConfiguration.class})
@SpringApplicationConfiguration(classes = {
RestTemplateTraceAspectIntegrationTests.CorrelationIdAspectTestConfiguration.class })
@RunWith(JUnitParamsRunner.class)
public class RestTemplateTraceAspectIntegrationTests extends AbstractMvcWiremockIntegrationTest {
public class RestTemplateTraceAspectIntegrationTests
extends AbstractMvcWiremockIntegrationTest {
@ClassRule public static final SpringClassRule SCR = new SpringClassRule();
@Rule public final SpringMethodRule springMethodRule = new SpringMethodRule();
@ClassRule
public static final SpringClassRule SCR = new SpringClassRule();
@Rule
public final SpringMethodRule springMethodRule = new SpringMethodRule();
@Before public void setupDefaultWireMockStubbing() {
@Before
public void setupDefaultWireMockStubbing() {
stubInteraction(get(urlMatching(".*")), aResponse().withStatus(200));
}
@Test
public void should_set_span_data_on_headers_via_aspect_in_synchronous_call() throws Exception {
public void should_set_span_data_on_headers_via_aspect_in_synchronous_call()
throws Exception {
whenARequestIsSentToASyncEndpoint();
thenTraceIdHasBeenSetOnARequestHeader();
}
@Test
public void should_set_span_data_on_headers_when_sending_a_request_via_async_rest_template() throws Exception {
public void should_set_span_data_on_headers_when_sending_a_request_via_async_rest_template()
throws Exception {
whenARequestIsSentToAAsyncRestTemplateEndpoint();
thenTraceIdHasBeenSetOnARequestHeader();
@@ -70,7 +78,8 @@ public class RestTemplateTraceAspectIntegrationTests extends AbstractMvcWiremock
@Test
@Parameters
public void should_set_span_data_on_headers_via_aspect_in_asynchronous_call(String url) throws Exception {
public void should_set_span_data_on_headers_via_aspect_in_asynchronous_call(
String url) throws Exception {
whenARequestIsSentToAnAsyncEndpoint(url);
thenTraceIdHasBeenSetOnARequestHeader();
@@ -81,39 +90,49 @@ public class RestTemplateTraceAspectIntegrationTests extends AbstractMvcWiremock
}
private void whenARequestIsSentToAAsyncRestTemplateEndpoint() throws Exception {
this.mockMvc.perform(MockMvcRequestBuilders.get("/asyncRestTemplate").accept(MediaType.TEXT_PLAIN)).andReturn();
this.mockMvc.perform(MockMvcRequestBuilders.get("/asyncRestTemplate")
.accept(MediaType.TEXT_PLAIN)).andReturn();
}
private void whenARequestIsSentToASyncEndpoint() throws Exception {
this.mockMvc.perform(MockMvcRequestBuilders.get("/syncPing").accept(MediaType.TEXT_PLAIN)).andReturn();
this.mockMvc.perform(
MockMvcRequestBuilders.get("/syncPing").accept(MediaType.TEXT_PLAIN))
.andReturn();
}
private void thenTraceIdHasBeenSetOnARequestHeader() {
this.wireMock.verifyThat(getRequestedFor(urlMatching(".*")).withHeader(Span.TRACE_ID_NAME, matching("^(?!\\s*$).+")));
this.wireMock.verifyThat(getRequestedFor(urlMatching(".*"))
.withHeader(Span.TRACE_ID_NAME, matching("^(?!\\s*$).+")));
}
private void whenARequestIsSentToAnAsyncEndpoint(String url) throws Exception {
MvcResult mvcResult = this.mockMvc.perform(MockMvcRequestBuilders.get(url).accept(MediaType.TEXT_PLAIN))
.andExpect(request().asyncStarted())
.andReturn();
MvcResult mvcResult = this.mockMvc
.perform(MockMvcRequestBuilders.get(url).accept(MediaType.TEXT_PLAIN))
.andExpect(request().asyncStarted()).andReturn();
mvcResult.getAsyncResult(SECONDS.toMillis(2));
this.mockMvc.perform(asyncDispatch(mvcResult)).
andDo(print()).
andExpect(status().isOk());
this.mockMvc.perform(asyncDispatch(mvcResult)).andDo(print())
.andExpect(status().isOk());
}
@EnableAsync
@DefaultTestAutoConfiguration
@Import(AspectTestingController.class)
public static class CorrelationIdAspectTestConfiguration {
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
@RestController
public static class AspectTestingController {
@Autowired HttpMockServer httpMockServer;
@Autowired RestTemplate restTemplate;
@Autowired AsyncRestTemplate asyncRestTemplate;
@Autowired
HttpMockServer httpMockServer;
@Autowired
RestTemplate restTemplate;
@Autowired
AsyncRestTemplate asyncRestTemplate;
@RequestMapping(value = "/asyncRestTemplate", method = RequestMethod.GET, produces = MediaType.TEXT_PLAIN_VALUE)
public String asyncRestTemplate()
@@ -147,13 +166,15 @@ public class RestTemplateTraceAspectIntegrationTests extends AbstractMvcWiremock
};
private String callWiremockAndReturnOk() {
this.restTemplate.getForObject("http://localhost:" + this.httpMockServer.port(), String.class);
this.restTemplate.getForObject(
"http://localhost:" + this.httpMockServer.port(), String.class);
return "OK";
}
private String callWiremockViaAsyncRestTemplateAndReturnOk()
throws ExecutionException, InterruptedException {
this.asyncRestTemplate.getForEntity("http://localhost:" + this.httpMockServer.port(), String.class).get();
this.asyncRestTemplate.getForEntity(
"http://localhost:" + this.httpMockServer.port(), String.class).get();
return "OK";
}
}

View File

@@ -115,6 +115,11 @@ public class TraceFilterCustomExtractorTests {
this.port = event.getEmbeddedServletContainer().getPort();
}
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
@Bean
CustomRestController customRestController() {
return new CustomRestController();

View File

@@ -19,11 +19,13 @@ package sample;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.integration.annotation.IntegrationComponentScan;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
/**
* @author Spencer Gibb
@@ -59,6 +61,11 @@ public class SampleMessagingApplication {
return this.transformer.send(msg);
}
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(SampleMessagingApplication.class, args);
}

View File

@@ -25,6 +25,7 @@ import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
import org.springframework.cloud.sleuth.zipkin.ZipkinSpanReporter;
import org.springframework.context.annotation.Bean;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.web.client.RestTemplate;
import zipkin.Span;
@@ -42,9 +43,14 @@ public class SampleRibbonApplication {
SpringApplication.run(SampleRibbonApplication.class, args);
}
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
// Use this for debugging (or if there is no Zipkin server running on port 9411)
@Bean
@ConditionalOnProperty(value="sample.zipkin.enabled", havingValue="false")
@ConditionalOnProperty(value = "sample.zipkin.enabled", havingValue = "false")
public ZipkinSpanReporter spanCollector() {
return new ZipkinSpanReporter() {
@Override

View File

@@ -36,8 +36,8 @@ import org.springframework.web.client.RestTemplate;
* @author Spencer Gibb
*/
@RestController
public class SampleController implements
ApplicationListener<EmbeddedServletContainerInitializedEvent> {
public class SampleController
implements ApplicationListener<EmbeddedServletContainerInitializedEvent> {
private static final Log log = LogFactory.getLog(SampleController.class);
@Autowired
@@ -48,16 +48,16 @@ ApplicationListener<EmbeddedServletContainerInitializedEvent> {
private SpanAccessor accessor;
@Autowired
private SampleBackground controller;
@Autowired
private Random random;
private Random random = new Random();
private int port;
@RequestMapping("/")
public String hi() throws InterruptedException {
Thread.sleep(this.random.nextInt(1000));
String s = this.restTemplate.getForObject("http://localhost:" + this.port
+ "/hi2", String.class);
String s = this.restTemplate
.getForObject("http://localhost:" + this.port + "/hi2", String.class);
return "hi/" + s;
}
@@ -68,7 +68,8 @@ ApplicationListener<EmbeddedServletContainerInitializedEvent> {
public String call() throws Exception {
int millis = SampleController.this.random.nextInt(1000);
Thread.sleep(millis);
SampleController.this.tracer.addTag("callable-sleep-millis", String.valueOf(millis));
SampleController.this.tracer.addTag("callable-sleep-millis",
String.valueOf(millis));
Span currentSpan = SampleController.this.accessor.getCurrentSpan();
return "async hi: " + currentSpan;
}
@@ -98,8 +99,8 @@ ApplicationListener<EmbeddedServletContainerInitializedEvent> {
Thread.sleep(millis);
this.tracer.addTag("random-sleep-millis", String.valueOf(millis));
String s = this.restTemplate.getForObject("http://localhost:" + this.port
+ "/call", String.class);
String s = this.restTemplate
.getForObject("http://localhost:" + this.port + "/call", String.class);
this.tracer.close(span);
return "traced/" + s;
}
@@ -111,8 +112,8 @@ ApplicationListener<EmbeddedServletContainerInitializedEvent> {
Thread.sleep(millis);
this.tracer.addTag("random-sleep-millis", String.valueOf(millis));
String s = this.restTemplate.getForObject("http://localhost:" + this.port
+ "/call", String.class);
String s = this.restTemplate
.getForObject("http://localhost:" + this.port + "/call", String.class);
return "start/" + s;
}

View File

@@ -21,6 +21,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.web.client.RestTemplate;
/**
* @author Spencer Gibb
@@ -32,6 +33,11 @@ public class SampleSleuthApplication {
public static final String CLIENT_NAME = "testApp";
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
@Bean
public SampleController sampleController() {
return new SampleController();

View File

@@ -25,6 +25,7 @@ import org.springframework.cloud.sleuth.zipkin.ZipkinSpanReporter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.web.client.RestTemplate;
/**
* @author Spencer Gibb
@@ -40,9 +41,14 @@ public class SampleZipkinApplication {
SpringApplication.run(SampleZipkinApplication.class, args);
}
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
// Use this for debugging (or if there is no Zipkin server running on port 9411)
@Bean
@ConditionalOnProperty(value="sample.zipkin.enabled", havingValue="false")
@ConditionalOnProperty(value = "sample.zipkin.enabled", havingValue = "false")
public ZipkinSpanReporter spanCollector() {
return new ZipkinSpanReporter() {
@Override

View File

@@ -36,8 +36,8 @@ import org.springframework.web.client.RestTemplate;
* @author Spencer Gibb
*/
@RestController
public class SampleController implements
ApplicationListener<EmbeddedServletContainerInitializedEvent> {
public class SampleController
implements ApplicationListener<EmbeddedServletContainerInitializedEvent> {
private static final Log log = LogFactory.getLog(SampleController.class);
@Autowired
private RestTemplate restTemplate;
@@ -47,16 +47,16 @@ ApplicationListener<EmbeddedServletContainerInitializedEvent> {
private SpanAccessor accessor;
@Autowired
private SampleBackground controller;
@Autowired
private Random random;
private Random random = new Random();
private int port;
@RequestMapping("/")
public String hi() throws InterruptedException {
Thread.sleep(this.random.nextInt(1000));
String s = this.restTemplate.getForObject("http://localhost:" + this.port
+ "/hi2", String.class);
String s = this.restTemplate
.getForObject("http://localhost:" + this.port + "/hi2", String.class);
return "hi/" + s;
}
@@ -67,7 +67,8 @@ ApplicationListener<EmbeddedServletContainerInitializedEvent> {
public String call() throws Exception {
int millis = SampleController.this.random.nextInt(1000);
Thread.sleep(millis);
SampleController.this.tracer.addTag("callable-sleep-millis", String.valueOf(millis));
SampleController.this.tracer.addTag("callable-sleep-millis",
String.valueOf(millis));
Span currentSpan = SampleController.this.accessor.getCurrentSpan();
return "async hi: " + currentSpan;
}
@@ -97,8 +98,8 @@ ApplicationListener<EmbeddedServletContainerInitializedEvent> {
Thread.sleep(millis);
this.tracer.addTag("random-sleep-millis", String.valueOf(millis));
String s = this.restTemplate.getForObject("http://localhost:" + this.port
+ "/call", String.class);
String s = this.restTemplate
.getForObject("http://localhost:" + this.port + "/call", String.class);
this.tracer.close(span);
return "traced/" + s;
}
@@ -110,8 +111,8 @@ ApplicationListener<EmbeddedServletContainerInitializedEvent> {
Thread.sleep(millis);
this.tracer.addTag("random-sleep-millis", String.valueOf(millis));
String s = this.restTemplate.getForObject("http://localhost:" + this.port
+ "/call", String.class);
String s = this.restTemplate
.getForObject("http://localhost:" + this.port + "/call", String.class);
return "start/" + s;
}

View File

@@ -21,6 +21,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.web.client.RestTemplate;
/**
* @author Spencer Gibb
@@ -32,6 +33,11 @@ public class SampleSleuthApplication {
public static final String CLIENT_NAME = "testApp";
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
@Bean
public SampleController sampleController() {
return new SampleController();