org.grycap.gpf4med.Gpf4MedService.java Source code

Java tutorial

Introduction

Here is the source code for org.grycap.gpf4med.Gpf4MedService.java

Source

/*
 * Copyright 2013 Institute for Molecular Imaging Instrumentation (I3M)
 * 
 * Licensed under the EUPL, Version 1.1 or - as soon they will be approved by 
 * the European Commission - subsequent versions of the EUPL (the "Licence");
 * You may not use this work except in compliance with the Licence.
 * You may obtain a copy of the Licence at:
 * 
 *   http://ec.europa.eu/idabc/eupl
 * 
 * Unless required by applicable law or agreed to in writing, software 
 * distributed under the Licence is distributed on an "AS IS" basis,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the Licence for the specific language governing permissions and 
 * limitations under the Licence.
 * 
 * This product combines work with different licenses. See the "NOTICE" text
 * file for details on the various modules and licenses.
 * The "NOTICE" text file is part of the distribution. Any derivative works
 * that you distribute must include a readable copy of the "NOTICE" text file.
 */

package org.grycap.gpf4med;

import static com.google.common.base.Preconditions.checkState;
import static com.google.common.collect.Collections2.transform;
import static com.google.common.collect.Sets.newHashSet;
import static com.google.common.collect.Sets.newLinkedHashSet;

import java.io.File;
import java.net.URI;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import javax.ws.rs.core.Application;

import org.glassfish.grizzly.http.server.HttpServer;
import org.glassfish.grizzly.http.server.StaticHttpHandler;
import org.glassfish.grizzly.nio.transport.TCPNIOTransport;
import org.glassfish.jersey.grizzly2.httpserver.GrizzlyHttpServerFactory;
import org.glassfish.jersey.moxy.json.MoxyJsonFeature;
import org.glassfish.jersey.server.ResourceConfig;
import org.grycap.gpf4med.conf.ConfigurationManager;
import org.grycap.gpf4med.ext.GraphConnector;
import org.grycap.gpf4med.ext.GraphConnectorManager;
import org.grycap.gpf4med.manager.ShutdownHook;
import org.grycap.gpf4med.rest.Gpf4MedResourceImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.base.Function;
import com.google.common.collect.ImmutableMap;
import com.google.common.util.concurrent.AbstractIdleService;

/**
 * Gpf4Med service.
 * @author Erik Torres <ertorser@upv.es>
 */
public class Gpf4MedService extends AbstractIdleService {

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

    public static final String SERVICE_NAME = ConfigurationManager.GPF4MED_NAME + " service";
    public static final String APP_NAME = "gpf4med";

    private final HttpServer server;
    private final ShutdownHook shutdownHook = new ShutdownHook();
    private final String baseUri;

    public Gpf4MedService() {
        // load configuration
        final String hostname = ConfigurationManager.INSTANCE.getContainerHostname();
        final int port = ConfigurationManager.INSTANCE.getContainerPort();
        // create base URI the Grizzly HTTP server will listen on
        baseUri = "http://" + hostname + ":" + port + "/" + APP_NAME + "/";
        // create the HTTP server
        server = Gpf4MedService.createServer(baseUri);
        checkState(server != null, "Uninitialized HTTP server");
        // register shutdown hook
        shutdownHook.register(this);
        LOGGER.info(String.format(
                SERVICE_NAME + " initialized successfully with WADL available at " + "%sapplication.wadl",
                baseUri));
    }

    /**
     * Creates a Grizzly HTTP server exposing JAX-RS resources defined in this service.
     * @return Grizzly HTTP server.
     */
    private static HttpServer createServer(final String baseUri) {
        HttpServer server = null;
        try {
            // scan for connectors
            final Set<Class<?>> classSet = newLinkedHashSet();
            final ImmutableMap<String, GraphConnector> connectors = GraphConnectorManager.INSTANCE.listConnectors();
            if (connectors != null && !connectors.isEmpty()) {
                classSet.addAll(transform(connectors.entrySet(),
                        new Function<Map.Entry<String, GraphConnector>, Class<?>>() {
                            @Override
                            public Class<?> apply(final Entry<String, GraphConnector> entry) {
                                return entry.getValue().restResourceImplementation();
                            }
                        }));
            }

            // create a resource configuration that scans for JAX-RS resources and providers
            final ResourceConfig resourceConfig = ResourceConfig.forApplication(new Application() {
                @Override
                public Set<Class<?>> getClasses() {
                    final Set<Class<?>> classes = newHashSet();
                    classes.add(Gpf4MedResourceImpl.class);
                    return classes;
                }
            }).register(MoxyJsonFeature.class);
            if (!classSet.isEmpty()) {
                resourceConfig.registerClasses(classSet);
            }

            // create a non-started-yet HttpServer instance
            server = GrizzlyHttpServerFactory.createHttpServer(URI.create(baseUri), resourceConfig, false);

            // serve static HTTP resources from file-system
            final File htdocsDir = ConfigurationManager.INSTANCE.getHtdocsDir();
            if (htdocsDir != null && htdocsDir.isDirectory() && htdocsDir.canRead()) {
                final StaticHttpHandler staticHttpHandler = new StaticHttpHandler(htdocsDir.getCanonicalPath());
                server.getServerConfiguration().addHttpHandler(staticHttpHandler, "/");
            }

            // apply any optional configuration to the HttpServer instance and start the service
            final TCPNIOTransport transport = server.getListener("grizzly").getTransport();
            transport.setTcpNoDelay(true);
        } catch (Exception e) {
            server = null;
            LOGGER.error("Failed to create HTTP server", e);
        }
        return server;
    }

    public String getBaseUri() {
        return baseUri;
    }

    @Override
    protected void startUp() throws Exception {
        // pre-load configuration and core services
        CloserService.INSTANCE.preload();
        // start HTTP server
        server.start();
        LOGGER.info(SERVICE_NAME + " started");
    }

    @Override
    protected void shutDown() throws Exception {
        // stop HTTP server
        server.shutdownNow();
        // close core services
        CloserService.INSTANCE.close();
        LOGGER.info(SERVICE_NAME + " terminated");
    }

}