Skip to content

Commit df360f1

Browse files
committed
graalvm gradle plugin task
1 parent 3333788 commit df360f1

File tree

25 files changed

+569
-0
lines changed

25 files changed

+569
-0
lines changed

integration/graalvm/build.gradle.kts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import java.util.Properties
2+
3+
allprojects {
4+
repositories {
5+
mavenCentral()
6+
mavenLocal {
7+
content {
8+
includeGroup("com.expediagroup")
9+
}
10+
}
11+
}
12+
13+
val properties = Properties()
14+
properties.load(File(rootDir.parentFile.parent, "gradle.properties").inputStream())
15+
for ((key, value) in properties) {
16+
if (!project.ext.has(key.toString())) {
17+
project.ext[key.toString()] = value
18+
}
19+
}
20+
}

integration/graalvm/gradle.properties

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
group = com.expediagroup.graalvm
2+
3+
org.gradle.jvmargs=-Xmx4g -XX:MaxMetaspaceSize=1g
4+
org.gradle.caching=true
5+
org.gradle.parallel=true
6+

integration/graalvm/gradle/wrapper

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../../gradle/wrapper

integration/graalvm/gradlew

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../../gradlew
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
2+
3+
@Suppress("DSL_SCOPE_VIOLATION") // TODO: remove once KTIJ-19369 / Gradle#22797 is fixed
4+
plugins {
5+
alias(libs.plugins.kotlin.jvm)
6+
application
7+
alias(libs.plugins.graalvm.native)
8+
id("com.expediagroup.graphql")
9+
}
10+
11+
dependencies {
12+
implementation("com.expediagroup", "graphql-kotlin-ktor-server")
13+
implementation(libs.logback)
14+
implementation(libs.ktor.server.cio)
15+
testImplementation(libs.kotlin.test)
16+
}
17+
18+
tasks.test {
19+
useJUnitPlatform()
20+
}
21+
22+
tasks.withType<KotlinCompile> {
23+
kotlinOptions.jvmTarget = "17"
24+
}
25+
26+
application {
27+
mainClass.set("com.expediagroup.graalvm.ktor.ApplicationKt")
28+
}
29+
30+
graalvmNative {
31+
toolchainDetection.set(false)
32+
binaries {
33+
named("main") {
34+
fallback.set(false)
35+
verbose.set(true)
36+
37+
buildArgs.add("--initialize-at-build-time=io.ktor,kotlin,ch.qos.logback,org.slf4j")
38+
buildArgs.add("--trace-object-instantiation=java.util.jar.JarFile")
39+
40+
buildArgs.add("-H:+InstallExitHandlers")
41+
buildArgs.add("-H:+ReportUnsupportedElementsAtRuntime")
42+
buildArgs.add("-H:+ReportExceptionStackTraces")
43+
44+
imageName.set("graal-server")
45+
// mainClass.set("org.test.Main")
46+
}
47+
metadataRepository {
48+
enabled.set(true)
49+
}
50+
}
51+
}
52+
53+
val graphQLGraalVmMetadata by tasks.getting(com.expediagroup.graphql.plugin.gradle.tasks.GraphQLGraalVmMetadataTask::class) {
54+
packages.set(listOf("com.expediagroup.graalvm.ktor"))
55+
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
package com.expediagroup.graalvm.ktor
2+
3+
import com.expediagroup.graalvm.ktor.context.CustomContextFactory
4+
import com.expediagroup.graalvm.ktor.hooks.CustomHooks
5+
import com.expediagroup.graalvm.ktor.schema.ArgumentQuery
6+
import com.expediagroup.graalvm.ktor.schema.AsyncQuery
7+
import com.expediagroup.graalvm.ktor.schema.BasicMutation
8+
import com.expediagroup.graalvm.ktor.schema.ContextualQuery
9+
import com.expediagroup.graalvm.ktor.schema.DataClassQuery
10+
import com.expediagroup.graalvm.ktor.schema.EnumQuery
11+
import com.expediagroup.graalvm.ktor.schema.ErrorQuery
12+
import com.expediagroup.graalvm.ktor.schema.ExampleInterface
13+
import com.expediagroup.graalvm.ktor.schema.ExampleUnion
14+
import com.expediagroup.graalvm.ktor.schema.FirstImpl
15+
import com.expediagroup.graalvm.ktor.schema.FirstUnionMember
16+
import com.expediagroup.graalvm.ktor.schema.InnerClassQuery
17+
import com.expediagroup.graalvm.ktor.schema.ListQuery
18+
import com.expediagroup.graalvm.ktor.schema.PolymorphicQuery
19+
import com.expediagroup.graalvm.ktor.schema.ScalarQuery
20+
import com.expediagroup.graalvm.ktor.schema.SecondImpl
21+
import com.expediagroup.graalvm.ktor.schema.SecondUnionMember
22+
import com.expediagroup.graalvm.ktor.schema.TypesQuery
23+
import com.expediagroup.graalvm.ktor.schema.dataloader.ExampleDataLoader
24+
import com.expediagroup.graphql.dataloader.KotlinDataLoaderRegistryFactory
25+
import com.expediagroup.graphql.server.ktor.GraphQL
26+
import com.expediagroup.graphql.server.ktor.graphQLGetRoute
27+
import com.expediagroup.graphql.server.ktor.graphQLPostRoute
28+
import com.expediagroup.graphql.server.ktor.graphQLSDLRoute
29+
import com.expediagroup.graphql.server.ktor.graphiQLRoute
30+
import io.ktor.server.application.install
31+
import io.ktor.server.cio.CIO
32+
import io.ktor.server.engine.embeddedServer
33+
import io.ktor.server.routing.routing
34+
35+
fun main() {
36+
embeddedServer(CIO, port = 8080, host = "0.0.0.0") {
37+
install(GraphQL) {
38+
schema {
39+
packages = listOf("com.expediagroup.graalvm.ktor")
40+
queries = listOf(
41+
ArgumentQuery(),
42+
AsyncQuery(),
43+
ContextualQuery(),
44+
DataClassQuery(),
45+
EnumQuery(),
46+
ErrorQuery(),
47+
InnerClassQuery(),
48+
PolymorphicQuery(),
49+
ScalarQuery(),
50+
TypesQuery(),
51+
ListQuery()
52+
)
53+
mutations = listOf(
54+
BasicMutation()
55+
)
56+
hooks = CustomHooks()
57+
typeHierarchy = mapOf(
58+
ExampleInterface::class to listOf(FirstImpl::class, SecondImpl::class),
59+
ExampleUnion::class to listOf(FirstUnionMember::class, SecondUnionMember::class)
60+
)
61+
}
62+
engine {
63+
dataLoaderRegistryFactory = KotlinDataLoaderRegistryFactory(
64+
ExampleDataLoader
65+
)
66+
}
67+
server {
68+
contextFactory = CustomContextFactory()
69+
}
70+
}
71+
routing {
72+
graphQLGetRoute()
73+
graphQLPostRoute()
74+
graphQLSDLRoute()
75+
graphiQLRoute()
76+
}
77+
}.start(wait = true)
78+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package com.expediagroup.graalvm.ktor.context
2+
3+
import com.expediagroup.graphql.generator.extensions.plus
4+
import com.expediagroup.graphql.server.ktor.DefaultKtorGraphQLContextFactory
5+
import graphql.GraphQLContext
6+
import io.ktor.server.request.ApplicationRequest
7+
import java.util.UUID
8+
9+
class CustomContextFactory : DefaultKtorGraphQLContextFactory() {
10+
override suspend fun generateContext(request: ApplicationRequest): GraphQLContext {
11+
return super.generateContext(request).plus(mapOf("custom" to UUID.randomUUID().toString()))
12+
}
13+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package com.expediagroup.graalvm.ktor.hooks
2+
3+
import com.expediagroup.graphql.generator.hooks.SchemaGeneratorHooks
4+
import graphql.language.StringValue
5+
import graphql.schema.Coercing
6+
import graphql.schema.CoercingParseLiteralException
7+
import graphql.schema.CoercingParseValueException
8+
import graphql.schema.CoercingSerializeException
9+
import graphql.schema.GraphQLScalarType
10+
import graphql.schema.GraphQLType
11+
import java.util.UUID
12+
import kotlin.reflect.KClass
13+
import kotlin.reflect.KType
14+
15+
class CustomHooks : SchemaGeneratorHooks {
16+
override fun willGenerateGraphQLType(type: KType): GraphQLType? = when (type.classifier as? KClass<*>) {
17+
UUID::class -> graphqlUUIDType
18+
else -> null
19+
}
20+
}
21+
22+
val graphqlUUIDType: GraphQLScalarType = GraphQLScalarType.newScalar()
23+
.name("UUID")
24+
.description("A type representing a formatted java.util.UUID")
25+
.coercing(UUIDCoercing)
26+
.build()
27+
28+
object UUIDCoercing : Coercing<UUID, String> {
29+
override fun parseValue(input: Any): UUID = runCatching {
30+
UUID.fromString(serialize(input))
31+
}.getOrElse {
32+
throw CoercingParseValueException("Expected valid UUID but was $input")
33+
}
34+
35+
override fun parseLiteral(input: Any): UUID {
36+
val uuidString = (input as? StringValue)?.value
37+
return runCatching {
38+
UUID.fromString(uuidString)
39+
}.getOrElse {
40+
throw CoercingParseLiteralException("Expected valid UUID literal but was $uuidString")
41+
}
42+
}
43+
44+
override fun serialize(dataFetcherResult: Any): String = runCatching {
45+
dataFetcherResult.toString()
46+
}.getOrElse {
47+
throw CoercingSerializeException("Data fetcher result $dataFetcherResult cannot be serialized to a String")
48+
}
49+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package com.expediagroup.graalvm.ktor.schema
2+
3+
import com.expediagroup.graphql.generator.scalars.ID
4+
import com.expediagroup.graphql.server.operations.Query
5+
import java.util.UUID
6+
7+
class ArgumentQuery : Query {
8+
fun idArg(arg: ID): ID = ID(arg.value.reversed())
9+
fun optionalIdArg(arg: ID? = null): ID? = arg?.let { ID(it.value.reversed()) }
10+
fun stringArg(arg: String): String = arg.reversed()
11+
fun optionalStringArg(arg: String? = null): String? = arg?.reversed()
12+
fun intArg(arg: Int): Int = arg.inc()
13+
fun optionalIntArg(arg: Int? = null): Int? = arg?.inc()
14+
fun doubleArg(arg: Double): Double = arg.inc()
15+
fun optionalDoubleArg(arg: Double? = null): Double? = arg?.inc()
16+
fun booleanArg(arg: Boolean): Boolean = arg.not()
17+
fun optionalBooleanArg(arg: Boolean? = null): Boolean? = arg?.not()
18+
// fun customScalarArg(arg: UUID): UUID = arg
19+
// fun optionalCustomScalarArg(arg: UUID? = null): UUID? = arg
20+
fun manyOptionalArgs(
21+
idArg: ID? = null,
22+
stringArg: String? = null,
23+
intArg: Int? = null,
24+
doubleArg: Double? = null,
25+
booleanArg: Boolean? = null
26+
): String? = if (idArg != null || stringArg != null || intArg != null || doubleArg != null || booleanArg != null) {
27+
"${idArg?.value}|$stringArg|$intArg|$doubleArg|$booleanArg"
28+
} else {
29+
null
30+
}
31+
// fun listArg(arg: List<String>): List<String> = arg.reversed()
32+
// fun optionalListArg(arg: List<String>? = null): List<String>? = arg?.reversed()
33+
fun objectArg(arg: SimpleType): SimpleType = arg
34+
fun optionalObjectArg(arg: SimpleType? = null): SimpleType? = arg
35+
// fun listObjectArg(arg: List<SimpleType>): String = UUID.randomUUID().toString()
36+
}
37+
38+
data class SimpleType(val id: Int, val description: String) {
39+
fun outputOnly(): String = UUID.randomUUID().toString()
40+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package com.expediagroup.graalvm.ktor.schema
2+
3+
import com.expediagroup.graalvm.ktor.schema.dataloader.EXAMPLE_LOADER
4+
import com.expediagroup.graphql.generator.scalars.ID
5+
import com.expediagroup.graphql.server.operations.Query
6+
import graphql.schema.DataFetchingEnvironment
7+
import kotlinx.coroutines.coroutineScope
8+
import kotlinx.coroutines.delay
9+
import java.util.concurrent.CompletableFuture
10+
import kotlin.random.Random
11+
12+
class AsyncQuery : Query {
13+
private val random: Random = Random(100)
14+
15+
fun future(): CompletableFuture<Int> = CompletableFuture.completedFuture(random.nextInt())
16+
17+
fun dataLoader(env: DataFetchingEnvironment, id: ID): CompletableFuture<String> = env.getDataLoader<ID, String>(EXAMPLE_LOADER).load(id)
18+
19+
suspend fun coroutine(): Int = coroutineScope {
20+
delay(10)
21+
random.nextInt()
22+
}
23+
24+
// TODO reactor monads
25+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package com.expediagroup.graalvm.ktor.schema
2+
3+
import com.expediagroup.graphql.server.operations.Mutation
4+
5+
class BasicMutation : Mutation {
6+
fun mutate(arg: String): String = arg.reversed()
7+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package com.expediagroup.graalvm.ktor.schema
2+
3+
import com.expediagroup.graphql.server.operations.Query
4+
import graphql.schema.DataFetchingEnvironment
5+
6+
class ContextualQuery : Query {
7+
fun contextualQuery(env: DataFetchingEnvironment): String = env.graphQlContext.getOrDefault("custom", "defaultValue")
8+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package com.expediagroup.graalvm.ktor.schema
2+
3+
import com.expediagroup.graphql.generator.scalars.ID
4+
import com.expediagroup.graphql.server.operations.Query
5+
import java.util.UUID
6+
import kotlin.random.Random
7+
8+
private val random: Random = Random(100)
9+
10+
class DataClassQuery : Query {
11+
fun dataClassQuery(): ExampleDataClass = ExampleDataClass(
12+
id = ID(UUID.randomUUID().toString()),
13+
nullableId = null,
14+
idList = listOf(ID(UUID.randomUUID().toString())),
15+
nullableIdList = null,
16+
stringValue = UUID.randomUUID().toString(),
17+
nullableString = null,
18+
stringList = listOf(UUID.randomUUID().toString()),
19+
nullableStringList = null,
20+
intValue = random.nextInt(),
21+
nullableInt = null,
22+
doubleValue = random.nextDouble(),
23+
nullableDouble = null,
24+
booleanValue = random.nextBoolean(),
25+
nullableBoolean = null
26+
)
27+
fun dataClassWithDefaultsQuery(): DefaultsDataClass = DefaultsDataClass()
28+
29+
fun dataClassList(): List<ExampleDataClass> = listOf(dataClassQuery())
30+
31+
fun dataClassArgQuery(arg: List<DefaultsDataClass>? = null) = arg
32+
}
33+
34+
data class ExampleDataClass(
35+
val id: ID,
36+
val nullableId: ID?,
37+
val idList: List<ID>,
38+
val nullableIdList: List<ID>?,
39+
val stringValue: String,
40+
val nullableString: String?,
41+
val stringList: List<String>,
42+
val nullableStringList: List<String>?,
43+
val intValue: Int,
44+
val nullableInt: Int?,
45+
val doubleValue: Double,
46+
val nullableDouble: Double?,
47+
val booleanValue: Boolean,
48+
val nullableBoolean: Boolean?,
49+
)
50+
51+
data class DefaultsDataClass(
52+
val id: ID = ID(UUID.randomUUID().toString()),
53+
val nullableId: ID? = null,
54+
val idList: List<ID> = listOf(ID(UUID.randomUUID().toString())),
55+
val nullableIdList: List<ID>? = null,
56+
val stringValue: String = UUID.randomUUID().toString(),
57+
val stringList: List<String> = listOf(UUID.randomUUID().toString()),
58+
val nullableStringList: List<String>? = null,
59+
val nullableString: String? = null,
60+
val intValue: Int = random.nextInt(),
61+
val nullableInt: Int? = null,
62+
val doubleValue: Double = random.nextDouble(),
63+
val nullableDouble: Double? = null,
64+
val booleanValue: Boolean = random.nextBoolean(),
65+
val nullableBoolean: Boolean? = null
66+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package com.expediagroup.graalvm.ktor.schema
2+
3+
import com.expediagroup.graphql.server.operations.Query
4+
5+
class EnumQuery : Query {
6+
fun enumQuery(): BinaryEnum = BinaryEnum.ONE
7+
fun enumArgQuery(arg: BinaryEnum): BinaryEnum = arg
8+
fun optionalEnum(arg: BinaryEnum? = null): BinaryEnum? = arg
9+
}
10+
11+
enum class BinaryEnum {
12+
ZERO,
13+
ONE
14+
}

0 commit comments

Comments
 (0)