-
Notifications
You must be signed in to change notification settings - Fork 778
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #155 from spring-cloud/issues_#124_asyncresttemplate
[#124] Added support for async rest template
- Loading branch information
Showing
7 changed files
with
320 additions
and
72 deletions.
There are no files selected for viewing
116 changes: 116 additions & 0 deletions
116
...ringframework/cloud/sleuth/instrument/web/client/AbstractTraceHttpRequestInterceptor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
/* | ||
* Copyright 2013-2016 the original author or authors. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package org.springframework.cloud.sleuth.instrument.web.client; | ||
|
||
import org.springframework.cloud.sleuth.Span; | ||
import org.springframework.cloud.sleuth.SpanAccessor; | ||
import org.springframework.cloud.sleuth.event.ClientReceivedEvent; | ||
import org.springframework.cloud.sleuth.event.ClientSentEvent; | ||
import org.springframework.context.ApplicationEvent; | ||
import org.springframework.context.ApplicationEventPublisher; | ||
import org.springframework.context.ApplicationEventPublisherAware; | ||
import org.springframework.http.HttpRequest; | ||
import org.springframework.util.StringUtils; | ||
|
||
/** | ||
* Abstraction over classes that interact with Http requests. Allows you | ||
* to enrich the request headers with trace related information. | ||
* | ||
* @author Marcin Grzejszczak | ||
*/ | ||
abstract class AbstractTraceHttpRequestInterceptor | ||
implements ApplicationEventPublisherAware { | ||
|
||
private ApplicationEventPublisher publisher; | ||
private final SpanAccessor accessor; | ||
|
||
protected AbstractTraceHttpRequestInterceptor(SpanAccessor accessor) { | ||
this.accessor = accessor; | ||
} | ||
|
||
@Override | ||
public void setApplicationEventPublisher(ApplicationEventPublisher publisher) { | ||
this.publisher = publisher; | ||
} | ||
|
||
private void enrichWithTraceHeaders(HttpRequest request, Span span) { | ||
setIdHeader(request, Span.TRACE_ID_NAME, span.getTraceId()); | ||
setIdHeader(request, Span.SPAN_ID_NAME, span.getSpanId()); | ||
if (!span.isExportable()) { | ||
setHeader(request, Span.NOT_SAMPLED_NAME, "true"); | ||
} | ||
setHeader(request, Span.SPAN_NAME_NAME, span.getName().toString()); | ||
setIdHeader(request, Span.PARENT_ID_NAME, getParentId(span)); | ||
setHeader(request, Span.PROCESS_ID_NAME, span.getProcessId()); | ||
} | ||
|
||
private Long getParentId(Span span) { | ||
return !span.getParents().isEmpty() ? span.getParents().get(0) : null; | ||
} | ||
|
||
protected void doNotSampleThisSpan(HttpRequest request) { | ||
setHeader(request, Span.NOT_SAMPLED_NAME, "true"); | ||
} | ||
|
||
private void setHeader(HttpRequest request, String name, String value) { | ||
if (StringUtils.hasText(value) && !request.getHeaders().containsKey(name) && | ||
this.accessor.isTracing()) { | ||
request.getHeaders().add(name, value); | ||
} | ||
} | ||
|
||
private void setIdHeader(HttpRequest request, String name, Long value) { | ||
if (value != null) { | ||
setHeader(request, name, Span.toHex(value)); | ||
} | ||
} | ||
|
||
/** | ||
* Enriches the request with proper headers and publishes | ||
* the client sent event | ||
*/ | ||
protected void publishStartEvent(HttpRequest request) { | ||
Span span = currentSpan(); | ||
enrichWithTraceHeaders(request, span); | ||
publish(new ClientSentEvent(this, span)); | ||
} | ||
|
||
/** | ||
* Close the current span and emit the ClientReceivedEvent | ||
*/ | ||
public void finish() { | ||
if (!isTracing()) { | ||
return; | ||
} | ||
publish(new ClientReceivedEvent(this, currentSpan())); | ||
} | ||
|
||
private void publish(ApplicationEvent event) { | ||
if (this.publisher != null) { | ||
this.publisher.publishEvent(event); | ||
} | ||
} | ||
|
||
private Span currentSpan() { | ||
return this.accessor.getCurrentSpan(); | ||
} | ||
|
||
protected boolean isTracing() { | ||
return this.accessor.isTracing(); | ||
} | ||
|
||
} |
58 changes: 58 additions & 0 deletions
58
...amework/cloud/sleuth/instrument/web/client/TraceAsyncClientHttpRequestFactoryWrapper.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
/* | ||
* Copyright 2013-2016 the original author or authors. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package org.springframework.cloud.sleuth.instrument.web.client; | ||
|
||
import java.io.IOException; | ||
import java.net.URI; | ||
|
||
import org.springframework.cloud.sleuth.SpanAccessor; | ||
import org.springframework.http.HttpMethod; | ||
import org.springframework.http.client.AsyncClientHttpRequest; | ||
import org.springframework.http.client.AsyncClientHttpRequestFactory; | ||
|
||
/** | ||
* Wrapper that adds trace related headers to the created AsyncClientHttpRequest | ||
* | ||
* @see org.springframework.web.client.RestTemplate | ||
* @see SpanAccessor | ||
* | ||
* @author Marcin Grzejszczak | ||
* @author Spencer Gibb | ||
*/ | ||
public class TraceAsyncClientHttpRequestFactoryWrapper extends AbstractTraceHttpRequestInterceptor | ||
implements AsyncClientHttpRequestFactory { | ||
|
||
private final AsyncClientHttpRequestFactory delegate; | ||
|
||
public TraceAsyncClientHttpRequestFactoryWrapper(SpanAccessor accessor, | ||
AsyncClientHttpRequestFactory delegate) { | ||
super(accessor); | ||
this.delegate = delegate; | ||
} | ||
|
||
@Override | ||
public AsyncClientHttpRequest createAsyncRequest(URI uri, HttpMethod httpMethod) | ||
throws IOException { | ||
AsyncClientHttpRequest request = this.delegate.createAsyncRequest(uri, httpMethod); | ||
if (!isTracing()) { | ||
doNotSampleThisSpan(request); | ||
return request; | ||
} | ||
publishStartEvent(request); | ||
return request; | ||
} | ||
} |
71 changes: 71 additions & 0 deletions
71
.../springframework/cloud/sleuth/instrument/web/client/TraceAsyncListenableTaskExecutor.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
/* | ||
* Copyright 2013-2016 the original author or authors. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package org.springframework.cloud.sleuth.instrument.web.client; | ||
|
||
import java.util.concurrent.Callable; | ||
import java.util.concurrent.Future; | ||
|
||
import org.springframework.cloud.sleuth.Tracer; | ||
import org.springframework.core.task.AsyncListenableTaskExecutor; | ||
import org.springframework.util.concurrent.ListenableFuture; | ||
|
||
/** | ||
* AsyncListenableTaskExecutor that wraps all Runnable / Callable tasks into | ||
* their trace related representation | ||
*/ | ||
public class TraceAsyncListenableTaskExecutor implements AsyncListenableTaskExecutor { | ||
|
||
private final AsyncListenableTaskExecutor delegate; | ||
private final Tracer tracer; | ||
|
||
TraceAsyncListenableTaskExecutor(AsyncListenableTaskExecutor delegate, | ||
Tracer tracer) { | ||
this.delegate = delegate; | ||
this.tracer = tracer; | ||
} | ||
|
||
@Override | ||
public ListenableFuture<?> submitListenable(Runnable task) { | ||
return this.delegate.submitListenable(this.tracer.wrap(task)); | ||
} | ||
|
||
@Override | ||
public <T> ListenableFuture<T> submitListenable(Callable<T> task) { | ||
return this.delegate.submitListenable(this.tracer.wrap(task)); | ||
} | ||
|
||
@Override | ||
public void execute(Runnable task, long startTimeout) { | ||
this.delegate.execute(this.tracer.wrap(task), startTimeout); | ||
} | ||
|
||
@Override | ||
public Future<?> submit(Runnable task) { | ||
return this.delegate.submit(this.tracer.wrap(task)); | ||
} | ||
|
||
@Override | ||
public <T> Future<T> submit(Callable<T> task) { | ||
return this.delegate.submit(this.tracer.wrap(task)); | ||
} | ||
|
||
@Override | ||
public void execute(Runnable task) { | ||
this.delegate.execute(this.tracer.wrap(task)); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.