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

com.helger.smpclient.config.SMPClientConfiguration Maven / Gradle / Ivy

/**
 * Copyright (C) 2015-2021 Philip Helger
 * philip[at]helger[dot]com
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *         http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.helger.smpclient.config;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
import java.security.KeyStore;

import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;

import org.apache.http.HttpHost;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.helger.commons.ValueEnforcer;
import com.helger.commons.concurrent.SimpleReadWriteLock;
import com.helger.commons.equals.EqualsHelper;
import com.helger.commons.exception.InitializationException;
import com.helger.commons.io.resource.IReadableResource;
import com.helger.commons.io.resourceprovider.ReadableResourceProviderChain;
import com.helger.commons.string.StringHelper;
import com.helger.commons.system.SystemProperties;
import com.helger.config.Config;
import com.helger.config.ConfigFactory;
import com.helger.config.IConfig;
import com.helger.config.source.EConfigSourceType;
import com.helger.config.source.MultiConfigurationValueProvider;
import com.helger.config.source.res.ConfigurationSourceProperties;
import com.helger.config.value.ConfiguredValue;
import com.helger.httpclient.HttpClientSettings;
import com.helger.peppol.utils.PeppolKeyStoreHelper;
import com.helger.security.keystore.EKeyStoreType;
import com.helger.security.keystore.KeyStoreHelper;

/**
 * This class manages the configuration properties of the SMP client. The order
 * of the properties file resolving is as follows:
 * 
    *
  1. Check for the value of the system property * peppol.smp.client.properties.path
  2. *
  3. Check for the value of the system property * smp.client.properties.path
  4. *
  5. The filename private-smp-client.properties in the root of * the classpath
  6. *
  7. The filename smp-client.properties in the root of the * classpath
  8. *
*

* Note: this class is also licensed under Apache 2 license, as it was not part * of the original implementation *

* * @author Philip Helger */ @Immutable public final class SMPClientConfiguration { private static final Logger LOGGER = LoggerFactory.getLogger (SMPClientConfiguration.class); static { // Since 8.2.0 if (StringHelper.hasText (SystemProperties.getPropertyValueOrNull ("peppol.smp.client.properties.path"))) throw new InitializationException ("The system property 'peppol.smp.client.properties.path' is no longer supported." + " See https://github.com/phax/ph-commons#ph-config for alternatives." + " Consider using the system property 'config.file' instead."); if (StringHelper.hasText (SystemProperties.getPropertyValueOrNull ("smp.client.properties.path"))) throw new InitializationException ("The system property 'smp.client.properties.path' is no longer supported." + " See https://github.com/phax/ph-commons#ph-config for alternatives." + " Consider using the system property 'config.file' instead."); if (StringHelper.hasText (System.getenv ().get ("SMP_CLIENT_CONFIG"))) throw new InitializationException ("The environment variable 'SMP_CLIENT_CONFIG' is no longer supported." + " See https://github.com/phax/ph-commons#ph-config for alternatives." + " Consider using the environment variable 'CONFIG_FILE' instead."); } /** * @return The configuration value provider for phase4 that contains backward * compatibility support. */ @Nonnull public static MultiConfigurationValueProvider createSMPClientValueProvider () { // Start with default setup final MultiConfigurationValueProvider ret = ConfigFactory.createDefaultValueProvider (); final ReadableResourceProviderChain aResourceProvider = ConfigFactory.createDefaultResourceProviderChain (); IReadableResource aRes; final int nBasePrio = ConfigFactory.APPLICATION_PROPERTIES_PRIORITY; // Lower priority than the standard files aRes = aResourceProvider.getReadableResourceIf ("private-smp-client.properties", IReadableResource::exists); if (aRes != null) { LOGGER.warn ("The support for the properties file 'private-smp-client.properties' is deprecated. Place the properties in 'application.properties' instead."); ret.addConfigurationSource (new ConfigurationSourceProperties (aRes, StandardCharsets.UTF_8), nBasePrio - 1); } aRes = aResourceProvider.getReadableResourceIf ("smp-client.properties", IReadableResource::exists); if (aRes != null) { LOGGER.warn ("The support for the properties file 'smp-client.properties' is deprecated. Place the properties in 'application.properties' instead."); ret.addConfigurationSource (new ConfigurationSourceProperties (aRes, StandardCharsets.UTF_8), nBasePrio - 2); } return ret; } private static final IConfig DEFAULT_INSTANCE = Config.create (createSMPClientValueProvider ()); private static final SimpleReadWriteLock s_aRWLock = new SimpleReadWriteLock (); private static IConfig s_aConfig = DEFAULT_INSTANCE; private SMPClientConfiguration () {} /** * @return The current global configuration. Never null. */ @Nonnull public static IConfig getConfig () { // Inline for performance s_aRWLock.readLock ().lock (); try { return s_aConfig; } finally { s_aRWLock.readLock ().unlock (); } } /** * Overwrite the global configuration. This is only needed for testing. * * @param aNewConfig * The configuration to use globally. May not be null. * @return The old value of {@link IConfig}. Never null. */ @Nonnull public static IConfig setConfig (@Nonnull final IConfig aNewConfig) { ValueEnforcer.notNull (aNewConfig, "NewConfig"); final IConfig ret; s_aRWLock.writeLock ().lock (); try { ret = s_aConfig; s_aConfig = aNewConfig; } finally { s_aRWLock.writeLock ().unlock (); } if (!EqualsHelper.identityEqual (ret, aNewConfig)) LOGGER.info ("The SMPClient configuration provider was changed to " + aNewConfig); return ret; } private static void _logRenamedConfig (@Nonnull final String sOld, @Nonnull final String sNew) { LOGGER.warn ("Please rename the configuration property '" + sOld + "' to '" + sNew + "'. Support for the old property name will be removed in v9.0."); } /** * @return The truststore type as specified in the configuration file by the * key truststore.type. If none is present * {@link PeppolKeyStoreHelper#TRUSTSTORE_TYPE} is returned as a * default. * @since 6.0.0 */ @Nonnull public static EKeyStoreType getTrustStoreType () { final String sType = getConfig ().getAsString ("truststore.type"); return EKeyStoreType.getFromIDCaseInsensitiveOrDefault (sType, PeppolKeyStoreHelper.TRUSTSTORE_TYPE); } /** * @return The truststore location as specified in the configuration file by * the key truststore.path. If none is present * {@link PeppolKeyStoreHelper#TRUSTSTORE_COMPLETE_CLASSPATH} is * returned as a default. Note: for backwards compatibility, also the * key truststore.location is evaluated. * @since 6.0.0 - was getTruststoreLocation before */ @Nonnull public static String getTrustStorePath () { String ret = getConfig ().getAsString ("truststore.path"); if (ret == null) { ret = getConfig ().getAsString ("truststore.location"); if (StringHelper.hasText (ret)) { _logRenamedConfig ("truststore.location", "truststore.path"); return ret; } } if (StringHelper.hasNoText (ret)) ret = PeppolKeyStoreHelper.TRUSTSTORE_COMPLETE_CLASSPATH; return ret; } /** * @return The truststore password as specified in the configuration file by * the key truststore.password. If none is present * {@link PeppolKeyStoreHelper#TRUSTSTORE_PASSWORD} is returned as a * default. */ @Nonnull public static String getTrustStorePassword () { return getConfig ().getAsString ("truststore.password", PeppolKeyStoreHelper.TRUSTSTORE_PASSWORD); } /** * Try to load the configured trust store. * * @return null if it cannot be loaded. * @since 8.1.1 */ @Nullable public static KeyStore loadTrustStore () { try { return KeyStoreHelper.loadKeyStoreDirect (getTrustStoreType (), getTrustStorePath (), getTrustStorePassword ()); } catch (final GeneralSecurityException | IOException ex) { return null; } } /** * @return The HttpProxy object to be used by SMP clients based on the Java * System properties "http.proxyHost" and "http.proxyPort". Note: * https is not needed, because SMPs must run on http only. */ @Nullable public static HttpHost getHttpProxy () { final String sProxyHost = getConfig ().getAsString ("http.proxyHost"); final int nProxyPort = getConfig ().getAsInt ("http.proxyPort", 0); if (sProxyHost != null && nProxyPort > 0) return new HttpHost (sProxyHost, nProxyPort); return null; } /** * @return The {@link UsernamePasswordCredentials} object to be used for proxy * server authentication. * @since 5.2.5 */ @Nullable public static UsernamePasswordCredentials getHttpProxyCredentials () { final String sProxyUsername = getConfig ().getAsString ("http.proxyUsername"); final String sProxyPassword = getConfig ().getAsString ("http.proxyPassword"); if (sProxyUsername != null && sProxyPassword != null) return new UsernamePasswordCredentials (sProxyUsername, sProxyPassword); return null; } /** * @return A pipe separated list of non-proxy hosts. E.g. * localhost|127.0.0.1. May be null. * @since 6.2.4 */ @Nullable public static String getNonProxyHosts () { return getConfig ().getAsString ("http.nonProxyHosts"); } /** * Get the content of the property "http.useSystemProperties" or * false if undefined. * * @return true if the SMP client proxy configuration should be * take from the system properties, or false if not. The * default behavior is to return false. * @since 5.2.4 */ public static boolean isUseProxySystemProperties () { return getConfig ().getAsBoolean ("http.useSystemProperties", HttpClientSettings.DEFAULT_USE_SYSTEM_PROPERTIES); } /** * Get the content of the property "http.useDNSClientCache" or * true if undefined. * * @return true if the SMP client should use DNS client caching * (default) or false if DNS caching should be disabled. * The default behavior is to return true. * @since 5.2.5 */ public static boolean isUseDNSClientCache () { return getConfig ().getAsBoolean ("http.useDNSClientCache", HttpClientSettings.DEFAULT_USE_DNS_CACHE); } /** * Get the content of the property "http.connect.timeout.ms" or the default * value. * * @return The connection timeout of the SMP client in milliseconds. Defaults * to 5 seconds. * @since 7.0.4 */ public static int getConnectionTimeoutMS () { return getConfig ().getAsInt ("http.connect.timeout.ms", HttpClientSettings.DEFAULT_CONNECTION_TIMEOUT_MS); } /** * Get the content of the property "http.request.timeout.ms" or the default * value. * * @return The request timeout of the SMP client in milliseconds. Defaults to * 10 seconds. * @since 7.0.4 */ public static int getRequestTimeoutMS () { return getConfig ().getAsInt ("http.request.timeout.ms", HttpClientSettings.DEFAULT_SOCKET_TIMEOUT_MS); } /** * This is a utility method, that takes the provided property names, checks if * they are defined in the configuration and if so, applies applies them as * System properties. It does it only when the configuration file was read * correctly. * * @param aPropertyNames * The property names to consider. */ public static void applyAsSystemProperties (@Nullable final String... aPropertyNames) { if (aPropertyNames != null) for (final String sProperty : aPropertyNames) { final ConfiguredValue aValue = getConfig ().getConfiguredValue (sProperty); if (aValue != null && aValue.getConfigurationSource ().getSourceType () == EConfigSourceType.RESOURCE && aValue.getValue () != null) { final String sConfigFileValue = aValue.getValue (); SystemProperties.setPropertyValue (sProperty, sConfigFileValue); if (LOGGER.isInfoEnabled ()) LOGGER.info ("Set Java system property from configuration: " + sProperty + "=" + sConfigFileValue); } } } /** * This is a utility method, that applies all Java network/proxy system * properties which are present in this configuration file. It does it only * when the configuration file was read correctly. * * @see SystemProperties#getAllJavaNetSystemProperties() */ public static void applyAllNetworkSystemProperties () { applyAsSystemProperties (SystemProperties.getAllJavaNetSystemProperties ()); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy