Skip to content

Commit e579cd2

Browse files
claymccoyAndy2003jexp
authored
update graphql-java to version 15 (#120)
* update graphql-java to version 15 This is an old version of a core dependency used in most graphql related projects in java. If this dependency isn't updated then you have conflicts with incompatible transitive versions of graphql-java. Unfortunately, it looks like a committer to graphql-java likes to make backwards a lot of uneccessarily incompatible changes to the library. So I had to make a lot of changes for this to compile and for the tests to pass. I had to do some archeology in the history of graphql-java to understand some of the changes. * GraphQLType.name no longer exists. simplePrint(GraphQLType) is used instead * GraphQLFieldDefinition is no longer a GraphQLType, but it looks like GraphQLFieldDefinition.originalType will get the type we are looking for. * ScalarInfo.STANDARD_SCALAR_DEFINITIONS was replaced with ScalarInfo.GRAPHQL_SPECIFICATION_SCALARS_DEFINITIONS * The value generic for the return type of GraphQLSchema.typeMap is now more specific so BuildingEnv's constructor had to change. * ShemaPrinter lost some include methods. One was previously mispelled. * DefaultSchemaPrinterComparatorRegistry became DefaultGraphqlTypeComparatorRegistry. I had to make some changes to the tests to make them pass, which makes me quite uncomfortable with this. Please check these over to see if I should have made more changes. I'm going ahead with this because the overall functionality still seems legit. I have no idea why these were needed. * In translator-tests1 'render values' I had to move the clauses of the where clause around. It mateches the order of the cypher params now, so it kind of makes sense. * The one line GraphQL query no longer works. It had to be broken up to multilines in several tests. * relationship-tests is a weird one. I changed the generated Cypher, but it makes more sense now. The relationship is player through memberships to team. So `playerMembershipsTeam: Team` makes a lot more sense than the original `playerMembershipsPlayer: Player`. It actually looks like it was incorrect originally. * adjustments for graphql-java update Co-authored-by: Andreas Berger <andreas@berger-ecommerce.com> Co-authored-by: Michael Hunger <github@jexp.de>
1 parent b419d00 commit e579cd2

File tree

9 files changed

+53
-60
lines changed

9 files changed

+53
-60
lines changed

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@
8888
<dependency>
8989
<groupId>com.graphql-java</groupId>
9090
<artifactId>graphql-java</artifactId>
91-
<version>12.0</version>
91+
<version>15.0</version>
9292
</dependency>
9393
<dependency>
9494
<groupId>org.junit.jupiter</groupId>

src/main/kotlin/org/neo4j/graphql/BuildingEnv.kt

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@ package org.neo4j.graphql
33
import graphql.Scalars
44
import graphql.schema.*
55

6-
class BuildingEnv(val types: MutableMap<String, GraphQLType>) {
6+
import graphql.schema.GraphQLTypeUtil.simplePrint
7+
8+
class BuildingEnv(val types: MutableMap<String, GraphQLNamedType>) {
79

810
private val typesForRelation = types.values
911
.filterIsInstance<GraphQLObjectType>()
@@ -23,7 +25,7 @@ class BuildingEnv(val types: MutableMap<String, GraphQLType>) {
2325
type = GraphQLNonNull(type)
2426
}
2527
return GraphQLFieldDefinition.newFieldDefinition()
26-
.name("$prefix${resultType.name}")
28+
.name("$prefix${simplePrint(resultType)}")
2729
.arguments(getInputValueDefinitions(scalarFields, forceOptionalProvider))
2830
.type(type.ref() as GraphQLOutputType)
2931
}
@@ -71,7 +73,7 @@ class BuildingEnv(val types: MutableMap<String, GraphQLType>) {
7173
}
7274
val existingFilterType = types[filterName]
7375
if (existingFilterType != null) {
74-
return (existingFilterType as? GraphQLInputType)?.name
76+
return simplePrint(existingFilterType as? GraphQLInputType)
7577
?: throw IllegalStateException("Filter type $filterName is already defined but not an input type")
7678
}
7779
createdTypes.add(filterName)
@@ -87,7 +89,7 @@ class BuildingEnv(val types: MutableMap<String, GraphQLType>) {
8789
.forEach { field ->
8890
val typeDefinition = field.type.inner()
8991
val filterType = when {
90-
typeDefinition.isNeo4jType() -> getInputType(typeDefinition).name
92+
typeDefinition.isNeo4jType() -> getInputType(typeDefinition).requiredName()
9193
typeDefinition.isScalar() -> typeDefinition.innerName()
9294
typeDefinition is GraphQLEnumType -> typeDefinition.innerName()
9395
else -> addFilterType(getInnerFieldsContainer(typeDefinition), createdTypes)
@@ -122,7 +124,7 @@ class BuildingEnv(val types: MutableMap<String, GraphQLType>) {
122124
val orderingName = "_${type.name}Ordering"
123125
var existingOrderingType = types[orderingName]
124126
if (existingOrderingType != null) {
125-
return (existingOrderingType as? GraphQLInputType)?.name
127+
return (existingOrderingType as? GraphQLInputType)?.requiredName()
126128
?: throw IllegalStateException("Ordering type $type.name is already defined but not an input type")
127129
}
128130
val sortingFields = type.fieldDefinitions
@@ -190,7 +192,7 @@ class BuildingEnv(val types: MutableMap<String, GraphQLType>) {
190192
?: throw IllegalArgumentException("${innerType.name} is unknown")
191193
}
192194
return innerType as? GraphQLFieldsContainer
193-
?: throw IllegalArgumentException("${innerType.name} is neither an object nor an interface")
195+
?: throw IllegalArgumentException("${innerType.name()} is neither an object nor an interface")
194196
}
195197

196198
private fun getInputType(type: GraphQLType): GraphQLInputType {
@@ -200,12 +202,12 @@ class BuildingEnv(val types: MutableMap<String, GraphQLType>) {
200202
}
201203
if (inner.isNeo4jType()) {
202204
return neo4jTypeDefinitions
203-
.find { it.typeDefinition == inner.name }
205+
.find { it.typeDefinition == inner.name() }
204206
?.let { types[it.inputDefinition] } as? GraphQLInputType
205-
?: throw IllegalArgumentException("Cannot find input type for ${inner.name}")
207+
?: throw IllegalArgumentException("Cannot find input type for ${inner.name()}")
206208
}
207209
return type as? GraphQLInputType
208-
?: throw IllegalArgumentException("${type.name} is not allowed for input")
210+
?: throw IllegalArgumentException("${type.name()} is not allowed for input")
209211
}
210212

211-
}
213+
}

src/main/kotlin/org/neo4j/graphql/GraphQLExtensions.kt

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,11 @@ fun GraphQLType.inner(): GraphQLType = when (this) {
3333
else -> this
3434
}
3535

36+
fun GraphQLType.name(): String? = (this as? GraphQLNamedType)?.name
37+
fun GraphQLType.requiredName(): String = requireNotNull(name()) { -> "name is required but cannot be determined for " + this.javaClass }
38+
3639
fun GraphQLType.isList() = this is GraphQLList || (this is GraphQLNonNull && this.wrappedType is GraphQLList)
37-
fun GraphQLType.isScalar() = this.inner().let { it is GraphQLScalarType || it.name.startsWith("_Neo4j") }
40+
fun GraphQLType.isScalar() = this.inner().let { it is GraphQLScalarType || it.innerName().startsWith("_Neo4j") }
3841
fun GraphQLType.isNeo4jType() = this.innerName().startsWith("_Neo4j")
3942
fun GraphQLType.isNeo4jSpatialType() = this.innerName().startsWith("_Neo4jPoint")
4043
fun GraphQLFieldDefinition.isNeo4jType(): Boolean = this.type.isNeo4jType()
@@ -119,7 +122,7 @@ fun GraphQLType.ref(): GraphQLType = when (this) {
119122
is GraphQLScalarType -> this
120123
is GraphQLEnumType -> this
121124
is GraphQLTypeReference -> this
122-
else -> GraphQLTypeReference(name)
125+
else -> GraphQLTypeReference(name())
123126
}
124127

125128
fun relDetails(type: GraphQLFieldsContainer, relDirective: GraphQLDirective): RelationshipInfo {
@@ -183,7 +186,8 @@ data class RelationshipInfo(
183186
}
184187

185188
fun Field.aliasOrName() = (this.alias ?: this.name).quote()
186-
fun GraphQLType.innerName(): String = inner().name
189+
fun GraphQLType.innerName(): String = inner().name()
190+
?: throw IllegalStateException("inner name cannot be retrieved for " + this.javaClass)
187191

188192
fun GraphQLFieldDefinition.propertyName() = getDirectiveArgument(PROPERTY, PROPERTY_NAME, this.name)!!
189193

src/main/kotlin/org/neo4j/graphql/Neo4jTypes.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ data class Neo4jQueryConversion(val name: String, val propertyName: String, val
5858
if (!isNeo4jType) {
5959
Neo4jQueryConversion(name, name)
6060
}
61-
val converter = getNeo4jTypeConverter(fieldDefinition.type.inner().name)
61+
val converter = getNeo4jTypeConverter(fieldDefinition.type.innerName())
6262
val objectValue = (value as? ObjectValue)
6363
?.objectFields
6464
?.map { it.name to it.value }
@@ -80,4 +80,4 @@ val neo4jTypeDefinitions = listOf(
8080
TypeDefinition("Time", "_Neo4jLocalTime"),
8181
TypeDefinition("LocalDateTime", "_Neo4jLocalDateTime"),
8282
TypeDefinition("Point", "_Neo4jPoint")
83-
)
83+
)

src/main/kotlin/org/neo4j/graphql/Predicates.kt

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ data class ExpressionPredicate(
112112
) : Predicate {
113113
val not = if (op.not) "NOT " else ""
114114
override fun toExpression(variable: String): Cypher {
115-
val paramName: String = ProjectionBase.FILTER + paramName(variable, name, value).capitalize() + "_" + op.name + nestedField.replace('.','_')
115+
val paramName: String = ProjectionBase.FILTER + paramName(variable, name, value).capitalize() + "_" + op.name + nestedField.replace('.', '_')
116116
val query = if (fieldDefinition.isNativeId()) {
117117
if (op.list) {
118118
"${not}ID($variable) ${op.op} [id IN \$$paramName | toInteger(id)]"
@@ -151,7 +151,7 @@ data class RelationPredicate(val fieldName: String, val op: RelationOperator, va
151151
RelationOperator.NOT -> "ALL" // bc of not
152152
else -> op.op
153153
}
154-
if (type.getFieldDefinition(fieldName).isList()) {
154+
if (type.getFieldDefinition(fieldName).type.isList()) {
155155
if (op == RelationOperator.EQ_OR_NOT_EXISTS) {
156156
LOGGER.info("$fieldName on type ${type.name} was used for filtering, consider using ${fieldName}${RelationOperator.EVERY.suffix} instead")
157157
}
@@ -254,7 +254,7 @@ enum class FieldOperator(
254254
fun resolve(queriedField: String, field: GraphQLFieldDefinition, value: Any?): FieldOperator? {
255255
val fieldName = field.name
256256
if (value == null) {
257-
return listOf(IS_NULL, IS_NOT_NULL).find { queriedField == fieldName + it.suffix } ?: return null
257+
return listOf(IS_NULL, IS_NOT_NULL).find { queriedField == fieldName + it.suffix }
258258
}
259259
val ops = enumValues<FieldOperator>().filterNot { it == IS_NULL || it == IS_NOT_NULL }
260260
return ops.find { queriedField == fieldName + it.suffix }
@@ -263,7 +263,6 @@ enum class FieldOperator(
263263
} else {
264264
null
265265
}
266-
?: return null
267266
}
268267

269268
fun forType(type: GraphQLType): List<FieldOperator> =
@@ -277,7 +276,7 @@ enum class FieldOperator(
277276
// todo list types
278277
!type.isScalar() -> listOf(EQ, NEQ, IN, NIN)
279278
else -> listOf(EQ, NEQ, IN, NIN, LT, LTE, GT, GTE) +
280-
if (type.name == "String" || type.name == "ID") listOf(C, NC, SW, NSW, EW, NEW) else emptyList()
279+
if (type.name() == "String" || type.name() == "ID") listOf(C, NC, SW, NSW, EW, NEW) else emptyList()
281280
}
282281
}
283282

src/main/kotlin/org/neo4j/graphql/SchemaBuilder.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import graphql.Scalars
44
import graphql.language.*
55
import graphql.schema.*
66
import graphql.schema.idl.RuntimeWiring
7-
import graphql.schema.idl.ScalarInfo.STANDARD_SCALAR_DEFINITIONS
7+
import graphql.schema.idl.ScalarInfo.GRAPHQL_SPECIFICATION_SCALARS_DEFINITIONS
88
import graphql.schema.idl.SchemaGenerator
99
import graphql.schema.idl.SchemaParser
1010
import graphql.schema.idl.TypeDefinitionRegistry
@@ -43,7 +43,7 @@ object SchemaBuilder {
4343

4444
val builder = RuntimeWiring.newRuntimeWiring()
4545
typeDefinitionRegistry.scalars()
46-
.filterNot { entry -> STANDARD_SCALAR_DEFINITIONS.containsKey(entry.key) }
46+
.filterNot { entry -> GRAPHQL_SPECIFICATION_SCALARS_DEFINITIONS.containsKey(entry.key) }
4747
.forEach { (name, definition) ->
4848
val scalar = when (name) {
4949
"DynamicProperties" -> DynamicProperties.INSTANCE

src/test/kotlin/org/neo4j/graphql/TranslatorExceptionTests.kt

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,16 +16,26 @@ class TranslatorExceptionTests : AsciiDocTestSuite("translator-tests1.adoc") {
1616
}
1717

1818
override fun schemaTestFactory(schema: String): List<DynamicNode> {
19-
val translator = Translator(SchemaBuilder.buildSchema(schema));
19+
val translator = Translator(SchemaBuilder.buildSchema(schema))
2020
return listOf(
2121
DynamicTest.dynamicTest("unknownType") {
2222
Assertions.assertThrows(IllegalArgumentException::class.java) {
23-
translator.translate(" { company { name } } ")
23+
translator.translate("""
24+
{
25+
company {
26+
name
27+
}
28+
}
29+
""")
2430
}
2531
},
2632
DynamicTest.dynamicTest("mutation") {
2733
Assertions.assertThrows(InvalidSyntaxException::class.java) {
28-
translator.translate(" { createPerson() } ")
34+
translator.translate("""
35+
{
36+
createPerson()
37+
}
38+
""".trimIndent())
2939
}
3040
}
3141

src/test/kotlin/org/neo4j/graphql/utils/GraphQLSchemaTestSuite.kt

Lines changed: 8 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,23 @@
11
package org.neo4j.graphql.utils
22

33
import graphql.language.InterfaceTypeDefinition
4-
import graphql.schema.GraphQLFieldDefinition
5-
import graphql.schema.GraphQLObjectType
64
import graphql.schema.GraphQLSchema
75
import graphql.schema.GraphQLType
86
import graphql.schema.diff.DiffSet
97
import graphql.schema.diff.SchemaDiff
108
import graphql.schema.diff.reporting.CapturingReporter
11-
import graphql.schema.idl.*
9+
import graphql.schema.idl.RuntimeWiring
10+
import graphql.schema.idl.SchemaGenerator
11+
import graphql.schema.idl.SchemaParser
12+
import graphql.schema.idl.SchemaPrinter
1213
import org.assertj.core.api.Assertions.assertThat
1314
import org.junit.jupiter.api.Assumptions
1415
import org.junit.jupiter.api.DynamicNode
1516
import org.junit.jupiter.api.DynamicTest
1617
import org.neo4j.graphql.DynamicProperties
1718
import org.neo4j.graphql.SchemaBuilder
1819
import org.neo4j.graphql.SchemaConfig
20+
import org.neo4j.graphql.requiredName
1921
import org.opentest4j.AssertionFailedError
2022
import java.util.*
2123
import java.util.regex.Pattern
@@ -76,40 +78,16 @@ class GraphQLSchemaTestSuite(fileName: String) : AsciiDocTestSuite(fileName) {
7678
private val SCHEMA_PRINTER = SchemaPrinter(SchemaPrinter.Options.defaultOptions()
7779
.includeDirectives(true)
7880
.includeScalarTypes(true)
79-
.includeExtendedScalarTypes(true)
80-
.includeSchemaDefintion(true)
81+
.includeSchemaDefinition(true)
8182
.includeIntrospectionTypes(false)
82-
.setComparators(DefaultSchemaPrinterComparatorRegistry.newComparators()
83-
.addComparator({ env ->
84-
env.parentType(GraphQLObjectType::class.java)
85-
env.elementType(GraphQLFieldDefinition::class.java)
86-
}, GraphQLFieldDefinition::class.java, fun(o1: GraphQLFieldDefinition, o2: GraphQLFieldDefinition): Int {
87-
val (op1, name1) = o1.splitName()
88-
val (op2, name2) = o2.splitName()
89-
if (op1 == null && op2 == null) {
90-
return name1.compareTo(name2)
91-
}
92-
if (op1 == null) {
93-
return -1
94-
}
95-
if (op2 == null) {
96-
return 1
97-
}
98-
val prio1 = name1.compareTo(name2)
99-
if (prio1 == 0) {
100-
return op1.compareTo(op2)
101-
}
102-
return prio1
103-
})
104-
.build())
10583
)
10684

10785
fun GraphQLType.splitName(): Pair<String?, String> {
108-
val m = METHOD_PATTERN.matcher(this.name)
86+
val m = METHOD_PATTERN.matcher(this.requiredName())
10987
return if (m.find()) {
11088
m.group(1) to m.group(2).toLowerCase()
11189
} else {
112-
null to this.name.toLowerCase()
90+
null to this.requiredName().toLowerCase()
11391
}
11492
}
11593

src/test/resources/translator-tests1.adoc

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -499,12 +499,12 @@ query($_param:String) { p:values(_param:$_param) { age } }
499499
----
500500
MATCH (p:Person)
501501
WHERE p._param = $_param
502+
AND p._string = $p_string
503+
AND p._int = $p_int
504+
AND p._float = $p_float
502505
AND p._array = $p_array
503-
AND p._boolean = $p_boolean
504506
AND p._enum = $p_enum
505-
AND p._float = $p_float
506-
AND p._int = $p_int
507-
AND p._string = $p_string
507+
AND p._boolean = $p_boolean
508508
RETURN p { .age } AS p
509509
----
510510

0 commit comments

Comments
 (0)