Skip to content

Commit

Permalink
[3.x] 4.x Upgrade GraphQL Java to 20.x (helidon-io#9135)
Browse files Browse the repository at this point in the history
  • Loading branch information
tmiddlet2666 authored Aug 14, 2024
1 parent b799893 commit cdfd971
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 20 deletions.
4 changes: 2 additions & 2 deletions dependencies/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@
<version.lib.google-error-prone>2.3.3</version.lib.google-error-prone>
<version.lib.google-protobuf>3.21.7</version.lib.google-protobuf>
<version.lib.graalvm>22.3.0</version.lib.graalvm>
<version.lib.graphql-java>18.6</version.lib.graphql-java>
<version.lib.graphql-java.extended.scalars>18.3</version.lib.graphql-java.extended.scalars>
<version.lib.graphql-java>22.1</version.lib.graphql-java>
<version.lib.graphql-java.extended.scalars>22.0</version.lib.graphql-java.extended.scalars>
<version.lib.gson>2.9.0</version.lib.gson>
<version.lib.grpc>1.60.0</version.lib.grpc>
<version.lib.guava>32.0.1-jre</version.lib.guava>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, 2021 Oracle and/or its affiliates.
* Copyright (c) 2020, 2024 Oracle and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand All @@ -16,6 +16,7 @@

package io.helidon.graphql.server;

import java.lang.System.Logger.Level;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
Expand All @@ -25,8 +26,8 @@
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import graphql.ExceptionWhileDataFetching;
import graphql.ExecutionInput;
Expand All @@ -49,7 +50,12 @@
import static io.helidon.graphql.server.GraphQlConstants.PATH;

class InvocationHandlerImpl implements InvocationHandler {
private static final Logger LOGGER = Logger.getLogger(InvocationHandlerImpl.class.getName());
private static final System.Logger LOGGER = System.getLogger(InvocationHandlerImpl.class.getName());
private static final Pattern VALIDATION_ERROR_PATTERN = Pattern.compile("Validation error \\((\\w+)@\\[(.*)]\\) : (.*$)");
private static final Pattern ERROR_ENUM_REPLACE_PATTERN =
Pattern.compile("Literal value not in allowable values for enum '.*?' - ('.*\\{.*}')");
private static final Pattern INVALID_TYPE_REPLACE_PATTERN =
Pattern.compile("- Expected an AST type of ('.*?') but it was a ('.*?') (@.*?)$");

private final String defaultErrorMessage;
private final Set<String> exceptionDenySet = new HashSet<>();
Expand All @@ -76,7 +82,7 @@ public Map<String, Object> execute(String query, String operationName, Map<Strin
try {
return doExecute(query, operationName, variables);
} catch (RuntimeException e) {
LOGGER.log(Level.FINE, "Failed to execute query " + query, e);
LOGGER.log(Level.DEBUG, "Failed to execute query " + query, e);
Map<String, Object> result = new HashMap<>();
addError(result, e, e.getMessage());
return result;
Expand Down Expand Up @@ -202,7 +208,71 @@ private void addError(Map<String, Object> resultMap,
path = listPath.get(0).toString();
}

addErrorPayload(resultMap, error.getMessage(), path, line, column, error.getExtensions());
addErrorPayload(resultMap, fixMessage(error.getMessage()), path, line, column, error.getExtensions());
}

// this works around https://github.com/eclipse/microprofile-graphql/issues/520
// once the TCK is fixed, we can remove this work-around
// this is depending on version of GraphQL (heavily), and any change in error message format
// will result in wrong responses
private String fixMessage(String message) {
if (!message.startsWith("Validation error")) {
return message;
}
/*
What we get (first) and what we want (second)
Validation error (FieldUndefined@[allHeroes/weaknesses]) : Field 'weaknesses' in type 'SuperHero' is undefined
Validation error of type FieldUndefined: Field 'weaknesses' in type 'SuperHero' is undefined @ 'allHeroes/weaknesses'
*/
/*
1: type of error (FieldUndefined)
2: path (allHeroes/weaknesses)
3: Message (Field 'weaknesses' in type 'SuperHero' is undefined)
*/
Matcher matcher = VALIDATION_ERROR_PATTERN.matcher(message);
if (matcher.matches()) {
String fixedMessage = "Validation error of type " + matcher.group(1)
+ ": " + matcher.group(3)
+ " @ '" + matcher.group(2) + "'";

if (fixedMessage.contains("Literal value not in allowable values for enum")) {
/*
What we get (first) and what we want (second)
Validation error (WrongType@[createNewHero]) : argument 'hero.tshirtSize' with value 'EnumValue{name='XLTall'}'
is not a valid 'ShirtSize' - Literal value not in allowable values for enum 'ShirtSize'
- 'EnumValue{name='XLTall'}'
Validation error of type WrongType: argument 'hero.tshirtSize' with value 'EnumValue{name='XLTall'}' is not a valid
'ShirtSize' - Expected enum literal value not in allowable values
- 'EnumValue{name='XLTall'}'. @ 'createNewHero'
*/
// enum failures
return ERROR_ENUM_REPLACE_PATTERN.matcher(fixedMessage)
.replaceAll("Expected enum literal value not in allowable values - $1.");
}

/*
actual graphql message
fixed graphql message
expected graphql message
Validation error (WrongType@[updateItemPowerLevel]) : argument 'powerLevel' with value
'StringValue{value='Unlimited'}' is not a valid 'Int' -
Expected an AST type of 'IntValue' but it was a 'StringValue'
Validation error of type WrongType: argument 'powerLevel' with value 'StringValue{value='Unlimited'}'
is not a valid 'Int' - Expected an AST type of 'IntValue' but it
was a 'StringValue' @ 'updateItemPowerLevel'
Validation error of type WrongType: argument 'powerLevel' with value 'StringValue{value='Unlimited'}'
is not a valid 'Int' - Expected AST type 'IntValue' but
was 'StringValue'. @ 'updateItemPowerLevel
*/
if (fixedMessage.contains("type WrongType")) {
return INVALID_TYPE_REPLACE_PATTERN.matcher(fixedMessage)
.replaceAll("- Expected AST type $1 but was $2. $3");
}

return fixedMessage;
} else {
return message;
}
}

@SuppressWarnings("unchecked")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2020, 2021 Oracle and/or its affiliates.
* Copyright (c) 2020, 2024 Oracle and/or its affiliates.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Expand Down Expand Up @@ -41,13 +41,15 @@
import java.util.Set;
import java.util.TreeSet;
import java.util.UUID;
import java.util.function.Supplier;
import java.util.logging.Logger;

import io.helidon.graphql.server.ExecutionContext;

import graphql.GraphQLException;
import graphql.schema.DataFetcher;
import graphql.schema.DataFetchingEnvironment;
import graphql.schema.GraphQLFieldDefinition;
import graphql.schema.PropertyDataFetcher;
import graphql.schema.PropertyDataFetcherHelper;
import jakarta.enterprise.inject.spi.CDI;
Expand Down Expand Up @@ -192,7 +194,7 @@ static <S, V> DataFetcher<Collection<V>> newMapValuesDataFetcher(String property

// retrieve the map and return the collection of V
Map<?, V> map = (Map<?, V>) PropertyDataFetcherHelper
.getPropertyValue(propertyName, source, environment.getFieldType(), environment);
.getPropertyValue(propertyName, source, environment.getFieldType(), () -> environment);
return map.values();
};
}
Expand Down Expand Up @@ -452,7 +454,7 @@ protected static Object parseArgumentValue(Class<?> originalType, String argumen
* An implementation of a {@link PropertyDataFetcher} which returns a formatted number.
*/
@SuppressWarnings("rawtypes")
static class NumberFormattingDataFetcher extends PropertyDataFetcher {
static class NumberFormattingDataFetcher extends PropertyDataFetcher<Object> {

/**
* {@link NumberFormat} to format with.
Expand Down Expand Up @@ -482,6 +484,12 @@ static class NumberFormattingDataFetcher extends PropertyDataFetcher {
isScalar = SchemaGeneratorHelper.getScalar(type) != null;
}

@Override
public Object get(GraphQLFieldDefinition fieldDefinition, Object source,
Supplier<DataFetchingEnvironment> environmentSupplier) throws Exception {
return formatNumber(super.get(environmentSupplier.get()), isScalar, numberFormat);
}

@Override
public Object get(DataFetchingEnvironment environment) {
return formatNumber(super.get(environment), isScalar, numberFormat);
Expand All @@ -492,7 +500,7 @@ public Object get(DataFetchingEnvironment environment) {
* An implementation of a {@link PropertyDataFetcher} which returns a formatted date.
*/
@SuppressWarnings({ "rawtypes" })
static class DateFormattingDataFetcher extends PropertyDataFetcher {
static class DateFormattingDataFetcher extends PropertyDataFetcher<Object> {

/**
* {@link DateTimeFormatter} to format with.
Expand All @@ -519,11 +527,14 @@ static class DateFormattingDataFetcher extends PropertyDataFetcher {
// must be java.util.Date
simpleDateFormat = new SimpleDateFormat(valueFormat);
}
System.err.println("DateFormattingDataFetcher: propertyName=" + propertyName
+ ", type=" + type
+ ", valueFormat=" + valueFormat
+ ", dateTimeFormatter=" + dateTimeFormatter
+ ", simpleDateFormat=" + simpleDateFormat);
}

@Override
public Object get(GraphQLFieldDefinition fieldDefinition, Object source,
Supplier<DataFetchingEnvironment> environmentSupplier) throws Exception {
return dateTimeFormatter != null
? formatDate(super.get(environmentSupplier.get()), dateTimeFormatter)
: formatDate(super.get(environmentSupplier.get()), simpleDateFormat);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright (c) 2020, 2023 Oracle and/or its affiliates.
Copyright (c) 2020, 2024 Oracle and/or its affiliates.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand All @@ -20,7 +20,7 @@
xmlns="http://jboss.org/schema/arquillian"
xsi:schemaLocation="
http://jboss.org/schema/arquillian
http://jboss.org/schema/arquillian/arquillian_1_0.xsd">
https://jboss.org/schema/arquillian/arquillian_1_0.xsd">

<engine>
<property name="deploymentExportPath">target/deployments</property>
Expand All @@ -35,4 +35,4 @@
<property name="useParentClassloader">false</property>
</configuration>
</container>
</arquillian>
</arquillian>

0 comments on commit cdfd971

Please sign in to comment.