Skip to content
This repository has been archived by the owner on Dec 19, 2023. It is now read-only.

Commit

Permalink
Merge pull request #514 from graphql-java-kickstart/feature/326-mono-…
Browse files Browse the repository at this point in the history
…support

Autoconfigure Generic wrapper for Mono fix #326
  • Loading branch information
oliemansm authored Jan 16, 2021
2 parents 1b730d3 + e5850d4 commit e0552aa
Show file tree
Hide file tree
Showing 13 changed files with 203 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
@Slf4j
@Configuration
@ConditionalOnClass(SchemaParser.class)
@AutoConfigureAfter({JacksonAutoConfiguration.class})
@AutoConfigureAfter(JacksonAutoConfiguration.class)
@EnableConfigurationProperties(GraphQLToolsProperties.class)
public class GraphQLJavaToolsAutoConfiguration {

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,7 @@ dependencies {
implementation "org.springframework.boot:spring-boot-autoconfigure"
implementation "com.graphql-java-kickstart:graphql-java-kickstart:$LIB_GRAPHQL_SERVLET_VER"
implementation "org.springframework.boot:spring-boot-starter-webflux"

testImplementation "org.springframework.boot:spring-boot-starter-test"
testImplementation(project(":graphql-kickstart-spring-boot-starter-tools"))
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package graphql.kickstart.spring.webflux.boot;

import static graphql.kickstart.execution.GraphQLObjectMapper.newBuilder;
import static org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type.REACTIVE;

import graphql.execution.instrumentation.dataloader.DataLoaderDispatcherInstrumentationOptions;
import graphql.kickstart.execution.BatchedDataLoaderGraphQLBuilder;
Expand Down Expand Up @@ -39,6 +40,7 @@
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
Expand All @@ -50,8 +52,9 @@
@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
@Slf4j
@Configuration
@ConditionalOnBean({GraphQLSchema.class})
@AutoConfigureAfter({GraphQLJavaToolsAutoConfiguration.class})
@ConditionalOnWebApplication(type = REACTIVE)
@ConditionalOnBean(GraphQLSchema.class)
@AutoConfigureAfter(GraphQLJavaToolsAutoConfiguration.class)
@Import({GraphQLController.class, ReactiveWebSocketSubscriptionsHandler.class})
public class GraphQLSpringWebfluxAutoConfiguration {

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package graphql.kickstart.spring.webflux.boot;

import static org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type.REACTIVE;

import graphql.kickstart.tools.SchemaParser;
import graphql.kickstart.tools.SchemaParserOptions.GenericWrapper;
import graphql.kickstart.tools.boot.GraphQLJavaToolsAutoConfiguration;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureBefore;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import reactor.core.publisher.Mono;

@Configuration
@ConditionalOnClass(SchemaParser.class)
@ConditionalOnWebApplication(type = REACTIVE)
@AutoConfigureBefore(GraphQLJavaToolsAutoConfiguration.class)
public class MonoAutoConfiguration {

@Bean
GenericWrapper monoWrapper(@Autowired(required = false) List<GenericWrapper> genericWrappers) {
if (notWrapsMono(genericWrappers)) {
return GenericWrapper.withTransformer(
Mono.class,
0,
Mono::toFuture,
t -> t
);
}
return null;
}

private boolean notWrapsMono(List<GenericWrapper> genericWrappers) {
return genericWrappers == null ||
genericWrappers.stream().noneMatch(it -> it.getType().isAssignableFrom(Mono.class));
}

}
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
graphql.kickstart.spring.webflux.boot.GraphQLSpringWebfluxAutoConfiguration
graphql.kickstart.spring.webflux.boot.GraphQLSpringWebfluxAutoConfiguration,\
graphql.kickstart.spring.webflux.boot.MonoAutoConfiguration
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package graphql.kickstart.spring.webflux.boot;

import graphql.kickstart.tools.GraphQLQueryResolver;
import org.springframework.stereotype.Component;
import reactor.core.publisher.Mono;

@Component
class HelloQuery implements GraphQLQueryResolver {

public Mono<String> hello() {
return Mono.just("Hello world");
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package graphql.kickstart.spring.webflux.boot;

import static org.assertj.core.api.Assertions.assertThat;

import lombok.RequiredArgsConstructor;
import lombok.val;
import org.json.JSONException;
import org.json.JSONObject;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.web.reactive.server.WebTestClient;

@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
@RequiredArgsConstructor
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class MonoAutoConfigurationTest {

@Autowired
private WebTestClient webTestClient;

@Test
void monoWrapper() throws JSONException {
val result = webTestClient.post()
.uri("/graphql")
.contentType(MediaType.APPLICATION_JSON)
.bodyValue("{ \"query\": \"query { hello } \"}")
.exchange()
.returnResult(String.class);
val response = result.getResponseBody().blockFirst();
val json = new JSONObject(response);
assertThat(json.getJSONObject("data").get("hello")).isEqualTo("Hello world");
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package graphql.kickstart.spring.webflux.boot;

import static org.assertj.core.api.Assertions.assertThat;

import graphql.kickstart.tools.SchemaParserOptions.GenericWrapper;
import lombok.RequiredArgsConstructor;
import lombok.val;
import org.json.JSONException;
import org.json.JSONObject;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.web.reactive.server.WebTestClient;
import reactor.core.publisher.Mono;

@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
@RequiredArgsConstructor
@ExtendWith(SpringExtension.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
class MonoGenericWrapperAlreadyDefinedTest {

@Autowired
private WebTestClient webTestClient;

@Test
void monoWrapper() throws JSONException {
val result = webTestClient.post()
.uri("/graphql")
.contentType(MediaType.APPLICATION_JSON)
.bodyValue("{ \"query\": \"query { hello } \"}")
.exchange()
.returnResult(String.class);
val response = result.getResponseBody().blockFirst();
val json = new JSONObject(response);
assertThat(json.getJSONObject("data").get("hello")).isEqualTo("Hello world");
}

@TestConfiguration
static class MonoConfiguration {
@Bean
GenericWrapper genericWrapper() {
return GenericWrapper.withTransformer(
Mono.class,
0,
Mono::toFuture,
t -> t
);
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package graphql.kickstart.spring.webflux.boot;

import graphql.kickstart.tools.GraphQLSubscriptionResolver;
import graphql.schema.DataFetchingEnvironment;
import java.time.Duration;
import org.reactivestreams.Publisher;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Flux;

@Service
class MySubscriptionResolver implements GraphQLSubscriptionResolver {

Publisher<Integer> hello(DataFetchingEnvironment env) {
return Flux.range(0, 100).delayElements(Duration.ofSeconds(1));
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package graphql.kickstart.spring.webflux.boot;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class WebfluxApplication {

public static void main(String[] args) {
SpringApplication.run(WebfluxApplication.class, args);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
query {
hello
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
type Query {
hello: String
}

type Subscription {
hello: Int
}
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication.Type;
import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
Expand All @@ -92,7 +93,7 @@
@Slf4j
@Configuration
@RequiredArgsConstructor
@ConditionalOnWebApplication
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass(DispatcherServlet.class)
@Conditional(OnSchemaOrSchemaProviderBean.class)
@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
Expand Down

0 comments on commit e0552aa

Please sign in to comment.