use of reactor.util.context.Context in project spring-cloud-sleuth by spring-cloud.
the class TraceWebFilter method filter.
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
if (tracer().currentSpan() != null) {
// clear any previous trace
tracer().withSpanInScope(null);
}
ServerHttpRequest request = exchange.getRequest();
ServerHttpResponse response = exchange.getResponse();
String uri = request.getPath().pathWithinApplication().value();
if (log.isDebugEnabled()) {
log.debug("Received a request to uri [" + uri + "]");
}
Span spanFromAttribute = getSpanFromAttribute(exchange);
final String CONTEXT_ERROR = "sleuth.webfilter.context.error";
return chain.filter(exchange).compose(f -> f.then(Mono.subscriberContext()).onErrorResume(t -> Mono.subscriberContext().map(c -> c.put(CONTEXT_ERROR, t))).flatMap(c -> {
// reactivate span from context
Span span = spanFromContext(c);
Mono<Void> continuation;
Throwable t = null;
if (c.hasKey(CONTEXT_ERROR)) {
t = c.get(CONTEXT_ERROR);
continuation = Mono.error(t);
} else {
continuation = Mono.empty();
}
Object attribute = exchange.getAttribute(HandlerMapping.BEST_MATCHING_HANDLER_ATTRIBUTE);
if (attribute instanceof HandlerMethod) {
HandlerMethod handlerMethod = (HandlerMethod) attribute;
addClassMethodTag(handlerMethod, span);
addClassNameTag(handlerMethod, span);
}
addResponseTagsForSpanWithoutParent(exchange, response, span);
handler().handleSend(response, t, span);
if (log.isDebugEnabled()) {
log.debug("Handled send of " + span);
}
return continuation;
}).subscriberContext(c -> {
Span span;
if (c.hasKey(Span.class)) {
Span parent = c.get(Span.class);
span = tracer().nextSpan(TraceContextOrSamplingFlags.create(parent.context())).start();
if (log.isDebugEnabled()) {
log.debug("Found span in reactor context" + span);
}
} else {
if (spanFromAttribute != null) {
span = spanFromAttribute;
if (log.isDebugEnabled()) {
log.debug("Found span in attribute " + span);
}
} else {
span = handler().handleReceive(extractor(), request.getHeaders(), request);
if (log.isDebugEnabled()) {
log.debug("Handled receive of span " + span);
}
}
exchange.getAttributes().put(TRACE_REQUEST_ATTR, span);
}
return c.put(Span.class, span);
}));
}
use of reactor.util.context.Context in project reactor-netty by reactor.
the class HttpServerTests method testRestart.
// from https://github.com/reactor/reactor-netty/issues/90
@Test
public void testRestart() {
// start a first server with a handler that answers HTTP 200 OK
NettyContext context = HttpServer.create(8080).newHandler((req, resp) -> resp.status(200).send().log()).block();
HttpClientResponse response = HttpClient.create(8080).get("/").block();
// checking the response status, OK
assertThat(response.status().code()).isEqualTo(200);
// dispose the Netty context and wait for the channel close
response.dispose();
context.dispose();
context.onClose().block();
// REQUIRED - bug pool does not detect/translate properly lifecycle
HttpResources.reset();
// create a totally new server instance, with a different handler that answers HTTP 201
context = HttpServer.create(8080).newHandler((req, resp) -> resp.status(201).send()).block();
response = HttpClient.create(8080).get("/").block();
// fails, response status is 200 and debugging shows the the previous handler is called
assertThat(response.status().code()).isEqualTo(201);
response.dispose();
context.dispose();
context.onClose().block();
}
use of reactor.util.context.Context in project reactor-netty by reactor.
the class HttpServerTests method assertSendFile.
private void assertSendFile(Function<HttpServerResponse, NettyOutbound> fn) {
NettyContext context = HttpServer.create(opt -> opt.host("localhost")).newHandler((req, resp) -> fn.apply(resp)).block();
HttpClientResponse response = HttpClient.create(opt -> opt.connectAddress(() -> context.address())).get("/foo").block(Duration.ofSeconds(120));
context.dispose();
context.onClose().block();
String body = response.receive().aggregate().asString(StandardCharsets.UTF_8).block();
assertThat(body).startsWith("This is an UTF-8 file that is larger than 1024 bytes. " + "It contains accents like é.").contains("1024 mark here -><- 1024 mark here").endsWith("End of File");
}
use of reactor.util.context.Context in project reactor-netty by reactor.
the class HttpServerTests method doTestSendFileAsync.
private void doTestSendFileAsync(int chunk) throws IOException, URISyntaxException {
Path largeFile = Paths.get(getClass().getResource("/largeFile.txt").toURI());
Path tempFile = Files.createTempFile(largeFile.getParent(), "temp", ".txt");
tempFile.toFile().deleteOnExit();
byte[] fileBytes = Files.readAllBytes(largeFile);
for (int i = 0; i < 1000; i++) {
Files.write(tempFile, fileBytes, StandardOpenOption.APPEND);
}
ByteBufAllocator allocator = ByteBufAllocator.DEFAULT;
AsynchronousFileChannel channel = AsynchronousFileChannel.open(tempFile, StandardOpenOption.READ);
Flux<ByteBuf> content = Flux.create(fluxSink -> {
fluxSink.onDispose(() -> {
try {
if (channel != null) {
channel.close();
}
} catch (IOException ignored) {
}
});
ByteBuffer buf = ByteBuffer.allocate(chunk);
channel.read(buf, 0, buf, new TestCompletionHandler(channel, fluxSink, allocator, chunk));
});
NettyContext context = HttpServer.create(opt -> opt.host("localhost")).newHandler((req, resp) -> resp.sendByteArray(req.receive().aggregate().asByteArray())).block();
byte[] response = HttpClient.create(opt -> opt.connectAddress(() -> context.address())).request(HttpMethod.POST, "/", req -> req.send(content).then()).flatMap(res -> res.receive().aggregate().asByteArray()).block();
assertThat(response).isEqualTo(Files.readAllBytes(tempFile));
context.dispose();
}
use of reactor.util.context.Context in project reactor-netty by reactor.
the class HttpServerTests method contextShouldBeTransferredFromDownStreamToUpsream.
@Test
public void contextShouldBeTransferredFromDownStreamToUpsream() {
AtomicReference<Context> context = new AtomicReference<>();
NettyContext server = HttpServer.create(0).newHandler((req, res) -> res.status(200).send()).block(Duration.ofSeconds(300));
HttpClient client = HttpClient.create(ops -> ops.connectAddress(() -> server.address()).poolResources(PoolResources.fixed("test", 1)));
try {
Mono<String> content = client.post("/", req -> req.failOnClientError(false).sendString(Mono.just("bodysample").subscriberContext(c -> {
context.set(c);
return c;
}))).flatMap(res -> res.receive().aggregate().asString()).subscriberContext(c -> c.put("Hello", "World"));
StepVerifier.create(content).expectComplete().verify(Duration.ofSeconds(300));
assertThat(context.get().get("Hello").equals("World")).isTrue();
} finally {
server.dispose();
}
}
Aggregations