From 819173929dbfb5e8537f92f0dbcb9d01d98cbd48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Marti=C5=A1ka?= Date: Thu, 1 Jul 2021 07:45:26 +0200 Subject: [PATCH 1/3] Upgrade SmallRye GraphQL to 1.2.7 --- bom/application/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bom/application/pom.xml b/bom/application/pom.xml index f90dc199072f0..64ff94449185c 100644 --- a/bom/application/pom.xml +++ b/bom/application/pom.xml @@ -46,7 +46,7 @@ 3.1.1 3.0.1 2.1.7 - 1.2.5 + 1.2.7 2.0.0 5.1.0 3.2.0 From 0bbf08585d749c53f21078b1078cc0a5bce5f6bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Marti=C5=A1ka?= Date: Mon, 28 Jun 2021 10:45:34 +0200 Subject: [PATCH 2/3] Test for GraphQL client with NonNull types in native mode --- .../graphql/client/LuckyNumbersClientApi.java | 6 ++++++ .../graphql/client/LuckyNumbersResource.java | 8 ++++++++ .../graphql/client/TypesafeClientTest.java | 14 ++++++++++++++ 3 files changed, 28 insertions(+) diff --git a/integration-tests/smallrye-graphql-client/src/main/java/io/quarkus/io/smallrye/graphql/client/LuckyNumbersClientApi.java b/integration-tests/smallrye-graphql-client/src/main/java/io/quarkus/io/smallrye/graphql/client/LuckyNumbersClientApi.java index 5589ee327b3a6..bf9ad68d47d1c 100644 --- a/integration-tests/smallrye-graphql-client/src/main/java/io/quarkus/io/smallrye/graphql/client/LuckyNumbersClientApi.java +++ b/integration-tests/smallrye-graphql-client/src/main/java/io/quarkus/io/smallrye/graphql/client/LuckyNumbersClientApi.java @@ -1,6 +1,9 @@ package io.quarkus.io.smallrye.graphql.client; +import java.util.List; + import org.eclipse.microprofile.graphql.Mutation; +import org.eclipse.microprofile.graphql.NonNull; import org.eclipse.microprofile.graphql.Query; import io.smallrye.graphql.client.typesafe.api.GraphQLClientApi; @@ -13,4 +16,7 @@ public interface LuckyNumbersClientApi { @Mutation(value = "set") Integer setLuckyNumber(Integer newLuckyNumber); + + @Query(value = "echoList") + List echoList(@NonNull List list); } diff --git a/integration-tests/smallrye-graphql-client/src/main/java/io/quarkus/io/smallrye/graphql/client/LuckyNumbersResource.java b/integration-tests/smallrye-graphql-client/src/main/java/io/quarkus/io/smallrye/graphql/client/LuckyNumbersResource.java index 7d01ab7534e84..492d3305a5213 100644 --- a/integration-tests/smallrye-graphql-client/src/main/java/io/quarkus/io/smallrye/graphql/client/LuckyNumbersResource.java +++ b/integration-tests/smallrye-graphql-client/src/main/java/io/quarkus/io/smallrye/graphql/client/LuckyNumbersResource.java @@ -1,9 +1,12 @@ package io.quarkus.io.smallrye.graphql.client; +import java.util.List; + import javax.enterprise.context.ApplicationScoped; import org.eclipse.microprofile.graphql.GraphQLApi; import org.eclipse.microprofile.graphql.Mutation; +import org.eclipse.microprofile.graphql.NonNull; import org.eclipse.microprofile.graphql.Query; import io.smallrye.graphql.api.Subscription; @@ -31,4 +34,9 @@ public Multi primeNumbers() { return Multi.createFrom().items(2, 3, 5, 7, 11, 13); } + @Query(value = "echoList") + public List echoList(@NonNull List list) { + return list; + } + } diff --git a/integration-tests/smallrye-graphql-client/src/test/java/io/quarkus/it/smallrye/graphql/client/TypesafeClientTest.java b/integration-tests/smallrye-graphql-client/src/test/java/io/quarkus/it/smallrye/graphql/client/TypesafeClientTest.java index 0b600d16e3fa0..b31034e7202f7 100644 --- a/integration-tests/smallrye-graphql-client/src/test/java/io/quarkus/it/smallrye/graphql/client/TypesafeClientTest.java +++ b/integration-tests/smallrye-graphql-client/src/test/java/io/quarkus/it/smallrye/graphql/client/TypesafeClientTest.java @@ -3,6 +3,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import java.net.URL; +import java.util.List; import org.junit.jupiter.api.Test; @@ -25,4 +26,17 @@ public void testTypesafeClient() throws Exception { client.setLuckyNumber(21); assertEquals(21, client.luckyNumber()); } + + /** + * Test a method that contains a `@NonNull` parameter. + */ + @Test + public void testNonNull() throws Exception { + LuckyNumbersClientApi client = TypesafeGraphQLClientBuilder.newBuilder() + .endpoint(url.toString() + "/graphql") + .build(LuckyNumbersClientApi.class); + List someNumbers = List.of(12, 33); + List returned = client.echoList(someNumbers); + assertEquals(someNumbers, returned); + } } From 5b7f51f69f17034b8edd1042c5f10811ba11b3c8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Marti=C5=A1ka?= Date: Wed, 23 Jun 2021 08:12:35 +0200 Subject: [PATCH 3/3] GraphQL client configuration rework --- .../asciidoc/smallrye-graphql-client.adoc | 6 +- .../SmallRyeGraphQLClientProcessor.java | 64 +++++++++++++++-- .../TypesafeGraphQLClientInjectionTest.java | 20 +++--- ...LClientInjectionWithQuarkusConfigTest.java | 20 +++--- .../GraphQLClientConfigurationMergerBean.java | 68 +++++++++++++++++++ .../client/runtime/GraphQLClientSupport.java | 24 +++++++ .../SmallRyeGraphQLClientRecorder.java | 42 ++++++++---- 7 files changed, 202 insertions(+), 42 deletions(-) create mode 100644 extensions/smallrye-graphql-client/runtime/src/main/java/io/quarkus/smallrye/graphql/client/runtime/GraphQLClientConfigurationMergerBean.java create mode 100644 extensions/smallrye-graphql-client/runtime/src/main/java/io/quarkus/smallrye/graphql/client/runtime/GraphQLClientSupport.java diff --git a/docs/src/main/asciidoc/smallrye-graphql-client.adoc b/docs/src/main/asciidoc/smallrye-graphql-client.adoc index 3df8571a01254..348cd5e39f430 100644 --- a/docs/src/main/asciidoc/smallrye-graphql-client.adoc +++ b/docs/src/main/asciidoc/smallrye-graphql-client.adoc @@ -235,7 +235,7 @@ specify that within the `@GraphQLClientApi` annotation (by setting the `endpoint or move this over to the configuration file, `application.properties`: ---- -star-wars-typesafe/mp-graphql/url=https://swapi-graphql.netlify.app/.netlify/functions/index +quarkus.smallrye-graphql-client.star-wars-typesafe.url=https://swapi-graphql.netlify.app/.netlify/functions/index ---- `star-wars-typesafe` is the name of the configured client instance, and corresponds to the `configKey` @@ -274,7 +274,7 @@ representations of the GraphQL types and documents. The client API interface is We still need to configure the URL for the client, so let's put this into `application.properties`: ---- -star-wars-dynamic/mp-graphql/url=https://swapi-graphql.netlify.app/.netlify/functions/index +quarkus.smallrye-graphql-client.star-wars-dynamic.url=https://swapi-graphql.netlify.app/.netlify/functions/index ---- We decided to name the client `star-wars-dynamic`. We will use this name when injecting a dynamic client @@ -283,7 +283,7 @@ to properly qualify the injection point. If you need to add an authorization header, or any other custom HTTP header (in our case it's not required), this can be done by: ---- -star-wars-dynamic/mp-graphql/header/HEADER-KEY=HEADER-VALUE" +quarkus.smallrye-graphql-client.star-wars-dynamic.header.HEADER-KEY=HEADER-VALUE" ---- Add this to the `StarWarsResource` created earlier: diff --git a/extensions/smallrye-graphql-client/deployment/src/main/java/io/quarkus/smallrye/graphql/client/deployment/SmallRyeGraphQLClientProcessor.java b/extensions/smallrye-graphql-client/deployment/src/main/java/io/quarkus/smallrye/graphql/client/deployment/SmallRyeGraphQLClientProcessor.java index 79c64801bd4a9..1fe495e2d5913 100644 --- a/extensions/smallrye-graphql-client/deployment/src/main/java/io/quarkus/smallrye/graphql/client/deployment/SmallRyeGraphQLClientProcessor.java +++ b/extensions/smallrye-graphql-client/deployment/src/main/java/io/quarkus/smallrye/graphql/client/deployment/SmallRyeGraphQLClientProcessor.java @@ -3,7 +3,9 @@ import static io.quarkus.deployment.annotations.ExecutionTime.RUNTIME_INIT; import static io.quarkus.deployment.annotations.ExecutionTime.STATIC_INIT; +import java.util.ArrayList; import java.util.HashMap; +import java.util.List; import java.util.Map; import javax.inject.Singleton; @@ -17,6 +19,7 @@ import io.quarkus.arc.deployment.AdditionalBeanBuildItem; import io.quarkus.arc.deployment.AutoInjectAnnotationBuildItem; import io.quarkus.arc.deployment.BeanArchiveIndexBuildItem; +import io.quarkus.arc.deployment.BeanContainerBuildItem; import io.quarkus.arc.deployment.SyntheticBeanBuildItem; import io.quarkus.deployment.Feature; import io.quarkus.deployment.annotations.BuildProducer; @@ -27,6 +30,9 @@ import io.quarkus.deployment.builditem.nativeimage.ReflectiveClassBuildItem; import io.quarkus.deployment.builditem.nativeimage.ReflectiveHierarchyBuildItem; import io.quarkus.deployment.builditem.nativeimage.ServiceProviderBuildItem; +import io.quarkus.runtime.RuntimeValue; +import io.quarkus.smallrye.graphql.client.runtime.GraphQLClientConfigurationMergerBean; +import io.quarkus.smallrye.graphql.client.runtime.GraphQLClientSupport; import io.quarkus.smallrye.graphql.client.runtime.GraphQLClientsConfig; import io.quarkus.smallrye.graphql.client.runtime.SmallRyeGraphQLClientRecorder; @@ -109,21 +115,67 @@ void initializeTypesafeClient(BeanArchiveIndexBuildItem index, reflectiveClass.produce(ReflectiveClassBuildItem.builder("java.util.Collection").methods(true).build()); } + /** + * io.smallrye.graphql.client.GraphQLClientsConfiguration bean requires knowledge of all interfaces annotated + * with `@GraphQLClientApi` + */ + @BuildStep + @Record(STATIC_INIT) + void setTypesafeApiClasses(BeanArchiveIndexBuildItem index, + BeanContainerBuildItem beanContainerBuildItem, + SmallRyeGraphQLClientRecorder recorder) { + List apiClassNames = new ArrayList<>(); + for (AnnotationInstance annotation : index.getIndex().getAnnotations(GRAPHQL_CLIENT_API)) { + ClassInfo apiClassInfo = annotation.target().asClass(); + apiClassNames.add(apiClassInfo.name().toString()); + } + recorder.setTypesafeApiClasses(apiClassNames); + } + + /** + * Allows the optional usage of short class names in GraphQL client configuration rather than + * fully qualified names. This method computes a mapping between short names and qualified names, + * and the configuration merger bean will take it into account when merging Quarkus configuration + * with SmallRye-side configuration. + */ @BuildStep @Record(RUNTIME_INIT) - void translateClientConfiguration(BeanArchiveIndexBuildItem index, + void shortNamesToQualifiedNames(BuildProducer syntheticBeans, SmallRyeGraphQLClientRecorder recorder, - GraphQLClientsConfig config) { - // Map with all classes annotated with @GraphQLApi, the key is its short name, - // value is the fully qualified name. The reason is being able to match short name - // used in the configuration to a class + GraphQLClientsConfig quarkusConfig, + BeanArchiveIndexBuildItem index) { Map shortNamesToQualifiedNames = new HashMap<>(); for (AnnotationInstance annotation : index.getIndex().getAnnotations(GRAPHQL_CLIENT_API)) { ClassInfo clazz = annotation.target().asClass(); shortNamesToQualifiedNames.put(clazz.name().withoutPackagePrefix(), clazz.name().toString()); } - recorder.translateClientConfiguration(config, shortNamesToQualifiedNames); + RuntimeValue support = recorder.clientSupport(shortNamesToQualifiedNames); + + DotName supportClassName = DotName.createSimple(GraphQLClientSupport.class.getName()); + SyntheticBeanBuildItem bean = SyntheticBeanBuildItem + .configure(supportClassName) + .addType(supportClassName) + .scope(Singleton.class) + .runtimeValue(support) + .setRuntimeInit() + .unremovable() + .done(); + syntheticBeans.produce(bean); + } + + @BuildStep + AdditionalBeanBuildItem configurationMergerBean() { + return AdditionalBeanBuildItem.unremovableOf(GraphQLClientConfigurationMergerBean.class); + } + + // FIXME: this seems unnecessary, but is needed to make sure that the GraphQLClientConfigurationMergerBean + // gets initialized, can this be done differently? + @BuildStep + @Record(RUNTIME_INIT) + void initializeConfigMergerBean(BeanContainerBuildItem containerBuildItem, + SmallRyeGraphQLClientRecorder recorder) { + recorder.initializeConfigurationMergerBean(); } } diff --git a/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/TypesafeGraphQLClientInjectionTest.java b/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/TypesafeGraphQLClientInjectionTest.java index 24359f315dea5..a132d5b327656 100644 --- a/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/TypesafeGraphQLClientInjectionTest.java +++ b/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/TypesafeGraphQLClientInjectionTest.java @@ -27,10 +27,8 @@ public class TypesafeGraphQLClientInjectionTest { static QuarkusUnitTest test = new QuarkusUnitTest() .setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class) .addClasses(TestingGraphQLApi.class, TestingGraphQLClientApi.class, Person.class) - .addAsResource(new StringAsset("typesafeclient/mp-graphql/url=" + url), - // TODO: adding headers via config is not supported by typesafe client yet - // + "\n" + - // "typesafeclient/mp-graphql/header/My-Header=My-Value"), + .addAsResource(new StringAsset("typesafeclient/mp-graphql/url=" + url + "\n" + + "typesafeclient/mp-graphql/header/My-Header=My-Value"), "application.properties") .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml")); @@ -44,10 +42,14 @@ public void performQuery() { assertEquals("Arthur", people.get(1).getFirstName()); } - // TODO: adding headers via config is not supported by typesafe client yet - // @Test - // public void checkHeaders() throws ExecutionException, InterruptedException { - // assertEquals("My-Value", client.returnHeader("My-Header")); - // } + /** + * Verify that configured HTTP headers are applied by the client. + * We do this by asking the server side to read the header received from the client and send + * its value back to the client. + */ + @Test + public void checkHeaders() { + assertEquals("My-Value", client.returnHeader("My-Header")); + } } diff --git a/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/TypesafeGraphQLClientInjectionWithQuarkusConfigTest.java b/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/TypesafeGraphQLClientInjectionWithQuarkusConfigTest.java index f7dca13874515..982786578d94c 100644 --- a/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/TypesafeGraphQLClientInjectionWithQuarkusConfigTest.java +++ b/extensions/smallrye-graphql-client/deployment/src/test/java/io/quarkus/smallrye/graphql/client/deployment/TypesafeGraphQLClientInjectionWithQuarkusConfigTest.java @@ -27,10 +27,8 @@ public class TypesafeGraphQLClientInjectionWithQuarkusConfigTest { static QuarkusUnitTest test = new QuarkusUnitTest() .setArchiveProducer(() -> ShrinkWrap.create(JavaArchive.class) .addClasses(TestingGraphQLApi.class, TestingGraphQLClientApi.class, Person.class) - .addAsResource(new StringAsset("quarkus.smallrye-graphql-client.typesafeclient.url=" + url), - // TODO: adding headers via config is not supported by typesafe client yet - // + "\n" + - // "quarkus.smallrye-graphql-client.typesafeclient.header.My-Header=My-Value"), + .addAsResource(new StringAsset("quarkus.smallrye-graphql-client.typesafeclient.url=" + url + "\n" + + "quarkus.smallrye-graphql-client.typesafeclient.header.My-Header=My-Value"), "application.properties") .addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml")); @@ -44,10 +42,14 @@ public void performQuery() { assertEquals("Arthur", people.get(1).getFirstName()); } - // TODO: adding headers via config is not supported by typesafe client yet - // @Test - // public void checkHeaders() throws ExecutionException, InterruptedException { - // assertEquals("My-Value", client.returnHeader("My-Header")); - // } + /** + * Verify that configured HTTP headers are applied by the client. + * We do this by asking the server side to read the header received from the client and send + * its value back to the client. + */ + @Test + public void checkHeaders() { + assertEquals("My-Value", client.returnHeader("My-Header")); + } } diff --git a/extensions/smallrye-graphql-client/runtime/src/main/java/io/quarkus/smallrye/graphql/client/runtime/GraphQLClientConfigurationMergerBean.java b/extensions/smallrye-graphql-client/runtime/src/main/java/io/quarkus/smallrye/graphql/client/runtime/GraphQLClientConfigurationMergerBean.java new file mode 100644 index 0000000000000..f90f741f5a80a --- /dev/null +++ b/extensions/smallrye-graphql-client/runtime/src/main/java/io/quarkus/smallrye/graphql/client/runtime/GraphQLClientConfigurationMergerBean.java @@ -0,0 +1,68 @@ +package io.quarkus.smallrye.graphql.client.runtime; + +import java.util.Map; + +import javax.annotation.PostConstruct; +import javax.inject.Inject; +import javax.inject.Singleton; + +import io.smallrye.graphql.client.GraphQLClientConfiguration; +import io.smallrye.graphql.client.GraphQLClientsConfiguration; + +/** + * On startup, this beans takes Quarkus-specific configuration of GraphQL clients (quarkus.* properties) + * and merges this configuration with the configuration parsed by SmallRye GraphQL itself (CLIENT/mp-graphql/* properties) + * + * The resulting merged configuration resides in the application-scoped `io.smallrye.graphql.client.GraphQLClientConfiguration` + * + * Quarkus configuration overrides SmallRye configuration where applicable. + */ +@Singleton +public class GraphQLClientConfigurationMergerBean { + + @Inject + GraphQLClientsConfiguration upstreamConfiguration; + + @Inject + GraphQLClientsConfig quarkusConfiguration; + + @Inject + GraphQLClientSupport support; + + @PostConstruct + void enhanceGraphQLConfiguration() { + for (Map.Entry client : quarkusConfiguration.clients.entrySet()) { + // the raw config key provided in the config, this might be a short class name, + // so translate that into the fully qualified name if applicable + String rawConfigKey = client.getKey(); + Map shortNamesToQualifiedNamesMapping = support.getShortNamesToQualifiedNamesMapping(); + String configKey = shortNamesToQualifiedNamesMapping != null && + shortNamesToQualifiedNamesMapping.containsKey(rawConfigKey) + ? shortNamesToQualifiedNamesMapping.get(rawConfigKey) + : rawConfigKey; + + GraphQLClientConfig quarkusConfig = client.getValue(); + // if SmallRye configuration does not contain this client, simply use it + if (!upstreamConfiguration.getClients().containsKey(configKey)) { + GraphQLClientConfiguration transformed = new GraphQLClientConfiguration(); + transformed.setHeaders(quarkusConfig.headers); + transformed.setUrl(quarkusConfig.url); + upstreamConfiguration.getClients().put(configKey, transformed); + } else { + // if SmallRye configuration already contains this client, override it with the Quarkus configuration + GraphQLClientConfiguration upstreamConfig = upstreamConfiguration.getClients().get(configKey); + if (quarkusConfig.url != null) { + upstreamConfig.setUrl(quarkusConfig.url); + } + // merge the headers + if (quarkusConfig.headers != null) { + upstreamConfig.getHeaders().putAll(quarkusConfig.headers); + } + } + } + + } + + public void nothing() { + } +} diff --git a/extensions/smallrye-graphql-client/runtime/src/main/java/io/quarkus/smallrye/graphql/client/runtime/GraphQLClientSupport.java b/extensions/smallrye-graphql-client/runtime/src/main/java/io/quarkus/smallrye/graphql/client/runtime/GraphQLClientSupport.java new file mode 100644 index 0000000000000..2055789e4973f --- /dev/null +++ b/extensions/smallrye-graphql-client/runtime/src/main/java/io/quarkus/smallrye/graphql/client/runtime/GraphQLClientSupport.java @@ -0,0 +1,24 @@ +package io.quarkus.smallrye.graphql.client.runtime; + +import java.util.Map; + +/** + * Items from build time needed to make available at runtime. + */ +public class GraphQLClientSupport { + + /** + * Allows the optional usage of short class names in GraphQL client configuration rather than + * fully qualified names. The configuration merger bean will take it into account + * when merging Quarkus configuration with SmallRye-side configuration. + */ + private Map shortNamesToQualifiedNamesMapping; + + public Map getShortNamesToQualifiedNamesMapping() { + return shortNamesToQualifiedNamesMapping; + } + + public void setShortNamesToQualifiedNamesMapping(Map shortNamesToQualifiedNamesMapping) { + this.shortNamesToQualifiedNamesMapping = shortNamesToQualifiedNamesMapping; + } +} diff --git a/extensions/smallrye-graphql-client/runtime/src/main/java/io/quarkus/smallrye/graphql/client/runtime/SmallRyeGraphQLClientRecorder.java b/extensions/smallrye-graphql-client/runtime/src/main/java/io/quarkus/smallrye/graphql/client/runtime/SmallRyeGraphQLClientRecorder.java index 4d9f20f24e792..c9a16d643631e 100644 --- a/extensions/smallrye-graphql-client/runtime/src/main/java/io/quarkus/smallrye/graphql/client/runtime/SmallRyeGraphQLClientRecorder.java +++ b/extensions/smallrye-graphql-client/runtime/src/main/java/io/quarkus/smallrye/graphql/client/runtime/SmallRyeGraphQLClientRecorder.java @@ -1,9 +1,14 @@ package io.quarkus.smallrye.graphql.client.runtime; +import java.util.List; import java.util.Map; import java.util.function.Supplier; +import java.util.stream.Collectors; +import io.quarkus.arc.Arc; +import io.quarkus.runtime.RuntimeValue; import io.quarkus.runtime.annotations.Recorder; +import io.smallrye.graphql.client.GraphQLClientsConfiguration; import io.smallrye.graphql.client.typesafe.api.TypesafeGraphQLClientBuilder; @Recorder @@ -16,21 +21,28 @@ public Supplier typesafeClientSupplier(Class targetClassName) { }; } - /** - * Translates quarkus.* configuration properties to system properties understood by SmallRye GraphQL. - */ - public void translateClientConfiguration(GraphQLClientsConfig clientsConfig, - Map shortNamesToQualifiedNames) { - for (Map.Entry client : clientsConfig.clients.entrySet()) { - String configKey = client.getKey(); - // the config key can be a short class name, in which case we try to translate it to a fully qualified name - // and use the FQ name in the set property, because that's what SmallRye GraphQL understands - String clientName = shortNamesToQualifiedNames.getOrDefault(configKey, configKey); - GraphQLClientConfig config = client.getValue(); - System.setProperty(clientName + "/mp-graphql/url", config.url); - for (Map.Entry header : config.headers.entrySet()) { - System.setProperty(clientName + "/mp-graphql/header/" + header.getKey(), header.getValue()); + public void setTypesafeApiClasses(List apiClassNames) { + GraphQLClientsConfiguration configBean = Arc.container().instance(GraphQLClientsConfiguration.class).get(); + List> classes = apiClassNames.stream().map(className -> { + try { + return Class.forName(className, true, Thread.currentThread().getContextClassLoader()); + } catch (ClassNotFoundException e) { + throw new RuntimeException(e); } - } + }).collect(Collectors.toList()); + configBean.apiClasses(classes); } + + public RuntimeValue clientSupport(Map shortNamesToQualifiedNames) { + GraphQLClientSupport support = new GraphQLClientSupport(); + support.setShortNamesToQualifiedNamesMapping(shortNamesToQualifiedNames); + return new RuntimeValue<>(support); + } + + public void initializeConfigurationMergerBean() { + GraphQLClientConfigurationMergerBean merger = Arc.container() + .instance(GraphQLClientConfigurationMergerBean.class).get(); + merger.nothing(); + } + }