Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: add reactor context propagation example #10220

Merged
merged 9 commits into from
Dec 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,13 @@ After that, all the thread-local propagated elements can restore their thread-lo

NOTE: The thread-local values are read-only. To modify them, the `PropagatedContext` instance needs to be changed and put into the Reactor's context.

To add the context in the middle of the reactive chain, do something like the following:

snippet::io.micronaut.docs.propagation.reactor.HelloController[tags="imports,example", indent=0]

<1> Obtain the current context that has been modified, e.g. with `PropagatedContext.get().plus(...)`, etc.
<2> Add the context into the reactive chain.

If you have Micrometer Context Propagation on the classpath but don't want to use it, apply the following configuration:

.Disable Micrometer Context Propagation in Reactor
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package io.micronaut.docs.propagation.reactor

// tag::imports[]
import io.micronaut.core.async.propagation.ReactorPropagation
import io.micronaut.core.propagation.PropagatedContext
import io.micronaut.core.propagation.PropagatedContextElement
import io.micronaut.http.annotation.Controller
import io.micronaut.http.annotation.Get
import io.micronaut.http.annotation.QueryValue
import reactor.core.publisher.Mono
// end::imports[]
import io.micronaut.context.annotation.Requires

@Requires(property = 'spec.name', value = 'PropagatedContextSpec')
// tag::example[]
@Controller
class HelloController {

@Get('/hello')
Mono<String> hello(@QueryValue('name') String name) {
PropagatedContext propagatedContext = PropagatedContext.get() + new MyContextElement(name) // <1>
return Mono.just("Hello, $name")
.contextWrite(ctx -> ReactorPropagation.addPropagatedContext(ctx, propagatedContext)) // <2>
}
}

record MyContextElement(String value) implements PropagatedContextElement { }
// end::example[]
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package io.micronaut.docs.propagation.reactor

import io.micronaut.context.annotation.Property
import io.micronaut.core.type.Argument
import io.micronaut.http.HttpRequest
import io.micronaut.http.client.HttpClient
import io.micronaut.http.client.annotation.Client
import io.micronaut.http.uri.UriBuilder
import io.micronaut.test.extensions.spock.annotation.MicronautTest
import jakarta.inject.Inject
import spock.lang.Specification

@Property(name = 'spec.name', value = 'PropagatedContextSpec')
@MicronautTest
class PropagatedContextSpec extends Specification {

@Inject
@Client("/")
HttpClient client

void "test Mono Request"() {
when:
URI uri = UriBuilder.of('/hello').queryParam('name', 'Dean').build()
String hello = client.toBlocking().retrieve(HttpRequest.GET(uri), Argument.of(String))

then:
'Hello, Dean' == hello
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package io.micronaut.docs.propagation.reactor;

// tag::imports[]
import io.micronaut.core.async.propagation.ReactorPropagation;
import io.micronaut.core.propagation.PropagatedContext;
import io.micronaut.core.propagation.PropagatedContextElement;
import io.micronaut.http.annotation.Controller;
import io.micronaut.http.annotation.Get;
import io.micronaut.http.annotation.QueryValue;
import reactor.core.publisher.Mono;
// end::imports[]
import io.micronaut.context.annotation.Requires;

@Requires(property = "spec.name", value = "PropagatedContextSpec")
// tag::example[]
@Controller
class HelloController {

@Get("/hello")
Mono<String> hello(@QueryValue("name") String name) {
PropagatedContext propagatedContext = PropagatedContext.get().plus(new MyContextElement(name)); // <1>
return Mono.just("Hello, " + name)
.contextWrite(ctx -> ReactorPropagation.addPropagatedContext(ctx, propagatedContext)); // <2>
}
}

record MyContextElement(String value) implements PropagatedContextElement { }
// end::example[]
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package io.micronaut.docs.propagation.reactor;

import io.micronaut.context.annotation.Property;
import io.micronaut.core.type.Argument;
import io.micronaut.http.HttpRequest;
import io.micronaut.http.client.HttpClient;
import io.micronaut.http.client.annotation.Client;
import io.micronaut.http.uri.UriBuilder;
import io.micronaut.test.extensions.junit5.annotation.MicronautTest;
import jakarta.inject.Inject;
import org.junit.jupiter.api.Test;

import java.net.URI;

import static org.junit.jupiter.api.Assertions.assertEquals;

@Property(name = "spec.name", value = "PropagatedContextSpec")
@MicronautTest
class PropagatedContextTest {

@Inject
@Client("/")
HttpClient client;

@Test
void testMonoRequest() {
URI uri = UriBuilder.of("/hello").queryParam("name", "Dean").build();
String hello = client.toBlocking().retrieve(HttpRequest.GET(uri), Argument.of(String.class));
assertEquals("Hello, Dean", hello);
}
}
Loading