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

Update dependency com.graphql-java:graphql-java to v18 #645

Merged
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
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
<kotlin.version>1.6.21</kotlin.version>
<kotlin-coroutines.version>1.6.1-native-mt</kotlin-coroutines.version>
<jackson.version>2.13.2.20220328</jackson.version>
<graphql-java.version>17.3</graphql-java.version>
<graphql-java.version>18.0</graphql-java.version>
<reactive-streams.version>1.0.3</reactive-streams.version>

<maven.compiler.source>${java.version}</maven.compiler.source>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import graphql.kickstart.tools.util.BiMap
import graphql.kickstart.tools.util.JavaType
import graphql.language.FieldDefinition
import graphql.language.ObjectTypeDefinition
import graphql.language.SDLNamedDefinition
import graphql.language.TypeDefinition
import graphql.schema.GraphQLScalarType

Expand All @@ -13,7 +14,7 @@ import graphql.schema.GraphQLScalarType
*/
internal data class ScannedSchemaObjects(
val dictionary: TypeClassDictionary,
val definitions: Set<TypeDefinition<*>>,
val definitions: Set<SDLNamedDefinition<*>>,
val customScalars: CustomScalarMap,
val rootInfo: RootTypeInfo,
val fieldResolversByType: Map<ObjectTypeDefinition, MutableMap<FieldDefinition, FieldResolver>>,
Expand Down
8 changes: 6 additions & 2 deletions src/main/kotlin/graphql/kickstart/tools/SchemaClassScanner.kt
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ internal class SchemaClassScanner(
private val initialDictionary = initialDictionary.mapValues { InitialDictionaryEntry(it.value) }
private val extensionDefinitions = allDefinitions.filterIsInstance<ObjectTypeExtensionDefinition>()
private val inputExtensionDefinitions = allDefinitions.filterIsInstance<InputObjectTypeExtensionDefinition>()
private val directiveDefinitions = allDefinitions.filterIsInstance<DirectiveDefinition>()
private val scalarDefinitions = allDefinitions.filterIsInstance<ScalarTypeDefinition>()

private val definitionsByName = (allDefinitions.filterIsInstance<TypeDefinition<*>>() - extensionDefinitions - inputExtensionDefinitions).associateBy { it.name }
private val objectDefinitions = (allDefinitions.filterIsInstance<ObjectTypeDefinition>() - extensionDefinitions)
Expand All @@ -42,7 +44,7 @@ internal class SchemaClassScanner(
private val fieldResolverScanner = FieldResolverScanner(options)
private val typeClassMatcher = TypeClassMatcher(definitionsByName)
private val dictionary = mutableMapOf<TypeDefinition<*>, DictionaryEntry>()
private val unvalidatedTypes = mutableSetOf<TypeDefinition<*>>()
private val unvalidatedTypes = mutableSetOf<TypeDefinition<*>>(*scalarDefinitions.toTypedArray())
private val queue = linkedSetOf<QueueItem>()

private val fieldResolversByType = mutableMapOf<ObjectTypeDefinition, MutableMap<FieldDefinition, FieldResolver>>()
Expand Down Expand Up @@ -193,7 +195,9 @@ internal class SchemaClassScanner(
validateRootResolversWereUsed(rootTypeHolder.mutation, fieldResolvers)
validateRootResolversWereUsed(rootTypeHolder.subscription, fieldResolvers)

return ScannedSchemaObjects(dictionary, observedDefinitions + extensionDefinitions + inputExtensionDefinitions, scalars, rootInfo, fieldResolversByType.toMap(), unusedDefinitions)
val definitions = observedDefinitions + extensionDefinitions + inputExtensionDefinitions + directiveDefinitions

return ScannedSchemaObjects(dictionary, definitions, scalars, rootInfo, fieldResolversByType.toMap(), unusedDefinitions)
}

private fun validateRootResolversWereUsed(rootType: RootType?, fieldResolvers: List<FieldResolver>) {
Expand Down
7 changes: 3 additions & 4 deletions src/main/kotlin/graphql/kickstart/tools/SchemaObjects.kt
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
package graphql.kickstart.tools

import graphql.schema.GraphQLCodeRegistry
import graphql.schema.GraphQLObjectType
import graphql.schema.GraphQLSchema
import graphql.schema.GraphQLType
import graphql.schema.*

/**
* @author Andrew Potter
Expand All @@ -13,6 +10,7 @@ data class SchemaObjects(
val mutation: GraphQLObjectType?,
val subscription: GraphQLObjectType?,
val dictionary: Set<GraphQLType>,
val directives: Set<GraphQLDirective>,
val codeRegistryBuilder: GraphQLCodeRegistry.Builder,
val description: String?
) {
Expand All @@ -26,6 +24,7 @@ data class SchemaObjects(
.mutation(mutation)
.subscription(subscription)
.additionalTypes(dictionary)
.additionalDirectives(directives)
.codeRegistry(codeRegistryBuilder.build())
.build()
}
Expand Down
92 changes: 79 additions & 13 deletions src/main/kotlin/graphql/kickstart/tools/SchemaParser.kt
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class SchemaParser internal constructor(
private val inputObjectDefinitions = (definitions.filterIsInstance<InputObjectTypeDefinition>() - inputExtensionDefinitions)
private val enumDefinitions = definitions.filterIsInstance<EnumTypeDefinition>()
private val interfaceDefinitions = definitions.filterIsInstance<InterfaceTypeDefinition>()
private val directiveDefinitions = definitions.filterIsInstance<DirectiveDefinition>()

private val unionDefinitions = definitions.filterIsInstance<UnionTypeDefinition>()

Expand Down Expand Up @@ -82,6 +83,8 @@ class SchemaParser internal constructor(
val unions = unionDefinitions.map { createUnionObject(it, objects) }
val enums = enumDefinitions.map { createEnumObject(it) }

val directives = directiveDefinitions.map { createDirective(it, inputObjects) }.toSet()

// Assign type resolver to interfaces now that we know all of the object types
interfaces.forEach { codeRegistryBuilder.typeResolver(it, InterfaceTypeResolver(dictionary.inverse(), it)) }
unions.forEach { codeRegistryBuilder.typeResolver(it, UnionTypeResolver(dictionary.inverse(), it)) }
Expand All @@ -101,7 +104,7 @@ class SchemaParser internal constructor(
val additionalObjects = objects.filter { o -> o != query && o != subscription && o != mutation }

val types = (additionalObjects.toSet() as Set<GraphQLType>) + inputObjects + enums + interfaces + unions
return SchemaObjects(query, mutation, subscription, types, codeRegistryBuilder, rootInfo.getDescription())
return SchemaObjects(query, mutation, subscription, types, directives, codeRegistryBuilder, rootInfo.getDescription())
}

/**
Expand All @@ -123,6 +126,7 @@ class SchemaParser internal constructor(
.description(getDocumentation(objectDefinition, options))

builder.withDirectives(*buildDirectives(objectDefinition.directives, Introspection.DirectiveLocation.OBJECT))
builder.withAppliedDirectives(*buildAppliedDirectives(objectDefinition.directives))

objectDefinition.implements.forEach { implementsDefinition ->
val interfaceName = (implementsDefinition as TypeName).name
Expand Down Expand Up @@ -163,6 +167,7 @@ class SchemaParser internal constructor(
.description(getDocumentation(definition, options))

builder.withDirectives(*buildDirectives(definition.directives, Introspection.DirectiveLocation.INPUT_OBJECT))
builder.withAppliedDirectives(*buildAppliedDirectives(definition.directives))

referencingInputObjects.add(definition.name)

Expand All @@ -175,6 +180,7 @@ class SchemaParser internal constructor(
.apply { inputDefinition.defaultValue?.let { v -> defaultValueLiteral(v) } }
.type(determineInputType(inputDefinition.type, inputObjects, referencingInputObjects))
.withDirectives(*buildDirectives(inputDefinition.directives, Introspection.DirectiveLocation.INPUT_FIELD_DEFINITION))
.withAppliedDirectives(*buildAppliedDirectives(inputDefinition.directives))
builder.field(fieldBuilder.build())
}
}
Expand All @@ -194,20 +200,23 @@ class SchemaParser internal constructor(
.description(getDocumentation(definition, options))

builder.withDirectives(*buildDirectives(definition.directives, Introspection.DirectiveLocation.ENUM))
builder.withAppliedDirectives(*buildAppliedDirectives(definition.directives))

definition.enumValueDefinitions.forEach { enumDefinition ->
val enumName = enumDefinition.name
val enumValue = type.unwrap().enumConstants.find { (it as Enum<*>).name == enumName }
?: throw SchemaError("Expected value for name '$enumName' in enum '${type.unwrap().simpleName}' but found none!")

val enumValueDirectives = buildDirectives(enumDefinition.directives, Introspection.DirectiveLocation.ENUM_VALUE)
val enumValueAppliedDirectives = buildAppliedDirectives(enumDefinition.directives)
getDeprecated(enumDefinition.directives).let {
val enumValueDefinition = GraphQLEnumValueDefinition.newEnumValueDefinition()
.name(enumName)
.description(getDocumentation(enumDefinition, options))
.value(enumValue)
.deprecationReason(it)
.withDirectives(*enumValueDirectives)
.withAppliedDirectives(*enumValueAppliedDirectives)
.definition(enumDefinition)
.build()

Expand All @@ -226,6 +235,7 @@ class SchemaParser internal constructor(
.description(getDocumentation(interfaceDefinition, options))

builder.withDirectives(*buildDirectives(interfaceDefinition.directives, Introspection.DirectiveLocation.INTERFACE))
builder.withAppliedDirectives(*buildAppliedDirectives(interfaceDefinition.directives))

interfaceDefinition.fieldDefinitions.forEach { fieldDefinition ->
builder.field { field -> createField(field, fieldDefinition, inputObjects) }
Expand All @@ -247,6 +257,7 @@ class SchemaParser internal constructor(
.description(getDocumentation(definition, options))

builder.withDirectives(*buildDirectives(definition.directives, Introspection.DirectiveLocation.UNION))
builder.withAppliedDirectives(*buildAppliedDirectives(definition.directives))

getLeafUnionObjects(definition, types).forEach { builder.possibleType(it) }
return schemaGeneratorDirectiveHelper.onUnion(builder.build(), schemaDirectiveParameters)
Expand Down Expand Up @@ -288,14 +299,44 @@ class SchemaParser internal constructor(
.type(determineInputType(argumentDefinition.type, inputObjects, setOf()))
.apply { argumentDefinition.defaultValue?.let { defaultValueLiteral(it) } }
.withDirectives(*buildDirectives(argumentDefinition.directives, Introspection.DirectiveLocation.ARGUMENT_DEFINITION))
.withAppliedDirectives(*buildAppliedDirectives(argumentDefinition.directives))

field.argument(argumentBuilder.build())
}
field.withDirectives(*buildDirectives(fieldDefinition.directives, Introspection.DirectiveLocation.FIELD_DEFINITION))
field.withAppliedDirectives(*buildAppliedDirectives(fieldDefinition.directives))

return field
}

private fun createDirective(definition: DirectiveDefinition, inputObjects: List<GraphQLInputObjectType>): GraphQLDirective {
val locations = definition.directiveLocations.map { Introspection.DirectiveLocation.valueOf(it.name) }.toTypedArray()

val graphQLDirective = GraphQLDirective.newDirective()
.name(definition.name)
.description(getDocumentation(definition, options))
.definition(definition)
.comparatorRegistry(runtimeWiring.comparatorRegistry)
.validLocations(*locations)
.repeatable(definition.isRepeatable)
.apply {
definition.inputValueDefinitions.forEach { arg ->
argument(GraphQLArgument.newArgument()
.name(arg.name)
.definition(arg)
.description(getDocumentation(arg, options))
.type(determineInputType(arg.type, inputObjects, setOf()))
.apply { arg.defaultValue?.let { defaultValueLiteral(it) } }
.withDirectives(*buildDirectives(arg.directives, Introspection.DirectiveLocation.ARGUMENT_DEFINITION))
.withAppliedDirectives(*buildAppliedDirectives(arg.directives))
.build())
}
}
.build()

return graphQLDirective
}

private fun buildDirectives(directives: List<Directive>, directiveLocation: Introspection.DirectiveLocation): Array<GraphQLDirective> {
val names = mutableSetOf<String>()

Expand Down Expand Up @@ -326,14 +367,43 @@ class SchemaParser internal constructor(
return output.toTypedArray()
}

private fun buildAppliedDirectives(directives: List<Directive>): Array<GraphQLAppliedDirective> {
val names = mutableSetOf<String>()

val output = mutableListOf<GraphQLAppliedDirective>()
for (directive in directives) {
if (!names.contains(directive.name)) {
names.add(directive.name)
val graphQLDirective = GraphQLAppliedDirective.newDirective()
.name(directive.name)
.description(getDocumentation(directive, options))
.comparatorRegistry(runtimeWiring.comparatorRegistry)
.apply {
directive.arguments.forEach { arg ->
argument(GraphQLAppliedDirectiveArgument.newArgument()
.name(arg.name)
.type(buildDirectiveInputType(arg.value))
.valueLiteral(arg.value)
.build())
}
}
.build()

output.add(graphQLDirective)
}
}

return output.toTypedArray()
}

private fun buildDirectiveInputType(value: Value<*>): GraphQLInputType? {
when (value) {
is NullValue -> return Scalars.GraphQLString
is FloatValue -> return Scalars.GraphQLFloat
is StringValue -> return Scalars.GraphQLString
is IntValue -> return Scalars.GraphQLInt
is BooleanValue -> return Scalars.GraphQLBoolean
is ArrayValue -> return GraphQLList.list(buildDirectiveInputType(getArrayValueWrappedType(value)))
return when (value) {
is NullValue -> Scalars.GraphQLString
is FloatValue -> Scalars.GraphQLFloat
is StringValue -> Scalars.GraphQLString
is IntValue -> Scalars.GraphQLInt
is BooleanValue -> Scalars.GraphQLBoolean
is ArrayValue -> GraphQLList.list(buildDirectiveInputType(getArrayValueWrappedType(value)))
else -> throw SchemaError("Directive values of type '${value::class.simpleName}' are not supported yet.")
}
}
Expand Down Expand Up @@ -448,14 +518,10 @@ class SchemaParser internal constructor(
* indicating no deprecation directive was found within the directives list.
*/
private fun getDeprecated(directives: List<Directive>): String? =
getDirective(directives, "deprecated")?.let { directive ->
directives.find { it.name == "deprecated" }?.let { directive ->
(directive.arguments.find { it.name == "reason" }?.value as? StringValue)?.value
?: DEFAULT_DEPRECATION_MESSAGE
}

private fun getDirective(directives: List<Directive>, name: String): Directive? = directives.find {
it.name == name
}
}

class SchemaError(message: String, cause: Throwable? = null) : RuntimeException(message, cause)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,7 @@
import graphql.Internal;
import graphql.language.NamedNode;
import graphql.language.NodeParentTree;
import graphql.schema.DataFetcher;
import graphql.schema.FieldCoordinates;
import graphql.schema.GraphQLCodeRegistry;
import graphql.schema.GraphQLDirective;
import graphql.schema.GraphQLDirectiveContainer;
import graphql.schema.GraphQLFieldDefinition;
import graphql.schema.GraphQLFieldsContainer;
import graphql.schema.GraphqlElementParentTree;
import graphql.schema.*;
import graphql.schema.idl.SchemaDirectiveWiringEnvironment;
import graphql.schema.idl.TypeDefinitionRegistry;
import graphql.util.FpKit;
Expand All @@ -31,6 +24,7 @@ public class SchemaDirectiveWiringEnvironmentImpl<T extends GraphQLDirectiveCont

private final T element;
private final Map<String, GraphQLDirective> directives;
private final Map<String, GraphQLAppliedDirective> appliedDirectives;
private final NodeParentTree<NamedNode<?>> nodeParentTree;
private final TypeDefinitionRegistry typeDefinitionRegistry;
private final Map<String, Object> context;
Expand All @@ -40,11 +34,18 @@ public class SchemaDirectiveWiringEnvironmentImpl<T extends GraphQLDirectiveCont
private final GraphQLFieldDefinition fieldDefinition;
private final GraphQLDirective registeredDirective;

public SchemaDirectiveWiringEnvironmentImpl(T element, List<GraphQLDirective> directives, GraphQLDirective registeredDirective, SchemaGeneratorDirectiveHelper.Parameters parameters) {
public SchemaDirectiveWiringEnvironmentImpl(
T element,
List<GraphQLDirective> directives,
List<GraphQLAppliedDirective> appliedDirectives,
GraphQLDirective registeredDirective,
SchemaGeneratorDirectiveHelper.Parameters parameters
) {
this.element = element;
this.registeredDirective = registeredDirective;
this.typeDefinitionRegistry = parameters.getTypeRegistry();
this.directives = FpKit.getByName(directives, GraphQLDirective::getName);
this.appliedDirectives = FpKit.getByName(appliedDirectives, GraphQLAppliedDirective::getName);
this.context = parameters.getContext();
this.codeRegistry = parameters.getCodeRegistry();
this.nodeParentTree = parameters.getNodeParentTree();
Expand Down Expand Up @@ -73,6 +74,16 @@ public GraphQLDirective getDirective(String directiveName) {
return directives.get(directiveName);
}

@Override
public Map<String, GraphQLAppliedDirective> getAppliedDirectives() {
return appliedDirectives;
}

@Override
public GraphQLAppliedDirective getAppliedDirective(String directiveName) {
return appliedDirectives.get(directiveName);
}

@Override
public boolean containsDirective(String directiveName) {
return directives.containsKey(directiveName);
Expand Down
Loading