Skip to content

Commit

Permalink
Fixes to get the prototype working after rebase from master.
Browse files Browse the repository at this point in the history
  • Loading branch information
srinivasankavitha authored and paulbakker committed Dec 15, 2023
1 parent f7d70e6 commit 0961e04
Show file tree
Hide file tree
Showing 11 changed files with 82 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ void withHeaders() {
MockHttpServletRequest servletRequest = new MockHttpServletRequest();
servletRequest.addHeader("demo-header", "demo-header-value");

String message = queryExecutor.executeAndExtractJsonPath("{headers}", "data.headers", new ServletWebRequest(servletRequest));
String message = queryExecutor.executeAndExtractJsonPath("{demoHeader}", "data.demoHeader", new ServletWebRequest(servletRequest));
assertThat(message).isEqualTo("demo-header-value");
}

Expand All @@ -53,7 +53,7 @@ void withHeadersAndNoRequest() {
HttpHeaders headers = new HttpHeaders();
headers.add("demo-header", "demo-header-value");

String message = queryExecutor.executeAndExtractJsonPath("{headers}", "data.headers", headers);
String message = queryExecutor.executeAndExtractJsonPath("{demoHeader}", "data.demoHeader", headers);
assertThat(message).isEqualTo("demo-header-value");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,14 @@

@DgsComponent
public class RequestHeadersDataFetcher {

@DgsData(parentType = "Query", field = "headers")
public String headers(DgsDataFetchingEnvironment dfe) {
HttpHeaders headers = dfe.getDgsContext().getRequestData().getHeaders();
return headers.toString();
}

@DgsData(parentType = "Query", field = "demoHeader")
public String headers(DgsDataFetchingEnvironment dfe, @RequestHeader("demo-header") String demoHeader) {
return demoHeader;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ type Query {

headers: String
referer: String
demoHeader: String

### To show how to handle HttpHeaders
helloWithHeaders(name: String): String
Expand Down Expand Up @@ -97,7 +98,3 @@ scalar LocalTime

directive @connection on OBJECT



>>>>>>> bcff65a3 (Initial integration with spring-graphql with an example app.)

6 changes: 6 additions & 0 deletions graphql-dgs-spring-graphql-example-java/dependencies.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 9 additions & 3 deletions graphql-dgs-spring-graphql-starter/dependencies.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions graphql-dgs-spring-graphql/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ dependencies {
implementation("org.springframework:spring-webmvc")
implementation("org.springframework.boot:spring-boot-starter-graphql:3.1.0")
//implementation("org.springframework.graphql:spring-graphql:1.2.0")
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
implementation("com.fasterxml.jackson.datatype:jackson-datatype-jsr310")


compileOnly("org.springframework:spring-test")
Expand Down
18 changes: 18 additions & 0 deletions graphql-dgs-spring-graphql/dependencies.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,11 @@
*/

package com.netflix.graphql.dgs.autoconfig
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import com.netflix.graphql.dgs.DgsQueryExecutor
import com.netflix.graphql.dgs.internal.DefaultDgsGraphQLContextBuilder
import com.netflix.graphql.dgs.internal.DefaultDgsQueryExecutor
import com.netflix.graphql.dgs.internal.DgsDataLoaderProvider
import com.netflix.graphql.dgs.internal.DgsSchemaProvider
import com.netflix.graphql.dgs.internal.*
import com.netflix.graphql.dgs.internal.method.ArgumentResolver
import com.netflix.graphql.dgs.mvc.internal.method.HandlerMethodArgumentResolverAdapter
import graphql.GraphQL
Expand All @@ -37,6 +37,7 @@ import org.springframework.beans.factory.annotation.Qualifier
import org.springframework.beans.factory.config.ConfigurableBeanFactory
import org.springframework.boot.autoconfigure.AutoConfiguration
import org.springframework.boot.autoconfigure.AutoConfigureBefore
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication
import org.springframework.boot.autoconfigure.graphql.GraphQlSourceBuilderCustomizer
import org.springframework.context.annotation.Bean
Expand Down Expand Up @@ -129,8 +130,15 @@ open class DgsSpringGraphQLAutoConfiguration {
}

@Bean
open fun springGraphQLDgsQueryExecutor(executionService: DefaultExecutionGraphQlService, dgsContextBuilder: DefaultDgsGraphQLContextBuilder, dgsDataLoaderProvider: DgsDataLoaderProvider): DgsQueryExecutor {
return SpringGraphQLDgsQueryExecutor(executionService, dgsContextBuilder, dgsDataLoaderProvider)
open fun springGraphQLDgsQueryExecutor(executionService: DefaultExecutionGraphQlService, dgsContextBuilder: DefaultDgsGraphQLContextBuilder, dgsDataLoaderProvider: DgsDataLoaderProvider, requestCustomizer: ObjectProvider<DgsQueryExecutorRequestCustomizer>): DgsQueryExecutor {
return SpringGraphQLDgsQueryExecutor(executionService, dgsContextBuilder, dgsDataLoaderProvider, requestCustomizer = requestCustomizer.getIfAvailable(DgsQueryExecutorRequestCustomizer::DEFAULT_REQUEST_CUSTOMIZER))
}

@Bean
@Qualifier("dgsObjectMapper")
@ConditionalOnMissingBean(name = ["dgsObjectMapper"])
open fun dgsObjectMapper(): ObjectMapper {
return jacksonObjectMapper().registerModule(JavaTimeModule())
}

@Configuration(proxyBeanMethods = false)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,21 +23,19 @@ import com.jayway.jsonpath.spi.mapper.MappingException
import com.netflix.graphql.dgs.DgsQueryExecutor
import com.netflix.graphql.dgs.exceptions.DgsQueryExecutionDataExtractionException
import com.netflix.graphql.dgs.exceptions.QueryException
import com.netflix.graphql.dgs.internal.BaseDgsQueryExecutor
import com.netflix.graphql.dgs.internal.DefaultDgsGraphQLContextBuilder
import com.netflix.graphql.dgs.internal.DgsDataLoaderProvider
import com.netflix.graphql.dgs.internal.DgsWebMvcRequestData
import com.netflix.graphql.dgs.internal.*
import graphql.ExecutionResult
import graphql.GraphQLContext
import graphql.GraphQLError
import org.springframework.graphql.execution.DefaultExecutionGraphQlService
import org.springframework.graphql.support.DefaultExecutionGraphQlRequest
import org.springframework.http.HttpHeaders
import org.springframework.web.context.request.RequestContextHolder
import org.springframework.web.context.request.ServletWebRequest
import org.springframework.web.context.request.WebRequest
import java.util.concurrent.CompletableFuture

class SpringGraphQLDgsQueryExecutor(val executionService: DefaultExecutionGraphQlService, private val dgsContextBuilder: DefaultDgsGraphQLContextBuilder, private val dgsDataLoaderProvider: DgsDataLoaderProvider) : DgsQueryExecutor {
class SpringGraphQLDgsQueryExecutor(val executionService: DefaultExecutionGraphQlService, private val dgsContextBuilder: DefaultDgsGraphQLContextBuilder, private val dgsDataLoaderProvider: DgsDataLoaderProvider, private val requestCustomizer: DgsQueryExecutorRequestCustomizer = DgsQueryExecutorRequestCustomizer.DEFAULT_REQUEST_CUSTOMIZER) : DgsQueryExecutor {

override fun execute(
query: String,
Expand All @@ -56,7 +54,8 @@ class SpringGraphQLDgsQueryExecutor(val executionService: DefaultExecutionGraphQ
null
)

val dgsContext = dgsContextBuilder.build(DgsWebMvcRequestData(request.extensions, headers, webRequest))
val httpRequest = requestCustomizer.apply(webRequest ?: RequestContextHolder.getRequestAttributes() as? WebRequest, headers)
val dgsContext = dgsContextBuilder.build(DgsWebMvcRequestData(request.extensions, headers, httpRequest))
val graphQLContextFuture = CompletableFuture<GraphQLContext>()
val dataLoaderRegistry = dgsDataLoaderProvider.buildRegistryWithContextSupplier { graphQLContextFuture.get() }

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,9 @@ import org.springframework.core.io.Resource
import org.springframework.core.io.support.ResourcePatternUtils
import org.springframework.util.ReflectionUtils
import java.io.IOException
import java.io.InputStreamReader
import java.lang.reflect.Method
import java.nio.charset.StandardCharsets
import java.util.Optional
import java.util.concurrent.CompletableFuture
import java.util.concurrent.CompletionStage
Expand Down Expand Up @@ -105,6 +107,7 @@ class DgsSchemaProvider(
private val dataFetcherMetricsInstrumentationEnabled = mutableMapOf<String, Boolean>()

private val dataFetchers = mutableListOf<DataFetcherReference>()
private val scalars = mutableMapOf<String, GraphQLScalarType>()

/**
* Returns an immutable list of [DataFetcherReference]s that were identified after the schema was loaded.
Expand Down Expand Up @@ -211,7 +214,7 @@ class DgsSchemaProvider(

val runtimeWiring = runtimeWiringBuilder.build()

findEntityFetchers(dgsComponents, mergedRegistry, runtimeWiring)
findEntityFetchers(dgsComponents, mergedRegistry, scalars)

val federationResolverInstance =
federationResolver.orElseGet {
Expand Down Expand Up @@ -245,8 +248,9 @@ class DgsSchemaProvider(
// runtime wiring
fun buildRuntimeWiring(schema: String? = null, runtimeWiringBuilder: RuntimeWiring.Builder): RuntimeWiring.Builder {
val startTime = System.currentTimeMillis()
val dgsComponents =
applicationContext.getBeansWithAnnotation(DgsComponent::class.java).values.filter(componentFilter)
val dgsComponents = applicationContext.getBeansWithAnnotation<DgsComponent>().values.let { beans ->
if (componentFilter != null) beans.filter(componentFilter) else beans
}
val hasDynamicTypeRegistry =
dgsComponents.any { it.javaClass.methods.any { m -> m.isAnnotationPresent(DgsTypeDefinitionRegistry::class.java) } }

Expand Down Expand Up @@ -291,7 +295,7 @@ class DgsSchemaProvider(
findDirectives(applicationContext, runtimeWiringBuilder)
findDataFetchers(dgsComponents, codeRegistryBuilder, mergedRegistry)
findTypeResolvers(dgsComponents, runtimeWiringBuilder, mergedRegistry)
findEntityFetchers(dgsComponents)
findEntityFetchers(dgsComponents, mergedRegistry, scalars)

dgsComponents.forEach { dgsComponent ->
invokeDgsCodeRegistry(
Expand Down Expand Up @@ -585,7 +589,7 @@ class DgsSchemaProvider(
}
}

private fun findEntityFetchers(dgsComponents: Collection<Any>, registry: TypeDefinitionRegistry, runtimeWiring: RuntimeWiring) {
private fun findEntityFetchers(dgsComponents: Collection<Any>, registry: TypeDefinitionRegistry, scalars: Map<String, GraphQLScalarType>) {
dgsComponents.forEach { dgsComponent ->
val javaClass = AopUtils.getTargetClass(dgsComponent)

Expand Down Expand Up @@ -625,7 +629,7 @@ class DgsSchemaProvider(
.map {
Pair(
it,
traverseType(it.iterator(), typeDefinition, registry, runtimeWiring)
traverseType(it.iterator(), typeDefinition, registry, scalars)
)
}
.filter { it.second != null }
Expand All @@ -638,7 +642,7 @@ class DgsSchemaProvider(
}
}

private fun traverseType(path: Iterator<String>, type: ImplementingTypeDefinition<*>?, registry: TypeDefinitionRegistry, runtimeWiring: RuntimeWiring): Coercing<*, *>? {
private fun traverseType(path: Iterator<String>, type: ImplementingTypeDefinition<*>?, registry: TypeDefinitionRegistry, scalars: Map<String, GraphQLScalarType>): Coercing<*, *>? {
if (type == null || !path.hasNext()) {
return null
}
Expand All @@ -652,8 +656,8 @@ class DgsSchemaProvider(

if (fieldType.isPresent) {
return when (val unwrappedFieldType = fieldType.get()) {
is ObjectTypeDefinition -> traverseType(path, unwrappedFieldType, registry, runtimeWiring)
is ScalarTypeDefinition -> runtimeWiring.scalars.get(unwrappedFieldType.name)?.coercing
is ObjectTypeDefinition -> traverseType(path, unwrappedFieldType, registry, scalars)
is ScalarTypeDefinition -> scalars.get(unwrappedFieldType.name)?.coercing
else -> null
}
}
Expand Down Expand Up @@ -775,9 +779,11 @@ class DgsSchemaProvider(
applicationContext.getBeansWithAnnotation<DgsScalar>().values.forEach { scalarComponent ->
val annotation = scalarComponent::class.java.getAnnotation(DgsScalar::class.java)
when (scalarComponent) {
is Coercing<*, *> -> runtimeWiringBuilder.scalar(
GraphQLScalarType.newScalar().name(annotation.name).coercing(scalarComponent).build()
)
is Coercing<*, *> -> {
val newScalar = GraphQLScalarType.newScalar().name(annotation.name).coercing(scalarComponent).build()
runtimeWiringBuilder.scalar(newScalar)
scalars[annotation.name] = newScalar
}
else -> throw RuntimeException("Invalid @DgsScalar type: the class must implement graphql.schema.Coercing")
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,7 @@

package com.netflix.graphql.dgs

<<<<<<< HEAD
import com.netflix.graphql.dgs.exceptions.DataFetcherSchemaMismatchException
import com.netflix.graphql.dgs.exceptions.InvalidDgsConfigurationException
=======
>>>>>>> bcff65a3 (Initial integration with spring-graphql with an example app.)
import com.netflix.graphql.dgs.exceptions.InvalidTypeResolverException
import com.netflix.graphql.dgs.exceptions.NoSchemaFoundException
import com.netflix.graphql.dgs.internal.DefaultInputObjectMapper
Expand Down

0 comments on commit 0961e04

Please sign in to comment.