diff --git a/.github/workflows/graalvm-integration.yml b/.github/workflows/graalvm-integration.yml new file mode 100644 index 0000000000..80bb36e331 --- /dev/null +++ b/.github/workflows/graalvm-integration.yml @@ -0,0 +1,78 @@ +name: GraaLVM Integration Tests + +on: + workflow_call: + pull_request: + branches: + - master + paths: + - 'generator/**' + - 'servers/**' + - 'plugins/**' + - 'integration/graalvm/**' + +jobs: + graalvm-integration: + timeout-minutes: 20 + runs-on: ubuntu-latest + defaults: + run: + working-directory: integration/graalvm + strategy: + matrix: + server: ['ktor-graalvm-server'] + + steps: + - name: Checkout Repository + uses: actions/checkout@v3 + + - name: Validate Gradle wrapper + uses: gradle/wrapper-validation-action@v1 + + - name: Setup GraalVM + uses: graalvm/setup-graalvm@v1 + with: + version: '22.3.1' + java-version: '17' + components: 'native-image' + native-image-job-reports: 'true' + + - name: Set up Gradle cache + uses: gradle/gradle-build-action@v2 + + - name: Build server + run: ./gradlew :${server}:build :${server}:nativeCompile + env: + server: ${{ matrix.server }} + + - name: Build and start the native image + id: start_server + run: | + set -x + echo "starting server" + ./${server}/build/native/nativeCompile/${server} & + echo "SERVER_PID=$(echo $!)" >> $GITHUB_OUTPUT + env: + server: ${{ matrix.server }} + + - name: Integration Test + run: | + echo "sending a test query" + curl --request POST \ + --verbose \ + --header 'content-type: application/json' \ + --url http://localhost:8080/graphql \ + --data '{"query":"query($inputArg: InputOnlyInput){ inputTypeQuery(arg: $inputArg) }","variables":{"inputArg": { "id": 123 }}}' \ + > response.json + + echo "received GraphQL response" + cat response.json + + echo "verifying response" + jq -e '.data.inputTypeQuery == "InputOnly(id=123)"' response.json + + - name: Stop server + if: ${{ always() }} + run: | + echo "shutting down server" + kill -9 ${{ steps.start_server.outputs.SERVER_PID }} diff --git a/integration/graalvm/build.gradle.kts b/integration/graalvm/build.gradle.kts new file mode 100644 index 0000000000..e1fff3a012 --- /dev/null +++ b/integration/graalvm/build.gradle.kts @@ -0,0 +1,20 @@ +import java.util.Properties + +allprojects { + repositories { + mavenCentral() + mavenLocal { + content { + includeGroup("com.expediagroup") + } + } + } + + val properties = Properties() + properties.load(File(rootDir.parentFile.parent, "gradle.properties").inputStream()) + for ((key, value) in properties) { + if (!project.ext.has(key.toString())) { + project.ext[key.toString()] = value + } + } +} diff --git a/integration/graalvm/gradle.properties b/integration/graalvm/gradle.properties new file mode 100644 index 0000000000..e4c5148d70 --- /dev/null +++ b/integration/graalvm/gradle.properties @@ -0,0 +1,6 @@ +group = com.expediagroup.graalvm + +org.gradle.jvmargs=-Xmx4g -XX:MaxMetaspaceSize=1g +org.gradle.caching=true +org.gradle.parallel=true + diff --git a/integration/graalvm/gradle/wrapper b/integration/graalvm/gradle/wrapper new file mode 120000 index 0000000000..166ffc09a8 --- /dev/null +++ b/integration/graalvm/gradle/wrapper @@ -0,0 +1 @@ +../../../gradle/wrapper \ No newline at end of file diff --git a/integration/graalvm/gradlew b/integration/graalvm/gradlew new file mode 120000 index 0000000000..343e0d2caa --- /dev/null +++ b/integration/graalvm/gradlew @@ -0,0 +1 @@ +../../gradlew \ No newline at end of file diff --git a/integration/graalvm/ktor-graalvm-server/build.gradle.kts b/integration/graalvm/ktor-graalvm-server/build.gradle.kts new file mode 100644 index 0000000000..17bc9f919d --- /dev/null +++ b/integration/graalvm/ktor-graalvm-server/build.gradle.kts @@ -0,0 +1,53 @@ +import com.expediagroup.graphql.plugin.gradle.graphql +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + +@Suppress("DSL_SCOPE_VIOLATION") // TODO: remove once KTIJ-19369 / Gradle#22797 is fixed +plugins { + alias(libs.plugins.kotlin.jvm) + application + alias(libs.plugins.graalvm.native) + id("com.expediagroup.graphql") +} + +dependencies { + implementation("com.expediagroup", "graphql-kotlin-ktor-server") + implementation("com.expediagroup", "graphql-kotlin-hooks-provider") + implementation(libs.logback) + implementation(libs.ktor.server.cio) + testImplementation(libs.junit.api) + testImplementation(libs.kotlin.test) + testImplementation(libs.ktor.client.content) + testImplementation(libs.ktor.server.test.host) +} + +tasks.test { + useJUnitPlatform() +} + +tasks.withType { + kotlinOptions.jvmTarget = "17" +} + +application { + mainClass.set("com.expediagroup.graalvm.ktor.ApplicationKt") +} + +graalvmNative { + toolchainDetection.set(false) + binaries { + named("main") { + verbose.set(true) + buildArgs.add("--initialize-at-build-time=io.ktor,kotlin,ch.qos.logback,org.slf4j") + buildArgs.add("-H:+ReportExceptionStackTraces") + } + metadataRepository { + enabled.set(true) + } + } +} + +graphql { + graalVm { + packages = listOf("com.expediagroup.graalvm.ktor") + } +} diff --git a/integration/graalvm/ktor-graalvm-server/src/main/kotlin/com/expediagroup/graalvm/ktor/Application.kt b/integration/graalvm/ktor-graalvm-server/src/main/kotlin/com/expediagroup/graalvm/ktor/Application.kt new file mode 100644 index 0000000000..ecf1d7aac3 --- /dev/null +++ b/integration/graalvm/ktor-graalvm-server/src/main/kotlin/com/expediagroup/graalvm/ktor/Application.kt @@ -0,0 +1,96 @@ +/* + * 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. + * 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.graalvm.ktor + +import com.expediagroup.graalvm.ktor.context.CustomContextFactory +import com.expediagroup.graalvm.ktor.hooks.CustomHooks +import com.expediagroup.graalvm.ktor.schema.ArgumentQuery +import com.expediagroup.graalvm.ktor.schema.AsyncQuery +import com.expediagroup.graalvm.ktor.schema.BasicMutation +import com.expediagroup.graalvm.ktor.schema.ContextualQuery +import com.expediagroup.graalvm.ktor.schema.CustomScalarQuery +import com.expediagroup.graalvm.ktor.schema.EnumQuery +import com.expediagroup.graalvm.ktor.schema.ErrorQuery +import com.expediagroup.graalvm.ktor.schema.IdQuery +import com.expediagroup.graalvm.ktor.schema.model.ExampleInterface +import com.expediagroup.graalvm.ktor.schema.model.ExampleUnion +import com.expediagroup.graalvm.ktor.schema.InnerClassQuery +import com.expediagroup.graalvm.ktor.schema.ListQuery +import com.expediagroup.graalvm.ktor.schema.PolymorphicQuery +import com.expediagroup.graalvm.ktor.schema.ScalarQuery +import com.expediagroup.graalvm.ktor.schema.TypesQuery +import com.expediagroup.graalvm.ktor.schema.dataloader.ExampleDataLoader +import com.expediagroup.graalvm.ktor.schema.model.FirstImpl +import com.expediagroup.graalvm.ktor.schema.model.FirstUnionMember +import com.expediagroup.graalvm.ktor.schema.model.SecondImpl +import com.expediagroup.graalvm.ktor.schema.model.SecondUnionMember +import com.expediagroup.graphql.dataloader.KotlinDataLoaderRegistryFactory +import com.expediagroup.graphql.server.ktor.GraphQL +import com.expediagroup.graphql.server.ktor.graphQLGetRoute +import com.expediagroup.graphql.server.ktor.graphQLPostRoute +import com.expediagroup.graphql.server.ktor.graphQLSDLRoute +import com.expediagroup.graphql.server.ktor.graphiQLRoute +import io.ktor.server.application.install +import io.ktor.server.cio.CIO +import io.ktor.server.engine.embeddedServer +import io.ktor.server.routing.routing + +fun main() { + embeddedServer(CIO, port = 8080, host = "0.0.0.0") { + install(GraphQL) { + schema { + packages = listOf("com.expediagroup.graalvm.ktor") + queries = listOf( + ArgumentQuery(), + AsyncQuery(), + ContextualQuery(), + CustomScalarQuery(), + EnumQuery(), + ErrorQuery(), + IdQuery(), + InnerClassQuery(), + ListQuery(), + PolymorphicQuery(), + ScalarQuery(), + TypesQuery() + ) + mutations = listOf( + BasicMutation() + ) + hooks = CustomHooks() + typeHierarchy = mapOf( + ExampleInterface::class to listOf(FirstImpl::class, SecondImpl::class), + ExampleUnion::class to listOf(FirstUnionMember::class, SecondUnionMember::class) + ) + } + engine { + dataLoaderRegistryFactory = KotlinDataLoaderRegistryFactory( + ExampleDataLoader + ) + } + server { + contextFactory = CustomContextFactory() + } + } + routing { + graphQLGetRoute() + graphQLPostRoute() + graphQLSDLRoute() + graphiQLRoute() + } + }.start(wait = true) +} diff --git a/integration/graalvm/ktor-graalvm-server/src/main/kotlin/com/expediagroup/graalvm/ktor/context/CustomContextFactory.kt b/integration/graalvm/ktor-graalvm-server/src/main/kotlin/com/expediagroup/graalvm/ktor/context/CustomContextFactory.kt new file mode 100644 index 0000000000..d8327a2015 --- /dev/null +++ b/integration/graalvm/ktor-graalvm-server/src/main/kotlin/com/expediagroup/graalvm/ktor/context/CustomContextFactory.kt @@ -0,0 +1,29 @@ +/* + * 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. + * 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.graalvm.ktor.context + +import com.expediagroup.graphql.generator.extensions.plus +import com.expediagroup.graphql.server.ktor.DefaultKtorGraphQLContextFactory +import graphql.GraphQLContext +import io.ktor.server.request.ApplicationRequest +import java.util.UUID + +class CustomContextFactory : DefaultKtorGraphQLContextFactory() { + override suspend fun generateContext(request: ApplicationRequest): GraphQLContext { + return super.generateContext(request).plus(mapOf("custom" to (request.headers["X-Custom-Header"] ?: UUID.randomUUID().toString()))) + } +} diff --git a/integration/graalvm/ktor-graalvm-server/src/main/kotlin/com/expediagroup/graalvm/ktor/hooks/CustomHooks.kt b/integration/graalvm/ktor-graalvm-server/src/main/kotlin/com/expediagroup/graalvm/ktor/hooks/CustomHooks.kt new file mode 100644 index 0000000000..ba18020074 --- /dev/null +++ b/integration/graalvm/ktor-graalvm-server/src/main/kotlin/com/expediagroup/graalvm/ktor/hooks/CustomHooks.kt @@ -0,0 +1,70 @@ +/* + * 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. + * 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.graalvm.ktor.hooks + +import com.expediagroup.graphql.generator.hooks.SchemaGeneratorHooks +import com.expediagroup.graphql.plugin.schema.hooks.SchemaGeneratorHooksProvider +import graphql.language.StringValue +import graphql.schema.Coercing +import graphql.schema.CoercingParseLiteralException +import graphql.schema.CoercingParseValueException +import graphql.schema.CoercingSerializeException +import graphql.schema.GraphQLScalarType +import graphql.schema.GraphQLType +import java.util.UUID +import kotlin.reflect.KClass +import kotlin.reflect.KType + +class CustomHooks : SchemaGeneratorHooks { + override fun willGenerateGraphQLType(type: KType): GraphQLType? = when (type.classifier as? KClass<*>) { + UUID::class -> graphqlUUIDType + else -> null + } +} + +class CustomHooksProvider : SchemaGeneratorHooksProvider { + override fun hooks(): SchemaGeneratorHooks = CustomHooks() +} + +val graphqlUUIDType: GraphQLScalarType = GraphQLScalarType.newScalar() + .name("UUID") + .description("A type representing a formatted java.util.UUID") + .coercing(UUIDCoercing) + .build() + +object UUIDCoercing : Coercing { + override fun parseValue(input: Any): UUID = runCatching { + UUID.fromString(serialize(input)) + }.getOrElse { + throw CoercingParseValueException("Expected valid UUID but was $input") + } + + override fun parseLiteral(input: Any): UUID { + val uuidString = (input as? StringValue)?.value + return runCatching { + UUID.fromString(uuidString) + }.getOrElse { + throw CoercingParseLiteralException("Expected valid UUID literal but was $uuidString") + } + } + + override fun serialize(dataFetcherResult: Any): String = runCatching { + dataFetcherResult.toString() + }.getOrElse { + throw CoercingSerializeException("Data fetcher result $dataFetcherResult cannot be serialized to a String") + } +} diff --git a/integration/graalvm/ktor-graalvm-server/src/main/kotlin/com/expediagroup/graalvm/ktor/schema/ArgumentQuery.kt b/integration/graalvm/ktor-graalvm-server/src/main/kotlin/com/expediagroup/graalvm/ktor/schema/ArgumentQuery.kt new file mode 100644 index 0000000000..852001cc10 --- /dev/null +++ b/integration/graalvm/ktor-graalvm-server/src/main/kotlin/com/expediagroup/graalvm/ktor/schema/ArgumentQuery.kt @@ -0,0 +1,46 @@ +/* + * 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. + * 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.graalvm.ktor.schema + +import com.expediagroup.graphql.generator.scalars.ID +import com.expediagroup.graphql.server.operations.Query + +/** + * Queries verifying passing scalar arguments. + */ +class ArgumentQuery : Query { + + fun stringArg(arg: String): String = arg.reversed() + fun optionalStringArg(arg: String? = null): String? = arg?.reversed() + fun intArg(arg: Int): Int = arg.inc() + fun optionalIntArg(arg: Int? = null): Int? = arg?.inc() + fun doubleArg(arg: Double): Double = arg.inc() + fun optionalDoubleArg(arg: Double? = null): Double? = arg?.inc() + fun booleanArg(arg: Boolean): Boolean = arg.not() + fun optionalBooleanArg(arg: Boolean? = null): Boolean? = arg?.not() + fun manyOptionalArgs( + idArg: ID? = null, + stringArg: String? = null, + intArg: Int? = null, + doubleArg: Double? = null, + booleanArg: Boolean? = null + ): String? = if (idArg != null || stringArg != null || intArg != null || doubleArg != null || booleanArg != null) { + "${idArg?.value}|$stringArg|$intArg|$doubleArg|$booleanArg" + } else { + null + } +} diff --git a/integration/graalvm/ktor-graalvm-server/src/main/kotlin/com/expediagroup/graalvm/ktor/schema/AsyncQuery.kt b/integration/graalvm/ktor-graalvm-server/src/main/kotlin/com/expediagroup/graalvm/ktor/schema/AsyncQuery.kt new file mode 100644 index 0000000000..858df15b27 --- /dev/null +++ b/integration/graalvm/ktor-graalvm-server/src/main/kotlin/com/expediagroup/graalvm/ktor/schema/AsyncQuery.kt @@ -0,0 +1,44 @@ +/* + * 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. + * 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.graalvm.ktor.schema + +import com.expediagroup.graalvm.ktor.schema.dataloader.EXAMPLE_LOADER +import com.expediagroup.graphql.generator.scalars.ID +import com.expediagroup.graphql.server.operations.Query +import graphql.schema.DataFetchingEnvironment +import kotlinx.coroutines.coroutineScope +import kotlinx.coroutines.delay +import java.util.concurrent.CompletableFuture +import kotlin.random.Random + +/** + * Queries verifying async models. + */ +class AsyncQuery : Query { + private val random: Random = Random(100) + + fun future(): CompletableFuture = CompletableFuture.completedFuture(random.nextInt()) + + fun dataLoader(env: DataFetchingEnvironment, id: ID): CompletableFuture = env.getDataLoader(EXAMPLE_LOADER).load(id) + + suspend fun coroutine(): Int = coroutineScope { + delay(10) + random.nextInt() + } + + // TODO reactor monads +} diff --git a/integration/graalvm/ktor-graalvm-server/src/main/kotlin/com/expediagroup/graalvm/ktor/schema/BasicMutation.kt b/integration/graalvm/ktor-graalvm-server/src/main/kotlin/com/expediagroup/graalvm/ktor/schema/BasicMutation.kt new file mode 100644 index 0000000000..803e0b8b1e --- /dev/null +++ b/integration/graalvm/ktor-graalvm-server/src/main/kotlin/com/expediagroup/graalvm/ktor/schema/BasicMutation.kt @@ -0,0 +1,26 @@ +/* + * 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. + * 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.graalvm.ktor.schema + +import com.expediagroup.graphql.server.operations.Mutation + +/** + * Example mutation. + */ +class BasicMutation : Mutation { + fun mutate(arg: String): String = arg.reversed() +} diff --git a/integration/graalvm/ktor-graalvm-server/src/main/kotlin/com/expediagroup/graalvm/ktor/schema/ContextualQuery.kt b/integration/graalvm/ktor-graalvm-server/src/main/kotlin/com/expediagroup/graalvm/ktor/schema/ContextualQuery.kt new file mode 100644 index 0000000000..aef4595292 --- /dev/null +++ b/integration/graalvm/ktor-graalvm-server/src/main/kotlin/com/expediagroup/graalvm/ktor/schema/ContextualQuery.kt @@ -0,0 +1,27 @@ +/* + * 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. + * 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.graalvm.ktor.schema + +import com.expediagroup.graphql.server.operations.Query +import graphql.schema.DataFetchingEnvironment + +/** + * Query verifying ability to retrieve contextual data. + */ +class ContextualQuery : Query { + fun contextualQuery(env: DataFetchingEnvironment): String = env.graphQlContext.getOrDefault("custom", "defaultValue") +} diff --git a/integration/graalvm/ktor-graalvm-server/src/main/kotlin/com/expediagroup/graalvm/ktor/schema/CustomScalarQuery.kt b/integration/graalvm/ktor-graalvm-server/src/main/kotlin/com/expediagroup/graalvm/ktor/schema/CustomScalarQuery.kt new file mode 100644 index 0000000000..7c1c8b94c1 --- /dev/null +++ b/integration/graalvm/ktor-graalvm-server/src/main/kotlin/com/expediagroup/graalvm/ktor/schema/CustomScalarQuery.kt @@ -0,0 +1,30 @@ +/* + * 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. + * 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.graalvm.ktor.schema + +import com.expediagroup.graphql.server.operations.Query +import java.util.UUID + +/** + * Queries used to verify custom scalar functionality. + */ +class CustomScalarQuery : Query { + fun customScalarQuery(): UUID = UUID.randomUUID() + fun nullableCustomScalarQuery(): UUID? = null + fun customScalarArg(arg: UUID): UUID = arg + fun optionalCustomScalarArg(arg: UUID? = null): UUID? = arg +} diff --git a/integration/graalvm/ktor-graalvm-server/src/main/kotlin/com/expediagroup/graalvm/ktor/schema/EnumQuery.kt b/integration/graalvm/ktor-graalvm-server/src/main/kotlin/com/expediagroup/graalvm/ktor/schema/EnumQuery.kt new file mode 100644 index 0000000000..5e399c69c7 --- /dev/null +++ b/integration/graalvm/ktor-graalvm-server/src/main/kotlin/com/expediagroup/graalvm/ktor/schema/EnumQuery.kt @@ -0,0 +1,33 @@ +/* + * 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. + * 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.graalvm.ktor.schema + +import com.expediagroup.graphql.server.operations.Query + +/** + * Queries used to verify returning/accepting enums. + */ +class EnumQuery : Query { + fun enumQuery(): BinaryEnum = BinaryEnum.ONE + fun enumArgQuery(arg: BinaryEnum): BinaryEnum = arg + fun optionalEnum(arg: BinaryEnum? = null): BinaryEnum? = arg +} + +enum class BinaryEnum { + ZERO, + ONE +} diff --git a/integration/graalvm/ktor-graalvm-server/src/main/kotlin/com/expediagroup/graalvm/ktor/schema/ErrorQuery.kt b/integration/graalvm/ktor-graalvm-server/src/main/kotlin/com/expediagroup/graalvm/ktor/schema/ErrorQuery.kt new file mode 100644 index 0000000000..aa65c4a9f4 --- /dev/null +++ b/integration/graalvm/ktor-graalvm-server/src/main/kotlin/com/expediagroup/graalvm/ktor/schema/ErrorQuery.kt @@ -0,0 +1,38 @@ +/* + * 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. + * 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.graalvm.ktor.schema + +import com.expediagroup.graphql.server.operations.Query +import graphql.GraphqlErrorBuilder +import graphql.execution.DataFetcherResult +import kotlin.random.Random + +/** + * Query verifying partial return type with data and errors. + */ +class ErrorQuery : Query { + private val random: Random = Random(100) + + fun resultsWithError(): DataFetcherResult = DataFetcherResult.newResult() + .data(random.nextInt()) + .error( + GraphqlErrorBuilder.newError() + .message("example error") + .build() + ) + .build() +} diff --git a/integration/graalvm/ktor-graalvm-server/src/main/kotlin/com/expediagroup/graalvm/ktor/schema/IdQuery.kt b/integration/graalvm/ktor-graalvm-server/src/main/kotlin/com/expediagroup/graalvm/ktor/schema/IdQuery.kt new file mode 100644 index 0000000000..1f675d8f3b --- /dev/null +++ b/integration/graalvm/ktor-graalvm-server/src/main/kotlin/com/expediagroup/graalvm/ktor/schema/IdQuery.kt @@ -0,0 +1,31 @@ +/* + * 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. + * 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.graalvm.ktor.schema + +import com.expediagroup.graphql.generator.scalars.ID +import com.expediagroup.graphql.server.operations.Query +import java.util.UUID + +/** + * Queries used to verify returning/accepting ID. + */ +class IdQuery : Query { + fun idQuery(): ID = ID(UUID.randomUUID().toString()) + fun nullableIdQuery(): ID? = null + fun idArg(arg: ID): ID = ID(arg.value.reversed()) + fun optionalIdArg(arg: ID? = null): ID? = arg?.let { ID(it.value.reversed()) } +} diff --git a/integration/graalvm/ktor-graalvm-server/src/main/kotlin/com/expediagroup/graalvm/ktor/schema/InnerClassQuery.kt b/integration/graalvm/ktor-graalvm-server/src/main/kotlin/com/expediagroup/graalvm/ktor/schema/InnerClassQuery.kt new file mode 100644 index 0000000000..94a967e536 --- /dev/null +++ b/integration/graalvm/ktor-graalvm-server/src/main/kotlin/com/expediagroup/graalvm/ktor/schema/InnerClassQuery.kt @@ -0,0 +1,29 @@ +/* + * 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. + * 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.graalvm.ktor.schema + +import com.expediagroup.graphql.server.operations.Query + +/** + * Query used to verify proper metadata references of the inner classes. + */ +class InnerClassQuery : Query { + + fun inner(): InnerClass = InnerClass(1, "foo") + + data class InnerClass(val id: Int, val name: String) +} diff --git a/integration/graalvm/ktor-graalvm-server/src/main/kotlin/com/expediagroup/graalvm/ktor/schema/ListQuery.kt b/integration/graalvm/ktor-graalvm-server/src/main/kotlin/com/expediagroup/graalvm/ktor/schema/ListQuery.kt new file mode 100644 index 0000000000..1087fbd7fd --- /dev/null +++ b/integration/graalvm/ktor-graalvm-server/src/main/kotlin/com/expediagroup/graalvm/ktor/schema/ListQuery.kt @@ -0,0 +1,32 @@ +/* + * 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. + * 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.graalvm.ktor.schema + +import com.expediagroup.graalvm.ktor.schema.model.InputOnly +import com.expediagroup.graalvm.ktor.schema.model.OutputOnly +import com.expediagroup.graphql.server.operations.Query + +/** + * Queries verifying handling of lists. + */ +class ListQuery : Query { + fun listQuery(): List? = null + fun listObjectQuery(): List = listOf(OutputOnly(id = 123, description = "foo")) + fun listPrimitiveArg(arg: List): List = arg + fun listObjectArg(arg: List): String = "foobar" + fun optionalPrimitiveListArg(arg: List? = null): List? = arg +} diff --git a/integration/graalvm/ktor-graalvm-server/src/main/kotlin/com/expediagroup/graalvm/ktor/schema/PolymorphicQuery.kt b/integration/graalvm/ktor-graalvm-server/src/main/kotlin/com/expediagroup/graalvm/ktor/schema/PolymorphicQuery.kt new file mode 100644 index 0000000000..9df350f29b --- /dev/null +++ b/integration/graalvm/ktor-graalvm-server/src/main/kotlin/com/expediagroup/graalvm/ktor/schema/PolymorphicQuery.kt @@ -0,0 +1,57 @@ +/* + * 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. + * 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.graalvm.ktor.schema + +import com.expediagroup.graalvm.ktor.schema.model.ExampleInterface +import com.expediagroup.graalvm.ktor.schema.model.ExampleUnion +import com.expediagroup.graalvm.ktor.schema.model.FirstImpl +import com.expediagroup.graalvm.ktor.schema.model.FirstUnionMember +import com.expediagroup.graalvm.ktor.schema.model.SecondImpl +import com.expediagroup.graalvm.ktor.schema.model.SecondUnionMember +import com.expediagroup.graphql.server.operations.Query +import kotlin.random.Random + +private val random: Random = Random(100) + +/** + * Queries verifying polymorphism. + */ +class PolymorphicQuery : Query { + fun interfaceQuery(): ExampleInterface = if (random.nextBoolean()) { + FirstImpl() + } else { + SecondImpl() + } + + fun unionQuery(): ExampleUnion = if (random.nextBoolean()) { + FirstUnionMember() + } else { + SecondUnionMember() + } + +// fun sealedQuery(): SealedUnion = if (random.nextBoolean()) { +// SealedUnion.SealedValueA(random.nextInt()) +// } else { +// SealedUnion.SealedValueB(random.nextDouble()) +// } +} + +//sealed class SealedUnion(val common: String) { +// data class SealedValueA(val a: Int) : SealedUnion(UUID.randomUUID().toString()) +// +// data class SealedValueB(val b: Double) : SealedUnion(UUID.randomUUID().toString()) +//} diff --git a/integration/graalvm/ktor-graalvm-server/src/main/kotlin/com/expediagroup/graalvm/ktor/schema/ScalarQuery.kt b/integration/graalvm/ktor-graalvm-server/src/main/kotlin/com/expediagroup/graalvm/ktor/schema/ScalarQuery.kt new file mode 100644 index 0000000000..772582cc70 --- /dev/null +++ b/integration/graalvm/ktor-graalvm-server/src/main/kotlin/com/expediagroup/graalvm/ktor/schema/ScalarQuery.kt @@ -0,0 +1,37 @@ +/* + * 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. + * 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.graalvm.ktor.schema + +import com.expediagroup.graphql.server.operations.Query +import java.util.UUID +import kotlin.random.Random + +/** + * Queries verifying returning scalar values. + */ +class ScalarQuery : Query { + private val random: Random = Random(100) + + fun stringQuery(): String = UUID.randomUUID().toString() + fun nullableStringQuery(): String? = null + fun intQuery(): Int = random.nextInt() + fun nullableIntQuery(): Int? = null + fun doubleQuery(): Double = random.nextDouble() + fun nullableDoubleQuery(): Double? = null + fun booleanQuery(): Boolean = random.nextBoolean() + fun nullableBooleanQuery(): Boolean? = null +} diff --git a/integration/graalvm/ktor-graalvm-server/src/main/kotlin/com/expediagroup/graalvm/ktor/schema/TypesQuery.kt b/integration/graalvm/ktor-graalvm-server/src/main/kotlin/com/expediagroup/graalvm/ktor/schema/TypesQuery.kt new file mode 100644 index 0000000000..f5e2f683c6 --- /dev/null +++ b/integration/graalvm/ktor-graalvm-server/src/main/kotlin/com/expediagroup/graalvm/ktor/schema/TypesQuery.kt @@ -0,0 +1,31 @@ +/* + * 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. + * 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.graalvm.ktor.schema + +import com.expediagroup.graalvm.ktor.schema.model.InputAndOutput +import com.expediagroup.graalvm.ktor.schema.model.InputOnly +import com.expediagroup.graalvm.ktor.schema.model.OutputOnly +import com.expediagroup.graphql.server.operations.Query + +/** + * Queries verifying handling of input/output types. + */ +class TypesQuery : Query { + fun outputTypeQuery(): OutputOnly = OutputOnly(id = 123, description = "foobar") + fun inputTypeQuery(arg: InputOnly? = null): String? = arg?.toString() + fun inputAndOutputQuery(arg: InputAndOutput? = null): InputAndOutput? = arg +} diff --git a/integration/graalvm/ktor-graalvm-server/src/main/kotlin/com/expediagroup/graalvm/ktor/schema/dataloader/ExampleDataLoader.kt b/integration/graalvm/ktor-graalvm-server/src/main/kotlin/com/expediagroup/graalvm/ktor/schema/dataloader/ExampleDataLoader.kt new file mode 100644 index 0000000000..073e564446 --- /dev/null +++ b/integration/graalvm/ktor-graalvm-server/src/main/kotlin/com/expediagroup/graalvm/ktor/schema/dataloader/ExampleDataLoader.kt @@ -0,0 +1,33 @@ +/* + * 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. + * 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.graalvm.ktor.schema.dataloader + +import com.expediagroup.graphql.dataloader.KotlinDataLoader +import com.expediagroup.graphql.generator.scalars.ID +import org.dataloader.DataLoaderFactory +import java.util.concurrent.CompletableFuture + +const val EXAMPLE_LOADER = "EXAMPLE_LOADER" + +val ExampleDataLoader = object : KotlinDataLoader { + override val dataLoaderName = EXAMPLE_LOADER + override fun getDataLoader() = DataLoaderFactory.newDataLoader { ids -> + CompletableFuture.supplyAsync { + ids.map { it.value } + } + } +} diff --git a/integration/graalvm/ktor-graalvm-server/src/main/kotlin/com/expediagroup/graalvm/ktor/schema/model/ExampleInterface.kt b/integration/graalvm/ktor-graalvm-server/src/main/kotlin/com/expediagroup/graalvm/ktor/schema/model/ExampleInterface.kt new file mode 100644 index 0000000000..b3d26c4063 --- /dev/null +++ b/integration/graalvm/ktor-graalvm-server/src/main/kotlin/com/expediagroup/graalvm/ktor/schema/model/ExampleInterface.kt @@ -0,0 +1,35 @@ +/* + * 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. + * 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.graalvm.ktor.schema.model + +import com.expediagroup.graphql.generator.scalars.ID +import java.util.UUID +import kotlin.random.Random + +interface ExampleInterface { + fun common(): String +} + +class FirstImpl : ExampleInterface { + override fun common(): String = "common value from first implementation" + fun specific(): Int = Random(100).nextInt() +} + +class SecondImpl : ExampleInterface { + override fun common(): String = "common value from second implementation" + fun unique(): ID = ID(UUID.randomUUID().toString()) +} diff --git a/integration/graalvm/ktor-graalvm-server/src/main/kotlin/com/expediagroup/graalvm/ktor/schema/model/ExampleUnion.kt b/integration/graalvm/ktor-graalvm-server/src/main/kotlin/com/expediagroup/graalvm/ktor/schema/model/ExampleUnion.kt new file mode 100644 index 0000000000..e2c6361f3f --- /dev/null +++ b/integration/graalvm/ktor-graalvm-server/src/main/kotlin/com/expediagroup/graalvm/ktor/schema/model/ExampleUnion.kt @@ -0,0 +1,30 @@ +/* + * 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. + * 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.graalvm.ktor.schema.model + +import java.util.UUID +import kotlin.random.Random + +interface ExampleUnion + +class FirstUnionMember : ExampleUnion { + fun one(): String = UUID.randomUUID().toString() +} + +class SecondUnionMember : ExampleUnion { + fun two(): Int = Random(100).nextInt() +} diff --git a/integration/graalvm/ktor-graalvm-server/src/main/kotlin/com/expediagroup/graalvm/ktor/schema/model/InputAndOutput.kt b/integration/graalvm/ktor-graalvm-server/src/main/kotlin/com/expediagroup/graalvm/ktor/schema/model/InputAndOutput.kt new file mode 100644 index 0000000000..cef93e8e13 --- /dev/null +++ b/integration/graalvm/ktor-graalvm-server/src/main/kotlin/com/expediagroup/graalvm/ktor/schema/model/InputAndOutput.kt @@ -0,0 +1,23 @@ +/* + * 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. + * 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.graalvm.ktor.schema.model + +import kotlin.random.Random + +data class InputAndOutput(val id: Int, val flag: Boolean? = true) { + fun outputOnly(): Int = Random(100).nextInt() +} diff --git a/integration/graalvm/ktor-graalvm-server/src/main/kotlin/com/expediagroup/graalvm/ktor/schema/model/InputOnly.kt b/integration/graalvm/ktor-graalvm-server/src/main/kotlin/com/expediagroup/graalvm/ktor/schema/model/InputOnly.kt new file mode 100644 index 0000000000..bb4e96d67f --- /dev/null +++ b/integration/graalvm/ktor-graalvm-server/src/main/kotlin/com/expediagroup/graalvm/ktor/schema/model/InputOnly.kt @@ -0,0 +1,19 @@ +/* + * 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. + * 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.graalvm.ktor.schema.model + +data class InputOnly(val id: Int) diff --git a/integration/graalvm/ktor-graalvm-server/src/main/kotlin/com/expediagroup/graalvm/ktor/schema/model/OutputOnly.kt b/integration/graalvm/ktor-graalvm-server/src/main/kotlin/com/expediagroup/graalvm/ktor/schema/model/OutputOnly.kt new file mode 100644 index 0000000000..1a26aeaa51 --- /dev/null +++ b/integration/graalvm/ktor-graalvm-server/src/main/kotlin/com/expediagroup/graalvm/ktor/schema/model/OutputOnly.kt @@ -0,0 +1,23 @@ +/* + * 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. + * 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.graalvm.ktor.schema.model + +import kotlin.random.Random + +data class OutputOnly(val id: Int, val description: String) { + fun calculate(): Int = Random(100).nextInt() +} diff --git a/integration/graalvm/ktor-graalvm-server/src/main/resources/META-INF/services/com.expediagroup.graphql.plugin.schema.hooks.SchemaGeneratorHooksProvider b/integration/graalvm/ktor-graalvm-server/src/main/resources/META-INF/services/com.expediagroup.graphql.plugin.schema.hooks.SchemaGeneratorHooksProvider new file mode 100644 index 0000000000..83a2d8e011 --- /dev/null +++ b/integration/graalvm/ktor-graalvm-server/src/main/resources/META-INF/services/com.expediagroup.graphql.plugin.schema.hooks.SchemaGeneratorHooksProvider @@ -0,0 +1 @@ +com.expediagroup.graalvm.ktor.hooks.CustomHooksProvider diff --git a/integration/graalvm/ktor-graalvm-server/src/test/kotlin/com/expediagroup/graalvm/ktor/schema/TypesQueryTest.kt b/integration/graalvm/ktor-graalvm-server/src/test/kotlin/com/expediagroup/graalvm/ktor/schema/TypesQueryTest.kt new file mode 100644 index 0000000000..53074cc40d --- /dev/null +++ b/integration/graalvm/ktor-graalvm-server/src/test/kotlin/com/expediagroup/graalvm/ktor/schema/TypesQueryTest.kt @@ -0,0 +1,50 @@ +package com.expediagroup.graalvm.ktor.schema + +import com.expediagroup.graalvm.ktor.schema.model.InputOnly +import com.expediagroup.graphql.server.ktor.GraphQL +import com.expediagroup.graphql.server.ktor.graphQLPostRoute +import com.expediagroup.graphql.server.types.GraphQLRequest +import io.ktor.client.plugins.contentnegotiation.ContentNegotiation +import io.ktor.client.request.post +import io.ktor.client.request.setBody +import io.ktor.client.statement.bodyAsText +import io.ktor.http.ContentType +import io.ktor.http.HttpStatusCode +import io.ktor.http.contentType +import io.ktor.serialization.jackson.jackson +import io.ktor.server.application.install +import io.ktor.server.routing.routing +import io.ktor.server.testing.testApplication +import org.junit.jupiter.api.Test +import kotlin.test.assertEquals + +class TypesQueryTest { + + @Test + fun `verify input only query`() = testApplication { + application { + install(GraphQL) { + schema { + packages = listOf("com.expediagroup.graalvm.ktor.schema") + queries = listOf(TypesQuery()) + typeHierarchy = emptyMap() + } + } + routing { + graphQLPostRoute() + } + } + + val client = createClient { + install(ContentNegotiation) { + jackson() + } + } + val response = client.post("/graphql") { + contentType(ContentType.Application.Json) + setBody(GraphQLRequest(query = "query InputOnlyQuery(\$inputArg: InputOnlyInput){ inputTypeQuery(arg: \$inputArg) }", operationName = "InputOnlyQuery", variables = mapOf("inputArg" to InputOnly(id = 123)))) + } + assertEquals(HttpStatusCode.OK, response.status) + assertEquals("""{"data":{"inputTypeQuery":"InputOnly(id=123)"}}""", response.bodyAsText().trim()) + } +} diff --git a/integration/graalvm/settings.gradle.kts b/integration/graalvm/settings.gradle.kts new file mode 100644 index 0000000000..5b139d2afc --- /dev/null +++ b/integration/graalvm/settings.gradle.kts @@ -0,0 +1,22 @@ +rootProject.name = "graalvm-integration-tests" + +pluginManagement { + repositories { + mavenCentral() + gradlePluginPortal() + } +} + +dependencyResolutionManagement { + versionCatalogs { + create("libs") { + from(files("../../gradle/libs.versions.toml")) + } + } +} + +// composite graphql-kotlin library build +includeBuild("../..") + +//include(":spring-graalvm-server") +include(":ktor-graalvm-server") diff --git a/plugins/server/graphql-kotlin-graalvm-metadata-generator/src/main/kotlin/com/expediagroup/graphql/plugin/graalvm/GenerateGraalVmMetadata.kt b/plugins/server/graphql-kotlin-graalvm-metadata-generator/src/main/kotlin/com/expediagroup/graphql/plugin/graalvm/GenerateGraalVmMetadata.kt index d26d566bb5..75d207653a 100644 --- a/plugins/server/graphql-kotlin-graalvm-metadata-generator/src/main/kotlin/com/expediagroup/graphql/plugin/graalvm/GenerateGraalVmMetadata.kt +++ b/plugins/server/graphql-kotlin-graalvm-metadata-generator/src/main/kotlin/com/expediagroup/graphql/plugin/graalvm/GenerateGraalVmMetadata.kt @@ -38,6 +38,7 @@ import org.slf4j.Logger import org.slf4j.LoggerFactory import java.io.File import java.nio.file.Files +import java.nio.file.StandardCopyOption import java.util.ServiceLoader private val logger: Logger = LoggerFactory.getLogger("generateGraalVmMetadata") @@ -58,7 +59,7 @@ fun generateGraalVmMetadata(targetDirectory: File, supportedPackages: List - Files.copy(resourceConfigStream, targetDirectory.toPath().resolve("resource-config.json")) + Files.copy(resourceConfigStream, targetDirectory.toPath().resolve("resource-config.json"), StandardCopyOption.REPLACE_EXISTING) } }