Skip to content

Commit

Permalink
Upgrade to SmallRye GraphQL 1.7.0 (graphql-java 19.0)
Browse files Browse the repository at this point in the history
Signed-off-by: Phillip Kruger <phillip.kruger@gmail.com>
  • Loading branch information
phillip-kruger committed Aug 10, 2022
1 parent 52c1281 commit 2b87b5c
Show file tree
Hide file tree
Showing 19 changed files with 346 additions and 10 deletions.
2 changes: 1 addition & 1 deletion bom/application/pom.xml
Expand Up @@ -44,7 +44,7 @@
<smallrye-health.version>3.2.1</smallrye-health.version>
<smallrye-metrics.version>3.0.5</smallrye-metrics.version>
<smallrye-open-api.version>2.1.23</smallrye-open-api.version>
<smallrye-graphql.version>1.6.2</smallrye-graphql.version>
<smallrye-graphql.version>1.7.0</smallrye-graphql.version>
<smallrye-opentracing.version>2.1.1</smallrye-opentracing.version>
<smallrye-fault-tolerance.version>5.5.0</smallrye-fault-tolerance.version>
<smallrye-jwt.version>3.5.3</smallrye-jwt.version>
Expand Down
Expand Up @@ -52,7 +52,7 @@ public void testAddAndRemoveFieldChange() {
.statusCode(200)
.and()
.body(CoreMatchers.containsString(
"{\"errors\":[{\"message\":\"Validation error of type FieldUndefined: Field 'foo' in type 'TestPojo' is undefined @ 'foo/foo'\",\"locations\":[{\"line\":7,\"column\":5}],\"extensions\":{\"classification\":\"ValidationError\"}}],\"data\":null}"));
"{\"errors\":[{\"message\":\"Validation error (FieldUndefined@[foo/foo]) : Field 'foo' in type 'TestPojo' is undefined\",\"locations\":[{\"line\":7,\"column\":5}],\"extensions\":{\"classification\":\"ValidationError\"}}],\"data\":null}"));
LOG.info("Initial request done");

// Make a code change (add a field)
Expand Down Expand Up @@ -94,7 +94,7 @@ public void testAddAndRemoveFieldChange() {
.statusCode(200)
.and()
.body(CoreMatchers.containsString(
"{\"errors\":[{\"message\":\"Validation error of type FieldUndefined: Field 'foo' in type 'TestPojo' is undefined @ 'foo/foo'\",\"locations\":[{\"line\":7,\"column\":5}],\"extensions\":{\"classification\":\"ValidationError\"}}],\"data\":null}"));
"{\"errors\":[{\"message\":\"Validation error (FieldUndefined@[foo/foo]) : Field 'foo' in type 'TestPojo' is undefined\",\"locations\":[{\"line\":7,\"column\":5}],\"extensions\":{\"classification\":\"ValidationError\"}}],\"data\":null}"));

LOG.info("Code change done - field removed");

Expand Down
@@ -0,0 +1,84 @@
package io.quarkus.smallrye.graphql.deployment;

import static io.quarkus.smallrye.graphql.deployment.AbstractGraphQLTest.getPropertyAsString;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.nullValue;

import java.util.HashMap;
import java.util.Map;

import org.eclipse.microprofile.graphql.GraphQLApi;
import org.eclipse.microprofile.graphql.Query;
import org.eclipse.microprofile.graphql.Source;
import org.jboss.shrinkwrap.api.asset.EmptyAsset;
import org.jboss.shrinkwrap.api.asset.StringAsset;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;

import io.quarkus.test.QuarkusUnitTest;
import io.restassured.RestAssured;
import io.smallrye.common.annotation.NonBlocking;

public class InstrumentationTest extends AbstractGraphQLTest {

@RegisterExtension
static QuarkusUnitTest test = new QuarkusUnitTest()
.withApplicationRoot((jar) -> jar
.addClasses(FooApi.class, Foo.class)
.addAsResource(new StringAsset(getPropertyAsString(configuration())), "application.properties")
.addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml"));

@Test
public void testQueryDepth() {
String query = getPayload("{ foo { nestedFoo { nestedFoo { message}}}}");
RestAssured.given()
.body(query)
.contentType(MEDIATYPE_JSON)
.post("/graphql/")
.then()
.log().all()
.assertThat()
.body("errors[0].message", equalTo("maximum query depth exceeded 4 > 1"))
.body("data", nullValue());
}

private static Map<String, String> configuration() {
Map<String, String> m = new HashMap<>();
m.put("quarkus.smallrye-graphql.events.enabled", "true");
m.put("quarkus.smallrye-graphql.instrumentation-query-depth", "1");
return m;
}

public static class Foo {

private String message;

public Foo(String foo) {
this.message = foo;
}

public String getMessage() {
return message;
}

public void setMessage(String message) {
this.message = message;
}

}

@GraphQLApi
public static class FooApi {

@Query
@NonBlocking
public Foo foo() {
return new Foo("foo");
}

public Foo nestedFoo(@Source Foo foo) {
return new Foo("foo");
}
}

}
Expand Up @@ -152,17 +152,59 @@ public class SmallRyeGraphQLConfig {
public Optional<List<String>> unwrapExceptions;

/**
* SmallRye GraphQL UI configuration
* Subprotocols that should be supported by the server for graphql-over-websocket use cases.
* Allowed subprotocols are "graphql-ws" and "graphql-transport-ws". By default, both are enabled.
*/
@ConfigItem
@ConfigDocSection
public SmallRyeGraphQLUIConfig ui;
public Optional<List<String>> websocketSubprotocols;

/**
* Subprotocols that should be supported by the server for graphql-over-websocket use cases.
* Allowed subprotocols are "graphql-ws" and "graphql-transport-ws". By default, both are enabled.
* Set to true if ignored chars should be captured as AST nodes. Default to false
*/
@ConfigItem
public Optional<List<String>> websocketSubprotocols;
public Optional<Boolean> parserCaptureIgnoredChars;

/**
* Set to true if `graphql.language.Comment`s should be captured as AST nodes
*/
@ConfigItem
public Optional<Boolean> parserCaptureLineComments;

/**
* Set to true true if `graphql.language.SourceLocation`s should be captured as AST nodes. Default to true
*/
@ConfigItem
public Optional<Boolean> parserCaptureSourceLocation;

/**
* The maximum number of raw tokens the parser will accept, after which an exception will be thrown. Default to 15000
*/
@ConfigItem
public Optional<Integer> parserMaxTokens;

/**
* The maximum number of raw whitespace tokens the parser will accept, after which an exception will be thrown. Default to
* 200000
*/
@ConfigItem
public Optional<Integer> parserMaxWhitespaceTokens;

/**
* Abort a query if the total number of data fields queried exceeds the defined limit. Default to no limit
*/
@ConfigItem
public Optional<Integer> instrumentationQueryComplexity;

/**
* Abort a query if the total depth of the query exceeds the defined limit. Default to no limit
*/
@ConfigItem
public Optional<Integer> instrumentationQueryDepth;

/**
* SmallRye GraphQL UI configuration
*/
@ConfigItem
@ConfigDocSection
public SmallRyeGraphQLUIConfig ui;
}
Expand Up @@ -49,6 +49,13 @@ private static Map<String, String> relocations() {
mapKey(relocations, ConfigKey.LOG_PAYLOAD, QUARKUS_LOG_PAYLOAD);
mapKey(relocations, ConfigKey.FIELD_VISIBILITY, QUARKUS_FIELD_VISIBILITY);
mapKey(relocations, ConfigKey.UNWRAP_EXCEPTIONS, QUARKUS_UNWRAP_EXCEPTIONS);
mapKey(relocations, ConfigKey.PARSER_CAPTURE_IGNORED_CHARS, QUARKUS_PARSER_CAPTURE_IGNORED_CHARS);
mapKey(relocations, ConfigKey.PARSER_CAPTURE_LINE_COMMENTS, QUARKUS_PARSER_CAPTURE_LINE_COMMENTS);
mapKey(relocations, ConfigKey.PARSER_CAPTURE_SOURCE_LOCATION, QUARKUS_PARSER_CAPTURE_SOURCE_LOCATION);
mapKey(relocations, ConfigKey.PARSER_MAX_TOKENS, QUARKUS_PARSER_MAX_TOKENS);
mapKey(relocations, ConfigKey.PARSER_MAX_WHITESPACE_TOKENS, QUARKUS_PARSER_MAX_WHITESPACE_TOKENS);
mapKey(relocations, ConfigKey.INSTRUMENTATION_QUERY_COMPLEXITY, QUARKUS_INSTRUMENTATION_QUERY_COMPLEXITY);
mapKey(relocations, ConfigKey.INSTRUMENTATION_QUERY_DEPTH, QUARKUS_INSTRUMENTATION_QUERY_DEPTH);
mapKey(relocations, SHOW_ERROR_MESSAGE, QUARKUS_SHOW_ERROR_MESSAGE);
mapKey(relocations, HIDE_ERROR_MESSAGE, QUARKUS_HIDE_ERROR_MESSAGE);
return Collections.unmodifiableMap(relocations);
Expand All @@ -75,5 +82,12 @@ private static void mapKey(Map<String, String> map, String quarkusKey, String ot
private static final String QUARKUS_LOG_PAYLOAD = "quarkus.smallrye-graphql.log-payload";
private static final String QUARKUS_FIELD_VISIBILITY = "quarkus.smallrye-graphql.field-visibility";
private static final String QUARKUS_UNWRAP_EXCEPTIONS = "quarkus.smallrye-graphql.unwrap-exceptions";
private static final String QUARKUS_PARSER_CAPTURE_IGNORED_CHARS = "quarkus.smallrye-graphql.parser-capture-ignored-chars";
private static final String QUARKUS_PARSER_CAPTURE_LINE_COMMENTS = "quarkus.smallrye-graphql.parser-capture-line-comments";
private static final String QUARKUS_PARSER_CAPTURE_SOURCE_LOCATION = "quarkus.smallrye-graphql.parser-capture-source-location";
private static final String QUARKUS_PARSER_MAX_TOKENS = "quarkus.smallrye-graphql.parser-max-tokens";
private static final String QUARKUS_PARSER_MAX_WHITESPACE_TOKENS = "quarkus.smallrye-graphql.parser-max-whitespace-tokens";
private static final String QUARKUS_INSTRUMENTATION_QUERY_COMPLEXITY = "quarkus.smallrye-graphql.instrumentation-query-complexity";
private static final String QUARKUS_INSTRUMENTATION_QUERY_DEPTH = "quarkus.smallrye-graphql.instrumentation-query-depth";

}
2 changes: 1 addition & 1 deletion jakarta/rewrite.yml
Expand Up @@ -451,7 +451,7 @@ recipeList:
newValue: 6.0.0-RC4
- org.openrewrite.maven.ChangePropertyValue:
key: smallrye-graphql.version
newValue: 2.0.0.RC6
newValue: 2.0.0.RC7
- org.openrewrite.maven.ChangePropertyValue:
key: smallrye-health.version
newValue: 4.0.0-RC2
Expand Down
@@ -0,0 +1,14 @@
{
"errors": [
{
"message": "Validation error (WrongType@[createNewHero]) : argument 'hero.name' with value 'NullValue{}' must not be null",
"locations": [
{
"line": 2,
"column": 19
}
]
}
],
"data": null
}
@@ -0,0 +1,14 @@
{
"errors": [
{
"message": "Validation error (WrongType@[createNewHero]) : argument 'hero' with value 'ObjectValue{objectFields=[ObjectField{name='realName', value=StringValue{value='John Smith'}}]}' is missing required fields '[name]'",
"locations": [
{
"line": 2,
"column": 19
}
]
}
],
"data": null
}
@@ -0,0 +1,16 @@
{
"errors": [
{
"message": "argument 'powerLevel' with value 'StringValue{value='Unlimited'}' is not a valid 'Int'",
"locations": [
{
"line": 2,
"column": 37
}
]
}
],
"data": {
"updateItemPowerLevel": null
}
}
@@ -0,0 +1,14 @@
{
"errors": [
{
"message": "Validation error (WrongType@[createNewHero]) : argument 'hero.tshirtSize' with value 'EnumValue{name='XLTall'}' is not a valid 'ShirtSize' - Expected enum literal value not in allowable values - 'EnumValue{name='XLTall'}'.",
"locations": [
{
"line": 3,
"column": 19
}
]
}
],
"data": null
}
@@ -0,0 +1,16 @@
{
"errors": [
{
"message": "argument 'date' with value 'StringValue{value='Today'}' is not a valid 'Date'",
"locations": [
{
"line": 2,
"column": 49
}
]
}
],
"data": {
"checkInWithCorrectDateFormat": null
}
}
@@ -0,0 +1,16 @@
{
"errors": [
{
"message": "argument 'dateTime' with value 'StringValue{value='Today'}' is not a valid 'DateTime'",
"locations": [
{
"line": 2,
"column": 48
}
]
}
],
"data": {
"battleWithCorrectDateFormat": null
}
}
@@ -0,0 +1,16 @@
{
"errors": [
{
"message": "argument 'dateTime' with value 'StringValue{value='Today'}' is not a valid 'DateTime'",
"locations": [
{
"line": 2,
"column": 27
}
]
}
],
"data": {
"battle": null
}
}
@@ -0,0 +1,16 @@
{
"errors": [
{
"message": "argument 'date' with value 'StringValue{value='Today'}' is not a valid 'Date'",
"locations": [
{
"line": 2,
"column": 28
}
]
}
],
"data": {
"checkIn": null
}
}
@@ -0,0 +1,16 @@
{
"errors": [
{
"message": "argument 'time' with value 'StringValue{value='Today'}' is not a valid 'Time'",
"locations": [
{
"line": 2,
"column": 57
}
]
}
],
"data": {
"startPatrollingWithCorrectDateFormat": null
}
}
@@ -0,0 +1,16 @@
{
"errors": [
{
"message": "argument 'time' with value 'StringValue{value='Today'}' is not a valid 'Time'",
"locations": [
{
"line": 2,
"column": 36
}
]
}
],
"data": {
"startPatrolling": null
}
}
@@ -0,0 +1,14 @@
{
"errors": [
{
"message": "Validation error (FieldUndefined@[allHeroes/weaknesses]) : Field 'weaknesses' in type 'SuperHero' is undefined",
"locations": [
{
"line": 4,
"column": 5
}
]
}
],
"data": null
}

0 comments on commit 2b87b5c

Please sign in to comment.