|
|
|
|
@@ -17,14 +17,13 @@ package org.springframework.graphql.support;
|
|
|
|
|
|
|
|
|
|
import java.nio.charset.StandardCharsets;
|
|
|
|
|
import java.time.Duration;
|
|
|
|
|
import java.util.Collections;
|
|
|
|
|
import java.util.List;
|
|
|
|
|
import java.util.Map;
|
|
|
|
|
import java.util.function.Consumer;
|
|
|
|
|
|
|
|
|
|
import graphql.ExecutionInput;
|
|
|
|
|
import graphql.ExecutionResult;
|
|
|
|
|
import graphql.GraphQL;
|
|
|
|
|
import graphql.schema.DataFetcher;
|
|
|
|
|
import graphql.schema.idl.RuntimeWiring;
|
|
|
|
|
import org.junit.jupiter.api.Test;
|
|
|
|
|
import org.reactivestreams.Publisher;
|
|
|
|
|
@@ -43,53 +42,47 @@ public class ReactorDataFetcherAdapterTests {
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
void monoDataFetcher() throws Exception {
|
|
|
|
|
GraphQL graphQL = graphQL("type Query { greeting: String }",
|
|
|
|
|
"Query", "greeting", env ->
|
|
|
|
|
Mono.deferContextual(context -> {
|
|
|
|
|
Object name = context.get("name");
|
|
|
|
|
return Mono.delay(Duration.ofMillis(50)).map(aLong -> "Hello " + name);
|
|
|
|
|
}));
|
|
|
|
|
|
|
|
|
|
GraphQL graphQL = initGraphQL("type Query { greeting: String }", builder -> {
|
|
|
|
|
builder.type("Query", typeBuilder -> typeBuilder.dataFetcher("greeting",
|
|
|
|
|
env -> Mono.deferContextual(context -> {
|
|
|
|
|
Object name = context.get("name");
|
|
|
|
|
return Mono.delay(Duration.ofMillis(50)).map(aLong -> "Hello " + name);
|
|
|
|
|
})));
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
ExecutionInput executionInput = initExecutionInput("{ greeting }", Context.of("name", "007"));
|
|
|
|
|
Map<String, Object> data = graphQL.executeAsync(executionInput).get().getData();
|
|
|
|
|
ExecutionInput input = executionInput("{ greeting }", Context.of("name", "007"));
|
|
|
|
|
Map<String, Object> data = graphQL.executeAsync(input).get().getData();
|
|
|
|
|
|
|
|
|
|
assertThat(data).hasSize(1).containsEntry("greeting", "Hello 007");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
void fluxDataFetcher() throws Exception {
|
|
|
|
|
GraphQL graphQL = graphQL("type Query { greetings: [String] }",
|
|
|
|
|
"Query", "greetings", env ->
|
|
|
|
|
Mono.delay(Duration.ofMillis(50)).flatMapMany(aLong ->
|
|
|
|
|
Flux.deferContextual(context -> {
|
|
|
|
|
String name = context.get("name");
|
|
|
|
|
return Flux.just("Hi", "Bonjour", "Hola").map(s -> s + " " + name);
|
|
|
|
|
})));
|
|
|
|
|
|
|
|
|
|
GraphQL graphQL = initGraphQL("type Query { greetings: [String] }", builder -> {
|
|
|
|
|
builder.type("Query", typeBuilder -> typeBuilder.dataFetcher("greetings",
|
|
|
|
|
env -> Mono.delay(Duration.ofMillis(50)).flatMapMany(aLong ->
|
|
|
|
|
Flux.deferContextual(context -> {
|
|
|
|
|
String name = context.get("name");
|
|
|
|
|
return Flux.just("Hi", "Bonjour", "Hola").map(s -> s + " " + name);
|
|
|
|
|
}))));
|
|
|
|
|
});
|
|
|
|
|
ExecutionInput input = executionInput("{ greetings }", Context.of("name", "007"));
|
|
|
|
|
Map<String, Object> data = graphQL.executeAsync(input).get().getData();
|
|
|
|
|
|
|
|
|
|
ExecutionInput executionInput = initExecutionInput("{ greetings }", Context.of("name", "007"));
|
|
|
|
|
|
|
|
|
|
Map<String, Object> data = graphQL.executeAsync(executionInput).get().getData();
|
|
|
|
|
assertThat((List<String>) data.get("greetings")).containsExactly("Hi 007", "Bonjour 007", "Hola 007");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@Test
|
|
|
|
|
void fluxDataFetcherSubscription() throws Exception {
|
|
|
|
|
GraphQL graphQL = graphQL(
|
|
|
|
|
"type Query { greeting: String } type Subscription { greetings: String }",
|
|
|
|
|
"Subscription", "greetings", env ->
|
|
|
|
|
Mono.delay(Duration.ofMillis(50)).flatMapMany(aLong ->
|
|
|
|
|
Flux.deferContextual(context -> {
|
|
|
|
|
String name = context.get("name");
|
|
|
|
|
return Flux.just("Hi", "Bonjour", "Hola").map(s -> s + " " + name);
|
|
|
|
|
})));
|
|
|
|
|
|
|
|
|
|
GraphQL graphQL = initGraphQL(
|
|
|
|
|
"type Query { greeting: String } type Subscription { greetings: String }", builder ->
|
|
|
|
|
builder.type("Subscription", typeBuilder -> typeBuilder.dataFetcher("greetings",
|
|
|
|
|
env -> Mono.delay(Duration.ofMillis(50)).flatMapMany(aLong ->
|
|
|
|
|
Flux.deferContextual(context -> {
|
|
|
|
|
String name = context.get("name");
|
|
|
|
|
return Flux.just("Hi", "Bonjour", "Hola").map(s -> s + " " + name);
|
|
|
|
|
}))
|
|
|
|
|
)));
|
|
|
|
|
|
|
|
|
|
ExecutionInput input = initExecutionInput("subscription { greetings }", Context.of("name", "007"));
|
|
|
|
|
ExecutionInput input = executionInput("subscription { greetings }", Context.of("name", "007"));
|
|
|
|
|
Publisher<String> publisher = graphQL.executeAsync(input).get().getData();
|
|
|
|
|
|
|
|
|
|
List<String> actual = Flux.from(publisher)
|
|
|
|
|
@@ -102,20 +95,18 @@ public class ReactorDataFetcherAdapterTests {
|
|
|
|
|
assertThat(actual).containsExactly("Hi 007", "Bonjour 007", "Hola 007");
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private GraphQL initGraphQL(String schemaValue, Consumer<RuntimeWiring.Builder> consumer) {
|
|
|
|
|
RuntimeWiring.Builder wiringBuilder = RuntimeWiring.newRuntimeWiring();
|
|
|
|
|
consumer.accept(wiringBuilder);
|
|
|
|
|
|
|
|
|
|
private GraphQL graphQL(String schemaValue, String typeName, String fieldName, DataFetcher<?> dataFetcher) {
|
|
|
|
|
RuntimeWiring wiring = RuntimeWiring.newRuntimeWiring()
|
|
|
|
|
.type(typeName, builder -> builder.dataFetcher(fieldName, dataFetcher))
|
|
|
|
|
.build();
|
|
|
|
|
return GraphQLSource.builder()
|
|
|
|
|
.schemaResource(new ByteArrayResource(schemaValue.getBytes(StandardCharsets.UTF_8)))
|
|
|
|
|
.runtimeWiring(wiringBuilder.build())
|
|
|
|
|
.typeVisitors(Collections.singletonList(ReactorDataFetcherAdapter.TYPE_VISITOR))
|
|
|
|
|
.runtimeWiring(wiring)
|
|
|
|
|
.build()
|
|
|
|
|
.graphQL();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private ExecutionInput initExecutionInput(String query, Context reactorContext) {
|
|
|
|
|
private ExecutionInput executionInput(String query, Context reactorContext) {
|
|
|
|
|
ExecutionInput input = ExecutionInput.newExecutionInput().query(query).build();
|
|
|
|
|
ReactorDataFetcherAdapter.addReactorContext(input, reactorContext);
|
|
|
|
|
return input;
|
|
|
|
|
|