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

org.hudsonci.rest.server.internal.jersey.RestServlet Maven / Gradle / Ivy

The newest version!
/*******************************************************************************
 *
 * Copyright (c) 2010-2011 Sonatype, Inc.
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors: 
 *
 *   
 *     
 *
 *******************************************************************************/ 

package org.hudsonci.rest.server.internal.jersey;

import com.sun.jersey.api.core.DefaultResourceConfig;
import com.sun.jersey.api.core.ResourceConfig;
import com.sun.jersey.core.spi.component.ioc.IoCComponentProviderFactory;
import com.sun.jersey.spi.container.ContainerListener;
import com.sun.jersey.spi.container.ContainerNotifier;
import com.sun.jersey.spi.container.WebApplication;
import com.sun.jersey.spi.container.servlet.ServletContainer;
import com.sun.jersey.spi.container.servlet.WebConfig;
import com.sun.jersey.spi.container.servlet.WebServletConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.Path;
import javax.ws.rs.core.Application;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import static org.hudsonci.rest.common.Constants.HUDSON_HEADER;
import static org.hudsonci.utils.common.Varargs.$;

/**
 * Augmented Jersey REST servlet.
 *
 * This adds some additional logging and sets up the X-Hudson header, and provides Sisu injection support.
 *
 * @author Jeanfrancois Arcand
 * @author Jason Dillon
 * @since 2.1.0
 */
public class RestServlet
    extends ServletContainer
    implements ContainerNotifier
{
    private static final Logger log = LoggerFactory.getLogger(RestServlet.class);

    private static final long serialVersionUID = 1L;

    private final List listeners = new ArrayList();

    private final IoCComponentProviderFactory componentProviderFactory;

    private ResourceConfig resourceConfig;

    public RestServlet(final IoCComponentProviderFactory componentProviderFactory) {
        this.componentProviderFactory = checkNotNull(componentProviderFactory);
    }

    @Override
    protected ResourceConfig getDefaultResourceConfig(final Map props, final WebConfig webConfig) throws ServletException {
        DefaultResourceConfig config = new DefaultResourceConfig();
        // Need to attach a dummy resource, as Jersey will fail to initialize if there are no root resources configured
        config.getSingletons().add(new DummyResource());
        return config;
    }

    /**
     * Dummy root resource to configure Jersey with so that it can initialize, it needs at least one root resource or it will puke.
     */
    @Path("/internal/dummy-root-resource-for-jersey")
    private static class DummyResource
    {
        // empty
    }

    protected void initiate(final ResourceConfig config, final WebApplication webApp) {
        this.resourceConfig = checkNotNull(config);
        webApp.initiate(config, componentProviderFactory);
    }

    @Override
    public void init() throws ServletException {
        init(new WebServletConfig(this)
        {
            @Override
            public ResourceConfig getDefaultResourceConfig(final Map props) throws ServletException {
                checkNotNull(props);
                props.put(ResourceConfig.PROPERTY_CONTAINER_NOTIFIER, RestServlet.this);
                return super.getDefaultResourceConfig(props);
            }
        });
    }

    @Override
    public void service(final HttpServletRequest request, final HttpServletResponse response) throws ServletException, IOException {
        assert request != null;
        assert response != null;

        // Log the request URI+URL muck
        String uri = request.getRequestURI();
        if (request.getQueryString() != null) {
            uri = String.format("%s?%s", uri, request.getQueryString());
        }

        if (log.isDebugEnabled()) {
            log.debug("Processing: {} {} ({}) [{}]", $(request.getMethod(), uri, request.getRequestURL(), request.getHeader(HUDSON_HEADER)));
        }

        MDC.put(getClass().getName(), uri);
        try {
            super.service(request, response);
        }
        finally {
            MDC.remove(getClass().getName());
        }

        // Include the version details of the api + model
        response.addHeader(HUDSON_HEADER, String.format("api=%s", getApiVersion()));
    }

    private String getApiVersion() {
        return org.hudsonci.rest.api.Version.get().getVersion();
    }

    public synchronized void addApplication(final Application application) {
        checkNotNull(application);
        checkState(resourceConfig != null);
        resourceConfig.add(application);
        for (ContainerListener listener : listeners) {
            listener.onReload();
        }
    }

    public synchronized void addListener(final ContainerListener listener) {
        checkNotNull(listener);
        listeners.add(listener);
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy