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

[3.x] Upgrade GraphQL Java to 22.x #9135

Merged
merged 1 commit into from
Aug 14, 2024
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: 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>
Loading