Skip to content

Commit

Permalink
Merge pull request #754 from graphql-java-kickstart/renovate/major-gr…
Browse files Browse the repository at this point in the history
…aphql-java.version

Update dependency com.graphql-java:graphql-java to v21
  • Loading branch information
oryan-block authored Jul 28, 2023
2 parents cccbd2f + c0e533d commit 8b6971f
Show file tree
Hide file tree
Showing 19 changed files with 114 additions and 69 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/pull-request.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
java: [ '8', '11', '15' ]
java: [ '11', '15', '17' ]
steps:
- name: Checkout
uses: actions/checkout@v3
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ jobs:
- name: Setup java
uses: actions/setup-java@v3
with:
java-version: '8'
java-version: '11'
distribution: 'adopt'
- name: Build with Maven
run: mvn --batch-mode --update-snapshots verify
Expand All @@ -23,7 +23,7 @@ jobs:
- name: Setup Maven Central
uses: actions/setup-java@v3
with:
java-version: '8'
java-version: '11'
distribution: 'adopt'
server-id: ossrh
server-username: MAVEN_USERNAME
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/snapshot.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ jobs:
- name: Setup java
uses: actions/setup-java@v3
with:
java-version: '8'
java-version: '11'
distribution: 'adopt'
- name: Build with Maven
run: mvn --batch-mode --update-snapshots verify
Expand All @@ -26,7 +26,7 @@ jobs:
- name: Setup Maven Central
uses: actions/setup-java@v3
with:
java-version: '8'
java-version: '11'
distribution: 'adopt'
server-id: ossrh
server-username: MAVEN_USERNAME
Expand Down
8 changes: 4 additions & 4 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<java.version>1.8</java.version>
<java.version>11</java.version>
<kotlin.version>1.8.21</kotlin.version>
<kotlin-coroutines.version>1.6.4</kotlin-coroutines.version>
<jackson.version>2.14.2</jackson.version>
<graphql-java.version>20.1</graphql-java.version>
<graphql-java.version>21.0</graphql-java.version>
<reactive-streams.version>1.0.4</reactive-streams.version>

<maven.compiler.source>${java.version}</maven.compiler.source>
Expand Down Expand Up @@ -279,8 +279,8 @@
<artifactId>maven-compiler-plugin</artifactId>
<version>3.11.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<source>11</source>
<target>11</target>
</configuration>
</plugin>

Expand Down
5 changes: 2 additions & 3 deletions src/main/kotlin/graphql/kickstart/tools/GenericType.kt
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,7 @@ internal open class GenericType(protected val mostSpecificType: JavaType, protec
* Unwrap certain Java types to find the "real" class.
*/
fun unwrapGenericType(javaType: JavaType): JavaType {
val type = replaceTypeVariable(javaType)
return when (type) {
return when (val type = replaceTypeVariable(javaType)) {
is ParameterizedType -> {
val rawType = type.rawType
val genericType = options.genericWrappers.find { it.type == rawType }
Expand All @@ -107,7 +106,7 @@ internal open class GenericType(protected val mostSpecificType: JavaType, protec
}
}
is WildcardType -> type.upperBounds.firstOrNull()
?: throw error("Unable to unwrap type, wildcard has no upper bound: $type")
?: error("Unable to unwrap type, wildcard has no upper bound: $type")
is Class<*> -> if (type.isPrimitive) Primitives.wrap(type) else type
else -> error("Unable to unwrap type: $type")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ internal class SchemaClassScanner(
.coercing(provided.coercing)
.definition(definition)
.build()
}.associateBy { it.name!! }
}.associateBy { it.name }

val unusedDefinitions = (definitionsByName.values - observedDefinitions).toSet()
unusedDefinitions
Expand Down
47 changes: 28 additions & 19 deletions src/main/kotlin/graphql/kickstart/tools/SchemaParserBuilder.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import graphql.language.Definition
import graphql.language.Document
import graphql.parser.MultiSourceReader
import graphql.parser.Parser
import graphql.parser.ParserEnvironment
import graphql.parser.ParserOptions
import graphql.schema.GraphQLScalarType
import graphql.schema.idl.RuntimeWiring
Expand All @@ -25,6 +26,10 @@ class SchemaParserBuilder {
private val scalars = mutableListOf<GraphQLScalarType>()
private val runtimeWiringBuilder = RuntimeWiring.newRuntimeWiring()
private var options = SchemaParserOptions.defaultOptions()
private val parser = Parser()
private val parserOptions = ParserOptions
.getDefaultParserOptions()
.transform { o -> o.maxTokens(MAX_VALUE) }

/**
* Add GraphQL schema files from the classpath.
Expand Down Expand Up @@ -166,21 +171,14 @@ class SchemaParserBuilder {
}

private fun parseDocuments(): List<Document> {
val parser = Parser()
val documents = mutableListOf<Document>()
try {
val options = ParserOptions
.getDefaultParserOptions()
.transform { o -> o.maxTokens(MAX_VALUE) }
val documents = files.map { parseDocument(readFile(it), it) }.toMutableList()

files.forEach {
val sourceReader = MultiSourceReader.newMultiSourceReader().string(readFile(it), it).trackData(true).build()
documents.add(parser.parseDocument(sourceReader, options))
if (schemaString.isNotBlank()) {
documents.add(parseDocument(schemaString.toString()))
}

if (schemaString.isNotEmpty()) {
documents.add(parser.parseDocument(schemaString.toString(), options))
}
return documents
} catch (pce: ParseCancellationException) {
val cause = pce.cause
if (cause != null && cause is RecognitionException) {
Expand All @@ -189,23 +187,34 @@ class SchemaParserBuilder {
throw pce
}
}
return documents
}

private fun readFile(filename: String): String {
return java.io.BufferedReader(java.io.InputStreamReader(
object : Any() {}.javaClass.classLoader.getResourceAsStream(filename)
?: throw java.io.FileNotFoundException("classpath:$filename")
)).readText()
private fun parseDocument(input: String, sourceName: String? = null): Document {
val sourceReader = MultiSourceReader
.newMultiSourceReader()
.string(input, sourceName)
.trackData(true).build()
val environment = ParserEnvironment
.newParserEnvironment()
.document(sourceReader)
.parserOptions(parserOptions).build()
return parser.parseDocument(environment)
}

private fun readFile(filename: String) =
this::class.java.classLoader.getResource(filename)?.readText()
?: throw java.io.FileNotFoundException("classpath:$filename")

/**
* Build the parser with the supplied schema and dictionary.
*/
fun build() = SchemaParser(scan(), options, runtimeWiringBuilder.build())
}

class InvalidSchemaError(pce: ParseCancellationException, private val recognitionException: RecognitionException) : RuntimeException(pce) {
override val message: String?
class InvalidSchemaError(
pce: ParseCancellationException,
private val recognitionException: RecognitionException
) : RuntimeException(pce) {
override val message: String
get() = "Invalid schema provided (${recognitionException.javaClass.name}) at: ${recognitionException.offendingToken}"
}
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ internal class TypeClassMatcher(private val definitionsByName: Map<String, TypeD
is ListType -> {
if (realType is ParameterizedType && isListType(realType, potentialMatch)) {
match(potentialMatch, graphQLType.type, realType.actualTypeArguments.first())
} else if ((realType as Class<*>).isArray) {
} else if (realType is Class<*> && realType.isArray) {
match(potentialMatch, graphQLType.type, realType.componentType)
} else {
throw error(potentialMatch, "Java class is not a List or generic type information was lost: $realType")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ class SchemaDirectiveWiringEnvironmentImpl<T : GraphQLDirectiveContainer?>(
override fun getFieldDataFetcher(): DataFetcher<*> {
checkNotNull(fieldDefinition) { "An output field must be in context to call this method" }
checkNotNull(fieldsContainer) { "An output field container must be in context to call this method" }
return codeRegistry.getDataFetcher(fieldsContainer, fieldDefinition)
val coordinates = FieldCoordinates.coordinates(fieldsContainer, fieldDefinition)
return codeRegistry.getDataFetcher(coordinates, fieldDefinition)
}

override fun setFieldDataFetcher(newDataFetcher: DataFetcher<*>?): GraphQLFieldDefinition {
Expand Down
11 changes: 4 additions & 7 deletions src/test/kotlin/graphql/kickstart/tools/DirectiveTest.kt
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,7 @@ import graphql.GraphQL
import graphql.execution.AsyncExecutionStrategy
import graphql.relay.Connection
import graphql.relay.SimpleListConnection
import graphql.schema.DataFetcherFactories
import graphql.schema.DataFetchingEnvironment
import graphql.schema.GraphQLFieldDefinition
import graphql.schema.GraphQLObjectType
import graphql.schema.*
import graphql.schema.idl.SchemaDirectiveWiring
import graphql.schema.idl.SchemaDirectiveWiringEnvironment
import org.junit.Ignore
Expand Down Expand Up @@ -325,7 +322,7 @@ class DirectiveTest {

override fun onField(environment: SchemaDirectiveWiringEnvironment<GraphQLFieldDefinition>): GraphQLFieldDefinition {
val field = environment.element
val parentType = environment.fieldsContainer
val parentType = FieldCoordinates.coordinates(environment.fieldsContainer, environment.fieldDefinition)

val originalDataFetcher = environment.codeRegistry.getDataFetcher(parentType, field)
val wrappedDataFetcher = DataFetcherFactories.wrapDataFetcher(originalDataFetcher) { _, value ->
Expand All @@ -342,15 +339,15 @@ class DirectiveTest {

override fun onField(environment: SchemaDirectiveWiringEnvironment<GraphQLFieldDefinition>): GraphQLFieldDefinition {
val field = environment.element
val parentType = environment.fieldsContainer
val parentType = FieldCoordinates.coordinates(environment.fieldsContainer, environment.fieldDefinition)

val originalDataFetcher = environment.codeRegistry.getDataFetcher(parentType, field)
val wrappedDataFetcher = DataFetcherFactories.wrapDataFetcher(originalDataFetcher) { _, value ->
val string = value as? String
string + string
}

environment.codeRegistry.dataFetcher(parentType, field, wrappedDataFetcher)
environment.codeRegistry.dataFetcher(parentType, wrappedDataFetcher)

return field
}
Expand Down
51 changes: 34 additions & 17 deletions src/test/kotlin/graphql/kickstart/tools/EndToEndSpecHelper.kt
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package graphql.kickstart.tools

import graphql.GraphQLContext
import graphql.execution.CoercedVariables
import graphql.execution.DataFetcherResult
import graphql.language.ObjectValue
import graphql.language.StringValue
import graphql.language.Value
import graphql.schema.*
import kotlinx.coroutines.CompletableDeferred
import kotlinx.coroutines.channels.Channel
Expand Down Expand Up @@ -444,18 +447,22 @@ val customScalarId = GraphQLScalarType.newScalar()
.name("ID")
.description("Overrides built-in ID")
.coercing(object : Coercing<UUID, String> {
override fun serialize(input: Any): String? = when (input) {
override fun serialize(input: Any, context: GraphQLContext, locale: Locale) = when (input) {
is String -> input
is UUID -> input.toString()
else -> null
}

override fun parseValue(input: Any): UUID = parseLiteral(input)

override fun parseLiteral(input: Any): UUID = when (input) {
override fun parseValue(input: Any, context: GraphQLContext, locale: Locale) = when (input) {
is StringValue -> UUID.fromString(input.value)
else -> throw CoercingParseLiteralException()
}

override fun parseLiteral(input: Value<*>, variables: CoercedVariables, context: GraphQLContext, locale: Locale) =
when (input) {
is StringValue -> UUID.fromString(input.value)
else -> throw CoercingParseLiteralException()
}
})
.build()

Expand All @@ -464,18 +471,22 @@ val customScalarUUID = GraphQLScalarType.newScalar()
.description("UUID")
.coercing(object : Coercing<UUID, String> {

override fun serialize(input: Any): String? = when (input) {
override fun serialize(input: Any, context: GraphQLContext, locale: Locale): String? = when (input) {
is String -> input
is UUID -> input.toString()
else -> null
}

override fun parseValue(input: Any): UUID = parseLiteral(input)

override fun parseLiteral(input: Any): UUID = when (input) {
override fun parseValue(input: Any, context: GraphQLContext, locale: Locale): UUID = when (input) {
is StringValue -> UUID.fromString(input.value)
else -> throw CoercingParseLiteralException()
}

override fun parseLiteral(input: Value<*>, variables: CoercedVariables, context: GraphQLContext, locale: Locale): UUID =
when (input) {
is StringValue -> UUID.fromString(input.value)
else -> throw CoercingParseLiteralException()
}
})
.build()

Expand All @@ -485,12 +496,19 @@ val customScalarMap = GraphQLScalarType.newScalar()
.coercing(object : Coercing<Map<String, Any>, Map<String, Any>> {

@Suppress("UNCHECKED_CAST")
override fun parseValue(input: Any): Map<String, Any> = input as Map<String, Any>
override fun parseValue(input: Any, context: GraphQLContext, locale: Locale): Map<String, Any> = input as Map<String, Any>

@Suppress("UNCHECKED_CAST")
override fun serialize(dataFetcherResult: Any): Map<String, Any> = dataFetcherResult as Map<String, Any>

override fun parseLiteral(input: Any): Map<String, Any> = (input as ObjectValue).objectFields.associateBy { it.name }.mapValues { (it.value.value as StringValue).value }
override fun serialize(dataFetcherResult: Any, context: GraphQLContext, locale: Locale): Map<String, Any> =
dataFetcherResult as Map<String, Any>

override fun parseLiteral(
input: Value<*>,
variables: CoercedVariables,
context: GraphQLContext,
locale: Locale
): Map<String, Any> =
(input as ObjectValue).objectFields.associateBy { it.name }.mapValues { (it.value.value as StringValue).value }
})
.build()

Expand All @@ -499,11 +517,11 @@ val uploadScalar: GraphQLScalarType = GraphQLScalarType.newScalar()
.name("Upload")
.description("A file part in a multipart request")
.coercing(object : Coercing<Part?, Void?> {
override fun serialize(dataFetcherResult: Any): Void? {
override fun serialize(dataFetcherResult: Any, context: GraphQLContext, locale: Locale): Void? {
throw CoercingSerializeException("Upload is an input-only type")
}

override fun parseValue(input: Any): Part {
override fun parseValue(input: Any, context: GraphQLContext, locale: Locale): Part {
return when (input) {
is Part -> {
input
Expand All @@ -514,9 +532,8 @@ val uploadScalar: GraphQLScalarType = GraphQLScalarType.newScalar()
}
}

override fun parseLiteral(input: Any): Part {
throw CoercingParseLiteralException(
"Must use variables to specify Upload values")
override fun parseLiteral(input: Value<*>, variables: CoercedVariables, context: GraphQLContext, locale: Locale): Part {
throw CoercingParseLiteralException("Must use variables to specify Upload values")
}
}).build()

Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@ import graphql.language.TypeName
import graphql.relay.Connection
import graphql.relay.DefaultConnection
import graphql.relay.DefaultPageInfo
import kotlinx.coroutines.ExperimentalCoroutinesApi
import org.junit.Test
import java.util.*

@OptIn(ExperimentalCoroutinesApi::class)
class FieldResolverScannerTest {

private val options = defaultOptions()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package graphql.kickstart.tools
import graphql.ExecutionResult
import graphql.GraphQLContext
import graphql.execution.*
import graphql.execution.instrumentation.SimpleInstrumentation
import graphql.execution.instrumentation.SimplePerformantInstrumentation
import graphql.kickstart.tools.resolver.FieldResolverError
import graphql.kickstart.tools.resolver.FieldResolverScanner
import graphql.language.FieldDefinition
Expand All @@ -24,6 +24,7 @@ import org.reactivestreams.tck.TestEnvironment
import java.util.concurrent.CompletableFuture
import kotlin.coroutines.coroutineContext

@OptIn(ExperimentalCoroutinesApi::class)
class MethodFieldResolverDataFetcherTest {

@Test
Expand Down Expand Up @@ -311,7 +312,7 @@ class MethodFieldResolverDataFetcherTest {
}
val executionId = ExecutionId.from("executionId123")
return ExecutionContextBuilder.newExecutionContextBuilder()
.instrumentation(SimpleInstrumentation.INSTANCE)
.instrumentation(SimplePerformantInstrumentation.INSTANCE)
.executionId(executionId)
.queryStrategy(executionStrategy)
.mutationStrategy(executionStrategy)
Expand Down
Loading

0 comments on commit 8b6971f

Please sign in to comment.