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

software.xdev.mockserver.configuration.ServerConfigurationProperties Maven / Gradle / Ivy

There is a newer version: 1.0.8
Show newest version
/*
 * Copyright © 2024 XDEV Software (https://xdev.software)
 *
 * 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 software.xdev.mockserver.configuration;

import static software.xdev.mockserver.character.Character.NEW_LINE;
import static software.xdev.mockserver.logging.MockServerLoggerConfiguration.configureLogger;
import static software.xdev.mockserver.util.StringUtils.isBlank;
import static software.xdev.mockserver.util.StringUtils.isNotBlank;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.Map;
import java.util.Properties;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.event.Level;


@SuppressWarnings("checkstyle:MagicNumber")
public class ServerConfigurationProperties extends ConfigurationProperties
{
	private static final Logger LOG = LoggerFactory.getLogger(ServerConfigurationProperties.class);
	
	private static final String DEFAULT_LOG_LEVEL = "INFO";
	
	// logging
	private static final String MOCKSERVER_LOG_LEVEL = "mockserver.logLevel";
	private static final String MOCKSERVER_DISABLE_SYSTEM_OUT = "mockserver.disableSystemOut";
	private static final String MOCKSERVER_DISABLE_LOGGING = "mockserver.disableLogging";
	private static final String MOCKSERVER_DETAILED_MATCH_FAILURES = "mockserver.detailedMatchFailures";
	
	// memory usage
	private static final String MOCKSERVER_MAX_EXPECTATIONS = "mockserver.maxExpectations";
	private static final String MOCKSERVER_MAX_LOG_ENTRIES = "mockserver.maxLogEntries";
	
	// scalability
	private static final String MOCKSERVER_NIO_EVENT_LOOP_THREAD_COUNT = "mockserver.nioEventLoopThreadCount";
	private static final String MOCKSERVER_ACTION_HANDLER_THREAD_COUNT = "mockserver.actionHandlerThreadCount";
	private static final String MOCKSERVER_MATCHERS_FAIL_FAST = "mockserver.matchersFailFast";
	
	// socket
	private static final String MOCKSERVER_ALWAYS_CLOSE_SOCKET_CONNECTIONS = "mockserver.alwaysCloseSocketConnections";
	private static final String MOCKSERVER_LOCAL_BOUND_IP = "mockserver.localBoundIP";
	
	// http request parsing
	private static final String MOCKSERVER_MAX_INITIAL_LINE_LENGTH = "mockserver.maxInitialLineLength";
	private static final String MOCKSERVER_MAX_HEADER_SIZE = "mockserver.maxHeaderSize";
	private static final String MOCKSERVER_MAX_CHUNK_SIZE = "mockserver.maxChunkSize";
	private static final String MOCKSERVER_USE_SEMICOLON_AS_QUERY_PARAMETER_SEPARATOR =
		"mockserver.useSemicolonAsQueryParameterSeparator";
	private static final String MOCKSERVER_ASSUME_ALL_REQUESTS_ARE_HTTP = "mockserver.assumeAllRequestsAreHttp";
	
	// CORS
	private static final String MOCKSERVER_ENABLE_CORS_FOR_API = "mockserver.enableCORSForAPI";
	private static final String MOCKSERVER_ENABLE_CORS_FOR_ALL_RESPONSES = "mockserver.enableCORSForAllResponses";
	private static final String MOCKSERVER_CORS_ALLOW_ORIGIN = "mockserver.corsAllowOrigin";
	private static final String MOCKSERVER_CORS_ALLOW_METHODS = "mockserver.corsAllowMethods";
	private static final String MOCKSERVER_CORS_ALLOW_HEADERS = "mockserver.corsAllowHeaders";
	private static final String MOCKSERVER_CORS_ALLOW_CREDENTIALS = "mockserver.corsAllowCredentials";
	private static final String MOCKSERVER_CORS_MAX_AGE_IN_SECONDS = "mockserver.corsMaxAgeInSeconds";
	
	// verification
	private static final String MOCKSERVER_MAXIMUM_NUMBER_OF_REQUESTS_TO_RETURN_IN_VERIFICATION_FAILURE =
		"mockserver.maximumNumberOfRequestToReturnInVerificationFailure";
	
	// proxy
	private static final String MOCKSERVER_PROXY_SERVER_REALM = "mockserver.proxyAuthenticationRealm";
	private static final String MOCKSERVER_PROXY_AUTHENTICATION_USERNAME = "mockserver.proxyAuthenticationUsername";
	private static final String MOCKSERVER_PROXY_AUTHENTICATION_PASSWORD = "mockserver.proxyAuthenticationPassword";
	private static final String MOCKSERVER_NO_PROXY_HOSTS = "mockserver.noProxyHosts";
	
	// liveness
	private static final String MOCKSERVER_LIVENESS_HTTP_GET_PATH = "mockserver.livenessHttpGetPath";
	
	// properties file
	private static final String MOCKSERVER_PROPERTY_FILE = "mockserver.propertyFile";
	
	static
	{
		properties = readPropertyFile();
	}
	
	private static Map slf4jOrJavaLoggerToJavaLoggerLevelMapping;
	
	private static Map slf4jOrJavaLoggerToSLF4JLevelMapping;
	
	private static Map getSLF4JOrJavaLoggerToJavaLoggerLevelMapping()
	{
		if(slf4jOrJavaLoggerToJavaLoggerLevelMapping == null)
		{
			slf4jOrJavaLoggerToJavaLoggerLevelMapping = Map.ofEntries(
				Map.entry("TRACE", "FINEST"),
				Map.entry("DEBUG", "FINE"),
				Map.entry("INFO", "INFO"),
				Map.entry("WARN", "WARNING"),
				Map.entry("ERROR", "SEVERE"),
				Map.entry("FINEST", "FINEST"),
				Map.entry("FINE", "FINE"),
				Map.entry("WARNING", "WARNING"),
				Map.entry("SEVERE", "SEVERE"),
				Map.entry("OFF", "OFF")
			);
		}
		return slf4jOrJavaLoggerToJavaLoggerLevelMapping;
	}
	
	private static Map getSLF4JOrJavaLoggerToSLF4JLevelMapping()
	{
		if(slf4jOrJavaLoggerToSLF4JLevelMapping == null)
		{
			slf4jOrJavaLoggerToSLF4JLevelMapping = Map.ofEntries(
				Map.entry("FINEST", "TRACE"),
				Map.entry("FINE", "DEBUG"),
				Map.entry("INFO", "INFO"),
				Map.entry("WARNING", "WARN"),
				Map.entry("SEVERE", "ERROR"),
				Map.entry("TRACE", "TRACE"),
				Map.entry("DEBUG", "DEBUG"),
				Map.entry("WARN", "WARN"),
				Map.entry("ERROR", "ERROR"),
				Map.entry("OFF", "ERROR")
			);
		}
		return slf4jOrJavaLoggerToSLF4JLevelMapping;
	}
	
	private static String propertyFile()
	{
		if(isNotBlank(System.getProperty(MOCKSERVER_PROPERTY_FILE)) && System.getProperty(MOCKSERVER_PROPERTY_FILE)
			.equals("/config/mockserver.properties"))
		{
			return isBlank(System.getenv("MOCKSERVER_PROPERTY_FILE"))
				? System.getProperty(MOCKSERVER_PROPERTY_FILE)
				: System.getenv("MOCKSERVER_PROPERTY_FILE");
		}
		else
		{
			return System.getProperty(
				MOCKSERVER_PROPERTY_FILE,
				isBlank(System.getenv("MOCKSERVER_PROPERTY_FILE"))
					? "mockserver.properties"
					: System.getenv("MOCKSERVER_PROPERTY_FILE"));
		}
	}
	
	// logging
	
	public static Level logLevel()
	{
		final String logLevel = readPropertyHierarchically(
			properties,
			MOCKSERVER_LOG_LEVEL,
			"MOCKSERVER_LOG_LEVEL",
			DEFAULT_LOG_LEVEL).toUpperCase();
		if(isNotBlank(logLevel))
		{
			if(getSLF4JOrJavaLoggerToSLF4JLevelMapping().get(logLevel).equals("OFF"))
			{
				return null;
			}
			else
			{
				return Level.valueOf(getSLF4JOrJavaLoggerToSLF4JLevelMapping().get(logLevel));
			}
		}
		else
		{
			return Level.INFO;
		}
	}
	
	public static String javaLoggerLogLevel()
	{
		final String logLevel = readPropertyHierarchically(
			properties,
			MOCKSERVER_LOG_LEVEL,
			"MOCKSERVER_LOG_LEVEL",
			DEFAULT_LOG_LEVEL).toUpperCase();
		if(isNotBlank(logLevel))
		{
			if(getSLF4JOrJavaLoggerToJavaLoggerLevelMapping().get(logLevel).equals("OFF"))
			{
				return "OFF";
			}
			else
			{
				return getSLF4JOrJavaLoggerToJavaLoggerLevelMapping().get(logLevel);
			}
		}
		else
		{
			return "INFO";
		}
	}
	
	/**
	 * Override the default logging level of INFO
	 *
	 * @param level the log level, which can be TRACE, DEBUG, INFO, WARN, ERROR, OFF, FINEST, FINE, INFO, WARNING,
	 *              SEVERE
	 */
	public static void logLevel(final String level)
	{
		if(isNotBlank(level))
		{
			if(!getSLF4JOrJavaLoggerToSLF4JLevelMapping().containsKey(level))
			{
				throw new IllegalArgumentException("log level \"" + level
					+ "\" is not legal it must be one of SL4J levels: \"TRACE\", \"DEBUG\", \"INFO\", \"WARN\", "
					+ "\"ERROR\", \"OFF\", or the Java Logger levels: \"FINEST\", \"FINE\", \"INFO\", \"WARNING\", "
					+ "\"SEVERE\", \"OFF\"");
			}
			setProperty(MOCKSERVER_LOG_LEVEL, level);
		}
		configureLogger();
	}
	
	public static void temporaryLogLevel(final String level, final Runnable runnable)
	{
		final Level originalLogLevel = logLevel();
		try
		{
			logLevel(level);
			runnable.run();
		}
		finally
		{
			if(originalLogLevel != null)
			{
				logLevel(originalLogLevel.name());
			}
		}
	}
	
	public static boolean disableSystemOut()
	{
		return Boolean.parseBoolean(readPropertyHierarchically(
			properties,
			MOCKSERVER_DISABLE_SYSTEM_OUT,
			"MOCKSERVER_DISABLE_SYSTEM_OUT",
			String.valueOf(false)));
	}
	
	/**
	 * Disable printing log to system out for JVM, default is enabled
	 *
	 * @param disable printing log to system out for JVM
	 */
	public static void disableSystemOut(final boolean disable)
	{
		setProperty(MOCKSERVER_DISABLE_SYSTEM_OUT, String.valueOf(disable));
		configureLogger();
	}
	
	public static boolean disableLogging()
	{
		return Boolean.parseBoolean(readPropertyHierarchically(
			properties,
			MOCKSERVER_DISABLE_LOGGING,
			"MOCKSERVER_DISABLE_LOGGING",
			String.valueOf(false)));
	}
	
	/**
	 * Disable all logging and processing of log events
	 * 

* The default is false * * @param disable disable all logging */ public static void disableLogging(final boolean disable) { setProperty(MOCKSERVER_DISABLE_LOGGING, String.valueOf(disable)); configureLogger(); } public static boolean detailedMatchFailures() { return Boolean.parseBoolean(readPropertyHierarchically( properties, MOCKSERVER_DETAILED_MATCH_FAILURES, "MOCKSERVER_DETAILED_MATCH_FAILURES", String.valueOf(true))); } /** * If true (the default) the log event recording that a request matcher did not match will include a detailed * reason * why each non matching field did not match. * * @param enable enabled detailed match failure log events */ public static void detailedMatchFailures(final boolean enable) { setProperty(MOCKSERVER_DETAILED_MATCH_FAILURES, String.valueOf(enable)); } public static int maxExpectations() { return readIntegerProperty(MOCKSERVER_MAX_EXPECTATIONS, "MOCKSERVER_MAX_EXPECTATIONS", 5000); } /** *

* Maximum number of expectations stored in memory. Expectations are stored in a circular queue so once this limit * is reach the oldest and lowest priority expectations are overwritten *

*

* The default maximum depends on the available memory in the JVM with an upper limit of 5000 *

* * @param count maximum number of expectations to store */ public static void maxExpectations(final int count) { setProperty(MOCKSERVER_MAX_EXPECTATIONS, String.valueOf(count)); } public static int maxLogEntries() { return readIntegerProperty(MOCKSERVER_MAX_LOG_ENTRIES, "MOCKSERVER_MAX_LOG_ENTRIES", 60000); } /** *

* Maximum number of log entries stored in memory. Log entries are stored in a circular queue so once this * limit is * reach the oldest log entries are overwritten. *

*

* The default maximum depends on the available memory in the JVM with an upper limit of 60000, but can be * overridden using defaultMaxLogEntries *

* * @param count maximum number of expectations to store */ public static void maxLogEntries(final int count) { setProperty(MOCKSERVER_MAX_LOG_ENTRIES, String.valueOf(count)); } // scalability public static int nioEventLoopThreadCount() { return readIntegerProperty(MOCKSERVER_NIO_EVENT_LOOP_THREAD_COUNT, "MOCKSERVER_NIO_EVENT_LOOP_THREAD_COUNT", 5); } /** *

Netty worker thread pool size for handling requests and response. These threads are used for fast * non-blocking activities such as, reading and de-serialise all requests and responses.

* * @param count Netty worker thread pool size */ public static void nioEventLoopThreadCount(final int count) { setProperty(MOCKSERVER_NIO_EVENT_LOOP_THREAD_COUNT, String.valueOf(count)); } public static int actionHandlerThreadCount() { return readIntegerProperty( MOCKSERVER_ACTION_HANDLER_THREAD_COUNT, "MOCKSERVER_ACTION_HANDLER_THREAD_COUNT", Math.max(5, Runtime.getRuntime().availableProcessors())); } /** *

Number of threads for the action handler thread pool

*

These threads are used for handling actions such as:

*
    *
  • serialising and writing expectation or proxied responses
  • *
  • handling response delays in a non-blocking way (i.e. using a scheduler)
  • *
  • executing class callbacks
  • *
  • handling method / closure callbacks (using web sockets)
  • *
*

*

Default is maximum of 5 or available processors count

* * @param count Netty worker thread pool size */ public static void actionHandlerThreadCount(final int count) { setProperty(MOCKSERVER_ACTION_HANDLER_THREAD_COUNT, String.valueOf(count)); } public static boolean matchersFailFast() { return Boolean.parseBoolean(readPropertyHierarchically( properties, MOCKSERVER_MATCHERS_FAIL_FAST, "MOCKSERVER_MATCHERS_FAIL_FAST", String.valueOf(true))); } /** * If true (the default) request matchers will fail on the first non-matching field, if false request matchers will * compare all fields. This is useful to see all mismatching fields in the log event recording that a request * matcher did not match. * * @param enable enabled request matchers failing fast */ public static void matchersFailFast(final boolean enable) { setProperty(MOCKSERVER_MATCHERS_FAIL_FAST, String.valueOf(enable)); } // socket /** *

If true socket connections will always be closed after a response is returned, if false connection is only * closed if request header indicate connection should be closed.

*

* Default is false * * @param alwaysClose true socket connections will always be closed after a response is returned */ public static void alwaysCloseSocketConnections(final boolean alwaysClose) { setProperty(MOCKSERVER_ALWAYS_CLOSE_SOCKET_CONNECTIONS, String.valueOf(alwaysClose)); } public static boolean alwaysCloseSocketConnections() { return Boolean.parseBoolean(readPropertyHierarchically( properties, MOCKSERVER_ALWAYS_CLOSE_SOCKET_CONNECTIONS, "MOCKSERVER_ALWAYS_CLOSE_SOCKET_CONNECTIONS", "false")); } public static String localBoundIP() { return readPropertyHierarchically(properties, MOCKSERVER_LOCAL_BOUND_IP, "MOCKSERVER_LOCAL_BOUND_IP", ""); } /** * The local IP address to bind to for accepting new socket connections *

* Default is 0.0.0.0 * * @param localBoundIP local IP address to bind to for accepting new socket connections */ public static void localBoundIP(final String localBoundIP) { if(isNotBlank(localBoundIP)) { setProperty(MOCKSERVER_LOCAL_BOUND_IP, localBoundIP); } } // http request parsing public static int maxInitialLineLength() { return readIntegerProperty( MOCKSERVER_MAX_INITIAL_LINE_LENGTH, "MOCKSERVER_MAX_INITIAL_LINE_LENGTH", Integer.MAX_VALUE); } /** * Maximum size of the first line of an HTTP request *

* The default is Integer.MAX_VALUE * * @param length maximum size of the first line of an HTTP request */ public static void maxInitialLineLength(final int length) { setProperty(MOCKSERVER_MAX_INITIAL_LINE_LENGTH, String.valueOf(length)); } public static int maxHeaderSize() { return readIntegerProperty(MOCKSERVER_MAX_HEADER_SIZE, "MOCKSERVER_MAX_HEADER_SIZE", Integer.MAX_VALUE); } /** * Maximum size of HTTP request headers *

* The default is Integer.MAX_VALUE * * @param size maximum size of HTTP request headers */ public static void maxHeaderSize(final int size) { setProperty(MOCKSERVER_MAX_HEADER_SIZE, String.valueOf(size)); } public static int maxChunkSize() { return readIntegerProperty(MOCKSERVER_MAX_CHUNK_SIZE, "MOCKSERVER_MAX_CHUNK_SIZE", Integer.MAX_VALUE); } /** * Maximum size of HTTP chunks in request or responses *

* The default is Integer.MAX_VALUE * * @param size maximum size of HTTP chunks in request or responses */ public static void maxChunkSize(final int size) { setProperty(MOCKSERVER_MAX_CHUNK_SIZE, String.valueOf(size)); } /** * If true semicolons are treated as a separator for a query parameter string, if false the semicolon is treated as * a normal character that is part of a query parameter value. *

* The default is true * * @param useAsQueryParameterSeparator true semicolons are treated as a separator for a query parameter string */ public static void useSemicolonAsQueryParameterSeparator(final boolean useAsQueryParameterSeparator) { setProperty( MOCKSERVER_USE_SEMICOLON_AS_QUERY_PARAMETER_SEPARATOR, String.valueOf(useAsQueryParameterSeparator)); } public static boolean useSemicolonAsQueryParameterSeparator() { return Boolean.parseBoolean(readPropertyHierarchically( properties, MOCKSERVER_USE_SEMICOLON_AS_QUERY_PARAMETER_SEPARATOR, "MOCKSERVER_USE_SEMICOLON_AS_QUERY_PARAMETER_SEPARATOR", "true")); } /** * If true requests are assumed as binary if the method isn't one of "GET", "POST", "PUT", "HEAD", "OPTIONS", * "PATCH", "DELETE", "TRACE" or "CONNECT" *

* The default is true * * @param assumeAllRequestsAreHttp if true requests are assumed as binary if the method isn't one of "GET", "POST", * "PUT", "HEAD", "OPTIONS", "PATCH", "DELETE", "TRACE" or "CONNECT" */ public static void assumeAllRequestsAreHttp(final boolean assumeAllRequestsAreHttp) { setProperty(MOCKSERVER_ASSUME_ALL_REQUESTS_ARE_HTTP, String.valueOf(assumeAllRequestsAreHttp)); } public static boolean assumeAllRequestsAreHttp() { return Boolean.parseBoolean(readPropertyHierarchically( properties, MOCKSERVER_ASSUME_ALL_REQUESTS_ARE_HTTP, "MOCKSERVER_ASSUME_ALL_REQUESTS_ARE_HTTP", "false")); } // CORS public static boolean enableCORSForAPI() { return Boolean.parseBoolean(readPropertyHierarchically( properties, MOCKSERVER_ENABLE_CORS_FOR_API, "MOCKSERVER_ENABLE_CORS_FOR_API", "false")); } /** * Enable CORS for MockServer REST API so that the API can be used for javascript running in browsers, such as * selenium *

* The default is false * * @param enable CORS for MockServer REST API */ public static void enableCORSForAPI(final boolean enable) { setProperty(MOCKSERVER_ENABLE_CORS_FOR_API, String.valueOf(enable)); } public static boolean enableCORSForAllResponses() { return Boolean.parseBoolean(readPropertyHierarchically( properties, MOCKSERVER_ENABLE_CORS_FOR_ALL_RESPONSES, "MOCKSERVER_ENABLE_CORS_FOR_ALL_RESPONSES", "false")); } /** * Enable CORS for all responses from MockServer, including the REST API and expectation responses *

* The default is false * * @param enable CORS for all responses from MockServer */ public static void enableCORSForAllResponses(final boolean enable) { setProperty(MOCKSERVER_ENABLE_CORS_FOR_ALL_RESPONSES, String.valueOf(enable)); } public static String corsAllowOrigin() { return readPropertyHierarchically(properties, MOCKSERVER_CORS_ALLOW_ORIGIN, "MOCKSERVER_CORS_ALLOW_ORIGIN", ""); } /** *

the value used for CORS in the access-control-allow-origin header.

*

The default is ""

* * @param corsAllowOrigin the value used for CORS in the access-control-allow-methods header */ public static void corsAllowOrigin(final String corsAllowOrigin) { setProperty(MOCKSERVER_CORS_ALLOW_ORIGIN, corsAllowOrigin); } public static String corsAllowMethods() { return readPropertyHierarchically( properties, MOCKSERVER_CORS_ALLOW_METHODS, "MOCKSERVER_CORS_ALLOW_METHODS", ""); } /** *

The value used for CORS in the access-control-allow-methods header.

*

The default is "CONNECT, DELETE, GET, HEAD, OPTIONS, POST, PUT, PATCH, TRACE"

* * @param corsAllowMethods the value used for CORS in the access-control-allow-methods header */ public static void corsAllowMethods(final String corsAllowMethods) { setProperty(MOCKSERVER_CORS_ALLOW_METHODS, corsAllowMethods); } public static String corsAllowHeaders() { return readPropertyHierarchically( properties, MOCKSERVER_CORS_ALLOW_HEADERS, "MOCKSERVER_CORS_ALLOW_HEADERS", ""); } /** *

the value used for CORS in the access-control-allow-headers and access-control-expose-headers headers.

*

In addition to this default value any headers specified in the request header access-control-request-headers * also get added to access-control-allow-headers and access-control-expose-headers headers in a CORS response.

*

The default is "Allow, Content-Encoding, Content-Length, Content-Type, ETag, Expires, Last-Modified, * Location, Server, Vary, Authorization"

* * @param corsAllowHeaders the value used for CORS in the access-control-allow-headers and * access-control-expose-headers headers */ public static void corsAllowHeaders(final String corsAllowHeaders) { setProperty(MOCKSERVER_CORS_ALLOW_HEADERS, corsAllowHeaders); } public static boolean corsAllowCredentials() { return Boolean.parseBoolean(readPropertyHierarchically( properties, MOCKSERVER_CORS_ALLOW_CREDENTIALS, "MOCKSERVER_CORS_ALLOW_CREDENTIALS", "false")); } /** * The value used for CORS in the access-control-allow-credentials header. *

* The default is true * * @param allow the value used for CORS in the access-control-allow-credentials header */ public static void corsAllowCredentials(final boolean allow) { setProperty(MOCKSERVER_CORS_ALLOW_CREDENTIALS, String.valueOf(allow)); } public static int corsMaxAgeInSeconds() { return readIntegerProperty(MOCKSERVER_CORS_MAX_AGE_IN_SECONDS, "MOCKSERVER_CORS_MAX_AGE_IN_SECONDS", 0); } /** * The value used for CORS in the access-control-max-age header. *

* The default is 300 * * @param ageInSeconds the value used for CORS in the access-control-max-age header. */ public static void corsMaxAgeInSeconds(final int ageInSeconds) { setProperty(MOCKSERVER_CORS_MAX_AGE_IN_SECONDS, String.valueOf(ageInSeconds)); } // verification public static Integer maximumNumberOfRequestToReturnInVerificationFailure() { return readIntegerProperty( MOCKSERVER_MAXIMUM_NUMBER_OF_REQUESTS_TO_RETURN_IN_VERIFICATION_FAILURE, "MOCKSERVER_MAXIMUM_NUMBER_OF_REQUESTS_TO_RETURN_IN_VERIFICATION_FAILURE", 10); } /** * The maximum number of requests to return in verification failure result, if more expectations are found the * failure result does not list them separately * * @param maximumNumberOfRequestToReturnInVerification maximum number of expectations to return in verification * failure result */ public static void maximumNumberOfRequestToReturnInVerificationFailure( final Integer maximumNumberOfRequestToReturnInVerification) { setProperty( MOCKSERVER_MAXIMUM_NUMBER_OF_REQUESTS_TO_RETURN_IN_VERIFICATION_FAILURE, String.valueOf(maximumNumberOfRequestToReturnInVerification)); } // proxy public static String proxyAuthenticationRealm() { return readPropertyHierarchically( properties, MOCKSERVER_PROXY_SERVER_REALM, "MOCKSERVER_PROXY_SERVER_REALM", "MockServer HTTP Proxy"); } /** * The authentication realm for proxy authentication to MockServer * * @param proxyAuthenticationRealm the authentication realm for proxy authentication */ public static void proxyAuthenticationRealm(final String proxyAuthenticationRealm) { setProperty(MOCKSERVER_PROXY_SERVER_REALM, proxyAuthenticationRealm); } public static String proxyAuthenticationUsername() { return readPropertyHierarchically( properties, MOCKSERVER_PROXY_AUTHENTICATION_USERNAME, "MOCKSERVER_PROXY_AUTHENTICATION_USERNAME", ""); } /** *

The required username for proxy authentication to MockServer

*

Note: 8u111 Update Release Notes state * that the Basic authentication scheme has been deactivated when setting up an HTTPS tunnel. To resolve this * clear * or set to an empty string the following system properties: jdk.http.auth.tunneling.disabledSchemes and jdk.http.auth.proxying.disabledSchemes.

*

* The default is "" * * @param proxyAuthenticationUsername required username for proxy authentication to MockServer */ public static void proxyAuthenticationUsername(final String proxyAuthenticationUsername) { setProperty(MOCKSERVER_PROXY_AUTHENTICATION_USERNAME, proxyAuthenticationUsername); } public static String proxyAuthenticationPassword() { return readPropertyHierarchically( properties, MOCKSERVER_PROXY_AUTHENTICATION_PASSWORD, "MOCKSERVER_PROXY_AUTHENTICATION_PASSWORD", ""); } /** *

The list of hostnames to not use the configured proxy. Several values may be present, seperated by comma * (,)

The default is "" * * @param noProxyHosts Comma-seperated list of hosts to not be proxied. */ public static void noProxyHosts(final String noProxyHosts) { setProperty(MOCKSERVER_NO_PROXY_HOSTS, noProxyHosts); } public static String noProxyHosts() { return readPropertyHierarchically(properties, MOCKSERVER_NO_PROXY_HOSTS, "MOCKSERVER_NO_PROXY_HOSTS", ""); } /** *

The required password for proxy authentication to MockServer

*

Note: 8u111 Update Release Notes state * that the Basic authentication scheme has been deactivated when setting up an HTTPS tunnel. To resolve this * clear * or set to an empty string the following system properties: jdk.http.auth.tunneling.disabledSchemes and jdk.http.auth.proxying.disabledSchemes.

*

* The default is "" * * @param proxyAuthenticationPassword required password for proxy authentication to MockServer */ public static void proxyAuthenticationPassword(final String proxyAuthenticationPassword) { setProperty(MOCKSERVER_PROXY_AUTHENTICATION_PASSWORD, proxyAuthenticationPassword); } // liveness public static String livenessHttpGetPath() { return readPropertyHierarchically( properties, MOCKSERVER_LIVENESS_HTTP_GET_PATH, "MOCKSERVER_LIVENESS_HTTP_GET_PATH", ""); } /** * Path to support HTTP GET requests for status response (also available on PUT /mockserver/status). *

* If this value is not modified then only PUT /mockserver/status but is a none blank value is provided for this * value then GET requests to this path will return the 200 Ok status response showing the MockServer version and * bound ports. *

* A GET request to this path will be matched before any expectation matching or proxying of requests. *

* The default is "" * * @param livenessPath path to support HTTP GET requests for status response */ public static void livenessHttpGetPath(final String livenessPath) { setProperty(MOCKSERVER_LIVENESS_HTTP_GET_PATH, livenessPath); } @SuppressWarnings({"ConstantConditions", "PMD.CognitiveComplexity"}) private static Properties readPropertyFile() { final Properties properties = new Properties(); try(final InputStream inputStream = ServerConfigurationProperties.class.getClassLoader() .getResourceAsStream(propertyFile())) { if(inputStream != null) { try { properties.load(inputStream); } catch(final IOException e) { LOG.error("Exception loading property file [{}]", propertyFile(), e); } } else { if(LOG.isDebugEnabled()) { LOG.debug("Property file not found on classpath using path [{}]", propertyFile()); } try(final FileInputStream fis = new FileInputStream(propertyFile())) { properties.load(fis); } catch(final FileNotFoundException e) { if(LOG.isDebugEnabled()) { LOG.debug("Property file not found using path [{}]", propertyFile(), e); } } catch(final IOException e) { LOG.error("Exception loading property file [{}]", propertyFile(), e); } } } catch(final IOException ioe) { // ignore } if(!properties.isEmpty()) { final Enumeration propertyNames = properties.propertyNames(); final StringBuilder propertiesLogDump = new StringBuilder(50); propertiesLogDump.append("Reading properties from property file [") .append(propertyFile()) .append("]:") .append(NEW_LINE); while(propertyNames.hasMoreElements()) { final String propertyName = String.valueOf(propertyNames.nextElement()); propertiesLogDump.append(" ") .append(propertyName) .append(" = ") .append(properties.getProperty(propertyName)) .append(NEW_LINE); } final Level logLevel = Level.valueOf(getSLF4JOrJavaLoggerToSLF4JLevelMapping().get(readPropertyHierarchically( properties, MOCKSERVER_LOG_LEVEL, "MOCKSERVER_LOG_LEVEL", DEFAULT_LOG_LEVEL).toUpperCase())); if(LOG.isEnabledForLevel(logLevel)) { LOG.info(propertiesLogDump.toString()); } } return properties; } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy