org.dataone.proto.trove.mn.rest.base.AbstractWebController.java Source code

Java tutorial

Introduction

Here is the source code for org.dataone.proto.trove.mn.rest.base.AbstractWebController.java

Source

/*
 * This work was created by participants in the DataONE project, and is
 * jointly copyrighted by participating institutions in DataONE. For
 * more information on DataONE, see our web site at http://dataone.org.
 * 
 * Copyright 2014
 * 
 * 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.dataone.proto.trove.mn.rest.base;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.Enumeration;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.net.URLCodec;
import org.apache.log4j.Logger;
import org.dataone.proto.trove.mn.service.v1.SolrIndex;
import org.dataone.service.exceptions.AuthenticationTimeout;
import org.dataone.service.exceptions.BaseException;
import org.dataone.service.exceptions.IdentifierNotUnique;
import org.dataone.service.exceptions.InsufficientResources;
import org.dataone.service.exceptions.InvalidCredentials;
import org.dataone.service.exceptions.InvalidRequest;
import org.dataone.service.exceptions.InvalidSystemMetadata;
import org.dataone.service.exceptions.InvalidToken;
import org.dataone.service.exceptions.NotAuthorized;
import org.dataone.service.exceptions.NotFound;
import org.dataone.service.exceptions.NotImplemented;
import org.dataone.service.exceptions.ServiceFailure;
import org.dataone.service.exceptions.UnsupportedMetadataType;
import org.dataone.service.exceptions.UnsupportedType;
import org.dataone.service.types.v1.Event;
import org.dataone.service.types.v1.Log;
import org.dataone.service.types.v1.Node;
import org.dataone.service.types.v1.Session;
import org.dataone.proto.trove.mn.service.v1.impl.MNCoreImpl;
import org.dataone.service.types.v1.Identifier;
import org.dataone.service.types.v1.LogEntry;
import org.dataone.service.types.v1.Subject;
import org.jibx.runtime.JiBXException;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;

/**
 *
 * Provide base functionality for a DataONE Web Controller.
 *
 * @author waltz
 */
public abstract class AbstractWebController {

    protected MNCoreImpl mnCoreImpl = new MNCoreImpl();

    protected SolrIndex dataoneLogger;

    public SolrIndex getDataoneLogger() {
        return dataoneLogger;
    }

    public void setDataoneLogger(SolrIndex dataoneLogger) {
        this.dataoneLogger = dataoneLogger;
    }

    public Date ping() throws NotImplemented, ServiceFailure, InsufficientResources {
        return mnCoreImpl.ping();
    }

    protected Boolean logRequest(HttpServletRequest request, Event event, Identifier pid) {
        request.getRemoteHost();
        LogEntry logEntry = new LogEntry();
        logEntry.setIpAddress(request.getRemoteAddr());

        logEntry.setUserAgent(request.getHeader("User-Agent"));

        logEntry.getNodeIdentifier();
        Subject subject = new Subject();
        subject.setValue(org.dataone.service.util.Constants.SUBJECT_PUBLIC);
        logEntry.setSubject(subject);
        logEntry.setDateLogged(new Date());

        logEntry.setIdentifier(pid);

        getDataoneLogger().add(logEntry);
        return Boolean.TRUE;
    }

    public Log getLogRecords(Date fromDate, Date toDate, Event event, String pidFilter, Integer start,
            Integer count) throws InvalidRequest, InvalidToken, NotAuthorized, NotImplemented, ServiceFailure {
        return mnCoreImpl.getLogRecords(fromDate, toDate, event, pidFilter, start, count);
        // throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    public Log getLogRecords(Session session, Date fromDate, Date toDate, Event event, String pidFilter,
            Integer start, Integer count)
            throws InvalidRequest, InvalidToken, NotAuthorized, NotImplemented, ServiceFailure {
        return mnCoreImpl.getLogRecords(session, fromDate, toDate, event, pidFilter, start, count);
        // throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    public Node getCapabilities() throws NotImplemented, ServiceFailure {
        return mnCoreImpl.getCapabilities();
        //        throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
    }

    /*
     *
     400    Bad Request         Bad request if the request REST operation is invalid, serialization is erroneous, mime type is not supported, or resource is not supported.
     401    Unauthorized        Authentication failure. Credentials are required or were invalid.
     403    Forbidden           The current user does not have the right to perform the requested action.
     404    Not Found           The object does not exist.
     405    Method not allowed  The HTTP method used is not allowed on this resource. Response must include an Allow header indicating valid HTTP methods.
     406    Not Acceptable      The resource identified by the request is only capable of generating response entities which have content characteristics not acceptable according to the accept headers sent in the request.
     408    Request Timeout     The client did not produce a request within the time that the server was prepared to wait.
     409    Conflict            The request could not be completed due to a conflict with the current state of the resource.
     410    Gone                The resource is known to be permanently deleted (as opposed to 404 which indicates uncertainty about the state of the object).
     413    Request Entity Too Large    The server is refusing to process a request because the request entity is larger than the server is willing or able to process.
     415    Unsupported Media Type    The server is refusing to service the request because the entity of the request is in a format not supported by the requested resource for the requested method.
     500    Internal Server Error    The server encountered an unexpected condition which prevented it from fulfilling the request.
     501    Not Implemented    The server does not support the functionality required to fulfill the request. This is the appropriate response when the server does not recognize the request method and is not capable of supporting it for any resource.
     *
     *
     */
    Logger logger = Logger.getLogger(AbstractWebController.class.getName());
    private URLCodec urlCodec = new URLCodec();
    /* Exceptions.AuthenticationTimeout    408    The authentication request timed out. */

    @ResponseStatus(value = HttpStatus.REQUEST_TIMEOUT)
    @ExceptionHandler(AuthenticationTimeout.class)
    public void handleException(AuthenticationTimeout exception, HttpServletRequest request,
            HttpServletResponse response) {
        handleBaseException((BaseException) exception, request, response);
    }

    /* Exceptions.IdentifierNotUnique    409    The provided identifier conflicts with an existing identifier in the DataONE system. When serializing, the identifier in conflict should be rendered in traceInformation as the value of an identifier key. */
    @ResponseStatus(value = HttpStatus.CONFLICT)
    @ExceptionHandler(IdentifierNotUnique.class)
    public void handleException(IdentifierNotUnique exception, HttpServletRequest request,
            HttpServletResponse response) {
        handleBaseException((BaseException) exception, request, response);
    }

    /* Exceptions.InsufficientResources    413    There are insufficient resources at the node to support the requested operation. */
    @ResponseStatus(value = HttpStatus.REQUEST_ENTITY_TOO_LARGE)
    @ExceptionHandler(InsufficientResources.class)
    public void handleException(InsufficientResources exception, HttpServletRequest request,
            HttpServletResponse response) {
        handleBaseException((BaseException) exception, request, response);
    }

    /* Exceptions.InvalidCredentials    401    Indicates that the credentials supplied (to CN_crud.login() for example) are invalid for some reason. */
    @ResponseStatus(value = HttpStatus.UNAUTHORIZED)
    @ExceptionHandler(InvalidCredentials.class)
    public void handleException(InvalidCredentials exception, HttpServletRequest request,
            HttpServletResponse response) {
        handleBaseException((BaseException) exception, request, response);
    }

    /* Exceptions.InvalidRequest    400    The parameters provided in the call were invalid. The names and values of parameters should included in traceInformation. */
    @ResponseStatus(value = HttpStatus.BAD_REQUEST)
    @ExceptionHandler(InvalidRequest.class)
    public void handleException(InvalidRequest exception, HttpServletRequest request,
            HttpServletResponse response) {
        handleBaseException((BaseException) exception, request, response);
    }

    /* Exceptions.InvalidSystemMetadata    400    The supplied system metadata is invalid. This could be because some required field is not set, the metadata document is malformed, or the value of some field is not valid. The content of traceInformation should contain additional information about the error encountered (e.g. name of the field with bad value, if the document is malformed). */
    @ResponseStatus(value = HttpStatus.BAD_REQUEST)
    @ExceptionHandler(InvalidSystemMetadata.class)
    public void handleException(InvalidSystemMetadata exception, HttpServletRequest request,
            HttpServletResponse response) {
        handleBaseException((BaseException) exception, request, response);
    }

    /* Exceptions.InvalidToken    401    The supplied authentication token could not be verified as being valid. */
    @ResponseStatus(value = HttpStatus.UNAUTHORIZED)
    @ExceptionHandler(InvalidToken.class)
    public void handleException(InvalidToken exception, HttpServletRequest request, HttpServletResponse response) {
        handleBaseException((BaseException) exception, request, response);
    }

    /* Exceptions.NotAuthorized    401    The supplied identity information is not authorized for the requested operation. */
    @ResponseStatus(value = HttpStatus.UNAUTHORIZED)
    @ExceptionHandler(NotAuthorized.class)
    public void handleException(NotAuthorized exception, HttpServletRequest request, HttpServletResponse response) {
        handleBaseException((BaseException) exception, request, response);
    }

    /* Exceptions.NotFound    404    Used to indicate that an object is not present on the node where the exception was raised. The error message should include a reference to the CN_crud.resolve() method URL for the objec */
    @ResponseStatus(value = HttpStatus.NOT_FOUND)
    @ExceptionHandler(NotFound.class)
    public void handleException(NotFound exception, HttpServletRequest request, HttpServletResponse response) {
        handleBaseException((BaseException) exception, request, response);
    }

    /* Exceptions.NotImplemented    501    A method is not implemented, or alternatively, features of a particular method are not implemented. */
    @ResponseStatus(value = HttpStatus.NOT_IMPLEMENTED)
    @ExceptionHandler(NotImplemented.class)
    public void handleException(NotImplemented exception, HttpServletRequest request,
            HttpServletResponse response) {
        handleBaseException((BaseException) exception, request, response);
    }

    /* Exceptions.ServiceFailure    500    Some sort of system failure occurred that is preventing the requested operation from completing successfully. This error can be raised by any method in the DataONE API. */
    @ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
    @ExceptionHandler(ServiceFailure.class)
    public void handleException(ServiceFailure exception, HttpServletRequest request,
            HttpServletResponse response) {
        handleBaseException((BaseException) exception, request, response);
    }

    /* Exceptions.UnsupportedMetadataType    400    The science metadata document submitted is not of a type that is recognized by the DataONE system. */
    @ResponseStatus(value = HttpStatus.BAD_REQUEST)
    @ExceptionHandler(UnsupportedMetadataType.class)
    public void handleException(UnsupportedMetadataType exception, HttpServletRequest request,
            HttpServletResponse response) {
        handleBaseException((BaseException) exception, request, response);
    }
    /* Exceptions.UnsupportedType    400    The information presented appears to be unsupported. This error might be encountered when attempting to register unrecognized science metadata for e */

    @ResponseStatus(value = HttpStatus.BAD_REQUEST)
    @ExceptionHandler(UnsupportedType.class)
    public void handleException(UnsupportedType exception, HttpServletRequest request,
            HttpServletResponse response) {
        handleBaseException((BaseException) exception, request, response);
    }

    /* UnsupportedOperationException    501    A method is not implemented, or alternatively, features of a particular method are not implemented. */
    @ResponseStatus(value = HttpStatus.NOT_IMPLEMENTED)
    @ExceptionHandler(UnsupportedOperationException.class)
    public void handleException(UnsupportedOperationException exception, HttpServletRequest request,
            HttpServletResponse response) {
        NotImplemented notImplemented = new NotImplemented("000", exception.getMessage());
        handleBaseException((BaseException) notImplemented, request, response);
    }

    @ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
    @ExceptionHandler(IOException.class)
    public void handleException(IOException exception, HttpServletRequest request, HttpServletResponse response) {
        ServiceFailure serviceFailure = new ServiceFailure("000", exception.getMessage());
        handleBaseException((BaseException) serviceFailure, request, response);
    }

    @ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR)
    @ExceptionHandler(JiBXException.class)
    public void handleException(JiBXException exception, HttpServletRequest request, HttpServletResponse response) {
        ServiceFailure serviceFailure = new ServiceFailure("000", exception.getMessage());
        handleBaseException((BaseException) serviceFailure, request, response);
    }

    public void handleBaseException(BaseException exception, HttpServletRequest request,
            HttpServletResponse response) {

        if (request.getHeader("Accept") != null
                && request.getHeader("Accept").equalsIgnoreCase("application/json")) {
            try {
                response.setContentType("application/json");
                response.getOutputStream().write(exception.serialize(BaseException.FMT_JSON).getBytes());
                response.getOutputStream().close();
            } catch (IOException ex) {
                logger.error(ex.getMessage());
            }
        } else {
            try {
                response.setContentType("text/xml");
                response.getOutputStream().write(exception.serialize(BaseException.FMT_XML).getBytes());
                response.getOutputStream().close();
            } catch (IOException ex) {
                logger.error(ex.getMessage());
            }
        }
    }

    protected String getRequestPID(HttpServletRequest request, String delimiter) throws DecoderException {
        StringBuffer urlBuffer = request.getRequestURL();
        int objectStart = urlBuffer.indexOf(delimiter);
        String pid = urlBuffer.substring(objectStart + delimiter.length(), urlBuffer.length());
        String decodedPID = null;
        try {
            decodedPID = urlCodec.decode(pid, "UTF-8");
        } catch (UnsupportedEncodingException e) {
            decodedPID = urlCodec.decode(pid);
        }
        logger.info("decoding GUID/PID: " + pid + " to " + decodedPID);
        return decodedPID;
    }

    protected void debugRequest(HttpServletRequest request) {
        /*     see values with just a plain old request object being sent through */
        logger.debug("request RequestURL: " + request.getRequestURL());
        logger.debug("request RequestURI: " + request.getRequestURI());
        logger.debug("request PathInfo: " + request.getPathInfo());
        logger.debug("request PathTranslated: " + request.getPathTranslated());
        logger.debug("request QueryString: " + request.getQueryString());
        logger.debug("request ContextPath: " + request.getContextPath());
        logger.debug("request ServletPath: " + request.getServletPath());
        logger.debug("request toString:" + request.toString());
        Enumeration<String> attributeNames = request.getAttributeNames();
        while (attributeNames.hasMoreElements()) {
            String attributeName = attributeNames.nextElement();
            logger.debug("request " + attributeName + ": " + request.getAttribute(attributeName));
        }
        /*      values of proxyServletWrapper request object to be sent through */
        logger.info("");

        /*      uncomment to see what the parameters of servlet passed in are  */
        Map<String, String[]> parameterMap = request.getParameterMap();

        for (Object key : parameterMap.keySet()) {
            String[] values = parameterMap.get((String) key);
            for (int i = 0; i < values.length; ++i) {
                logger.info("request ParameterMap: " + (String) key + " = " + values[i]);
            }

        }
        logger.debug("");

    }
}