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

io.rxmicro.rest.server.RestServerConfig Maven / Gradle / Ivy

/*
 * Copyright (c) 2020. https://rxmicro.io
 *
 * 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 io.rxmicro.rest.server;

import io.rxmicro.common.meta.BuilderMethod;
import io.rxmicro.config.Config;
import io.rxmicro.rest.server.feature.RequestIdGenerator;

import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

import static io.rxmicro.common.util.Requires.require;

/**
 * Allows configuring a REST server options.
 *
 * @author nedis
 * @see RequestIdGeneratorProvider
 * @since 0.1
 */
@SuppressWarnings("UnusedReturnValue")
public class RestServerConfig extends Config {

    /**
     * Default "Handler not found" error status code.
     */
    public static final int DEFAULT_HANDLER_NOT_FOUND_ERROR_STATUS_CODE = 400;

    /**
     * Default "CORS not allowed" error status code.
     *
     * @see https://fetch.spec.whatwg.org/#cors-protocol
     */
    public static final int DEFAULT_CORS_NOT_ALLOWED_ERROR_STATUS_CODE = 200;

    /**
     * Default timeout used to verify that the next request id generation method is not blocked by operation system.
     *
     * @see RequestIdGeneratorProvider#getRequestIdGenerator(RestServerConfig)
     * @see io.rxmicro.rest.server.RequestIdGeneratorProvider.CurrentRequestIdGeneratorCantBeUsedException
     */
    public static final int DEFAULT_WAITING_FOR_REQUEST_ID_GENERATOR_INIT_TIMEOUT_IN_MILLIS = 3_000;

    private int handlerNotFoundErrorStatusCode = DEFAULT_HANDLER_NOT_FOUND_ERROR_STATUS_CODE;

    private String handlerNotFoundErrorMessage = "Handler not found";

    private int corsNotAllowedErrorStatusCode = DEFAULT_CORS_NOT_ALLOWED_ERROR_STATUS_CODE;

    private String corsNotAllowedErrorMessage = "CORS not allowed";

    private boolean humanReadableOutput;

    private boolean hideInternalErrorMessage = true;

    private boolean logHttpErrorExceptions = true;

    private Set staticResponseHeaders = new LinkedHashSet<>(
            List.of(
                    PredefinedStaticResponseHeader.SERVER,
                    PredefinedStaticResponseHeader.DATE
            )
    );

    private RequestIdGeneratorProvider requestIdGeneratorProvider = PredefinedRequestIdGeneratorProvider.DEFAULT_96_BIT;

    private boolean returnGeneratedRequestId = true;

    private boolean disableLoggerMessagesForHttpHealthChecks = true;

    private boolean showRuntimeEnv;

    private boolean useFullClassNamesForRouterMappingLogMessages = true;

    private boolean enableAdditionalValidations;

    private int waitingForRequestIdGeneratorInitTimeoutInMillis = DEFAULT_WAITING_FOR_REQUEST_ID_GENERATOR_INIT_TIMEOUT_IN_MILLIS;

    /**
     * Configures REST server for development environment.
     *
     * @param devModeEnable developer mode enable or not
     * @return the reference to this  {@link RestServerConfig} instance
     */
    @BuilderMethod
    public RestServerConfig setDevelopmentMode(final boolean devModeEnable) {
        if (devModeEnable) {
            return this
                    .setHumanReadableOutput(true)
                    .setHideInternalErrorMessage(false)
                    .setEnableAdditionalValidations(true);
        } else {
            return this
                    .setHumanReadableOutput(false)
                    .setHideInternalErrorMessage(true)
                    .setEnableAdditionalValidations(false);
        }
    }

    /**
     * Returns the error status code if the RxMicro framework can't find handler for current HTTP request.
     *
     * @return the error status code if the RxMicro framework can't find handler for current HTTP request
     */
    public int getHandlerNotFoundErrorStatusCode() {
        return handlerNotFoundErrorStatusCode;
    }

    /**
     * Sets the error status code if the RxMicro framework can't find handler for current HTTP request.
     *
     * @param handlerNotFoundErrorStatusCode the custom error status code
     * @return the reference to this  {@link RestServerConfig} instance
     */
    @BuilderMethod
    public RestServerConfig setHandlerNotFoundErrorStatusCode(final int handlerNotFoundErrorStatusCode) {
        this.handlerNotFoundErrorStatusCode = handlerNotFoundErrorStatusCode;
        return this;
    }

    /**
     * Returns the error message if the RxMicro framework can't find handler for current HTTP request.
     *
     * @return the error message if the RxMicro framework can't find handler for current HTTP request
     */
    public String getHandlerNotFoundErrorMessage() {
        return handlerNotFoundErrorMessage;
    }

    /**
     * Sets the error message if the RxMicro framework can't find handler for current HTTP request.
     *
     * @param handlerNotFoundErrorMessage the custom error message
     * @return the reference to this  {@link RestServerConfig} instance
     */
    @BuilderMethod
    public RestServerConfig setHandlerNotFoundErrorMessage(final String handlerNotFoundErrorMessage) {
        this.handlerNotFoundErrorMessage = require(handlerNotFoundErrorMessage);
        return this;
    }

    /**
     * Returns the error status code if the RxMicro framework does not support CORS feature for the current HTTP request.
     *
     * @return the error status code if the RxMicro framework does not support CORS feature for the current HTTP request
     */
    public int getCorsNotAllowedErrorStatusCode() {
        return corsNotAllowedErrorStatusCode;
    }

    /**
     * Sets the error status code if the RxMicro framework does not support CORS feature for the current HTTP request.
     *
     * @param corsNotAllowedErrorStatusCode the custom error status code
     * @return the reference to this  {@link RestServerConfig} instance
     */
    @BuilderMethod
    public RestServerConfig setCorsNotAllowedErrorStatusCode(final int corsNotAllowedErrorStatusCode) {
        this.corsNotAllowedErrorStatusCode = corsNotAllowedErrorStatusCode;
        return this;
    }

    /**
     * Returns the error message if the RxMicro framework does not support CORS feature for the current HTTP request.
     *
     * @return the error message if the RxMicro framework does not support CORS feature for the current HTTP request
     */
    public String getCorsNotAllowedErrorMessage() {
        return corsNotAllowedErrorMessage;
    }

    /**
     * Sets the error message if the RxMicro framework does not support CORS feature for the current HTTP request.
     *
     * @param corsNotAllowedErrorMessage the custom error message
     * @return the reference to this  {@link RestServerConfig} instance
     */
    @BuilderMethod
    public RestServerConfig setCorsNotAllowedErrorMessage(final String corsNotAllowedErrorMessage) {
        this.corsNotAllowedErrorMessage = require(corsNotAllowedErrorMessage);
        return this;
    }

    /**
     * Returns {@code true} if the RxMicro framework returns HTTP response body in human readable format.
     *
     * @return {@code true} if the RxMicro framework returns HTTP response body in human readable format
     */
    public boolean isHumanReadableOutput() {
        return humanReadableOutput;
    }

    /**
     * Activates or disables the human readable of response.
     *
     * 

* It is recommended to activate this option on development environment only! * * @param humanReadableOutput human readable or not * @return the reference to this {@link RestServerConfig} instance */ @BuilderMethod public RestServerConfig setHumanReadableOutput(final boolean humanReadableOutput) { this.humanReadableOutput = humanReadableOutput; return this; } /** * Returns {@code true} if the RxMicro framework hides a cause of internal error from client. * * @return {@code true} if the RxMicro framework hides a cause of internal error from client */ public boolean isHideInternalErrorMessage() { return hideInternalErrorMessage; } /** * Activates or disables the displaying of cause of internal error if it occur. * *

* It is recommended to activate this option on production environment only! * * @param hideInternalErrorMessage hide internal error cause or not * @return the reference to this {@link RestServerConfig} instance */ @BuilderMethod public RestServerConfig setHideInternalErrorMessage(final boolean hideInternalErrorMessage) { this.hideInternalErrorMessage = hideInternalErrorMessage; return this; } /** * Returns {@code true} if the RxMicro framework must log all not errors (i.e. status codes from 300 to 599). * * @return {@code true} if the RxMicro framework must log all not errors (i.e. status codes from 300 to 599) */ public boolean isLogHttpErrorExceptions() { return logHttpErrorExceptions; } /** * Activates or disables the logging of client and server errors. * * @param logHttpErrorExceptions log not server errors or not * @return the reference to this {@link RestServerConfig} instance */ @BuilderMethod public RestServerConfig setLogHttpErrorExceptions(final boolean logHttpErrorExceptions) { this.logHttpErrorExceptions = logHttpErrorExceptions; return this; } /** * Returns all defined static HTTP response headers for all HTTP request handlers. * * @return all defined static HTTP response headers for all HTTP request handlers */ public Set getStaticResponseHeaders() { return staticResponseHeaders; } /** * Allows customizing static HTTP response headers for all HTTP request handlers. * * @param staticResponseHeaders static response header set * @return the reference to this {@link RestServerConfig} instance */ @BuilderMethod public RestServerConfig setStaticResponseHeaders(final Set staticResponseHeaders) { this.staticResponseHeaders = require(staticResponseHeaders); return this; } /** * Allows customizing static HTTP response headers for all HTTP request handlers. * * @param staticResponseHeader a new static response header * @return the reference to this {@link RestServerConfig} instance */ @BuilderMethod public RestServerConfig addStaticResponseHeader(final StaticResponseHeader staticResponseHeader) { this.staticResponseHeaders.add(require(staticResponseHeader)); return this; } /** * Returns the configured {@link RequestIdGenerator} instance. * * @return the configured {@link RequestIdGenerator} instance. */ public RequestIdGenerator getRequestIdGenerator() { return requestIdGeneratorProvider.getRequestIdGenerator(this); } /** * Allows changing a {@link RequestIdGeneratorProvider}. * * @param requestIdGeneratorProvider generator type * @return the reference to this {@link RestServerConfig} instance */ @BuilderMethod public RestServerConfig setRequestIdGeneratorProvider(final RequestIdGeneratorProvider requestIdGeneratorProvider) { this.requestIdGeneratorProvider = require(requestIdGeneratorProvider); return this; } /** * Returns the waiting for request id generator initialization timeout in millis. * * @return the waiting for request id generator initialization timeout in millis. * @see RequestIdGeneratorProvider#getRequestIdGenerator(RestServerConfig) * @see io.rxmicro.rest.server.RequestIdGeneratorProvider.CurrentRequestIdGeneratorCantBeUsedException */ public int getWaitingForRequestIdGeneratorInitTimeoutInMillis() { return waitingForRequestIdGeneratorInitTimeoutInMillis; } /** * Sets the waiting for request id generator initialization timeout in millis. * * @param waitingForRequestIdGeneratorInitTimeoutInMillis new timeout in millis * @return the reference to this {@link RestServerConfig} instance * @see RequestIdGeneratorProvider#getRequestIdGenerator(RestServerConfig) * @see io.rxmicro.rest.server.RequestIdGeneratorProvider.CurrentRequestIdGeneratorCantBeUsedException */ @BuilderMethod public RestServerConfig setWaitingForRequestIdGeneratorInitTimeoutInMillis(final int waitingForRequestIdGeneratorInitTimeoutInMillis) { this.waitingForRequestIdGeneratorInitTimeoutInMillis = waitingForRequestIdGeneratorInitTimeoutInMillis; return this; } /** * Returns {@code true} if the RxMicro framework must returns generated request id for each HTTP request. * * @return {@code true} if the RxMicro framework must returns generated request id for each HTTP request */ public boolean isReturnGeneratedRequestId() { return returnGeneratedRequestId; } /** * Activates or disables the returning of generated request id for each HTTP request. * * @param returnGeneratedRequestId return generated Request-Id o not * @return the reference to this {@link RestServerConfig} instance */ @BuilderMethod public RestServerConfig setReturnGeneratedRequestId(final boolean returnGeneratedRequestId) { this.returnGeneratedRequestId = returnGeneratedRequestId; return this; } /** * Returns {@code true} if the RxMicro framework must disable logger for http health checks. * * @return {@code true} if the RxMicro framework must disable logger for http health checks */ public boolean isDisableLoggerMessagesForHttpHealthChecks() { return disableLoggerMessagesForHttpHealthChecks; } /** * Activates or disables logger messages for http health checks. * * @param disableLoggerMessagesForHttpHealthChecks disable logger messages for http health checks or not * @return the reference to this {@link RestServerConfig} instance */ @BuilderMethod public RestServerConfig setDisableLoggerMessagesForHttpHealthChecks( final boolean disableLoggerMessagesForHttpHealthChecks) { this.disableLoggerMessagesForHttpHealthChecks = disableLoggerMessagesForHttpHealthChecks; return this; } /** * Returns {@code true} if the RxMicro framework must print current runtime env after HTTP server is started successful. * * @return {@code true} if the RxMicro framework must print current runtime env after HTTP server is started successful. */ public boolean isShowRuntimeEnv() { return showRuntimeEnv; } /** * If this variable is set and HTTP server is started, * the RxMicro framework will print the short info about the current runtime: available processor cores and memory usage. * * @param showRuntimeEnv print runtime environment or not * @return the reference to this {@link RestServerConfig} instance */ @BuilderMethod public RestServerConfig setShowRuntimeEnv(final boolean showRuntimeEnv) { this.showRuntimeEnv = showRuntimeEnv; return this; } /** * Returns {@code true} if rest server must use full class names for router mapping log messages. * *

* If {@code useFullClassNamesForRouterMappingLogMessages} is {@code true}, then log message will be: *


     * [DEBUG] Router : Mapped "POST '/send' onto examples.controller.PublicController.send(examples.model.SendRequest)
     * 
* Otherwise the log message will be: *

     * [DEBUG] Router : Mapped "POST '/send' onto PublicController.send(SendRequest)
     * 
* * @return {@code true} if rest server must use full class names for router mapping log messages. */ public boolean isUseFullClassNamesForRouterMappingLogMessages() { return useFullClassNamesForRouterMappingLogMessages; } /** * Sets {@code true} if rest server must use full class names for router mapping log messages. * *

* If {@code useFullClassNamesForRouterMappingLogMessages} is {@code true}, then log message will be: *


     * [DEBUG] Router : Mapped "POST '/send' onto examples.controller.PublicController.send(examples.model.SendRequest)
     * 
* Otherwise the log message will be: *

     * [DEBUG] Router : Mapped "POST '/send' onto PublicController.send(SendRequest)
     * 
* * @param useFullClassNamesForRouterMappingLogMessages enable full class name for router mapping log messages. * @return the reference to this {@link RestServerConfig} instance */ @BuilderMethod public RestServerConfig setUseFullClassNamesForRouterMappingLogMessages(final boolean useFullClassNamesForRouterMappingLogMessages) { this.useFullClassNamesForRouterMappingLogMessages = useFullClassNamesForRouterMappingLogMessages; return this; } /** * Returns {@code true} if additional validations are enabled. * * @return {@code true} if additional validations are enabled */ public boolean isEnableAdditionalValidations() { return enableAdditionalValidations; } /** * Sets {@code true} if additional validations must be activated. * * @param enableAdditionalValidations enable additional validations or not * @return the reference to this {@link RestServerConfig} instance */ @BuilderMethod public RestServerConfig setEnableAdditionalValidations(final boolean enableAdditionalValidations) { this.enableAdditionalValidations = enableAdditionalValidations; return this; } @Override public String toString() { return "RestServerConfig{" + "handlerNotFoundErrorStatusCode=" + handlerNotFoundErrorStatusCode + ", handlerNotFoundErrorMessage='" + handlerNotFoundErrorMessage + '\'' + ", corsNotAllowedErrorStatusCode=" + corsNotAllowedErrorStatusCode + ", corsNotAllowedErrorMessage='" + corsNotAllowedErrorMessage + '\'' + ", humanReadableOutput=" + humanReadableOutput + ", hideInternalErrorMessage=" + hideInternalErrorMessage + ", logNotServerErrors=" + logHttpErrorExceptions + ", staticResponseHeaders=" + staticResponseHeaders + ", generatorType=" + requestIdGeneratorProvider + ", returnGeneratedRequestId=" + returnGeneratedRequestId + ", disableLoggerMessagesForHttpHealthChecks=" + disableLoggerMessagesForHttpHealthChecks + ", showRuntimeEnv=" + showRuntimeEnv + ", useFullClassNamesForRouterMappingLogMessages=" + useFullClassNamesForRouterMappingLogMessages + ", enableAdditionalValidations=" + enableAdditionalValidations + ", waitingForRequestIdGeneratorInitTimeoutInMillis=" + waitingForRequestIdGeneratorInitTimeoutInMillis + '}'; } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy