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

Support records as inputs in clients #1041

Merged
merged 2 commits into from
Sep 14, 2021
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
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
java: [8, 11]
java: [8, 11, 16]
name: build with jdk ${{matrix.java}}

steps:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ public void setOtherFields(Map<String, JsonValue> otherFields) {

@Override
public String toString() {
String other = otherFields.isEmpty() ? "" : ", otherFields=" + otherFields;
String other = (otherFields == null || otherFields.isEmpty()) ? "" : ", otherFields=" + otherFields;
return "GraphQLError{message=" + message +
", locations=" + locations +
", path=" + Arrays.toString(path) +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,22 +27,31 @@ Object read() {
}

private Object readObject() {
Object instance = newInstance();
type.fields().forEach(field -> {
Object fieldValue = buildValue(location, value, field);
field.set(instance, fieldValue);
});
return instance;
if (!type.isRecord()) {
Object instance = newInstance();
type.fields().forEach(field -> {
Object fieldValue = buildValue(location, value, field);
field.set(instance, fieldValue);
});
return instance;
} else {
Object[] values = type.fields().map(field -> buildValue(location, value, field)).toArray(Object[]::new);
return newInstance(values);
}
}

private Object newInstance() {
private Object newInstance(Object[] parameters) {
try {
return type.newInstance();
return type.newInstance(parameters);
} catch (Exception e) {
throw new GraphQLClientException("can't create " + location, e);
}
}

private Object newInstance() {
return newInstance(new Object[0]);
}

private Object buildValue(Location location, JsonObject value, FieldInfo field) {
String fieldName = field.getAlias().orElseGet(field::getName);
Location fieldLocation = new Location(field.getType(), location.getDescription() + "." + fieldName);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import java.security.PrivilegedAction;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.Arrays;
import java.util.Collection;
import java.util.Optional;
import java.util.function.Predicate;
Expand Down Expand Up @@ -150,6 +151,10 @@ public boolean isErrorOr() {
return ErrorOr.class.equals(getRawType());
}

public boolean isRecord() {
return rawType.getSuperclass().getName().equals("java.lang.Record");
}

public boolean isScalar() {
return isPrimitive()
|| Number.class.isAssignableFrom(getRawType())
Expand Down Expand Up @@ -194,22 +199,42 @@ private boolean hasOneStringParameter(Executable executable) {
return executable.getParameterCount() == 1 && CharSequence.class.isAssignableFrom(executable.getParameterTypes()[0]);
}

public Object newInstance() {
public Object newInstance(Object[] args) {
try {
Constructor<?> noArgsConstructor = getDeclaredConstructor(getRawType());
noArgsConstructor.setAccessible(true);
return noArgsConstructor.newInstance();
if (args.length == 0) {
Constructor<?> noArgsConstructor = getDeclaredConstructor(getRawType());
noArgsConstructor.setAccessible(true);
return noArgsConstructor.newInstance();
} else {
Class<?> rawType = getRawType();
Optional<Constructor<?>> constructor = Arrays.stream(rawType.getDeclaredConstructors())
.filter(c -> !c.getDeclaringClass().equals(Class.class))
.filter(c -> c.getParameterCount() == args.length)
.findAny();
if (constructor.isPresent()) {
Constructor<?> c = constructor.get();
c.setAccessible(true);
return c.newInstance(args);
} else {
throw new RuntimeException("Could not find a suitable constructor of type " + type);
}
}
} catch (ReflectiveOperationException e) {
throw new RuntimeException("can't instantiate " + type, e);
}
}

private Constructor<?> getDeclaredConstructor(Class<?> type) throws NoSuchMethodException {
return getDeclaredConstructor(type, new Class[0]);
}

private Constructor<?> getDeclaredConstructor(Class<?> type, Class<?>[] parameters) throws NoSuchMethodException {
if (System.getSecurityManager() == null) {
return type.getDeclaredConstructor();
return type.getDeclaredConstructor(parameters);
}
try {
return AccessController.doPrivileged((PrivilegedExceptionAction<Constructor<?>>) type::getDeclaredConstructor);
return AccessController
.doPrivileged((PrivilegedExceptionAction<Constructor<?>>) () -> type.getDeclaredConstructor(parameters));
} catch (PrivilegedActionException pae) {
if (pae.getCause() instanceof NoSuchMethodException) {
throw (NoSuchMethodException) pae.getCause();
Expand Down
16 changes: 16 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -411,5 +411,21 @@
</plugins>
</build>
</profile>
<profile>
<id>jdk16plus</id>
<activation>
<jdk>[16,)</jdk>
</activation>
<modules>
<module>server/integration-tests-jdk16</module>
</modules>
<properties>
<!-- FIXME: hack to allow powerannotations TCK to pass on JDK 16 -->
<powerannotations.tck.argLine>--add-opens java.base/java.util=ALL-UNNAMED</powerannotations.tck.argLine>
<!-- FIXME: find out why Gradle build doesn't work on JDK 16 in GH actions,
but seems to work locally -->
<skip.gradle.build>true</skip.gradle.build>
</properties>
</profile>
</profiles>
</project>
2 changes: 2 additions & 0 deletions power-annotations/tck/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<groups>!InheritedAnnotationsTestSuite &amp; !TypeToMemberAnnotationsTestSuite</groups>
<!-- FIXME: this is a dirty hack to make the TCK pass on JDK 16 -->
<argLine>${powerannotations.tck.argLine}</argLine>
</configuration>
</plugin>
</plugins>
Expand Down
221 changes: 221 additions & 0 deletions server/integration-tests-jdk16/pom.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>smallrye-graphql-server-parent</artifactId>
<groupId>io.smallrye</groupId>
<version>1.3.4-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>

<artifactId>smallrye-graphql-integration-tests-jdk16</artifactId>
<name>SmallRye: GraphQL Server :: Integration Tests :: Java 16+ tests</name>

<properties>
<maven.compiler.target>16</maven.compiler.target>
<maven.compiler.source>16</maven.compiler.source>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

<dependencies>
<dependency>
<groupId>org.jboss.arquillian.container</groupId>
<artifactId>arquillian-container-test-spi</artifactId>
</dependency>
<dependency>
<groupId>org.jboss.shrinkwrap.resolver</groupId>
<artifactId>shrinkwrap-resolver-impl-maven</artifactId>
</dependency>

<!-- Test -->
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.arquillian.junit</groupId>
<artifactId>arquillian-junit-container</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<scope>test</scope>
</dependency>

<!-- Dynamic client -->
<dependency>
<groupId>io.smallrye</groupId>
<artifactId>smallrye-graphql-client-implementation-vertx</artifactId>
<scope>test</scope>
</dependency>
<!-- The API is copied into SmallRye for now -->
<!-- <dependency>-->
<!-- <groupId>org.eclipse.microprofile.graphql</groupId>-->
<!-- <artifactId>microprofile-graphql-client-api</artifactId>-->
<!-- <scope>test</scope>-->
<!-- </dependency>-->

<!-- Container -->
<dependency>
<groupId>org.jboss.arquillian.container</groupId>
<artifactId>arquillian-jetty-embedded-9</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-webapp</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-deploy</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-annotations</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.websocket</groupId>
<artifactId>javax-websocket-client-impl</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.jetty.websocket</groupId>
<artifactId>javax-websocket-server-impl</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jboss.weld.servlet</groupId>
<artifactId>weld-servlet-core</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse</groupId>
<artifactId>yasson</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>jakarta.validation</groupId>
<artifactId>jakarta.validation-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.microprofile.config</groupId>
<artifactId>microprofile-config-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.smallrye.config</groupId>
<artifactId>smallrye-config</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.microprofile.metrics</groupId>
<artifactId>microprofile-metrics-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.smallrye</groupId>
<artifactId>smallrye-metrics</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.opentracing</groupId>
<artifactId>opentracing-mock</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.smallrye</groupId>
<artifactId>smallrye-opentracing</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.microprofile.context-propagation</groupId>
<artifactId>microprofile-context-propagation-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.smallrye</groupId>
<artifactId>smallrye-context-propagation</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.smallrye.reactive</groupId>
<artifactId>mutiny</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.smallrye.reactive</groupId>
<artifactId>mutiny-smallrye-context-propagation</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.glassfish</groupId>
<artifactId>jakarta.el</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.eclipse.microprofile.graphql</groupId>
<artifactId>microprofile-graphql-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.smallrye</groupId>
<artifactId>smallrye-graphql-servlet</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.sonatype.plugins</groupId>
<artifactId>nexus-staging-maven-plugin</artifactId>
<configuration>
<skipNexusStagingDeployMojo>true</skipNexusStagingDeployMojo>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<reuseForks>false</reuseForks>
<forkCount>1</forkCount>
</configuration>
</plugin>
<!-- FIXME: There's no version of impsort plugin yet that properly supports
Java 16 sources. Exclude impsort on this module for now. -->
<plugin>
<groupId>net.revelc.code</groupId>
<artifactId>impsort-maven-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<release>16</release>
</configuration>
</plugin>
</plugins>
</build>


</project>
Loading