/**
* Copyright (C) 2011 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.web.analytics.rest;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import com.opengamma.util.auth.AuthUtils;
import com.opengamma.web.analytics.push.ConnectionManager;
import com.opengamma.web.analytics.push.LongPollingServlet;
import com.sun.jersey.api.core.HttpContext;
import com.sun.jersey.spi.container.ContainerRequest;
import com.sun.jersey.spi.container.ContainerRequestFilter;
import com.sun.jersey.spi.container.ContainerResponse;
import com.sun.jersey.spi.container.ContainerResponseFilter;
import com.sun.jersey.spi.container.ResourceFilter;
/**
* Jersey filter that sets up subscriptions for masters that are queried via the REST interface. When any data changes
* in the master a notification is sent to the client containing the REST URL used to perform the original query.
* An instance of the filter is associated with each REST method annotated with {@link SubscribeMaster}.
*/
public class MasterSubscriptionFilter implements ResourceFilter {
private final HttpContext _httpContext;
private final List<MasterType> _masterTypes;
private final ConnectionManager _updateManager;
private final HttpServletRequest _servletRequest;
public MasterSubscriptionFilter(ConnectionManager updateManager,
List<MasterType> masterTypes,
HttpContext httpContext,
HttpServletRequest servletRequest) {
_httpContext = httpContext;
_updateManager = updateManager;
_masterTypes = masterTypes;
_servletRequest = servletRequest;
}
/**
* @return null
*/
@Override
public ContainerRequestFilter getRequestFilter() {
return null;
}
/**
* @return A {@link ResponseFilter}
*/
@Override
public ContainerResponseFilter getResponseFilter() {
return new ResponseFilter(_masterTypes);
}
/**
* Filter that examines the response and sets up a subscription with
* {@link ConnectionManager#subscribe(String, String, MasterType, String)}.
*/
private class ResponseFilter implements ContainerResponseFilter {
/** The masters whose data is returned by the REST method */
private final List<MasterType> _masterTypes;
/**
* @param masterTypes The masters whose data is returned by the REST method
*/
public ResponseFilter(List<MasterType> masterTypes) {
_masterTypes = masterTypes;
}
/**
* Extracts the client ID from the query parameter named {@link LongPollingServlet#CLIENT_ID} and subscribes
* for updates when the data changes in any of the masters in {@link #_masterTypes}.
* @param request The request
* @param response The response
* @return The unmodified response
*/
@Override
public ContainerResponse filter(ContainerRequest request, ContainerResponse response) {
// TODO check response status
String clientId = FilterUtils.getClientId(request, _httpContext);
// don't subscribe if there's no client ID
if (clientId == null) {
return response;
}
String userId = (AuthUtils.isPermissive() ? null : FilterUtils.getUserId(_httpContext));
String url = _servletRequest.getRequestURI();
// TODO should we only subscribe if there were query params, i.e. it was a search request, not just a request for the search page
for (MasterType masterType : _masterTypes) {
_updateManager.subscribe(userId, clientId, masterType, url);
}
return response;
}
}
}