Package com.dottydingo.hyperion.service.pipeline.phase

Source Code of com.dottydingo.hyperion.service.pipeline.phase.EndpointValidationPhase

package com.dottydingo.hyperion.service.pipeline.phase;

import com.dottydingo.hyperion.exception.BadRequestException;
import com.dottydingo.hyperion.exception.HyperionException;
import com.dottydingo.hyperion.exception.NotFoundException;
import com.dottydingo.hyperion.service.configuration.ApiVersionPlugin;
import com.dottydingo.hyperion.service.configuration.EntityPlugin;
import com.dottydingo.hyperion.service.configuration.ServiceRegistry;
import com.dottydingo.hyperion.service.context.HyperionRequest;
import com.dottydingo.hyperion.service.context.HyperionResponse;
import com.dottydingo.hyperion.service.context.HttpMethod;
import com.dottydingo.hyperion.service.pipeline.auth.AuthorizationContext;
import com.dottydingo.hyperion.service.pipeline.auth.AuthorizationProvider;
import com.dottydingo.hyperion.service.pipeline.UriParser;
import com.dottydingo.hyperion.service.pipeline.UriRequestResult;
import com.dottydingo.hyperion.service.configuration.HyperionEndpointConfiguration;
import com.dottydingo.hyperion.service.context.HyperionContext;
import com.dottydingo.service.endpoint.context.EndpointRequest;
import com.dottydingo.service.endpoint.pipeline.AbstractEndpointPhase;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.net.URLDecoder;


/**
*/
public class EndpointValidationPhase extends AbstractEndpointPhase<HyperionContext>
{
    private Logger logger = LoggerFactory.getLogger(EndpointValidationPhase.class);

    private ServiceRegistry serviceRegistry;
    private HyperionEndpointConfiguration hyperionEndpointConfiguration;
    private AuthorizationProvider authorizationProvider;
    private UriParser uriParser ;

    public void setServiceRegistry(ServiceRegistry serviceRegistry)
    {
        this.serviceRegistry = serviceRegistry;
    }

    public void setHyperionEndpointConfiguration(HyperionEndpointConfiguration hyperionEndpointConfiguration)
    {
        this.hyperionEndpointConfiguration = hyperionEndpointConfiguration;
    }

    public void setAuthorizationProvider(AuthorizationProvider authorizationProvider)
    {
        this.authorizationProvider = authorizationProvider;
    }

    public void setUriParser(UriParser uriParser)
    {
        this.uriParser = uriParser;
    }

    @Override
    protected void executePhase(HyperionContext phaseContext) throws Exception
    {
        HyperionRequest request = phaseContext.getEndpointRequest();
        HyperionResponse response = phaseContext.getEndpointResponse();

        UriRequestResult uriRequestResult = uriParser.parseRequestUri(request.getResourceUri());

        if(uriRequestResult == null)
            throw new NotFoundException(String.format("%s is not recognized.",request.getResourceUri()));

        String entityName = uriRequestResult.getEndpoint();

        EntityPlugin plugin = serviceRegistry.getPluginForName(entityName);
        if(plugin == null)
            throw new NotFoundException(String.format("%s is not a valid entity.",entityName));

        phaseContext.setEntityPlugin(plugin);

        phaseContext.setRequestMethod(getHttpMethod(request.getRequestMethod()));
        String requestMethod = getEffectiveMethod(request);
        HttpMethod httpMethod = getHttpMethod(requestMethod);

        if(!plugin.isMethodAllowed(httpMethod))
            throw new HyperionException(405,String.format("%s is not allowed.",httpMethod));

        phaseContext.setEffectiveMethod(httpMethod);

        // special case where version is in the URI
        String version = uriRequestResult.getVersion();

        if(version == null || version.length() == 0)
        {
            version = request.getFirstParameter(hyperionEndpointConfiguration.getVersionParameterName());
            if(version == null || version.length() == 0)
                version = request.getFirstHeader(hyperionEndpointConfiguration.getVersionHeaderName());

            if(hyperionEndpointConfiguration.isRequireVersion() && httpMethod != HttpMethod.DELETE &&
                    (version == null || version.length()==0))
                throw new BadRequestException(String.format("The %s parameter must be specified",hyperionEndpointConfiguration.getVersionParameterName()));
        }


        if(version != null)
        {
            try
            {
                phaseContext.setVersion(Integer.parseInt(version));
            }
            catch(NumberFormatException e)
            {
                throw new BadRequestException(String.format("%s is not a valid value for version.",version));
            }
        }

        if(!validateMethod(httpMethod,uriRequestResult))
            throw new HyperionException(405,"Not allowed.");

        if(uriRequestResult.getId() != null)
            phaseContext.setId(URLDecoder.decode(uriRequestResult.getId()));
        phaseContext.setHistory(uriRequestResult.isHistory());

        ApiVersionPlugin versionPlugin = plugin.getApiVersionRegistry().getPluginForVersion(phaseContext.getVersion());
        phaseContext.setVersionPlugin(versionPlugin);

        logRequestInformation(phaseContext);

        if(phaseContext.getEffectiveMethod() == HttpMethod.GET)
        {
            response.setCacheMaxAge(plugin.getCacheMaxAge());
        }

        AuthorizationContext authorizationContext = authorizationProvider.authorize(phaseContext);
        phaseContext.setAuthorizationContext(authorizationContext);

        if(!authorizationContext.isAuthorized())
            throw new HyperionException(403,"Not Authorized");

    }

    protected HttpMethod getHttpMethod(String methodName)
    {
        HttpMethod httpMethod;
        try
        {
            httpMethod = HttpMethod.valueOf(methodName);
        }
        catch (IllegalArgumentException e)
        {
            throw new HyperionException(405,String.format("%s is not allowed.", methodName));
        }
        return httpMethod;
    }

    protected void logRequestInformation(HyperionContext context)
    {
        if(!logger.isDebugEnabled())
            return;

        HyperionRequest request = context.getEndpointRequest();

        logger.debug("Correlation ID: {}",context.getCorrelationId());
        logger.debug("Request URL: {}",request.getRequestUrl());
        logger.debug("Base URL: {}",request.getBaseUrl());
        logger.debug("Request URI: {}",request.getRequestUri());
        logger.debug("Resource URI: {}",request.getResourceUri());
        logger.debug("Request Query String: {}",request.getQueryString());
        logger.debug("Request Method: {}",request.getRequestMethod());
        logger.debug("Effective Method: {}",context.getEffectiveMethod());
        logger.debug("Endpoint Name: {}",context.getEntityPlugin().getEndpointName());
        logger.debug("ContentType: {}",request.getContentType());
        logger.debug("User ID: {}",context.getUserContext().getUserId());
        logger.debug("User Name: {}",context.getUserContext().getUserName());
        logger.debug("Id: {}",context.getId());
        logger.debug("History: {}",context.isHistory());

        for (String name : request.getHeaderNames())
        {
            logger.debug("Header name: {} value:{}",name,request.getHeader(name));
        }

        for (String name : request.getParameterNames())
        {
            logger.debug("Parameter name: {} value:{}",name,request.getParameter(name));
        }

        logger.debug("Request Version: {}",context.getVersion());
    }

    protected String getEffectiveMethod(EndpointRequest request)
    {
        if(request.getRequestMethod().equalsIgnoreCase("POST") && request.getContentType() != null &&
                request.getContentType().contains("application/x-www-form-urlencoded"))
        {
            return "GET";
        }
        else if(request.getRequestMethod().equalsIgnoreCase("HEAD"))
            return "GET";

        return request.getRequestMethod();
    }

    protected boolean validateMethod(HttpMethod method,UriRequestResult requestResult)
    {
        switch (method)
        {
            case DELETE:
                return (requestResult.getId() != null && !requestResult.isHistory());
            case POST:
                return (requestResult.getId() == null && !requestResult.isHistory());
            case PUT:
                return (!requestResult.isHistory());
            case GET:
                return (requestResult.isHistory() && requestResult.getId() != null) || !requestResult.isHistory();
            case OPTIONS:
                return true;
            default:
                return false;
        }

    }
}
TOP

Related Classes of com.dottydingo.hyperion.service.pipeline.phase.EndpointValidationPhase

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.