org.frontcache.core.RequestContext.java Source code

Java tutorial

Introduction

Here is the source code for org.frontcache.core.RequestContext.java

Source

/**
 *        Copyright 2017 Eternita LLC
 *
 *  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 org.frontcache.core;

import java.io.InputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;

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

import org.apache.http.client.methods.CloseableHttpResponse;

/**
 * The Request Context holds request, response,  state information and data to access and share.
 * The RequestContext lives for the duration of the request and is ThreadLocal.
 * extensions of RequestContext can be substituted by setting the contextClass.
 * Most methods here are convenience wrapper methods; the RequestContext is an extension of a ConcurrentHashMap
 *
 */
@SuppressWarnings("serial")
public class RequestContext extends ConcurrentHashMap<String, Object> {

    private static final String FRONTCACHE_REQUEST_TYPE = "frontcacheRequestType"; // { toplevel | include }
    private static final String FRONTCACHE_REQUEST_ID = "frontcacheRequestID"; // 

    public RequestContext() {
        super();
    }

    /**
     * Convenience method to return a boolean value for a given key
     *
     * @param key
     * @return true or false depending what was set. default is false
     */
    public boolean getBoolean(String key) {
        return getBoolean(key, false);
    }

    /**
     * Convenience method to return a boolean value for a given key
     *
     * @param key
     * @param defaultResponse
     * @return true or false depending what was set. default defaultResponse
     */
    public boolean getBoolean(String key, boolean defaultResponse) {
        Boolean b = (Boolean) get(key);
        if (b != null) {
            return b.booleanValue();
        }
        return defaultResponse;
    }

    /**
     * sets a key value to Boolen.TRUE
     *
     * @param key
     */
    public void set(String key) {
        put(key, Boolean.TRUE);
    }

    /**
     * puts the key, value into the map. a null value will remove the key from the map
     *
     * @param key
     * @param value
     */
    public void set(String key, Object value) {
        if (value != null)
            put(key, value);
        else
            remove(key);
    }

    /**
     * @return the HttpServletRequest from the "request" key
     */
    public HttpServletRequest getRequest() {
        return (HttpServletRequest) get("request");
    }

    /**
     * sets the HttpServletRequest into the "request" key
     *
     * @param request
     */
    public void setRequest(HttpServletRequest request) {
        put("request", request);
    }

    /**
     * @return the HttpServletResponse from the "response" key
     */
    public HttpServletResponse getResponse() {
        return (HttpServletResponse) get("response");
    }

    /**
     * sets the "response" key to the HttpServletResponse passed in
     *
     * @param response
     */
    public void setResponse(HttpServletResponse response) {
        set("response", response);
    }

    /**
     * returns a set throwable
     *
     * @return a set throwable
     */
    public Throwable getThrowable() {
        return (Throwable) get("throwable");

    }

    /**
     * sets a throwable
     *
     * @param th
     */
    public void setThrowable(Throwable th) {
        put("throwable", th);

    }

    /**
     * sets frontCacheHost
     *
     * @param frontCacheHost a URL
     */
    public void setFrontCacheHost(String frontCacheHost) {
        set("frontCacheHost", frontCacheHost);
    }

    /**
     * @return "frontCacheHost" URL
     */
    public String getFrontCacheHost() {
        return (String) get("frontCacheHost");
    }

    /**
     * 
     * @param frontCacheProtocol
     */
    public void setFrontCacheProtocol(String frontCacheProtocol) {
        set("frontCacheProtocol", frontCacheProtocol);
    }

    /**
     * 
     * @return
     */
    public String getFrontCacheProtocol() {
        return (String) get("frontCacheProtocol");
    }

    public void setOriginURL(URL originURL) {
        set("originURL", originURL);
    }

    public URL getOriginURL() {
        return (URL) get("originURL");
    }

    /**
     * sets the "responseBody" value as a String. This is the response sent back to the client.
     *
     * @param body
     */
    public void setResponseBody(String body) {
        set("responseBody", body);
    }

    /**
     * @return the String response body to be snt back to the requesting client
     */
    public String getResponseBody() {
        return (String) get("responseBody");
    }

    /**
     * sets the InputStream of the response into the responseDataStream
     *
     * @param responseDataStream
     */
    public void setResponseDataStream(InputStream responseDataStream) {
        set("responseDataStream", responseDataStream);
    }

    /**
     * sets the flag responseGZipped if the response is gzipped
     *
     * @param gzipped
     */
    public void setResponseGZipped(boolean gzipped) {
        put("responseGZipped", gzipped);
    }

    /**
     * @return true if responseGZipped is true (the response is gzipped)
     */
    public boolean getResponseGZipped() {
        return getBoolean("responseGZipped", true);
    }

    /**
     * @return the InputStream Response
     */
    public InputStream getResponseDataStream() {
        return (InputStream) get("responseDataStream");
    }

    /**
     * returns the response status code. Default is 200
     *
     * @return
     */
    public int getResponseStatusCode() {
        return get("responseStatusCode") != null ? (Integer) get("responseStatusCode") : 500;
    }

    /**
     * Use this instead of response.setStatusCode()
     *
     * @param nStatusCode
     */
    public void setResponseStatusCode(int nStatusCode) {
        getResponse().setStatus(nStatusCode);
        set("responseStatusCode", nStatusCode);
    }

    /**
     * the Origin response headers
     *
     * @return the List<Pair<String, String>> of headers sent back from the origin
     */
    @SuppressWarnings("unchecked")
    public Map<String, List<String>> getOriginResponseHeaders() {
        if (get("originResponseHeaders") == null) {
            Map<String, List<String>> originResponseHeaders = new HashMap<String, List<String>>();
            putIfAbsent("originResponseHeaders", originResponseHeaders);
        }
        return (Map<String, List<String>>) get("originResponseHeaders");
    }

    /**
     * check if response has "Content-Type" header with "text" inside
     * @return
     */
    public boolean isCacheableResponse() {
        Map<String, List<String>> originResponseHeaders = getOriginResponseHeaders();

        for (String key : originResponseHeaders.keySet()) {
            for (String value : originResponseHeaders.get(key)) {
                if (FCHeaders.CONTENT_TYPE.equals(key) && -1 < value.indexOf("text"))
                    return true;
            }
        }
        return false;
    }

    /**
     * 
     * @return
     */
    public boolean isCacheableRequest() {

        if ("GET".equals(this.getRequest().getMethod().toUpperCase()))
            return true;

        if ("HEAD".equals(this.getRequest().getMethod().toUpperCase()))
            return true;

        //       if (-1 < this.getRequestURI().indexOf("jsessionid="))
        //          return false;

        return false;
        //bot's send requests without header (accept=text/html) #36
        //        final String requestEncoding = this.getRequest().getHeader(FCHeaders.ACCEPT);
        //        return requestEncoding != null && requestEncoding.toLowerCase().contains("text");
    }

    /**
     * adds a header to the origin response headers
     *
     * @param name
     * @param value
     */
    public void addOriginResponseHeader(String name, String value) {

        Map<String, List<String>> originResponseHeaders = getOriginResponseHeaders();

        List<String> hValues = originResponseHeaders.get(name);
        if (null == hValues) {
            hValues = new ArrayList<String>();
            originResponseHeaders.put(name, hValues);
        }
        hValues.add(value);
    }

    /**
     * returns the content-length of the origin response
     *
     * @return the content-length of the origin response
     */
    public Long getOriginContentLength() {
        return (Long) get("originContentLength");
    }

    /**
     * sets the content-length from the origin response
     *
     * @param v
     */
    public void setOriginContentLength(Long v) {
        set("originContentLength", v);
    }

    public void setRequestURI(String uri) {
        set("requestURI", uri);
    }

    public String getRequestURI() {
        return (String) get("requestURI");
    }

    public void setRequestQueryString(String requestQueryString) {
        set("requestQueryString", requestQueryString);
    }

    public String getRequestQueryString() {
        return (String) get("requestQueryString");
    }

    /**
     * sets the content-length from the origin response
     *
     * @param v parses the string into an int
     */
    public void setOriginContentLength(String v) {
        try {
            final Long i = Long.valueOf(v);
            set("originContentLength", i);
        } catch (NumberFormatException e) {
            e.printStackTrace();
        }
    }

    /**
     * @return true if the request body is chunked
     */
    public boolean isChunkedRequestBody() {
        final Object v = get("chunkedRequestBody");
        return (v != null) ? (Boolean) v : false;
    }

    /**
     * sets chunkedRequestBody to true
     */
    public void setChunkedRequestBody() {
        this.set("chunkedRequestBody", Boolean.TRUE);
    }

    /**
     * @return true is the client request can accept gzip encoding. Checks the "accept-encoding" header
     */
    public boolean isGzipRequested() {
        final String requestEncoding = this.getRequest().getHeader(FCHeaders.ACCEPT_ENCODING);
        return requestEncoding != null && requestEncoding.toLowerCase().contains("gzip");
    }

    /**
     * @return Map<String, List<String>>  of the request Query Parameters
     */
    @SuppressWarnings("unchecked")
    public Map<String, List<String>> getRequestQueryParams() {
        return (Map<String, List<String>>) get("requestQueryParams");
    }

    /**
     * sets the request query params list
     *
     * @param qp Map<String, List<String>> qp
     */
    public void setRequestQueryParams(Map<String, List<String>> qp) {
        put("requestQueryParams", qp);
    }

    public CloseableHttpResponse getHttpClientResponse() {
        return (CloseableHttpResponse) get("httpClientResponse");
    }

    public void setHttpClientResponse(CloseableHttpResponse response) {
        this.set("httpClientResponse", response);
    }

    public void setFrontCacheHttpPort(String frontCacheHttpPort) {
        set("frontCacheHttpPort", frontCacheHttpPort);
    }

    public String getFrontCacheHttpPort() {
        return (String) get("frontCacheHttpPort");
    }

    public void setFrontCacheHttpsPort(String frontCacheHttpsPort) {
        set("frontCacheHttpsPort", frontCacheHttpsPort);
    }

    public String getFrontCacheHttpsPort() {
        return (String) get("frontCacheHttpsPort");
    }

    public void setFilterChain(FilterChain filterChain) {
        set("filterChain", filterChain);
    }

    public FilterChain getFilterChain() {
        return (FilterChain) get("filterChain");
    }

    /**
     * Check if run as ServletFilter
     * 
     * @return
     */
    public boolean isFilterMode() {
        if (null != getFilterChain())
            return true;

        return false;
    }

    /**
     * 
     * @param frontCacheId
     */
    public void setFrontCacheId(String frontCacheId) {
        set("frontCacheId", frontCacheId);
    }

    /**
     * 
     * @return
     */
    public String getFrontCacheId() {
        return (String) get("frontCacheId");
    }

    public void setHystrixFallback() {
        set("hystrixError", true);
    }

    public boolean isHystrixFallback() {
        return getBoolean("hystrixError", false);
    }

    public void setRequestType(String frontcacheRequestType) {
        set(FRONTCACHE_REQUEST_TYPE, frontcacheRequestType);
    }

    public String getRequestType() {
        return (String) get(FRONTCACHE_REQUEST_TYPE);
    }

    public void setRequestId(String frontcacheRequestId) {
        set(FRONTCACHE_REQUEST_ID, frontcacheRequestId);
    }

    public String getRequestId() {
        return (String) get(FRONTCACHE_REQUEST_ID);
    }

    public void setRequestFromFrontcache() {
        set("RequestFromFrontcache", true);
    }

    public boolean getRequestFromFrontcache() {
        return getBoolean("RequestFromFrontcache", false);
    }

    public String getCurrentRequestURL() {
        return (String) get("currentRequestURL");
    }

    public void setCurrentRequestURL(String currentRequestURL) {
        set("currentRequestURL", currentRequestURL);
    }

    // bot | browser
    public String getClientType() {
        return (String) get("currentClientType");
    }

    // bot | browser
    public void setClientType(String currentClientType) {
        set("currentClientType", currentClientType);
    }

    public RequestContext copy() {

        RequestContext copy = new RequestContext();

        copy.putAll(this);
        copy.setRequestId(UUID.randomUUID().toString());

        return copy;
    }

    public void setDomainContext(DomainContext domainContext) {
        set("domainContext", domainContext);
    }

    public DomainContext getDomainContext() {
        return (DomainContext) get("domainContext");
    }

    public void setLogToHTTPHeaders() {
        set("LogToHTTPHeaders", true);
    }

    public boolean getLogToHTTPHeaders() {
        return getBoolean("LogToHTTPHeaders", false);
    }

    public void setIncludeLevel(String includeLevel) {
        set("IncludeLevel", includeLevel);
    }

    public String getIncludeLevel() {
        return get("IncludeLevel") != null ? (String) get("IncludeLevel") : "0";
    }

    public void setToplevelCached() {
        set("ToplevelCached", true);
    }

    public boolean isToplevelCached() {
        return getBoolean("ToplevelCached", false);
    }

    @Override
    public String toString() {
        String str = super.toString();
        str = str.replaceAll("(\\r|\\n|\\r\\n)+", " ");
        return "RequestContext: " + str;
    }

}