All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.smallrye.graphql.client.impl.GraphQLClientsConfiguration Maven / Gradle / Ivy

There is a newer version: 2.12.0
Show newest version
package io.smallrye.graphql.client.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.WeakHashMap;

import org.eclipse.microprofile.config.Config;
import org.eclipse.microprofile.config.ConfigProvider;

/**
 * The wrapper that stores configuration of all GraphQL clients.
 */
public class GraphQLClientsConfiguration {

    private static final Map INSTANCES = new WeakHashMap<>();
    private static volatile boolean singleApplication = false;
    Config mpConfig = ConfigProvider.getConfig();

    /**
     * This needs to be set to true if the runtime only supports a single deployment.
     */
    @SuppressWarnings("unused")
    public static void setSingleApplication(boolean singleApplication) {
        GraphQLClientsConfiguration.singleApplication = singleApplication;
    }

    public static GraphQLClientsConfiguration getInstance() {
        ClassLoader key = singleApplication ? null : Thread.currentThread().getContextClassLoader();
        return INSTANCES.computeIfAbsent(key, x -> new GraphQLClientsConfiguration());
    }

    // visible for testing
    public static void clear() {
        INSTANCES.clear();
    }

    /**
     * The map storing the configs of each individual client.
     * 

* The key in this map is: * For typesafe clients, the client's `configKey` or, if the `configKey` is not defined, the fully qualified class name * For dynamic clients, always the client's `configKey`. */ private final Map clients = new HashMap<>(); public GraphQLClientsConfiguration() { // Store configuration found in config properties Set detectedClientNames = new HashSet<>(); for (String propertyName : mpConfig.getPropertyNames()) { // assume that the name of a configured client can consist of // uppercase and lowercase letters, numbers, dashes and underscores if (propertyName.matches("^[A-Za-z0-9-_.$]+/mp-graphql/.+$")) { String key = propertyName.substring(0, propertyName.indexOf("/mp-graphql")); if (!clients.containsKey(key)) { detectedClientNames.add(key); } } } for (String clientName : detectedClientNames) { clients.put(clientName, readConfigurationByKey(clientName)); } } private GraphQLClientConfiguration readConfigurationByKey(String clientName) { GraphQLClientConfiguration configuration = new GraphQLClientConfiguration(); // URL mpConfig.getOptionalValue(clientName + "/mp-graphql/url", String.class) .ifPresent(configuration::setUrl); // HTTP headers configuration.setHeaders(getConfiguredHeaders(clientName, mpConfig)); // dynamic headers can't be configured via config properties configuration.setDynamicHeaders(new HashMap<>()); configuration.setInitPayload(getConfiguredInitPayload(clientName, mpConfig)); // websocket subprotocols Optional subprotocolList = mpConfig.getOptionalValue(clientName + "/mp-graphql/subprotocols", String[].class); configuration.setWebsocketSubprotocols(new ArrayList<>()); if (subprotocolList.isPresent()) { for (String s : subprotocolList.get()) { configuration.getWebsocketSubprotocols().add(s); } } // truststore configuration Optional truststore = mpConfig.getOptionalValue(clientName + "/mp-graphql/truststore", String.class); if (truststore.isPresent()) { configuration.setTrustStore(truststore.get()); configuration.setTrustStorePassword( mpConfig.getOptionalValue(clientName + "/mp-graphql/truststorePassword", String.class).orElse(null)); configuration.setTrustStoreType( mpConfig.getOptionalValue(clientName + "/mp-graphql/truststoreType", String.class).orElse(null)); } // keystore configuration Optional keystore = mpConfig.getOptionalValue(clientName + "/mp-graphql/keystore", String.class); if (keystore.isPresent()) { configuration.setKeyStore(keystore.get()); configuration.setKeyStorePassword( mpConfig.getOptionalValue(clientName + "/mp-graphql/keystorePassword", String.class).orElse(null)); configuration.setKeyStoreType( mpConfig.getOptionalValue(clientName + "/mp-graphql/keystoreType", String.class).orElse(null)); } // proxy settings mpConfig.getOptionalValue(clientName + "/mp-graphql/proxyHost", String.class).ifPresent(configuration::setProxyHost); mpConfig.getOptionalValue(clientName + "/mp-graphql/proxyPort", Integer.class).ifPresent(configuration::setProxyPort); mpConfig.getOptionalValue(clientName + "/mp-graphql/proxyUsername", String.class) .ifPresent(configuration::setProxyUsername); mpConfig.getOptionalValue(clientName + "/mp-graphql/proxyPassword", String.class) .ifPresent(configuration::setProxyPassword); mpConfig.getOptionalValue(clientName + "/mp-graphql/maxRedirects", Integer.class) .ifPresent(configuration::setMaxRedirects); mpConfig.getOptionalValue(clientName + "/mp-graphql/websocketInitializationTimeout", Integer.class) .ifPresent(configuration::setWebsocketInitializationTimeout); mpConfig.getOptionalValue(clientName + "/mp-graphql/executeSingleOperationsOverWebsocket", Boolean.class) .ifPresent(configuration::setExecuteSingleOperationsOverWebsocket); mpConfig.getOptionalValue(clientName + "/mp-graphql/allowUnexpectedResponseFields", Boolean.class) .ifPresent(configuration::setAllowUnexpectedResponseFields); return configuration; } /** * Scan the passed Java interfaces for `@GraphQLClientApi` annotations and create and register * client configuration objects for them. This needs to be called by the runtime some time during initialization, * before clients are actually created. * * @deprecated use {@link #initTypesafeClientApi(Class)} */ @Deprecated public void addTypesafeClientApis(List> apis) { if (apis == null) { SmallRyeGraphQLClientLogging.log.apisNotSet(); return; } apis.forEach(this::initTypesafeClientApi); } /** * Scan the passed Java interface for `@GraphQLClientApi` annotations and create and register * client configuration objects for it. This needs to be called by the runtime some time during initialization, * before clients are actually created. */ public void initTypesafeClientApi(Class api) { TypesafeClientConfigurationReader reader = new TypesafeClientConfigurationReader(api); clients.merge(reader.getConfigKey(), reader.getClientConfiguration(), GraphQLClientConfiguration::merge); } public GraphQLClientConfiguration getClient(String key) { return clients.computeIfAbsent(key, this::readConfigurationByKey); } public Map getClients() { return clients; } /** this method is required by Quarkus */ public void addClient(String key, GraphQLClientConfiguration config) { clients.put(key, config); } /** All headers that where configured via MP Config, e.g. xxx/mp-graphql/header/yyy = zzz */ public static Map getConfiguredHeaders(String configKey, Config config) { String prefix = configKey + "/mp-graphql/header/"; return extractMapOfString(config, prefix); } /** All headers that where configured via MP Config, e.g. xxx/mp-graphql/initPayload/yyy = zzz */ public static Map getConfiguredInitPayload(String configKey, Config config) { Map map = new HashMap<>(); String prefix = configKey + "/mp-graphql/initPayload/"; map.putAll(extractMapOfString(config, prefix)); return map; } private static Map extractMapOfString(Config config, String prefix) { Map map = new HashMap<>(); for (String propertyName : config.getPropertyNames()) { if (!propertyName.startsWith(prefix)) { continue; } String name = propertyName.substring(prefix.length()); String value = config.getValue(propertyName, String.class); map.put(name, value); } return map; } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy