From 2a87ca8fb0c93738498089cc4e1779ef7da60199 Mon Sep 17 00:00:00 2001 From: whodevil Date: Sun, 27 Aug 2023 16:49:30 -0700 Subject: [PATCH 1/2] wip --- .idea/gradle.xml | 1 + service/gradle.lockfile | 58 ++++++++++++++++++++++++++++++++++++++ service/service.gradle.kts | 14 +++++++++ 3 files changed, 73 insertions(+) create mode 100644 service/gradle.lockfile create mode 100644 service/service.gradle.kts diff --git a/.idea/gradle.xml b/.idea/gradle.xml index e3cc41d..a707f0b 100644 --- a/.idea/gradle.xml +++ b/.idea/gradle.xml @@ -10,6 +10,7 @@ diff --git a/service/gradle.lockfile b/service/gradle.lockfile new file mode 100644 index 0000000..b6a6941 --- /dev/null +++ b/service/gradle.lockfile @@ -0,0 +1,58 @@ +# This is a Gradle generated file for dependency locking. +# Manual edits can break the build and are not advised. +# This file is expected to be part of source control. +aopalliance:aopalliance:1.0=compileClasspath,runtimeClasspath +ch.qos.logback:logback-classic:1.2.3=compileClasspath,runtimeClasspath +ch.qos.logback:logback-core:1.2.3=compileClasspath,runtimeClasspath +com.fasterxml.jackson.core:jackson-annotations:2.14.2=compileClasspath,runtimeClasspath +com.fasterxml.jackson.core:jackson-core:2.14.2=compileClasspath,runtimeClasspath +com.fasterxml.jackson.core:jackson-databind:2.14.2=compileClasspath,runtimeClasspath +com.fasterxml.jackson:jackson-bom:2.14.2=compileClasspath,runtimeClasspath +com.google.code.findbugs:jsr305:3.0.2=compileClasspath,runtimeClasspath +com.google.errorprone:error_prone_annotations:2.3.4=compileClasspath,runtimeClasspath +com.google.guava:failureaccess:1.0.1=compileClasspath,runtimeClasspath +com.google.guava:guava:30.1-jre=compileClasspath,runtimeClasspath +com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=compileClasspath,runtimeClasspath +com.google.inject:guice:5.1.0=compileClasspath,runtimeClasspath +com.google.j2objc:j2objc-annotations:1.3=compileClasspath,runtimeClasspath +dev.misfitlabs.kotlinguice4:kotlin-guice:1.6.0=compileClasspath,runtimeClasspath +info.offthecob.platform:bom:1.0.11=compileClasspath,runtimeClasspath +info.offthecob.platform:common:1.0.11=compileClasspath,runtimeClasspath +io.github.microutils:kotlin-logging:1.7.6=compileClasspath,runtimeClasspath +io.javalin:javalin:5.6.1=compileClasspath,runtimeClasspath +jakarta.annotation:jakarta.annotation-api:2.1.1=compileClasspath,runtimeClasspath +jakarta.transaction:jakarta.transaction-api:2.0.0=compileClasspath,runtimeClasspath +javax.inject:javax.inject:1=compileClasspath,runtimeClasspath +net.logstash.logback:logstash-logback-encoder:7.3=compileClasspath,runtimeClasspath +org.checkerframework:checker-qual:3.5.0=compileClasspath,runtimeClasspath +org.eclipse.jetty.toolchain:jetty-jakarta-servlet-api:5.0.2=compileClasspath,runtimeClasspath +org.eclipse.jetty.websocket:websocket-core-common:11.0.15=compileClasspath,runtimeClasspath +org.eclipse.jetty.websocket:websocket-core-server:11.0.15=compileClasspath,runtimeClasspath +org.eclipse.jetty.websocket:websocket-jetty-api:11.0.15=compileClasspath,runtimeClasspath +org.eclipse.jetty.websocket:websocket-jetty-common:11.0.15=compileClasspath,runtimeClasspath +org.eclipse.jetty.websocket:websocket-jetty-server:11.0.15=compileClasspath,runtimeClasspath +org.eclipse.jetty.websocket:websocket-servlet:11.0.15=compileClasspath,runtimeClasspath +org.eclipse.jetty:jetty-annotations:11.0.15=compileClasspath,runtimeClasspath +org.eclipse.jetty:jetty-http:11.0.15=compileClasspath,runtimeClasspath +org.eclipse.jetty:jetty-io:11.0.15=compileClasspath,runtimeClasspath +org.eclipse.jetty:jetty-jndi:11.0.15=compileClasspath,runtimeClasspath +org.eclipse.jetty:jetty-plus:11.0.15=compileClasspath,runtimeClasspath +org.eclipse.jetty:jetty-security:11.0.15=compileClasspath,runtimeClasspath +org.eclipse.jetty:jetty-server:11.0.15=compileClasspath,runtimeClasspath +org.eclipse.jetty:jetty-servlet:11.0.15=compileClasspath,runtimeClasspath +org.eclipse.jetty:jetty-util:11.0.15=compileClasspath,runtimeClasspath +org.eclipse.jetty:jetty-webapp:11.0.15=compileClasspath,runtimeClasspath +org.eclipse.jetty:jetty-xml:11.0.15=compileClasspath,runtimeClasspath +org.jetbrains.kotlin:kotlin-reflect:1.4.32=compileClasspath,runtimeClasspath +org.jetbrains.kotlin:kotlin-stdlib-common:1.9.0=compileClasspath,runtimeClasspath +org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.9.0=compileClasspath,runtimeClasspath +org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.9.0=compileClasspath,runtimeClasspath +org.jetbrains.kotlin:kotlin-stdlib:1.9.0=compileClasspath,runtimeClasspath +org.jetbrains:annotations:24.0.1=compileClasspath,runtimeClasspath +org.ow2.asm:asm-commons:9.5=compileClasspath,runtimeClasspath +org.ow2.asm:asm-tree:9.5=compileClasspath,runtimeClasspath +org.ow2.asm:asm:9.5=compileClasspath,runtimeClasspath +org.slf4j:jcl-over-slf4j:1.7.25=compileClasspath,runtimeClasspath +org.slf4j:jul-to-slf4j:1.7.25=compileClasspath,runtimeClasspath +org.slf4j:slf4j-api:2.0.7=compileClasspath,runtimeClasspath +empty=annotationProcessor diff --git a/service/service.gradle.kts b/service/service.gradle.kts new file mode 100644 index 0000000..1e0a620 --- /dev/null +++ b/service/service.gradle.kts @@ -0,0 +1,14 @@ +plugins { + id("info.offthecob.Service") +} + +dependencies { + implementation(platform(libs.offthecob.platform)) + implementation("info.offthecob.platform:common") + implementation(libs.bundles.guice) + implementation(libs.bundles.logging) + implementation(libs.javalin) + + testImplementation(libs.bundles.groovy) + testImplementation(libs.bundles.spock) +} From 6beddf21785d353a452055648bf164c5c7cf1321 Mon Sep 17 00:00:00 2001 From: whodevil Date: Thu, 5 Oct 2023 22:16:34 -0700 Subject: [PATCH 2/2] Add graphql service example This service uses the java graphql api directly, in combination with javalin for the webserver routing. I'm using the dgs library to convert the graphql schema into beans that can be consumed by the graphql api, in the past I've managed those beans directly, and the generation in the library makes it silghtly easier. A more detailed README to come. --- .editorconfig | 2 + .gitignore | 2 + base/gradle.lockfile | 55 +++++++-------- base/src/main/kotlin/BaseModule.kt | 4 +- library/gradle.lockfile | 19 +++++ library/library.gradle.kts | 22 ++++++ library/src/main/resources/schema.graphql | 13 ++++ service/gradle.lockfile | 58 +++++++++------- service/service.gradle.kts | 4 ++ service/src/main/kotlin/DataFetchers.kt | 11 +++ service/src/main/kotlin/GraphQLHandler.kt | 65 +++++++++++++++++ service/src/main/kotlin/ServiceMain.kt | 24 +++++++ service/src/main/kotlin/ServiceModule.kt | 69 +++++++++++++++++++ service/src/main/resources/logback.xml | 11 +++ .../main/resources/static/graphiql/index.html | 55 +++++++++++++++ settings-gradle.lockfile | 2 +- settings.gradle.kts | 5 +- 17 files changed, 364 insertions(+), 57 deletions(-) create mode 100644 .editorconfig create mode 100644 library/gradle.lockfile create mode 100644 library/library.gradle.kts create mode 100644 library/src/main/resources/schema.graphql create mode 100644 service/src/main/kotlin/DataFetchers.kt create mode 100644 service/src/main/kotlin/GraphQLHandler.kt create mode 100644 service/src/main/kotlin/ServiceMain.kt create mode 100644 service/src/main/kotlin/ServiceModule.kt create mode 100644 service/src/main/resources/logback.xml create mode 100644 service/src/main/resources/static/graphiql/index.html diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..34a178f --- /dev/null +++ b/.editorconfig @@ -0,0 +1,2 @@ +[*.{kt,kts}] +ktlint_standard_no-wildcard-imports = disabled diff --git a/.gitignore b/.gitignore index 904f48d..5637fea 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,8 @@ # Ignore Gradle project-specific cache directory .gradle +.fleet # Ignore Gradle build output directory build +.idea/ diff --git a/base/gradle.lockfile b/base/gradle.lockfile index 54ea913..b386fdf 100644 --- a/base/gradle.lockfile +++ b/base/gradle.lockfile @@ -2,42 +2,43 @@ # Manual edits can break the build and are not advised. # This file is expected to be part of source control. aopalliance:aopalliance:1.0=compileClasspath,runtimeClasspath -ch.qos.logback:logback-classic:1.2.3=compileClasspath,runtimeClasspath -ch.qos.logback:logback-core:1.2.3=compileClasspath,runtimeClasspath -com.fasterxml.jackson.core:jackson-annotations:2.14.2=compileClasspath,runtimeClasspath -com.fasterxml.jackson.core:jackson-core:2.14.2=compileClasspath,runtimeClasspath -com.fasterxml.jackson.core:jackson-databind:2.14.2=compileClasspath,runtimeClasspath -com.fasterxml.jackson:jackson-bom:2.14.2=compileClasspath,runtimeClasspath +ch.qos.logback:logback-classic:1.4.11=compileClasspath,runtimeClasspath +ch.qos.logback:logback-core:1.4.11=compileClasspath,runtimeClasspath +com.fasterxml.jackson.core:jackson-annotations:2.15.2=compileClasspath,runtimeClasspath +com.fasterxml.jackson.core:jackson-core:2.15.2=compileClasspath,runtimeClasspath +com.fasterxml.jackson.core:jackson-databind:2.15.2=compileClasspath,runtimeClasspath +com.fasterxml.jackson:jackson-bom:2.15.2=compileClasspath,runtimeClasspath com.google.code.findbugs:jsr305:3.0.2=compileClasspath,runtimeClasspath -com.google.code.gson:gson:2.8.6=compileClasspath,runtimeClasspath -com.google.errorprone:error_prone_annotations:2.3.4=compileClasspath,runtimeClasspath +com.google.code.gson:gson:2.10=compileClasspath,runtimeClasspath +com.google.errorprone:error_prone_annotations:2.7.1=compileClasspath,runtimeClasspath com.google.guava:failureaccess:1.0.1=compileClasspath,runtimeClasspath -com.google.guava:guava:30.1-jre=compileClasspath,runtimeClasspath +com.google.guava:guava:31.0.1-jre=compileClasspath,runtimeClasspath com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=compileClasspath,runtimeClasspath -com.google.inject:guice:5.1.0=compileClasspath,runtimeClasspath +com.google.inject:guice:7.0.0=compileClasspath,runtimeClasspath com.google.j2objc:j2objc-annotations:1.3=compileClasspath,runtimeClasspath -com.konghq:unirest-java:3.11.09=compileClasspath,runtimeClasspath -commons-codec:commons-codec:1.11=compileClasspath,runtimeClasspath +com.konghq:unirest-java:3.14.5=compileClasspath,runtimeClasspath +commons-codec:commons-codec:1.15=compileClasspath,runtimeClasspath commons-logging:commons-logging:1.2=compileClasspath,runtimeClasspath -dev.misfitlabs.kotlinguice4:kotlin-guice:1.6.0=compileClasspath,runtimeClasspath -info.offthecob.platform:bom:1.0.11=compileClasspath,runtimeClasspath -info.offthecob.platform:common:1.0.11=compileClasspath,runtimeClasspath -io.github.microutils:kotlin-logging:1.7.6=compileClasspath,runtimeClasspath -javax.inject:javax.inject:1=compileClasspath,runtimeClasspath -net.logstash.logback:logstash-logback-encoder:7.3=compileClasspath,runtimeClasspath -org.apache.httpcomponents:httpasyncclient:4.1.4=compileClasspath,runtimeClasspath +dev.misfitlabs.kotlinguice4:kotlin-guice:3.0.0=compileClasspath,runtimeClasspath +info.offthecob.platform:bom:1.0.15=compileClasspath,runtimeClasspath +info.offthecob.platform:common:1.0.15=compileClasspath,runtimeClasspath +io.github.microutils:kotlin-logging-jvm:3.0.5=compileClasspath,runtimeClasspath +io.github.microutils:kotlin-logging:3.0.5=compileClasspath,runtimeClasspath +jakarta.inject:jakarta.inject-api:2.0.1=compileClasspath,runtimeClasspath +net.logstash.logback:logstash-logback-encoder:7.4=compileClasspath,runtimeClasspath +org.apache.httpcomponents:httpasyncclient:4.1.5=compileClasspath,runtimeClasspath org.apache.httpcomponents:httpclient:4.5.13=compileClasspath,runtimeClasspath org.apache.httpcomponents:httpcore-nio:4.4.13=compileClasspath,runtimeClasspath org.apache.httpcomponents:httpcore:4.4.13=compileClasspath,runtimeClasspath org.apache.httpcomponents:httpmime:4.5.13=compileClasspath,runtimeClasspath -org.checkerframework:checker-qual:3.5.0=compileClasspath,runtimeClasspath +org.checkerframework:checker-qual:3.12.0=compileClasspath,runtimeClasspath org.jetbrains.kotlin:kotlin-reflect:1.4.32=compileClasspath,runtimeClasspath -org.jetbrains.kotlin:kotlin-stdlib-common:1.9.0=compileClasspath,runtimeClasspath -org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.9.0=compileClasspath,runtimeClasspath -org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.9.0=compileClasspath,runtimeClasspath -org.jetbrains.kotlin:kotlin-stdlib:1.9.0=compileClasspath,runtimeClasspath +org.jetbrains.kotlin:kotlin-stdlib-common:1.9.10=compileClasspath,runtimeClasspath +org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.9.10=compileClasspath,runtimeClasspath +org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.9.10=compileClasspath,runtimeClasspath +org.jetbrains.kotlin:kotlin-stdlib:1.9.10=compileClasspath,runtimeClasspath org.jetbrains:annotations:13.0=compileClasspath,runtimeClasspath -org.slf4j:jcl-over-slf4j:1.7.25=compileClasspath,runtimeClasspath -org.slf4j:jul-to-slf4j:1.7.25=compileClasspath,runtimeClasspath -org.slf4j:slf4j-api:1.7.25=compileClasspath,runtimeClasspath +org.slf4j:jcl-over-slf4j:2.0.9=compileClasspath,runtimeClasspath +org.slf4j:jul-to-slf4j:2.0.9=compileClasspath,runtimeClasspath +org.slf4j:slf4j-api:2.0.9=compileClasspath,runtimeClasspath empty=annotationProcessor diff --git a/base/src/main/kotlin/BaseModule.kt b/base/src/main/kotlin/BaseModule.kt index cc5f67a..0b76bfa 100644 --- a/base/src/main/kotlin/BaseModule.kt +++ b/base/src/main/kotlin/BaseModule.kt @@ -1,13 +1,13 @@ +import com.google.inject.AbstractModule import com.google.inject.Provides import com.google.inject.Singleton import com.google.inject.name.Named -import dev.misfitlabs.kotlinguice4.KotlinModule const val WORD_URL = "word-url" const val MIT_ECPRICE_WORD_LIST = "https://www.mit.edu/~ecprice/wordlist.10000" const val NUMBER_OF_WORDS = "number-of-words" -class BaseModule : KotlinModule() { +class BaseModule : AbstractModule() { @Provides @Singleton @Named(WORD_URL) diff --git a/library/gradle.lockfile b/library/gradle.lockfile new file mode 100644 index 0000000..3b3a45e --- /dev/null +++ b/library/gradle.lockfile @@ -0,0 +1,19 @@ +# This is a Gradle generated file for dependency locking. +# Manual edits can break the build and are not advised. +# This file is expected to be part of source control. +com.fasterxml.jackson.core:jackson-annotations:2.15.2=compileClasspath,runtimeClasspath +com.fasterxml.jackson:jackson-bom:2.15.2=compileClasspath,runtimeClasspath +com.graphql-java:graphql-java:19.2=compileClasspath,runtimeClasspath +com.graphql-java:java-dataloader:3.2.0=compileClasspath,runtimeClasspath +com.netflix.graphql.dgs:graphql-dgs-platform-dependencies:5.5.1=compileClasspath,runtimeClasspath +com.netflix.graphql.dgs:graphql-dgs-platform:5.5.1=compileClasspath,runtimeClasspath +org.jetbrains.kotlin:kotlin-reflect:1.9.0=runtimeClasspath +org.jetbrains.kotlin:kotlin-stdlib-common:1.9.10=compileClasspath,runtimeClasspath +org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.9.10=compileClasspath,runtimeClasspath +org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.9.10=compileClasspath,runtimeClasspath +org.jetbrains.kotlin:kotlin-stdlib:1.9.10=compileClasspath,runtimeClasspath +org.jetbrains:annotations:13.0=compileClasspath,runtimeClasspath +org.reactivestreams:reactive-streams:1.0.3=compileClasspath,runtimeClasspath +org.slf4j:slf4j-api:1.7.30=compileClasspath +org.slf4j:slf4j-api:1.7.35=runtimeClasspath +empty=annotationProcessor diff --git a/library/library.gradle.kts b/library/library.gradle.kts new file mode 100644 index 0000000..ad68125 --- /dev/null +++ b/library/library.gradle.kts @@ -0,0 +1,22 @@ +import com.netflix.graphql.dgs.codegen.gradle.GenerateJavaTask + +plugins { + id("info.offthecob.Library") + id("com.netflix.dgs.codegen") version "6.0.2" +} + +dependencies { + api("com.fasterxml.jackson.core:jackson-annotations:2.15.2") +} + +tasks { + generateJava { + schemaPaths = mutableListOf("$projectDir/src/main/resources") + packageName = "info.offthecob.examples.library" + generateClient = false + language = "kotlin" + } + build { + dependsOn("generateJava") + } +} diff --git a/library/src/main/resources/schema.graphql b/library/src/main/resources/schema.graphql new file mode 100644 index 0000000..ff520ee --- /dev/null +++ b/library/src/main/resources/schema.graphql @@ -0,0 +1,13 @@ +type Word { + characters: String + weight: Int + color: String +} + +input WordsInput { + numberOfWords: Int +} + +type Query { + words(input: WordsInput!): [Word] +} \ No newline at end of file diff --git a/service/gradle.lockfile b/service/gradle.lockfile index b6a6941..45f847b 100644 --- a/service/gradle.lockfile +++ b/service/gradle.lockfile @@ -2,29 +2,37 @@ # Manual edits can break the build and are not advised. # This file is expected to be part of source control. aopalliance:aopalliance:1.0=compileClasspath,runtimeClasspath -ch.qos.logback:logback-classic:1.2.3=compileClasspath,runtimeClasspath -ch.qos.logback:logback-core:1.2.3=compileClasspath,runtimeClasspath -com.fasterxml.jackson.core:jackson-annotations:2.14.2=compileClasspath,runtimeClasspath -com.fasterxml.jackson.core:jackson-core:2.14.2=compileClasspath,runtimeClasspath -com.fasterxml.jackson.core:jackson-databind:2.14.2=compileClasspath,runtimeClasspath -com.fasterxml.jackson:jackson-bom:2.14.2=compileClasspath,runtimeClasspath +ch.qos.logback:logback-classic:1.4.11=compileClasspath,runtimeClasspath +ch.qos.logback:logback-core:1.4.11=compileClasspath,runtimeClasspath +com.fasterxml.jackson.core:jackson-annotations:2.15.2=compileClasspath,runtimeClasspath +com.fasterxml.jackson.core:jackson-core:2.15.2=compileClasspath,runtimeClasspath +com.fasterxml.jackson.core:jackson-databind:2.15.2=compileClasspath,runtimeClasspath +com.fasterxml.jackson:jackson-bom:2.15.2=compileClasspath,runtimeClasspath com.google.code.findbugs:jsr305:3.0.2=compileClasspath,runtimeClasspath -com.google.errorprone:error_prone_annotations:2.3.4=compileClasspath,runtimeClasspath +com.google.code.gson:gson:2.10.1=compileClasspath,runtimeClasspath +com.google.errorprone:error_prone_annotations:2.7.1=compileClasspath,runtimeClasspath com.google.guava:failureaccess:1.0.1=compileClasspath,runtimeClasspath -com.google.guava:guava:30.1-jre=compileClasspath,runtimeClasspath +com.google.guava:guava:31.0.1-jre=compileClasspath,runtimeClasspath com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=compileClasspath,runtimeClasspath -com.google.inject:guice:5.1.0=compileClasspath,runtimeClasspath +com.google.inject:guice:7.0.0=compileClasspath,runtimeClasspath com.google.j2objc:j2objc-annotations:1.3=compileClasspath,runtimeClasspath -dev.misfitlabs.kotlinguice4:kotlin-guice:1.6.0=compileClasspath,runtimeClasspath -info.offthecob.platform:bom:1.0.11=compileClasspath,runtimeClasspath -info.offthecob.platform:common:1.0.11=compileClasspath,runtimeClasspath -io.github.microutils:kotlin-logging:1.7.6=compileClasspath,runtimeClasspath +com.graphql-java:graphql-java:19.2=compileClasspath,runtimeClasspath +com.graphql-java:java-dataloader:3.2.0=compileClasspath,runtimeClasspath +com.netflix.graphql.dgs.codegen:graphql-dgs-codegen-shared-core:6.0.2=runtimeClasspath +com.netflix.graphql.dgs:graphql-dgs-platform-dependencies:5.5.1=runtimeClasspath +com.netflix.graphql.dgs:graphql-dgs-platform:5.5.1=runtimeClasspath +commons-io:commons-io:2.13.0=compileClasspath,runtimeClasspath +dev.misfitlabs.kotlinguice4:kotlin-guice:3.0.0=compileClasspath,runtimeClasspath +info.offthecob.platform:bom:1.0.15=compileClasspath,runtimeClasspath +info.offthecob.platform:common:1.0.15=compileClasspath,runtimeClasspath +io.github.microutils:kotlin-logging-jvm:3.0.5=compileClasspath,runtimeClasspath +io.github.microutils:kotlin-logging:3.0.5=compileClasspath,runtimeClasspath io.javalin:javalin:5.6.1=compileClasspath,runtimeClasspath jakarta.annotation:jakarta.annotation-api:2.1.1=compileClasspath,runtimeClasspath +jakarta.inject:jakarta.inject-api:2.0.1=compileClasspath,runtimeClasspath jakarta.transaction:jakarta.transaction-api:2.0.0=compileClasspath,runtimeClasspath -javax.inject:javax.inject:1=compileClasspath,runtimeClasspath -net.logstash.logback:logstash-logback-encoder:7.3=compileClasspath,runtimeClasspath -org.checkerframework:checker-qual:3.5.0=compileClasspath,runtimeClasspath +net.logstash.logback:logstash-logback-encoder:7.4=compileClasspath,runtimeClasspath +org.checkerframework:checker-qual:3.12.0=compileClasspath,runtimeClasspath org.eclipse.jetty.toolchain:jetty-jakarta-servlet-api:5.0.2=compileClasspath,runtimeClasspath org.eclipse.jetty.websocket:websocket-core-common:11.0.15=compileClasspath,runtimeClasspath org.eclipse.jetty.websocket:websocket-core-server:11.0.15=compileClasspath,runtimeClasspath @@ -43,16 +51,18 @@ org.eclipse.jetty:jetty-servlet:11.0.15=compileClasspath,runtimeClasspath org.eclipse.jetty:jetty-util:11.0.15=compileClasspath,runtimeClasspath org.eclipse.jetty:jetty-webapp:11.0.15=compileClasspath,runtimeClasspath org.eclipse.jetty:jetty-xml:11.0.15=compileClasspath,runtimeClasspath -org.jetbrains.kotlin:kotlin-reflect:1.4.32=compileClasspath,runtimeClasspath -org.jetbrains.kotlin:kotlin-stdlib-common:1.9.0=compileClasspath,runtimeClasspath -org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.9.0=compileClasspath,runtimeClasspath -org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.9.0=compileClasspath,runtimeClasspath -org.jetbrains.kotlin:kotlin-stdlib:1.9.0=compileClasspath,runtimeClasspath +org.jetbrains.kotlin:kotlin-reflect:1.4.32=compileClasspath +org.jetbrains.kotlin:kotlin-reflect:1.9.0=runtimeClasspath +org.jetbrains.kotlin:kotlin-stdlib-common:1.9.10=compileClasspath,runtimeClasspath +org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.9.10=compileClasspath,runtimeClasspath +org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.9.10=compileClasspath,runtimeClasspath +org.jetbrains.kotlin:kotlin-stdlib:1.9.10=compileClasspath,runtimeClasspath org.jetbrains:annotations:24.0.1=compileClasspath,runtimeClasspath org.ow2.asm:asm-commons:9.5=compileClasspath,runtimeClasspath org.ow2.asm:asm-tree:9.5=compileClasspath,runtimeClasspath org.ow2.asm:asm:9.5=compileClasspath,runtimeClasspath -org.slf4j:jcl-over-slf4j:1.7.25=compileClasspath,runtimeClasspath -org.slf4j:jul-to-slf4j:1.7.25=compileClasspath,runtimeClasspath -org.slf4j:slf4j-api:2.0.7=compileClasspath,runtimeClasspath +org.reactivestreams:reactive-streams:1.0.3=compileClasspath,runtimeClasspath +org.slf4j:jcl-over-slf4j:2.0.9=compileClasspath,runtimeClasspath +org.slf4j:jul-to-slf4j:2.0.9=compileClasspath,runtimeClasspath +org.slf4j:slf4j-api:2.0.9=compileClasspath,runtimeClasspath empty=annotationProcessor diff --git a/service/service.gradle.kts b/service/service.gradle.kts index 1e0a620..5313a2e 100644 --- a/service/service.gradle.kts +++ b/service/service.gradle.kts @@ -3,11 +3,15 @@ plugins { } dependencies { + implementation(project(":library")) implementation(platform(libs.offthecob.platform)) implementation("info.offthecob.platform:common") implementation(libs.bundles.guice) implementation(libs.bundles.logging) implementation(libs.javalin) + implementation(libs.gson) + implementation(libs.graphql) + implementation(libs.commons.io) testImplementation(libs.bundles.groovy) testImplementation(libs.bundles.spock) diff --git a/service/src/main/kotlin/DataFetchers.kt b/service/src/main/kotlin/DataFetchers.kt new file mode 100644 index 0000000..1c8d6c5 --- /dev/null +++ b/service/src/main/kotlin/DataFetchers.kt @@ -0,0 +1,11 @@ +import graphql.schema.DataFetcher +import info.offthecob.examples.library.types.Word + +class DataFetchers { + fun getWords(): DataFetcher> { + return DataFetcher> { input -> + input.variables["numberOfWords"] + listOf(Word("dude", 1, "FFFFFF")) + } + } +} diff --git a/service/src/main/kotlin/GraphQLHandler.kt b/service/src/main/kotlin/GraphQLHandler.kt new file mode 100644 index 0000000..4f20e3b --- /dev/null +++ b/service/src/main/kotlin/GraphQLHandler.kt @@ -0,0 +1,65 @@ +import com.google.gson.Gson +import com.google.inject.Inject +import graphql.ExecutionInput +import graphql.ExecutionResult +import graphql.GraphQL +import io.javalin.http.Context +import io.javalin.http.Handler + +data class GraphqlRequest( + val query: String, + val variables: Map?, + val operationName: String?, +) + +class GraphQLHandler @Inject constructor( + private val graphql: GraphQL, + private val gson: Gson, +) : Handler { + override fun handle(ctx: Context) { + if (ctx.body().isEmpty()) { + ctx.status(400) + ctx.result("Bad Request") + } else { + handleGraphqlRequest(ctx) + } + } + + private fun handleGraphqlRequest(ctx: Context) { + val graphqlRequest = gson.fromJson(ctx.body(), GraphqlRequest::class.java) + val executionInput = executionInput(graphqlRequest, ctx) + val executionResult = graphql.execute(executionInput) + handleGraphqlExecutionResult(executionResult, ctx) + } + + private fun handleGraphqlExecutionResult(executionResult: ExecutionResult, ctx: Context) { + if (executionResult.isDataPresent) { + ctx.result(gson.toJson(executionResult.toSpecification())) + ctx.status(200) + } else { + ctx.result("Bad Request") + ctx.status(400) + } + } + + private fun executionInput(graphqlRequest: GraphqlRequest, ctx: Context): ExecutionInput { + val executionInputBuilder = ExecutionInput + .newExecutionInput(graphqlRequest.query) + .context(ctx) + variables(graphqlRequest, executionInputBuilder) + operationName(graphqlRequest, executionInputBuilder) + return executionInputBuilder.build() + } + + private fun operationName(graphqlRequest: GraphqlRequest, executionInputBuilder: ExecutionInput.Builder) { + if (graphqlRequest.operationName?.isNotEmpty() == true) { + executionInputBuilder.operationName(graphqlRequest.operationName) + } + } + + private fun variables(graphqlRequest: GraphqlRequest, executionInputBuilder: ExecutionInput.Builder) { + if (graphqlRequest.variables?.isNotEmpty() == true) { + executionInputBuilder.variables(graphqlRequest.variables) + } + } +} diff --git a/service/src/main/kotlin/ServiceMain.kt b/service/src/main/kotlin/ServiceMain.kt new file mode 100644 index 0000000..63bb2c1 --- /dev/null +++ b/service/src/main/kotlin/ServiceMain.kt @@ -0,0 +1,24 @@ +import com.google.inject.Guice +import com.google.inject.Inject +import dev.misfitlabs.kotlinguice4.getInstance +import io.javalin.Javalin + +fun main() { + Guice + .createInjector(ServiceModule()) + .getInstance() + .apply { + go() + } +} + +class ServiceMain @Inject constructor( + private val javalin: Javalin, + private val graphQLHandler: GraphQLHandler, +) { + fun go() { + javalin + .post("/graphql", graphQLHandler) + .start() + } +} diff --git a/service/src/main/kotlin/ServiceModule.kt b/service/src/main/kotlin/ServiceModule.kt new file mode 100644 index 0000000..efa68f4 --- /dev/null +++ b/service/src/main/kotlin/ServiceModule.kt @@ -0,0 +1,69 @@ +import com.google.inject.AbstractModule +import com.google.inject.Provides +import com.google.inject.Singleton +import com.google.inject.name.Named +import graphql.GraphQL +import graphql.schema.idl.* +import info.offthecob.examples.library.DgsConstants.QUERY.Words +import info.offthecob.examples.library.DgsConstants.QUERY_TYPE +import io.javalin.Javalin +import org.apache.commons.io.IOUtils +import java.io.IOException +import java.nio.charset.StandardCharsets + +const val GRAPHQL_SCHEMA = "graphql-schema" +const val PORT = "port" + +class ServiceModule : AbstractModule() { + + @Provides + @Singleton + fun javalin(): Javalin { + return Javalin.create { config -> + config.staticFiles.add { staticFiles -> + staticFiles.directory = "/static" + } + } + } + + @Provides + @Named(GRAPHQL_SCHEMA) + @Throws(IOException::class) + fun graphQlSchema(): String { + ServiceModule::class.java.getResourceAsStream("/schema.graphql").use { inputStream -> + return IOUtils.toString( + inputStream, + StandardCharsets.UTF_8, + ) + } + } + + @Provides + @Singleton + fun runtimeWiringBuilder(dataFetchers: DataFetchers): RuntimeWiring { + return RuntimeWiring + .newRuntimeWiring() + .type(QUERY_TYPE) { builder -> + builder.dataFetcher(Words, dataFetchers.getWords()) + builder + }.build() + } + + @Provides + @Singleton + @Throws(IOException::class) + fun typeDefinitionRegistryProvider(@Named(GRAPHQL_SCHEMA) schema: String): TypeDefinitionRegistry { + return SchemaParser().parse(schema) + } + + @Provides + @Singleton + fun graphQL( + typeDefinitionRegistry: TypeDefinitionRegistry, + schemaGenerator: SchemaGenerator, + runtimeWiring: RuntimeWiring, + ): GraphQL { + val graphQLSchema = schemaGenerator.makeExecutableSchema(typeDefinitionRegistry, runtimeWiring) + return GraphQL.newGraphQL(graphQLSchema).build() + } +} diff --git a/service/src/main/resources/logback.xml b/service/src/main/resources/logback.xml new file mode 100644 index 0000000..35613bc --- /dev/null +++ b/service/src/main/resources/logback.xml @@ -0,0 +1,11 @@ + + + + %-5level %logger{36} - %msg%n + + + + + + + diff --git a/service/src/main/resources/static/graphiql/index.html b/service/src/main/resources/static/graphiql/index.html new file mode 100644 index 0000000..f632bc8 --- /dev/null +++ b/service/src/main/resources/static/graphiql/index.html @@ -0,0 +1,55 @@ + + + + GraphiQL + + + + + + + + + +
Loading...
+ + + diff --git a/settings-gradle.lockfile b/settings-gradle.lockfile index c769b65..7defbf6 100644 --- a/settings-gradle.lockfile +++ b/settings-gradle.lockfile @@ -1,5 +1,5 @@ # This is a Gradle generated file for dependency locking. # Manual edits can break the build and are not advised. # This file is expected to be part of source control. -info.offthecob.platform:catalog:1.0.11=incomingCatalogForLibs0 +info.offthecob.platform:catalog:1.0.15=incomingCatalogForLibs0 empty= diff --git a/settings.gradle.kts b/settings.gradle.kts index ccf8b16..0946fe8 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("info.offthecob.Settings") version "1.0.11" + id("info.offthecob.Settings") version "1.0.15" } rootProject.name = "offthecob-platform-examples" @@ -11,8 +11,7 @@ dependencyResolutionManagement { versionCatalogs { create("libs") { - from("info.offthecob.platform:catalog:1.0.11") - library("offthecob-platform", "info.offthecob.platform:bom:1.0.11") + from("info.offthecob.platform:catalog:1.0.15") } } }