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

com.fasterxml.clustermate.service.servlet.ServletBase Maven / Gradle / Ivy

There is a newer version: 0.10.5
Show newest version
package com.fasterxml.clustermate.service.servlet;

import java.io.IOException;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

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

import com.fasterxml.clustermate.service.OperationDiagnostics;
import com.fasterxml.clustermate.service.ServiceResponse;
import com.fasterxml.clustermate.service.cluster.ClusterViewByServer;

@SuppressWarnings("serial")
public class ServletBase extends HttpServlet
{
    protected final Logger LOG = LoggerFactory.getLogger(getClass());

    protected final ClusterViewByServer _clusterView;

    protected final String _basePath;
    
    /**
     * @param clusterView Handler to cluster information; needed to
     *   handling piggy-backed cluster state information
     * @param servletPathBase (optional) Server base path that is to
     *   be ignored when matching request paths: if null, uses
     *   method getServletPath of HttpServletRequest.
     */
    protected ServletBase(ClusterViewByServer clusterView,
            String servletPathBase)
    {
        _clusterView = clusterView;
        if (servletPathBase != null) {
            /* One tweak: ensure that base path ends with slash, to ensure
             * we are not left with leading slash in path passed.
             * Except in case of empty base.
             */
            if (!servletPathBase.endsWith("/") && servletPathBase.length() > 0) {
                servletPathBase += "/";
            }
        }
        _basePath = servletPathBase;
    }

    protected ClusterViewByServer getClusterView() { return _clusterView; }
    
    /*
    /**********************************************************************
    /* REST operation end points
    /**********************************************************************
     */

    @Override
    public final void doGet(HttpServletRequest req0, HttpServletResponse resp0) throws IOException
    {
        handleGet(constructRequest(req0), constructResponse(resp0), constructMetadata());
    }

    @Override
    public final void doHead(HttpServletRequest req0, HttpServletResponse resp0) throws IOException
    {
        handleHead(constructRequest(req0), constructResponse(resp0), constructMetadata());
    }
    
    @Override
    public final void doPost(HttpServletRequest req0, HttpServletResponse resp0) throws IOException
    {
        handlePost(constructRequest(req0), constructResponse(resp0), constructMetadata());
    }
    
    @Override
    public final void doPut(HttpServletRequest req0, HttpServletResponse resp0) throws IOException
    {
        handlePut(constructRequest(req0), constructResponse(resp0), constructMetadata());
    }

    @Override
    public final void doDelete(HttpServletRequest req0, HttpServletResponse resp0) throws IOException
    {
        handleDelete(constructRequest(req0), constructResponse(resp0), constructMetadata());
    }

    /*
    /**********************************************************************
    /* Overridable methods
    /**********************************************************************
     */

    public void handleGet(ServletServiceRequest request, ServletServiceResponse response,
            OperationDiagnostics stats)
        throws IOException
    {
        response = response.badMethod()
                .setContentTypeText().setEntity("No GET available for endpoint");
        // no need to track bytes returned since it's not real payload
        response.writeOut(null);
    }

    public void handleHead(ServletServiceRequest request, ServletServiceResponse response,
            OperationDiagnostics stats)
        throws IOException { }

    public void handlePut(ServletServiceRequest request, ServletServiceResponse response,
            OperationDiagnostics stats)
        throws IOException { }

    public void handlePost(ServletServiceRequest request, ServletServiceResponse response,
            OperationDiagnostics stats)
        throws IOException { }

    public void handleDelete(ServletServiceRequest request, ServletServiceResponse response,
            OperationDiagnostics stats)
        throws IOException { }

    /*
    /**********************************************************************
    /* Helper methods, overridable
    /**********************************************************************
     */

    protected ServletServiceRequest constructRequest(HttpServletRequest orig)
    {
        String path = orig.getRequestURI();
        
        /* First things first: remove servlet path prefix (either override,
         * or one used for registration)
         */
        if (_basePath == null) { // no base path; use whatever it was registered with
            path = _trimPath(path, orig.getServletPath(), true);
        } else {
            path = _trimPath(path, _basePath, false);
        }
        // false -> path not yet URL decoded
        return new ServletServiceRequest(orig, path, false);
    }

    /**
     * Overridable factory method that is used for creating optional
     * {@link OperationDiagnostics} object to pass through, to collect
     * statistics.
     */
    protected OperationDiagnostics constructMetadata() {
        /* 28-Mar-2013, tsaloranta: Let's construct this by default, since
         *   it will be needed to collect metrics.
         */
        return new OperationDiagnostics();
    }
    
    protected ServletServiceResponse constructResponse(HttpServletResponse orig) {
        return new ServletServiceResponse(orig);
    }
    
    /*
    /**********************************************************************
    /* Helper methods, other
    /**********************************************************************
     */

    protected String _trimPath(String originalPath, String expectedPrefix,
            boolean checkSlash)
    {
        int prefixLength = expectedPrefix.length();
        if (prefixLength == 0) {
            return originalPath;
        }
        if (!originalPath.startsWith(expectedPrefix)) {
            LOG.warn("Unexpected Servlet path to trim '{}'; does not start with '{}'; passing as-is",
                    originalPath, expectedPrefix);
            return originalPath;
        }
        // need to trim one char, slash?
        if (checkSlash
                && (originalPath.length() > prefixLength)
                && (expectedPrefix.charAt(prefixLength-1) != '/')
                && (originalPath.charAt(prefixLength) == '/')
        ) {
            ++prefixLength;
        }
        return originalPath.substring(prefixLength);
    }
    
    protected ServiceResponse _addStdHeaders(ServiceResponse response)
    {
        if (_clusterView != null) {
            response = _clusterView.addClusterStateInfo(response);
        }
        return response;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy