/* 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.riotfamily.statistics.web;
import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import org.riotfamily.common.web.filter.FilterPlugin;
import org.riotfamily.statistics.domain.RequestStatsItem;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class RequestStatsFilterPlugin implements FilterPlugin {
private Logger log = LoggerFactory.getLogger(RequestStatsFilterPlugin.class);
private RequestStats stats;
public RequestStatsFilterPlugin(RequestStats stats) {
this.stats = stats;
}
public void doFilter(HttpServletRequest request,
HttpServletResponse response, FilterChain filterChain)
throws IOException, ServletException {
if (!stats.isEnabled()) {
filterChain.doFilter(request, response);
return;
}
RequestStatsItem item = new RequestStatsItem(request);
synchronized (this) {
if (stats.signalFailure(item.getName())) {
log.error("Maximum number of currentRequests reached ({}). Signalling failure...", stats.getMaxRequests());
response.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
return;
}
}
stats.updateStatsBefore(item);
StatusResponseWrapper statusResponse = new StatusResponseWrapper(response);
try {
filterChain.doFilter(request, statusResponse);
}
finally {
stats.updateStatsAfter(item);
stats.checkFaultyResponse(request, statusResponse.getStatus());
}
}
private static class StatusResponseWrapper extends HttpServletResponseWrapper {
private int status = HttpServletResponse.SC_OK;
public StatusResponseWrapper(HttpServletResponse response) {
super(response);
}
@Override
public void sendError(int sc) throws IOException {
super.sendError(sc);
setStatusInternal(sc);
}
@Override
public void sendError(int sc, String msg) throws IOException {
super.sendError(sc, msg);
setStatusInternal(sc);
}
@Override
public void setStatus(int sc) {
super.setStatus(sc);
setStatusInternal(sc);
}
@Override
public void setStatus(int sc, String sm) {
super.setStatus(sc, sm);
setStatusInternal(sc);
}
private void setStatusInternal(int status) {
this.status = status;
}
public int getStatus() {
return status;
}
}
}