Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrade graphql-java from 6 to 16.2 #3044

Open
wants to merge 3 commits into
base: elide-4.x
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@
@SuppressWarnings("static-method")
public class EntityDictionary {

public static final String NO_VERSION = "";

protected final ConcurrentHashMap<String, Class<?>> bindJsonApiToEntity = new ConcurrentHashMap<>();
protected final ConcurrentHashMap<Class<?>, EntityBinding> entityBindings = new ConcurrentHashMap<>();
protected final CopyOnWriteArrayList<Class<?>> bindEntityRoots = new CopyOnWriteArrayList<>();
Expand Down

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion elide-graphql/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
<dependency>
<groupId>com.graphql-java</groupId>
<artifactId>graphql-java</artifactId>
<version>6.0</version>
<version>16.2</version>
</dependency>

<!-- Test -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ public Environment(DataFetchingEnvironment environment) {
parentResource = null;
}

field = environment.getFields().get(0);
field = environment.getMergedField().getFields().get(0);

this.ids = Optional.ofNullable((List<String>) args.get(ModelBuilder.ARGUMENT_IDS));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
import com.yahoo.elide.core.EntityDictionary;
import com.yahoo.elide.utils.coerce.CoerceUtil;
import com.yahoo.elide.utils.coerce.converters.ElideTypeConverter;
import com.yahoo.elide.utils.coerce.converters.Serde;

import graphql.Scalars;
import graphql.schema.DataFetcher;
Expand All @@ -35,6 +34,7 @@
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
* Contains methods that convert from a class to a GraphQL input or query type.
Expand All @@ -47,6 +47,7 @@ public class GraphQLConversionUtils {
protected static final String ERROR_MESSAGE = "Value should either be integer, String or float";

private final Map<Class<?>, GraphQLScalarType> scalarMap = new HashMap<>();
private Set<GraphQLObjectType> objectTypes;

protected NonEntityDictionary nonEntityDictionary;
protected EntityDictionary entityDictionary;
Expand All @@ -55,24 +56,33 @@ public class GraphQLConversionUtils {
private final Map<Class, GraphQLInputObjectType> inputConversions = new HashMap<>();
private final Map<Class, GraphQLEnumType> enumConversions = new HashMap<>();
private final Map<String, GraphQLList> mapConversions = new HashMap<>();
private final GraphQLNameUtils nameUtils;

public GraphQLConversionUtils(EntityDictionary entityDictionary, NonEntityDictionary nonEntityDictionary) {
public GraphQLConversionUtils(
EntityDictionary entityDictionary,
NonEntityDictionary nonEntityDictionary,
Set<GraphQLObjectType> objectTypes
) {
this.entityDictionary = entityDictionary;
this.nonEntityDictionary = nonEntityDictionary;
this.nameUtils = new GraphQLNameUtils(entityDictionary);
this.objectTypes = objectTypes;
registerCustomScalars();
}

private void registerCustomScalars() {
for (Class serdeType : CoerceUtil.getSerdes().keySet()) {
Serde serde = CoerceUtil.lookup(serdeType);
ElideTypeConverter elideTypeConverter = serde.getClass()
.getAnnotation(ElideTypeConverter.class);
if (elideTypeConverter != null) {
SerdeCoercing serdeCoercing = new SerdeCoercing(ERROR_MESSAGE, serde);
scalarMap.put(elideTypeConverter.type(), new GraphQLScalarType(elideTypeConverter.name(),
elideTypeConverter.description(), serdeCoercing));
}
}
CoerceUtil.getSerdes().forEach((type, serde) -> {
SerdeCoercing<?, ?> serdeCoercing = new SerdeCoercing<>(ERROR_MESSAGE, serde);
ElideTypeConverter elideTypeConverter = serde.getClass().getAnnotation(ElideTypeConverter.class);
String name = elideTypeConverter != null ? elideTypeConverter.name() : type.getSimpleName();
String description = elideTypeConverter != null ? elideTypeConverter.description() : type.getSimpleName();
scalarMap.put(type, GraphQLScalarType.newScalar()
.name(name)
.description(description)
.coercing(serdeCoercing)
.build());

});
}

/**
Expand All @@ -93,7 +103,7 @@ public GraphQLScalarType classToScalarType(Class<?> clazz) {
return Scalars.GraphQLFloat;
} else if (clazz.equals(short.class) || clazz.equals(Short.class)) {
return Scalars.GraphQLShort;
} else if (clazz.equals(String.class)) {
} else if (clazz.equals(String.class) || clazz.equals(Object.class)) {
return Scalars.GraphQLString;
} else if (clazz.equals(BigDecimal.class)) {
return Scalars.GraphQLBigDecimal;
Expand Down Expand Up @@ -148,20 +158,19 @@ public GraphQLList classToQueryMap(Class<?> keyClazz, Class<?> valueClazz, DataF
GraphQLOutputType keyType = fetchScalarOrObjectOutput(keyClazz, fetcher);
GraphQLOutputType valueType = fetchScalarOrObjectOutput(valueClazz, fetcher);

GraphQLList outputMap = new GraphQLList(
newObject()
GraphQLObjectType mapType = newObject()
.name(mapName)
.field(newFieldDefinition()
.name(KEY)
.dataFetcher(fetcher)
.type(keyType))
.field(newFieldDefinition()
.name(VALUE)
.dataFetcher(fetcher)
.type(valueType))
.build()
);
.build();

GraphQLList outputMap = new GraphQLList(mapType);

objectTypes.add(mapType);
mapConversions.put(mapName, outputMap);

return mapConversions.get(mapName);
Expand Down Expand Up @@ -268,7 +277,6 @@ protected GraphQLOutputType attributeToQueryObject(Class<?> parentClass,

// If this is a collection of a boxed type scalar, we want to unwrap it properly
return new GraphQLList(fetchScalarOrObjectOutput(listType, fetcher));

}
return fetchScalarOrObjectOutput(attributeClass, fetcher);
}
Expand Down Expand Up @@ -378,8 +386,7 @@ public GraphQLObjectType classToQueryObject(
Class<?> attributeClass = nonEntityDictionary.getType(clazz, attribute);

GraphQLFieldDefinition.Builder fieldBuilder = newFieldDefinition()
.name(attribute)
.dataFetcher(fetcher);
.name(attribute);

GraphQLOutputType attributeType =
attributeToQueryObject(clazz,
Expand All @@ -394,7 +401,7 @@ public GraphQLObjectType classToQueryObject(
}

GraphQLObjectType object = objectBuilder.build();

objectTypes.add(object);
outputConversions.put(clazz, object);

return object;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ public void serialize(GraphQLError value, JsonGenerator gen, SerializerProvider
}

if (errorSpec.containsKey("extensions")) {
gen.writeFieldName("extensions");
gen.writeObject(errorSpec.get("extensions"));
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Copyright 2017, Yahoo Inc.
* Licensed under the Apache License, Version 2.0
* See LICENSE file in project root for terms.
*/

package com.yahoo.elide.graphql;


import com.yahoo.elide.core.EntityDictionary;

import org.apache.commons.lang3.StringUtils;

public class GraphQLNameUtils {
private static final String INPUT_SUFFIX = "Input";
private static final String EDGE_SUFFIX = "Edge";

private final EntityDictionary dictionary;

public GraphQLNameUtils(EntityDictionary dictionary) {
this.dictionary = dictionary;
}

public String toOutputTypeName(Class<?> clazz) {
if (dictionary.hasBinding(clazz)) {
return StringUtils.capitalize(dictionary.getJsonAliasFor(clazz));
}
return clazz.getSimpleName();
}

public String toInputTypeName(Class<?> clazz) {
return toOutputTypeName(clazz) + INPUT_SUFFIX;
}

public String toEdgesName(Class<?> clazz) {
return toOutputTypeName(clazz) + EDGE_SUFFIX;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,10 @@ public class GraphQLScalars {
// TODO: Should we make this a class that can be configured? Should determine if there are other customizeable
// TODO: scalar types.
// NOTE: Non-final so it's overrideable if someone wants _different_ date representations.
public static GraphQLScalarType GRAPHQL_DATE_TYPE = new GraphQLScalarType(
"Date",
"Built-in date",
new Coercing<Date, Object>() {
public static GraphQLScalarType GRAPHQL_DATE_TYPE = GraphQLScalarType.newScalar()
.name("Date")
.description("Built-in date")
.coercing(new Coercing<Date, Object>() {
@Override
public Object serialize(Object o) {
Serde<Object, Date> dateSerde = CoerceUtil.lookup(Date.class);
Expand All @@ -57,13 +57,13 @@ public Date parseLiteral(Object o) {
}
return parseValue(input);
}
}
);
})
.build();

public static GraphQLScalarType GRAPHQL_DEFERRED_ID = new GraphQLScalarType(
"DeferredID",
"custom id type",
new Coercing() {
public static GraphQLScalarType GRAPHQL_DEFERRED_ID = GraphQLScalarType.newScalar()
.name("DeferredID")
.description("custom id type")
.coercing(new Coercing() {
@Override
public Object serialize(Object o) {
return o;
Expand All @@ -85,6 +85,6 @@ public String parseLiteral(Object o) {
log.debug("Found unexpected object type: {}", o.getClass());
return o.toString();
}
}
);
})
.build();
}
49 changes: 49 additions & 0 deletions elide-graphql/src/main/java/com/yahoo/elide/graphql/KeyWord.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Copyright 2019, Yahoo Inc.
* Licensed under the Apache License, Version 2.0
* See LICENSE file in project root for terms.
*/

package com.yahoo.elide.graphql;

import com.google.common.collect.ImmutableMap;

import lombok.Getter;

import java.util.Arrays;
import java.util.function.Function;

/**
* Key words used in graphql parsing.
*/
public enum KeyWord {
NODE("node"),
EDGES("edges"),
PAGE_INFO("pageInfo"),
PAGE_INFO_HAS_NEXT_PAGE("hasNextPage"),
PAGE_INFO_START_CURSOR("startCursor"),
PAGE_INFO_END_CURSOR("endCursor"),
PAGE_INFO_TOTAL_RECORDS("totalRecords"),
TYPENAME("__typename"),
SCHEMA("__schema"),
TYPE("__type"),
UNKNOWN("unknown");

private static final ImmutableMap<String, KeyWord> NAME_MAP =
Arrays.stream(values()).collect(ImmutableMap.toImmutableMap(KeyWord::getName, Function.identity()));

@Getter
private final String name;

KeyWord(String name) {
this.name = name;
}

public boolean hasName(String name) {
return this.name.equals(name);
}

public static KeyWord byName(String value) {
return NAME_MAP.getOrDefault(value, UNKNOWN);
}
}