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

io.telicent.smart.cache.server.jaxrs.applications.AbstractAppEntrypoint Maven / Gradle / Ivy

There is a newer version: 0.24.1
Show newest version
/**
 * Copyright (C) Telicent Ltd
 *
 * 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.telicent.smart.cache.server.jaxrs.applications;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * An abstract application entrypoint that allows running the application using an embedded Grizzly HTTP Server without
 * needing any additional Java Servlet container.
 */
public abstract class AbstractAppEntrypoint {

    private static final Logger LOGGER = LoggerFactory.getLogger(AbstractAppEntrypoint.class);

    /**
     * The server instance
     */
    protected Server server;

    /**
     * Builds the application server
     *
     * @return Server builder
     */
    protected abstract ServerBuilder buildServer();

    /**
     * Attempts to run the server.
     * 

* Derived classes should call this from their {@code main(String[] args)} method assuming they have appropriately * implemented {@link #buildServer()} to build their desired application server *

* * @param block Whether to block until the server is terminated by an interrupt signal. If {@code true} then * calling this method will block, if {@code false} then this method starts the server and returns, * calling code is then responsible for terminating the server. */ protected final void run(boolean block) { try { ServerBuilder builder = buildServer(); this.server = builder.build(); // Try to rename the thread to the servers display name, otherwise the default JVM thread name is super long // and ugly try { Thread.currentThread().setName(this.server.getDisplayName()); } catch (Throwable t) { // Ignore failures to change thread name, just use the default JVM thread name } LOGGER.info("Attempting to start {}...", server.getDisplayName()); this.server.start(); Runtime.getRuntime().addShutdownHook(new Thread(() -> server.shutdownNow())); LOGGER.info("{} started, check prior logs for any application startup errors.", server.getDisplayName()); LOGGER.info("{} available at {}", server.getDisplayName(), server.getBaseUri()); LOGGER.info("Stop the server by sending an interrupt to this process e.g. using CTRL+C"); if (block) { try { Thread.currentThread().join(); } catch (InterruptedException e) { // There are 2 scenarios in which this occurs: // 1 - The JVM is shutting down, in which case our shutdown hook might already have fired and called // shutdown but no harm in calling it again // 2 - The server was started on a background thread that has been interrupted (e.g. integration // testing) in which case we need the server to be shutdown to free up the port and not leak // resources LOGGER.info("Server process/thread interrupted, shutting down now..."); this.server.shutdownNow(); } } } catch (IllegalArgumentException e) { LOGGER.error("Bad server configuration: {}", e.getMessage()); } catch (IllegalStateException e) { LOGGER.error("Bad/insufficient server configuration: {}", e.getMessage()); } catch (Throwable e) { LOGGER.error("Unexpected error:", e); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy