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

com.englishtown.vertx.jersey.impl.DefaultJerseyOptions Maven / Gradle / Ivy

Go to download

Allows creating JAX-RS jersey resources that will handle incoming http requests to vert.x

The newest version!
/*
 * The MIT License (MIT)
 * Copyright © 2013 Englishtown 
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the “Software”), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */

package com.englishtown.vertx.jersey.impl;

import com.englishtown.vertx.jersey.JerseyOptions;
import com.englishtown.vertx.jersey.JerseyServerOptions;
import io.vertx.core.Vertx;
import io.vertx.core.http.HttpServerOptions;
import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;
import io.vertx.core.net.JksOptions;

import javax.inject.Inject;
import java.net.URI;
import java.util.*;
import java.util.function.Consumer;

/**
 * Default {@link com.englishtown.vertx.jersey.JerseyOptions} implementation
 */
public class DefaultJerseyOptions implements JerseyOptions, JerseyServerOptions {

    public final static String CONFIG_HOST = "host";
    public final static String CONFIG_PORT = "port";
    public final static String CONFIG_SSL = "ssl";
    public final static String CONFIG_JKS_OPTIONS = "jks_options";
    public final static String CONFIG_RECEIVE_BUFFER_SIZE = "receive_buffer_size";
    public final static String CONFIG_BACKLOG_SIZE = "backlog_size";
    public final static String CONFIG_RESOURCE_CONFIG = "resource_config";
    public final static String CONFIG_PROPERTIES = "properties";
    public final static String CONFIG_COMPRESSION_SUPPORTED = "compression_supported";

    public static final String CONFIG_BASE_PATH = "base_path";
    public static final String CONFIG_MAX_BODY_SIZE = "max_body_size";
    public static final String CONFIG_RESOURCES = "resources";
    public static final String CONFIG_PACKAGES = "packages";
    public static final String CONFIG_FEATURES = "features";
    public static final String CONFIG_COMPONENTS = "components";
    public static final String CONFIG_BINDERS = "binders";
    public static final String CONFIG_INSTANCES = "instances";
    public static final int DEFAULT_MAX_BODY_SIZE = 1024 * 1000; // Default max body size to 1MB

    private JsonObject config;
    private HttpServerOptions serverOptions;

    @Inject
    public DefaultJerseyOptions(Vertx vertx) {
        this(getConfig(vertx));
    }

    public DefaultJerseyOptions(JsonObject config) {
        this.config = config;
    }

    private static JsonObject getConfig(Vertx vertx) {
        JsonObject config = vertx.getOrCreateContext().config();
        return config.getJsonObject("jersey", config);
    }

    /**
     * Returns a list of packages to be scanned for resources and components
     *
     * @return
     */
    @Override
    public List getPackages() {
        List list = new ArrayList<>();

        Consumer reader = array -> {
            if ((array != null && !array.isEmpty())) {
                for (int i = 0; i < array.size(); i++) {
                    list.add(array.getString(i));
                }
            }
        };

        JsonArray resources = config.getJsonArray(CONFIG_RESOURCES, null);
        JsonArray packages = config.getJsonArray(CONFIG_PACKAGES, null);

        reader.accept(resources);
        reader.accept(packages);

        return list;
    }

    /**
     * Optional additional properties to be applied to Jersey resource configuration
     *
     * @return
     */
    @Override
    public Map getProperties() {
        JsonObject json = null;
        JsonObject tmp;

        tmp = config.getJsonObject(CONFIG_PROPERTIES);
        if (tmp != null) {
            json = tmp;
        }

        tmp = config.getJsonObject(CONFIG_RESOURCE_CONFIG);
        if (tmp != null) {
            if (json == null) {
                json = tmp;
            } else {
                json.mergeIn(tmp);
            }
        }

        return json == null ? null : json.getMap();
    }

    /**
     * List of components to be registered (features etc.)
     *
     * @return
     */
    @Override
    public Set> getComponents() {
        Set> set = new HashSet<>();
        ClassLoader cl = Thread.currentThread().getContextClassLoader();

        Consumer reader = array -> {
            if (array != null && array.size() > 0) {
                for (int i = 0; i < array.size(); i++) {
                    try {
                        set.add(cl.loadClass(array.getString(i)));
                    } catch (ClassNotFoundException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        };

        JsonArray features = config.getJsonArray(CONFIG_FEATURES, null);
        JsonArray components = config.getJsonArray(CONFIG_COMPONENTS, null);

        reader.accept(features);
        reader.accept(components);

        return set;
    }

    /**
     * Optional list of singleton instances to be registered (hk2 binders etc.)
     *
     * @return
     */
    @Override
    public Set getInstances() {
        Set set = new HashSet<>();
        ClassLoader cl = Thread.currentThread().getContextClassLoader();

        Consumer reader = array -> {
            if (array != null && array.size() > 0) {
                for (int i = 0; i < array.size(); i++) {
                    try {
                        Class clazz = cl.loadClass(array.getString(i));
                        set.add(clazz.newInstance());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
                        throw new RuntimeException(e);
                    }
                }
            }
        };

        JsonArray binders = config.getJsonArray(CONFIG_BINDERS, null);
        JsonArray instances = config.getJsonArray(CONFIG_INSTANCES, null);

        reader.accept(binders);
        reader.accept(instances);

        return set;
    }

    /**
     * The http web server host
     *
     * @return the http web server host to listen to
     */
    public String getHost() {
        return config.getString(CONFIG_HOST, "0.0.0.0");
    }

    /**
     * The http web server port
     *
     * @return the http web server port to listen to
     */
    public int getPort() {
        return config.getInteger(CONFIG_PORT, 80);
    }

    /**
     * Whether the web server should be https.
     *
     * @return whether the web server should be https.
     */
    public boolean getSSL() {
        return config.getBoolean(CONFIG_SSL, false);
    }

    /**
     * Vert.x http server key store options
     *
     * @return Java key store options
     */
    public JksOptions getKeyStoreOptions() {
        JsonObject json = config.getJsonObject(CONFIG_JKS_OPTIONS);
        return json == null ? null : new JksOptions(json);
    }

    /**
     * The TCP receive buffer size for connections in bytes
     *
     * @return buffer size in bytes
     */
    public Integer getReceiveBufferSize() {
        return config.getInteger(CONFIG_RECEIVE_BUFFER_SIZE);
    }

    /**
     * The accept backlog
     *
     * @return the accept backlog
     */
    public int getAcceptBacklog() {
        return config.getInteger(CONFIG_BACKLOG_SIZE, 10000);
    }

    /**
     * Returns the base URI used by Jersey
     *
     * @return base URI
     */
    @Override
    public URI getBaseUri() {
        String basePath = config.getString(CONFIG_BASE_PATH, "/");
        if (!basePath.endsWith("/")) {
            basePath += "/";
        }
        return URI.create(basePath);
    }

    /**
     * The max body size in bytes when reading the vert.x input stream
     *
     * @return the max body size bytes
     */
    @Override
    public int getMaxBodySize() {
        return config.getInteger(CONFIG_MAX_BODY_SIZE, DEFAULT_MAX_BODY_SIZE);
    }

    /**
     * Gets whether the server supports compression (defaults to false)
     *
     * @return whether compression is supported
     */
    public boolean getCompressionSupported() {
        return config.getBoolean(CONFIG_COMPRESSION_SUPPORTED, false);
    }

    /**
     * Gets the {@link HttpServerOptions} used to set up the vert.x http server
     *
     * @return
     */
    @Override
    public HttpServerOptions getServerOptions() {
        if (serverOptions == null) {
            serverOptions = createServerOptions();
        }

        return serverOptions;
    }

    protected HttpServerOptions createServerOptions() {
        // Setup the http server options
        HttpServerOptions serverOptions = new HttpServerOptions()
                .setHost(getHost())
                .setPort(getPort())
                .setAcceptBacklog(getAcceptBacklog()) // Performance tweak
                .setCompressionSupported(getCompressionSupported());

        // Enable https
        if (getSSL()) {
            serverOptions.setSsl(true);
        }
        if (getKeyStoreOptions() != null) {
            serverOptions.setKeyStoreOptions(getKeyStoreOptions());
        }

        Integer receiveBufferSize = getReceiveBufferSize();
        if (receiveBufferSize != null && receiveBufferSize > 0) {
            // TODO: This doesn't seem to actually affect buffer size for dataHandler.  Is this being used correctly or is it a Vertx bug?
            serverOptions.setReceiveBufferSize(receiveBufferSize);
        }

        return serverOptions;
    }

}