From 059311554bfa3febe4f0bb643908e2ff37ece017 Mon Sep 17 00:00:00 2001 From: Shane Myrick Date: Mon, 20 Sep 2021 14:44:09 -0700 Subject: [PATCH 1/3] Test scalar converters with Ulocale --- examples/build.gradle.kts | 1 + .../client/gradle-client/build.gradle.kts | 5 +- .../client/gradle/ULocaleScalarConverter.kt | 28 +++++++++++ .../src/main/resources/ExampleQuery.graphql | 2 + examples/client/maven-client/pom.xml | 14 ++++++ .../client/maven/ULocaleScalarConverter.kt | 28 +++++++++++ .../src/main/resources/ExampleQuery.graphql | 2 + .../examples/client/server/Application.kt | 32 ++----------- .../examples/client/server/SimpleQueries.kt | 5 +- .../client/server/model/ScalarWrapper.kt | 11 +++-- .../client/server/scalars/ULocaleCoercing.kt | 39 +++++++++++++++ .../client/server/scalars/UUIDCoercing.kt | 47 +++++++++++++++++++ 12 files changed, 181 insertions(+), 33 deletions(-) create mode 100644 examples/client/gradle-client/src/main/kotlin/com/expediagroup/graphql/examples/client/gradle/ULocaleScalarConverter.kt create mode 100644 examples/client/maven-client/src/main/kotlin/com/expediagroup/graphql/examples/client/maven/ULocaleScalarConverter.kt create mode 100644 examples/client/server/src/main/kotlin/com/expediagroup/graphql/examples/client/server/scalars/ULocaleCoercing.kt create mode 100644 examples/client/server/src/main/kotlin/com/expediagroup/graphql/examples/client/server/scalars/UUIDCoercing.kt diff --git a/examples/build.gradle.kts b/examples/build.gradle.kts index 976ff53f4f..5c57ab0b57 100644 --- a/examples/build.gradle.kts +++ b/examples/build.gradle.kts @@ -51,6 +51,7 @@ subprojects { implementation(kotlin("stdlib", kotlinVersion)) implementation(kotlin("reflect", kotlinVersion)) implementation("org.jetbrains.kotlinx:kotlinx-coroutines-jdk8:$kotlinCoroutinesVersion") + implementation("com.ibm.icu:icu4j:69.1") testImplementation(kotlin("test-junit5", kotlinVersion)) testImplementation("org.junit.jupiter:junit-jupiter-api:$junitVersion") testImplementation("org.junit.jupiter:junit-jupiter-engine:$junitVersion") diff --git a/examples/client/gradle-client/build.gradle.kts b/examples/client/gradle-client/build.gradle.kts index 4bf156ab92..46b8b0c88e 100644 --- a/examples/client/gradle-client/build.gradle.kts +++ b/examples/client/gradle-client/build.gradle.kts @@ -31,7 +31,10 @@ graphql { // optional allowDeprecatedFields = true headers = mapOf("X-Custom-Header" to "My-Custom-Header") - customScalars = listOf(GraphQLScalar("UUID", "java.util.UUID", "com.expediagroup.graphql.examples.client.gradle.UUIDScalarConverter")) + customScalars = listOf( + GraphQLScalar("UUID", "java.util.UUID", "com.expediagroup.graphql.examples.client.gradle.UUIDScalarConverter"), + GraphQLScalar("Locale", "com.ibm.icu.util.ULocale", "com.expediagroup.graphql.examples.client.gradle.ULocaleScalarConverter"), + ) serializer = GraphQLSerializer.KOTLINX } } diff --git a/examples/client/gradle-client/src/main/kotlin/com/expediagroup/graphql/examples/client/gradle/ULocaleScalarConverter.kt b/examples/client/gradle-client/src/main/kotlin/com/expediagroup/graphql/examples/client/gradle/ULocaleScalarConverter.kt new file mode 100644 index 0000000000..5271d0ed5f --- /dev/null +++ b/examples/client/gradle-client/src/main/kotlin/com/expediagroup/graphql/examples/client/gradle/ULocaleScalarConverter.kt @@ -0,0 +1,28 @@ +/* + * Copyright 2021 Expedia, Inc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.expediagroup.graphql.examples.client.gradle + +import com.expediagroup.graphql.client.converter.ScalarConverter +import com.ibm.icu.util.ULocale + +/** + * Public client converter for a [ULocale] + */ +class ULocaleScalarConverter : ScalarConverter { + override fun toScalar(rawValue: Any): ULocale = ULocale(rawValue.toString()) + override fun toJson(value: ULocale): Any = value.toString() +} diff --git a/examples/client/gradle-client/src/main/resources/ExampleQuery.graphql b/examples/client/gradle-client/src/main/resources/ExampleQuery.graphql index 244a5480fe..fcd1cd3a67 100644 --- a/examples/client/gradle-client/src/main/resources/ExampleQuery.graphql +++ b/examples/client/gradle-client/src/main/resources/ExampleQuery.graphql @@ -8,6 +8,8 @@ query ExampleQuery($simpleCriteria: SimpleArgumentInput) { name rating valid + locale + listLocale } listQuery { id diff --git a/examples/client/maven-client/pom.xml b/examples/client/maven-client/pom.xml index 6f6b955860..227ced788f 100755 --- a/examples/client/maven-client/pom.xml +++ b/examples/client/maven-client/pom.xml @@ -30,6 +30,11 @@ reactor-core ${reactor.version} + + com.ibm.icu + icu4j + 69.1 + @@ -79,6 +84,15 @@ used to convert to/from raw JSON and scalar type --> com.expediagroup.graphql.examples.client.maven.UUIDScalarConverter + + + Locale + + com.ibm.icu.util.ULocale + + com.expediagroup.graphql.examples.client.maven.ULocaleScalarConverter + JACKSON true diff --git a/examples/client/maven-client/src/main/kotlin/com/expediagroup/graphql/examples/client/maven/ULocaleScalarConverter.kt b/examples/client/maven-client/src/main/kotlin/com/expediagroup/graphql/examples/client/maven/ULocaleScalarConverter.kt new file mode 100644 index 0000000000..93bed49372 --- /dev/null +++ b/examples/client/maven-client/src/main/kotlin/com/expediagroup/graphql/examples/client/maven/ULocaleScalarConverter.kt @@ -0,0 +1,28 @@ +/* + * Copyright 2021 Expedia, Inc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.expediagroup.graphql.examples.client.maven + +import com.expediagroup.graphql.client.converter.ScalarConverter +import com.ibm.icu.util.ULocale + +/** + * Public client converter for a [ULocale] + */ +class ULocaleScalarConverter : ScalarConverter { + override fun toScalar(rawValue: Any): ULocale = ULocale(rawValue.toString()) + override fun toJson(value: ULocale): Any = value.toString() +} diff --git a/examples/client/maven-client/src/main/resources/ExampleQuery.graphql b/examples/client/maven-client/src/main/resources/ExampleQuery.graphql index 979a82c2a4..8ea3ce4533 100644 --- a/examples/client/maven-client/src/main/resources/ExampleQuery.graphql +++ b/examples/client/maven-client/src/main/resources/ExampleQuery.graphql @@ -8,6 +8,8 @@ query ExampleQuery($simpleCriteria: SimpleArgumentInput) { name rating valid + locale + listLocale } listQuery { id diff --git a/examples/client/server/src/main/kotlin/com/expediagroup/graphql/examples/client/server/Application.kt b/examples/client/server/src/main/kotlin/com/expediagroup/graphql/examples/client/server/Application.kt index 51428631f1..ae63ab4970 100644 --- a/examples/client/server/src/main/kotlin/com/expediagroup/graphql/examples/client/server/Application.kt +++ b/examples/client/server/src/main/kotlin/com/expediagroup/graphql/examples/client/server/Application.kt @@ -16,12 +16,10 @@ package com.expediagroup.graphql.examples.client.server +import com.expediagroup.graphql.examples.client.server.scalars.graphqlULocaleType +import com.expediagroup.graphql.examples.client.server.scalars.graphqlUUIDType import com.expediagroup.graphql.generator.hooks.SchemaGeneratorHooks -import graphql.language.StringValue -import graphql.schema.Coercing -import graphql.schema.CoercingParseLiteralException -import graphql.schema.CoercingParseValueException -import graphql.schema.GraphQLScalarType +import com.ibm.icu.util.ULocale import graphql.schema.GraphQLType import org.springframework.boot.autoconfigure.SpringBootApplication import org.springframework.boot.runApplication @@ -32,33 +30,11 @@ import kotlin.reflect.KType @SpringBootApplication class Application { - private val graphqlUUIDType = GraphQLScalarType.newScalar() - .name("UUID") - .description("Custom scalar representing UUID") - .coercing(object : Coercing { - 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 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 serialize(dataFetcherResult: Any): String = dataFetcherResult.toString() - }) - .build() - @Bean fun customHooks(): SchemaGeneratorHooks = object : SchemaGeneratorHooks { override fun willGenerateGraphQLType(type: KType): GraphQLType? = when (type.classifier) { UUID::class -> graphqlUUIDType + ULocale::class -> graphqlULocaleType else -> null } } diff --git a/examples/client/server/src/main/kotlin/com/expediagroup/graphql/examples/client/server/SimpleQueries.kt b/examples/client/server/src/main/kotlin/com/expediagroup/graphql/examples/client/server/SimpleQueries.kt index 6fb5f24bba..35b68cc6d9 100755 --- a/examples/client/server/src/main/kotlin/com/expediagroup/graphql/examples/client/server/SimpleQueries.kt +++ b/examples/client/server/src/main/kotlin/com/expediagroup/graphql/examples/client/server/SimpleQueries.kt @@ -31,6 +31,7 @@ import com.expediagroup.graphql.examples.client.server.repository.BasicObjectRep import com.expediagroup.graphql.generator.annotations.GraphQLDescription import com.expediagroup.graphql.generator.scalars.ID import com.expediagroup.graphql.server.operations.Query +import com.ibm.icu.util.ULocale import org.springframework.stereotype.Component import java.util.UUID import kotlin.random.Random @@ -54,7 +55,9 @@ class SimpleQueries(private val repository: BasicObjectRepository) : Query { count = 1, rating = null, custom = UUID.randomUUID(), - customList = listOf(UUID.randomUUID(), UUID.randomUUID()) + customList = listOf(UUID.randomUUID(), UUID.randomUUID()), + locale = ULocale.US, + listLocale = listOf(ULocale.US, ULocale.FRANCE) ) @GraphQLDescription("Query returning list of simple objects") diff --git a/examples/client/server/src/main/kotlin/com/expediagroup/graphql/examples/client/server/model/ScalarWrapper.kt b/examples/client/server/src/main/kotlin/com/expediagroup/graphql/examples/client/server/model/ScalarWrapper.kt index 7d3a26cec8..73649da239 100755 --- a/examples/client/server/src/main/kotlin/com/expediagroup/graphql/examples/client/server/model/ScalarWrapper.kt +++ b/examples/client/server/src/main/kotlin/com/expediagroup/graphql/examples/client/server/model/ScalarWrapper.kt @@ -18,6 +18,7 @@ package com.expediagroup.graphql.examples.client.server.model import com.expediagroup.graphql.generator.annotations.GraphQLDescription import com.expediagroup.graphql.generator.scalars.ID +import com.ibm.icu.util.ULocale import java.util.UUID @GraphQLDescription("Wrapper that holds all supported scalar types") @@ -32,8 +33,12 @@ data class ScalarWrapper( val count: Int?, @GraphQLDescription("A nullable signed double-precision floating-point value") val rating: Float?, - @GraphQLDescription("Custom scalar") + @GraphQLDescription("Custom scalar of UUID") val custom: UUID, - @GraphQLDescription("List of custom scalars") - val customList: List + @GraphQLDescription("List of custom scalar UUIDs") + val customList: List, + @GraphQLDescription("Custom scalar of Locale") + val locale: ULocale, + @GraphQLDescription("List of custom scalar Locales") + val listLocale: List ) diff --git a/examples/client/server/src/main/kotlin/com/expediagroup/graphql/examples/client/server/scalars/ULocaleCoercing.kt b/examples/client/server/src/main/kotlin/com/expediagroup/graphql/examples/client/server/scalars/ULocaleCoercing.kt new file mode 100644 index 0000000000..46e4501dff --- /dev/null +++ b/examples/client/server/src/main/kotlin/com/expediagroup/graphql/examples/client/server/scalars/ULocaleCoercing.kt @@ -0,0 +1,39 @@ +/* + * Copyright 2021 Expedia, Inc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.expediagroup.graphql.examples.client.server.scalars + +import graphql.language.StringValue +import graphql.schema.Coercing +import graphql.schema.CoercingParseLiteralException +import graphql.schema.CoercingParseValueException +import graphql.schema.GraphQLScalarType + +internal val graphqlULocaleType = GraphQLScalarType.newScalar() + .name("Locale") + .description("A type representing a Locale such as en_US or fr_FR") + .coercing(ULocaleCoercing) + .build() + +// We coerce between because jackson will +// take care of ser/deser for us within SchemaGenerator +private object ULocaleCoercing : Coercing { + override fun parseValue(input: Any): String = input as? String ?: throw CoercingParseValueException("$input can not be cast to String") + + override fun parseLiteral(input: Any): String = (input as? StringValue)?.value ?: throw CoercingParseLiteralException("$input can not be cast to StringValue") + + override fun serialize(dataFetcherResult: Any): String = dataFetcherResult.toString() +} diff --git a/examples/client/server/src/main/kotlin/com/expediagroup/graphql/examples/client/server/scalars/UUIDCoercing.kt b/examples/client/server/src/main/kotlin/com/expediagroup/graphql/examples/client/server/scalars/UUIDCoercing.kt new file mode 100644 index 0000000000..2afb7956b8 --- /dev/null +++ b/examples/client/server/src/main/kotlin/com/expediagroup/graphql/examples/client/server/scalars/UUIDCoercing.kt @@ -0,0 +1,47 @@ +/* + * Copyright 2021 Expedia, Inc + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.expediagroup.graphql.examples.client.server.scalars + +import graphql.language.StringValue +import graphql.schema.Coercing +import graphql.schema.CoercingParseLiteralException +import graphql.schema.CoercingParseValueException +import graphql.schema.GraphQLScalarType +import java.util.UUID + +internal val graphqlUUIDType = GraphQLScalarType.newScalar() + .name("UUID") + .description("Custom scalar representing UUID") + .coercing(object : Coercing { + 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 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 serialize(dataFetcherResult: Any): String = dataFetcherResult.toString() + }) + .build() From 5d4e9247fb11d110e2e0ae31b643487eb6a25402 Mon Sep 17 00:00:00 2001 From: Shane Myrick Date: Wed, 29 Sep 2021 10:57:47 -0700 Subject: [PATCH 2/3] Update wiremock schema --- .../src/integration/wiremock/__files/schema.graphql | 3 +++ .../generator/exceptions/InvalidSelectionSetException.kt | 2 +- .../src/test/resources/testSchema.graphql | 8 ++++++++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/examples/client/src/integration/wiremock/__files/schema.graphql b/examples/client/src/integration/wiremock/__files/schema.graphql index 9c03547c20..2c1fd1a301 100644 --- a/examples/client/src/integration/wiremock/__files/schema.graphql +++ b/examples/client/src/integration/wiremock/__files/schema.graphql @@ -172,6 +172,9 @@ enum CustomEnum { "Custom scalar representing UUID" scalar UUID +"A type representing a Locale such as en_US or fr_FR" +scalar Locale + "Some basic description" input BasicObjectInput { id: Int! diff --git a/plugins/client/graphql-kotlin-client-generator/src/main/kotlin/com/expediagroup/graphql/plugin/client/generator/exceptions/InvalidSelectionSetException.kt b/plugins/client/graphql-kotlin-client-generator/src/main/kotlin/com/expediagroup/graphql/plugin/client/generator/exceptions/InvalidSelectionSetException.kt index d1557e1a5a..a552450850 100644 --- a/plugins/client/graphql-kotlin-client-generator/src/main/kotlin/com/expediagroup/graphql/plugin/client/generator/exceptions/InvalidSelectionSetException.kt +++ b/plugins/client/graphql-kotlin-client-generator/src/main/kotlin/com/expediagroup/graphql/plugin/client/generator/exceptions/InvalidSelectionSetException.kt @@ -20,4 +20,4 @@ package com.expediagroup.graphql.plugin.client.generator.exceptions * Exception thrown when specified query file contains invalid selection set. */ internal class InvalidSelectionSetException(operationName: String, typeDefinitionName: String, typeName: String) : - RuntimeException("Operation $operationName specifies invalid selection set for $typeName - cannot select empty $typeDefinitionName") + RuntimeException("Operation $operationName specifies invalid selection set for $typeName - cannot find field '$typeDefinitionName'") diff --git a/plugins/client/graphql-kotlin-client-generator/src/test/resources/testSchema.graphql b/plugins/client/graphql-kotlin-client-generator/src/test/resources/testSchema.graphql index f42d2f4178..6ef946d88c 100755 --- a/plugins/client/graphql-kotlin-client-generator/src/test/resources/testSchema.graphql +++ b/plugins/client/graphql-kotlin-client-generator/src/test/resources/testSchema.graphql @@ -127,6 +127,10 @@ type ScalarWrapper { rating: Float "Either true or false" valid: Boolean! + "Custom scalar of Locale" + locale: Locale! + "List of custom scalar Locales" + listLocale: [Locale!]! } "Example interface implementation where value is a float" type SecondInterfaceImplementation implements BasicInterface { @@ -160,6 +164,10 @@ enum OtherEnum { } "Custom scalar representing UUID" scalar UUID + +"A type representing a Locale such as en_US or fr_FR" +scalar Locale + "Test input object" input SimpleArgumentInput { "Maximum value for test criteria" From 6348a31fdf3853eb348b39a15187c95b545742de Mon Sep 17 00:00:00 2001 From: Shane Myrick Date: Wed, 29 Sep 2021 11:10:45 -0700 Subject: [PATCH 3/3] Add fields to types --- .../client/src/integration/wiremock/__files/schema.graphql | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/examples/client/src/integration/wiremock/__files/schema.graphql b/examples/client/src/integration/wiremock/__files/schema.graphql index 2c1fd1a301..92162c33af 100644 --- a/examples/client/src/integration/wiremock/__files/schema.graphql +++ b/examples/client/src/integration/wiremock/__files/schema.graphql @@ -147,6 +147,10 @@ type ScalarWrapper { rating: Float "Either true or false" valid: Boolean! + "Custom scalar of Locale" + locale: Locale! + "List of custom scalar Locales" + listLocale: [Locale!]! } "Example interface implementation where value is a float"