Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions graphql-kotlin-federation/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@
<artifactId>graphql-kotlin-schema-generator</artifactId>
<version>${project.parent.version}</version>
</dependency>
<dependency>
<groupId>io.github.classgraph</groupId>
<artifactId>classgraph</artifactId>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-params</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@ import com.expediagroup.graphql.TopLevelObject
import com.expediagroup.graphql.federation.directives.ExtendsDirective
import com.expediagroup.graphql.generator.SchemaGenerator
import graphql.schema.GraphQLSchema
import org.reflections.Reflections
import io.github.classgraph.ClassGraph
import kotlin.reflect.full.createType
import kotlin.reflect.jvm.jvmName

/**
* Generates federated GraphQL schemas based on the specified configuration.
Expand All @@ -41,10 +42,12 @@ open class FederatedSchemaGenerator(generatorConfig: FederatedSchemaGeneratorCon
/**
* Scans specified packages for all the federated (extended) types and adds them to the target schema.
*/
@Suppress("Detekt.SpreadOperator")
fun GraphQLSchema.Builder.federation(supportedPackages: List<String>): GraphQLSchema.Builder {
supportedPackages
.map { pkg -> Reflections(pkg).getTypesAnnotatedWith(ExtendsDirective::class.java).map { it.kotlin } }
.flatten()
val scanResult = ClassGraph().enableAllInfo().whitelistPackages(*supportedPackages.toTypedArray()).scan()

scanResult.getClassesWithAnnotation(ExtendsDirective::class.jvmName)
.map { it.loadClass().kotlin }
.map {
val graphQLType = if (it.isAbstract) {
interfaceType(it)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,12 @@ package com.expediagroup.graphql.federation

import com.expediagroup.graphql.TopLevelObject
import com.expediagroup.graphql.extensions.print
import com.expediagroup.graphql.federation.data.queries.simple.NestedQuery
import com.expediagroup.graphql.federation.data.queries.simple.SimpleQuery
import com.expediagroup.graphql.federation.execution.FederatedTypeRegistry
import graphql.schema.GraphQLUnionType
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test
import test.data.queries.simple.NestedQuery
import test.data.queries.simple.SimpleQuery
import kotlin.test.assertNotNull
import kotlin.test.assertTrue

Expand Down Expand Up @@ -104,7 +104,7 @@ class FederatedSchemaGeneratorTest {
@Test
fun `verify can generate federated schema`() {
val config = FederatedSchemaGeneratorConfig(
supportedPackages = listOf("test.data.queries.federated"),
supportedPackages = listOf("com.expediagroup.graphql.federation.data.queries.federated"),
hooks = FederatedSchemaGeneratorHooks(FederatedTypeRegistry())
)

Expand Down Expand Up @@ -137,7 +137,7 @@ class FederatedSchemaGeneratorTest {
""".trimIndent()

val config = FederatedSchemaGeneratorConfig(
supportedPackages = listOf("test.data.queries.simple"),
supportedPackages = listOf("com.expediagroup.graphql.federation.data.queries.simple"),
hooks = FederatedSchemaGeneratorHooks(FederatedTypeRegistry())
)

Expand Down Expand Up @@ -169,7 +169,7 @@ class FederatedSchemaGeneratorTest {
""".trimIndent()

val config = FederatedSchemaGeneratorConfig(
supportedPackages = listOf("test.data.queries.simple"),
supportedPackages = listOf("com.expediagroup.graphql.federation.data.queries.simple"),
hooks = FederatedSchemaGeneratorHooks(FederatedTypeRegistry())
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@
* limitations under the License.
*/

package test.data
package com.expediagroup.graphql.federation.data

import com.expediagroup.graphql.federation.data.queries.federated.Book
import com.expediagroup.graphql.federation.data.queries.federated.User
import com.expediagroup.graphql.federation.execution.FederatedTypeResolver
import test.data.queries.federated.Book
import test.data.queries.federated.User

internal class BookResolver : FederatedTypeResolver<Book> {
override suspend fun resolve(representations: List<Map<String, Any>>): List<Book?> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
*/

package test.data
package com.expediagroup.graphql.federation.data

import com.expediagroup.graphql.federation.FederatedSchemaGeneratorConfig
import com.expediagroup.graphql.federation.FederatedSchemaGeneratorHooks
Expand All @@ -25,7 +25,7 @@ import graphql.schema.GraphQLSchema

internal fun federatedTestSchema(federatedTypeResolvers: Map<String, FederatedTypeResolver<*>> = emptyMap()): GraphQLSchema {
val config = FederatedSchemaGeneratorConfig(
supportedPackages = listOf("test.data.queries.federated"),
supportedPackages = listOf("com.expediagroup.graphql.federation.data.queries.federated"),
hooks = FederatedSchemaGeneratorHooks(FederatedTypeRegistry(federatedTypeResolvers))
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
*/

package test.data.queries.federated
package com.expediagroup.graphql.federation.data.queries.federated

import com.expediagroup.graphql.annotations.GraphQLDirective
import com.expediagroup.graphql.annotations.GraphQLIgnore
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
*/

package test.data.queries.simple
package com.expediagroup.graphql.federation.data.queries.simple

import kotlin.random.Random

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
* limitations under the License.
*/

package test.data.queries.simple
package com.expediagroup.graphql.federation.data.queries.simple

/*
type Query {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ import io.mockk.every
import io.mockk.mockk
import io.mockk.spyk
import org.junit.jupiter.api.Test
import test.data.BookResolver
import test.data.UserResolver
import test.data.queries.federated.Book
import test.data.queries.federated.User
import com.expediagroup.graphql.federation.data.BookResolver
import com.expediagroup.graphql.federation.data.UserResolver
import com.expediagroup.graphql.federation.data.queries.federated.Book
import com.expediagroup.graphql.federation.data.queries.federated.User
import kotlin.test.assertEquals

class EntityQueryResolverTest {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ package com.expediagroup.graphql.federation.execution
import graphql.ExecutionInput
import graphql.GraphQL
import org.junit.jupiter.api.Test
import test.data.BookResolver
import test.data.UserResolver
import test.data.federatedTestSchema
import com.expediagroup.graphql.federation.data.BookResolver
import com.expediagroup.graphql.federation.data.UserResolver
import com.expediagroup.graphql.federation.data.federatedTestSchema
import kotlin.test.assertEquals
import kotlin.test.assertFalse
import kotlin.test.assertNotNull
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@ import com.expediagroup.graphql.federation.toFederatedSchema
import graphql.ExecutionInput
import graphql.GraphQL
import org.junit.jupiter.api.Test
import test.data.queries.simple.NestedQuery
import test.data.queries.simple.SimpleQuery
import com.expediagroup.graphql.federation.data.queries.simple.NestedQuery
import com.expediagroup.graphql.federation.data.queries.simple.SimpleQuery
import kotlin.test.assertEquals
import kotlin.test.assertNotNull

Expand Down Expand Up @@ -72,7 +72,7 @@ class ServiceQueryResolverTest {
@Test
fun `verify can retrieve SDL using _service query`() {
val config = FederatedSchemaGeneratorConfig(
supportedPackages = listOf("test.data.queries.federated"),
supportedPackages = listOf("com.expediagroup.graphql.federation.data.queries.federated"),
hooks = FederatedSchemaGeneratorHooks(FederatedTypeRegistry())
)

Expand Down Expand Up @@ -101,7 +101,7 @@ class ServiceQueryResolverTest {
@Test
fun `verify can retrieve SDL using _service query for non-federated schemas`() {
val config = FederatedSchemaGeneratorConfig(
supportedPackages = listOf("test.data.queries.simple"),
supportedPackages = listOf("com.expediagroup.graphql.federation.data.queries.simple"),
hooks = FederatedSchemaGeneratorHooks(FederatedTypeRegistry())
)

Expand Down
10 changes: 8 additions & 2 deletions graphql-kotlin-schema-generator/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
<properties>
<project.root>${project.basedir}/..</project.root>
<rxjava2.version>2.2.12</rxjava2.version>
<guava.version>28.0-jre</guava.version>
</properties>

<dependencies>
Expand All @@ -32,8 +33,13 @@
<artifactId>kotlin-reflect</artifactId>
</dependency>
<dependency>
<groupId>org.reflections</groupId>
<artifactId>reflections</artifactId>
<groupId>io.github.classgraph</groupId>
<artifactId>classgraph</artifactId>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>${guava.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,35 @@

package com.expediagroup.graphql.generator

import org.reflections.Reflections
import io.github.classgraph.ClassGraph
import io.github.classgraph.ClassInfo
import io.github.classgraph.ClassInfoList
import kotlin.reflect.KClass
import kotlin.reflect.jvm.jvmName

internal class SubTypeMapper(supportedPackages: List<String>) {

private val reflections = Reflections(supportedPackages)
@Suppress("Detekt.SpreadOperator")
private val scanResult = ClassGraph()
.enableAllInfo()
.whitelistPackages(*supportedPackages.toTypedArray())
.scan()

fun getSubTypesOf(kclass: KClass<*>): List<KClass<*>> = reflections.getSubTypesOf(kclass.java).filterNot { it.kotlin.isAbstract }.map { it.kotlin }
fun getSubTypesOf(kclass: KClass<*>): List<KClass<*>> {
val classInfo = scanResult.getClassInfo(kclass.jvmName) ?: return emptyList()

return getImplementingClasses(classInfo)
.union(classInfo.subclasses)
.map { it.loadClass().kotlin }
.filterNot { it.isAbstract }
}

@Suppress("Detekt.SwallowedException")
private fun getImplementingClasses(classInfo: ClassInfo) =
try {
classInfo.classesImplementing
} catch (e: IllegalArgumentException) {
// Ignored, just return empty list
ClassInfoList.emptyList()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ import kotlin.test.assertEquals
@Suppress("Detekt.UnusedPrivateClass")
internal class SubTypeMapperTest {

private interface NoSubTypesInterface

private abstract class NoSubTypesClass

private interface MyInterface {
fun getValue(): Int
}
Expand Down Expand Up @@ -75,4 +79,20 @@ internal class SubTypeMapperTest {

assertEquals(expected = 0, actual = list.size)
}

@Test
fun `interface with no subtypes`() {
val mapper = SubTypeMapper(listOf("com.expediagroup.graphql"))
val list = mapper.getSubTypesOf(NoSubTypesInterface::class)

assertEquals(expected = 0, actual = list.size)
}

@Test
fun `abstract class with no subtypes`() {
val mapper = SubTypeMapper(listOf("com.expediagroup.graphql"))
val list = mapper.getSubTypesOf(NoSubTypesClass::class)

assertEquals(expected = 0, actual = list.size)
}
}
8 changes: 4 additions & 4 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@
<jackson-module-kotlin.version>2.10.0</jackson-module-kotlin.version>
<kotlin.version>1.3.50</kotlin.version>
<kotlin-coroutines.version>1.3.2</kotlin-coroutines.version>
<reflections.version>0.9.11</reflections.version>
<classgraph.version>4.8.52</classgraph.version>
<spring-boot.version>2.2.0.RELEASE</spring-boot.version>

<!-- Test Dependency Versions -->
Expand Down Expand Up @@ -273,9 +273,9 @@
<version>${kotlin.version}</version>
</dependency>
<dependency>
<groupId>org.reflections</groupId>
<artifactId>reflections</artifactId>
<version>${reflections.version}</version>
<groupId>io.github.classgraph</groupId>
<artifactId>classgraph</artifactId>
<version>${classgraph.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.module</groupId>
Expand Down