Skip to content

feat: update graphql-java version #1749

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

Merged
Merged
Show file tree
Hide file tree
Changes from 8 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 README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ A basic setup of a GraphQL client can be found on our [client documentation sect
More examples and documentation are available on our [documentation site](https://expediagroup.github.io/graphql-kotlin) hosted in GitHub Pages.
We also have the [examples](/examples) module which can be run locally for testing and shows example code using the libraries.

If you have a question about something you can not find in our documentation, the indivdual module `README`s, or [javadocs](https://www.javadoc.io/doc/com.expediagroup/graphql-kotlin-schema-generator), feel free to contribute to the docs or [start a disucssion](https://github.com/ExpediaGroup/graphql-kotlin/discussions) and tag it with the question label.
If you have a question about something you can not find in our documentation, the individual module `README`s, or [javadocs](https://www.javadoc.io/doc/com.expediagroup/graphql-kotlin-schema-generator), feel free to contribute to the docs or [start a discussion](https://github.com/ExpediaGroup/graphql-kotlin/discussions) and tag it with the question label.

If you would like to contribute to our documentation see the [website](/website) directory for more information.

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2021 Expedia, Inc
* Copyright 2023 Expedia, Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -17,12 +17,16 @@
package com.expediagroup.graphql.examples.client.server.scalars

import com.ibm.icu.util.ULocale
import graphql.GraphQLContext
import graphql.execution.CoercedVariables
import graphql.language.StringValue
import graphql.language.Value
import graphql.schema.Coercing
import graphql.schema.CoercingParseLiteralException
import graphql.schema.CoercingParseValueException
import graphql.schema.CoercingSerializeException
import graphql.schema.GraphQLScalarType
import java.util.Locale

internal val graphqlULocaleType = GraphQLScalarType.newScalar()
.name("Locale")
Expand All @@ -31,24 +35,26 @@ internal val graphqlULocaleType = GraphQLScalarType.newScalar()
.build()

private object ULocaleCoercing : Coercing<ULocale, String> {
override fun parseValue(input: Any): ULocale = runCatching {
ULocale(serialize(input))
}.getOrElse {
throw CoercingParseValueException("Expected valid ULocale but was $input")
}
override fun parseValue(input: Any, graphQLContext: GraphQLContext, locale: Locale): ULocale =
runCatching {
ULocale(serialize(input, graphQLContext, locale))
}.getOrElse {
throw CoercingParseValueException("Expected valid ULocale but was $input")
}

override fun parseLiteral(input: Any): ULocale {
val locale = (input as? StringValue)?.value
override fun parseLiteral(input: Value<*>, variables: CoercedVariables, graphQLContext: GraphQLContext, locale: Locale): ULocale {
val inputLocale = (input as? StringValue)?.value
return runCatching {
ULocale(locale)
ULocale(inputLocale)
}.getOrElse {
throw CoercingParseLiteralException("Expected valid ULocale literal but was $locale")
throw CoercingParseLiteralException("Expected valid ULocale literal but was $inputLocale")
}
}

override fun serialize(dataFetcherResult: Any): String = runCatching {
dataFetcherResult.toString()
}.getOrElse {
throw CoercingSerializeException("Data fetcher result $dataFetcherResult cannot be serialized to a String")
}
override fun serialize(dataFetcherResult: Any, graphQLContext: GraphQLContext, locale: Locale): String =
runCatching {
dataFetcherResult.toString()
}.getOrElse {
throw CoercingSerializeException("Data fetcher result $dataFetcherResult cannot be serialized to a String")
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2021 Expedia, Inc
* Copyright 2023 Expedia, Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -16,32 +16,39 @@

package com.expediagroup.graphql.examples.client.server.scalars

import graphql.GraphQLContext
import graphql.execution.CoercedVariables
import graphql.language.StringValue
import graphql.language.Value
import graphql.schema.Coercing
import graphql.schema.CoercingParseLiteralException
import graphql.schema.CoercingParseValueException
import graphql.schema.GraphQLScalarType
import java.util.UUID
import java.util.Locale

internal val graphqlUUIDType = GraphQLScalarType.newScalar()
.name("UUID")
.description("Custom scalar representing UUID")
.coercing(object : Coercing<UUID, String> {
override fun parseValue(input: Any): UUID = try {
UUID.fromString(
serialize(input)
)
} catch (e: Exception) {
throw CoercingParseValueException("Cannot parse value $input to UUID", e)
}
override fun parseValue(input: Any, graphQLContext: GraphQLContext, locale: Locale): UUID =
try {
UUID.fromString(
serialize(input, graphQLContext, locale)
)
} catch (e: Exception) {
throw CoercingParseValueException("Cannot parse value $input to UUID", e)
}

override fun parseLiteral(input: Any): UUID = try {
val uuidString = (input as? StringValue)?.value
UUID.fromString(uuidString)
} catch (e: Exception) {
throw CoercingParseLiteralException("Cannot parse literal $input to UUID", e)
}
override fun parseLiteral(input: Value<*>, variables: CoercedVariables, graphQLContext: GraphQLContext, locale: Locale): UUID =
try {
val uuidString = (input as? StringValue)?.value
UUID.fromString(uuidString)
} catch (e: Exception) {
throw CoercingParseLiteralException("Cannot parse literal $input to UUID", e)
}

override fun serialize(dataFetcherResult: Any): String = dataFetcherResult.toString()
override fun serialize(dataFetcherResult: Any, graphQLContext: GraphQLContext, locale: Locale): String =
dataFetcherResult.toString()
})
.build()
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright 2022 Expedia, Inc
* Copyright 2023 Expedia, Inc
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -19,8 +19,11 @@ package com.expediagroup.graphql.examples.server.spring.hooks
import com.expediagroup.graphql.examples.server.spring.model.MyValueClass
import com.expediagroup.graphql.generator.directives.KotlinDirectiveWiringFactory
import com.expediagroup.graphql.generator.hooks.SchemaGeneratorHooks
import graphql.GraphQLContext
import graphql.execution.CoercedVariables
import graphql.Scalars
import graphql.language.StringValue
import graphql.language.Value
import graphql.schema.Coercing
import graphql.schema.CoercingParseLiteralException
import graphql.schema.CoercingParseValueException
Expand All @@ -30,6 +33,7 @@ import graphql.schema.GraphQLType
import org.springframework.beans.factory.BeanFactoryAware
import reactor.core.publisher.Mono
import java.time.LocalDate
import java.util.Locale
import java.util.UUID
import kotlin.reflect.KClass
import kotlin.reflect.KType
Expand Down Expand Up @@ -83,13 +87,14 @@ internal val graphqlUUIDType = GraphQLScalarType.newScalar()
.build()

private object UUIDCoercing : Coercing<UUID, String> {
override fun parseValue(input: Any): UUID = runCatching {
UUID.fromString(serialize(input))
}.getOrElse {
throw CoercingParseValueException("Expected valid UUID but was $input")
}
override fun parseValue(input: Any, graphQLContext: GraphQLContext, locale: Locale): UUID =
runCatching {
UUID.fromString(serialize(input, graphQLContext, locale))
}.getOrElse {
throw CoercingParseValueException("Expected valid UUID but was $input")
}

override fun parseLiteral(input: Any): UUID {
override fun parseLiteral(input: Value<*>, variables: CoercedVariables, graphQLContext: GraphQLContext, locale: Locale): UUID {
val uuidString = (input as? StringValue)?.value
return runCatching {
UUID.fromString(uuidString)
Expand All @@ -98,11 +103,12 @@ private object UUIDCoercing : Coercing<UUID, String> {
}
}

override fun serialize(dataFetcherResult: Any): String = runCatching {
dataFetcherResult.toString()
}.getOrElse {
throw CoercingSerializeException("Data fetcher result $dataFetcherResult cannot be serialized to a String")
}
override fun serialize(dataFetcherResult: Any, graphQLContext: GraphQLContext, locale: Locale): String =
runCatching {
dataFetcherResult.toString()
}.getOrElse {
throw CoercingSerializeException("Data fetcher result $dataFetcherResult cannot be serialized to a String")
}
}

internal val graphqlPeriodType: GraphQLScalarType = GraphQLScalarType.newScalar()
Expand All @@ -114,23 +120,26 @@ internal val graphqlPeriodType: GraphQLScalarType = GraphQLScalarType.newScalar(
typealias Period = ClosedRange<LocalDate>

private object PeriodCoercing : Coercing<Period, String> {
override fun parseValue(input: Any): Period = runCatching {
input.toString().parseAsPeriod()
}.getOrElse {
throw CoercingParseValueException("Expected valid Period but was $input")
}
override fun parseValue(input: Any, graphQLContext: GraphQLContext, locale: Locale): Period =
runCatching {
input.toString().parseAsPeriod()
}.getOrElse {
throw CoercingParseValueException("Expected valid Period but was $input")
}

override fun parseLiteral(input: Any): Period = runCatching {
(input as? StringValue)?.value?.parseAsPeriod() ?: throw CoercingParseLiteralException("Expected valid Period literal but was $input")
}.getOrElse {
throw CoercingParseLiteralException("Expected valid Period literal but was $input")
}
override fun parseLiteral(input: Value<*>, variables: CoercedVariables, graphQLContext: GraphQLContext, locale: Locale): Period =
runCatching {
(input as? StringValue)?.value?.parseAsPeriod() ?: throw CoercingParseLiteralException("Expected valid Period literal but was $input")
}.getOrElse {
throw CoercingParseLiteralException("Expected valid Period literal but was $input")
}

override fun serialize(dataFetcherResult: Any): String = kotlin.runCatching {
toString()
}.getOrElse {
throw CoercingSerializeException("Data fetcher result $dataFetcherResult cannot be serialized to a String")
}
override fun serialize(dataFetcherResult: Any, graphQLContext: GraphQLContext, locale: Locale): String =
kotlin.runCatching {
toString()
}.getOrElse {
throw CoercingSerializeException("Data fetcher result $dataFetcherResult cannot be serialized to a String")
}

private fun String.parseAsPeriod(): Period = split("..").let {
if (it.size != 2) error("Cannot parse input $this as Period")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import com.expediagroup.graphql.examples.server.spring.directives.TRACK_TIMES_IN
import graphql.ExecutionResult
import graphql.execution.instrumentation.InstrumentationContext
import graphql.execution.instrumentation.InstrumentationState
import graphql.execution.instrumentation.SimpleInstrumentation
import graphql.execution.instrumentation.Instrumentation
import graphql.execution.instrumentation.SimpleInstrumentationContext
import graphql.execution.instrumentation.parameters.InstrumentationExecutionParameters
import graphql.execution.instrumentation.parameters.InstrumentationFieldFetchParameters
Expand All @@ -33,22 +33,22 @@ import java.util.concurrent.ConcurrentHashMap
* Adds field count tracking in the instrumentation layer if [com.expediagroup.graphql.examples.directives.TrackTimesInvoked] is present.
*/
@Component
class TrackTimesInvokedInstrumentation : SimpleInstrumentation() {
class TrackTimesInvokedInstrumentation : Instrumentation {

private val logger = LoggerFactory.getLogger(TrackTimesInvokedInstrumentation::class.java)

override fun createState(): InstrumentationState = TrackTimesInvokedInstrumenationState()

override fun beginFieldFetch(parameters: InstrumentationFieldFetchParameters): InstrumentationContext<Any> {
override fun beginFieldFetch(parameters: InstrumentationFieldFetchParameters, state: InstrumentationState?): InstrumentationContext<Any> {
if (parameters.field.getDirective(TRACK_TIMES_INVOKED_DIRECTIVE_NAME) != null) {
(parameters.getInstrumentationState() as? TrackTimesInvokedInstrumenationState)?.incrementCount(parameters.field.name)
(state as? TrackTimesInvokedInstrumenationState)?.incrementCount(parameters.field.name)
}

return SimpleInstrumentationContext<Any>()
}

override fun instrumentExecutionResult(executionResult: ExecutionResult, parameters: InstrumentationExecutionParameters): CompletableFuture<ExecutionResult> {
val count = (parameters.getInstrumentationState() as? TrackTimesInvokedInstrumenationState)?.getCount()
override fun instrumentExecutionResult(executionResult: ExecutionResult, parameters: InstrumentationExecutionParameters, state: InstrumentationState?): CompletableFuture<ExecutionResult> {
val count = (state as? TrackTimesInvokedInstrumenationState)?.getCount()
logger.info("Fields invoked: $count")
return super.instrumentExecutionResult(executionResult, parameters)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,9 @@ class PolymorphicQueryIT(@Autowired private val testClient: WebTestClient) {
.verifyError("Validation error")
.verifyError("WrongType")
.verifyError(
"argument 'type' with value 'EnumValue{name='$unknownType'}' is not a valid 'AnimalType' - " +
"Expected enum literal value not in allowable values - 'EnumValue{name='HELLO'}'"
"Validation error (WrongType@[animal]) : " +
"argument 'type' with value 'EnumValue{name='HELLO'}' is not a valid 'AnimalType' - " +
"Literal value not in allowable values for enum 'AnimalType' - 'EnumValue{name='HELLO'}'"
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ package com.expediagroup.graphql.generator.federation.types
import com.apollographql.federation.graphqljava._FieldSet
import com.expediagroup.graphql.generator.federation.directives.FieldSet
import com.expediagroup.graphql.generator.federation.exception.CoercingValueToLiteralException
import graphql.GraphQLContext
import graphql.Scalars
import graphql.execution.CoercedVariables
import graphql.language.StringValue
import graphql.language.Value
import graphql.schema.Coercing
Expand All @@ -32,6 +34,7 @@ import graphql.schema.GraphQLSchemaElement
import graphql.schema.GraphQLTypeVisitorStub
import graphql.util.TraversalControl
import graphql.util.TraverserContext
import java.util.Locale

internal const val FIELD_SET_SCALAR_NAME = "FieldSet"
internal const val FIELD_SET_ARGUMENT_NAME = "fields"
Expand All @@ -53,28 +56,36 @@ internal val FIELD_SET_ARGUMENT = GraphQLArgument.newArgument()
.build()

private object FieldSetCoercing : Coercing<FieldSet, String> {
override fun serialize(input: Any): String = if (input is FieldSet) {
input.value
} else {
throw CoercingSerializeException("Cannot serialize $input. Expected type 'FieldSet' but was '${input.javaClass.simpleName}'.")
}

override fun parseValue(input: Any): FieldSet = parseLiteral(input)
override fun serialize(dataFetcherResult: Any, graphQLContext: GraphQLContext, locale: Locale): String =
when (dataFetcherResult) {
is FieldSet -> dataFetcherResult.value
else -> throw CoercingSerializeException(
"Cannot serialize $dataFetcherResult. Expected type 'FieldSet' but was '${dataFetcherResult.javaClass.simpleName}'."
)
}

override fun parseLiteral(input: Any): FieldSet =
override fun parseValue(input: Any, graphQLContext: GraphQLContext, locale: Locale): FieldSet =
when (input) {
is FieldSet -> input
is StringValue -> FieldSet::class.constructors.first().call(input.value)
else -> {
throw CoercingParseLiteralException("Cannot parse $input to FieldSet. Expected AST type 'StringValue' but was '${input.javaClass.simpleName}'.")
}
else -> throw CoercingParseLiteralException(
"Cannot parse $input to FieldSet. Expected AST type 'StringValue' but was '${input.javaClass.simpleName}'."
)
}

override fun valueToLiteral(input: Any): Value<out Value<*>> = if (input is FieldSet) {
StringValue.newStringValue(input.value).build()
} else {
throw CoercingValueToLiteralException(_FieldSet::class, input)
}
override fun parseLiteral(input: Value<*>, variables: CoercedVariables, graphQLContext: GraphQLContext, locale: Locale): FieldSet =
when (input) {
is StringValue -> FieldSet::class.constructors.first().call(input.value)
else -> throw CoercingParseLiteralException(
"Cannot parse $input to FieldSet. Expected AST type 'StringValue' but was '${input.javaClass.simpleName}'."
)
}

override fun valueToLiteral(input: Any, graphQLContext: GraphQLContext, locale: Locale): Value<*> =
when (input) {
is FieldSet -> StringValue.newStringValue(input.value).build()
else -> throw CoercingValueToLiteralException(_FieldSet::class, input)
}
}

/**
Expand Down
Loading