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

org.dspace.services.sessions.SessionRequestServiceImpl Maven / Gradle / Ivy

There is a newer version: 8.0
Show newest version
/**
 * The contents of this file are subject to the license and copyright
 * detailed in the LICENSE and NOTICE files at the root of the source
 * tree and available online at
 *
 * http://www.dspace.org/license/
 */
package org.dspace.services.sessions;

import org.apache.commons.lang.StringUtils;
import org.dspace.kernel.mixins.InitializedService;
import org.dspace.kernel.mixins.ShutdownService;
import org.dspace.services.ConfigurationService;
import org.dspace.services.RequestService;
import org.dspace.services.SessionService;
import org.dspace.services.model.Request;
import org.dspace.services.model.RequestInterceptor;
import org.dspace.services.model.RequestInterceptor.RequestInterruptionException;
import org.dspace.services.model.Session;
import org.dspace.services.sessions.model.HttpRequestImpl;
import org.dspace.services.sessions.model.InternalRequestImpl;
import org.dspace.utils.servicemanager.OrderedServiceComparator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Required;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;


/**
 * Implementation of the session service.
 * 

* This depends on having something (a filter typically) which is * placing the current requests into a request storage cache. *

* TODO use a HttpSessionListener to keep track of all sessions? * * @author Aaron Zeckoski (azeckoski @ gmail.com) */ public final class SessionRequestServiceImpl implements SessionService, RequestService, InitializedService, ShutdownService { private static Logger log = LoggerFactory.getLogger(SessionRequestServiceImpl.class); private ConfigurationService configurationService; @Autowired @Required public void setConfigurationService(ConfigurationService configurationService) { this.configurationService = configurationService; } /** * map for holding onto the request interceptors which is classloader safe. */ private Map interceptorsMap = new HashMap(); /* (non-Javadoc) * @see org.dspace.kernel.mixins.InitializedService#init() */ public void init() { log.info("init"); } /* (non-Javadoc) * @see org.dspace.kernel.mixins.ShutdownService#shutdown() */ public void shutdown() { log.info("shutdown"); clear(); } /** * Clears out the settings inside this service. * Mostly for testing. */ public void clear() { // immediately clear all interceptors when the service is terminated this.requests.clear(); this.interceptorsMap.clear(); } /* (non-Javadoc) * @see org.dspace.services.RequestService#startRequest() */ public String startRequest() { return startRequest(new InternalRequestImpl()); } /* (non-Javadoc) * @see org.dspace.services.RequestService#startRequest() */ public String startRequest(ServletRequest request, ServletResponse response) { return startRequest(new HttpRequestImpl(request, response)); } private String startRequest(Request req) { // call the list of interceptors List interceptors = getInterceptors(false); for (RequestInterceptor requestInterceptor : interceptors) { if (requestInterceptor != null) { try { requestInterceptor.onStart(req.getRequestId(), req.getSession()); } catch (RequestInterruptionException e) { String message = "Request stopped from starting by exception from the interceptor ("+requestInterceptor+"): " + e.getMessage(); log.warn(message); throw new RequestInterruptionException(message, e); } catch (Exception e) { log.warn("Request interceptor ("+requestInterceptor+") failed to execute on start ("+req.getRequestId()+"): " + e.getMessage()); } } } requests.setCurrent(req); return req.getRequestId(); } /* (non-Javadoc) * @see org.dspace.services.RequestService#endRequest(java.lang.Exception) */ public String endRequest(Exception failure) { String requestId = null; try { requestId = getCurrentRequestId(); if (StringUtils.isEmpty(requestId)) { // request not found, just log a warning log.debug("Attempting to end a request when none currently exists"); } else { endRequest(requestId, failure); } } finally { requests.removeCurrent(); } return requestId; } private void endRequest(String requestId, Exception failure) { if (requestId != null) { Session session = null; Request req = requests.get(requestId); if (req != null) { session = req.getSession(); } List interceptors = getInterceptors(true); // reverse for (RequestInterceptor requestInterceptor : interceptors) { if (requestInterceptor != null) { try { requestInterceptor.onEnd(requestId, session, (failure == null), failure); } catch (RequestInterruptionException e) { log.warn("Attempt to stop request from ending by an exception from the interceptor ("+requestInterceptor+"), cannot stop requests from ending though so request end continues, this may be an error: " + e.getMessage()); } catch (Exception e) { log.warn("Request interceptor ("+requestInterceptor+") failed to execute on end ("+requestId+"): " + e.getMessage()); } } } } } /** * List this session's interceptors. * * @param reverse return the list in reverse order? * @return the current list of interceptors in the correct order */ private List getInterceptors(boolean reverse) { ArrayList l = new ArrayList( this.interceptorsMap.values() ); OrderedServiceComparator comparator = new OrderedServiceComparator(); Collections.sort(l, comparator ); if (reverse) { Collections.reverse(l); } return l; } /* (non-Javadoc) * @see org.dspace.services.RequestService#registerRequestListener(org.dspace.services.model.RequestInterceptor) */ public void registerRequestInterceptor(RequestInterceptor interceptor) { if (interceptor == null) { throw new IllegalArgumentException("Cannot register an interceptor that is null"); } if (interceptor.getOrder() <= 0) { throw new IllegalArgumentException("Interceptor ordering for RequestInterceptor's must be greater than 0"); } String key = interceptor.getOrder() + ":" + interceptor.getClass().getName(); this.interceptorsMap.put(key, interceptor); } /** * Makes a session from the existing HTTP session stuff in the * current request, or creates a new session of non-HTTP related * sessions. * * @return the new session object which is placed into the request * @throws IllegalStateException if not session can be created */ public Session getCurrentSession() { Request req = requests.getCurrent(); if (req != null) { return req.getSession(); } return null; } /* (non-Javadoc) * @see org.dspace.services.SessionService#getCurrentSessionId() */ public String getCurrentSessionId() { Request req = requests.getCurrent(); if (req != null) { Session session = req.getSession(); if (session != null) { return session.getSessionId(); } } return null; } /* (non-Javadoc) * @see org.dspace.services.SessionService#getCurrentUserId() */ public String getCurrentUserId() { String userId = null; Session session = getCurrentSession(); if (session != null) { userId = session.getUserId(); } return userId; } /* (non-Javadoc) * @see org.dspace.services.RequestService#getCurrentRequestId() */ public String getCurrentRequestId() { Request req = requests.getCurrent(); if (req != null) { return req.getRequestId(); } return null; } /* (non-Javadoc) * @see org.dspace.services.RequestService#getCurrentRequest() */ public Request getCurrentRequest() { return requests.getCurrent(); } /** * Class to hold the current request. Uses Map keyed on current thread id. */ private class RequestHolder { Map requestMap = new ConcurrentHashMap(); Request getCurrent() { return requestMap.get(Thread.currentThread().getId()); } void setCurrent(Request req) { requestMap.put(Thread.currentThread().getId(), req); } void removeCurrent() { requestMap.remove(Thread.currentThread().getId()); } Request get(String requestId) { if (!StringUtils.isEmpty(requestId)) { for (Request req : requestMap.values()) { if (req != null && requestId.equals(req.getRequestId())) { return req; } } } return null; } void remove(String requestId) { if (!StringUtils.isEmpty(requestId)) { for (Map.Entry reqEntry : requestMap.entrySet()) { if (reqEntry.getValue() != null && requestId.equals(reqEntry.getValue().getRequestId())) { requestMap.remove(reqEntry.getKey()); } } } } void clear() { for (Request request : requestMap.values()) { try { endRequest(request.getRequestId(), null); } catch (RuntimeException e) { log.error("Runtime exception ending request", e); } catch (Exception e) { log.error("Exception ending request", e); } } requestMap.clear(); } } private RequestHolder requests = new RequestHolder(); }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy