2 * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.controller.filtervalve.cors;
12 import java.io.IOException;
13 import java.util.Objects;
14 import javax.servlet.FilterChain;
15 import javax.servlet.ServletException;
16 import org.apache.catalina.connector.Request;
17 import org.apache.catalina.connector.Response;
18 import org.apache.catalina.valves.ValveBase;
19 import org.apache.commons.io.FileUtils;
20 import org.opendaylight.controller.filtervalve.cors.jaxb.Host;
21 import org.opendaylight.controller.filtervalve.cors.jaxb.Parser;
22 import org.opendaylight.controller.filtervalve.cors.model.FilterProcessor;
23 import org.slf4j.Logger;
24 import org.slf4j.LoggerFactory;
27 * Valve that allows adding filters per context. Each context can have its own filter definitions.
28 * Main purpose is to allow externalizing security filters from application bundles to a single
29 * file per OSGi distribution.
31 public class FilterValve extends ValveBase {
32 private static final Logger logger = LoggerFactory.getLogger(FilterValve.class);
33 private FilterProcessor filterProcessor;
35 public void invoke(final Request request, final Response response) throws IOException, ServletException {
36 if (filterProcessor == null) {
37 throw new IllegalStateException("Initialization error");
40 FilterChain nextValveFilterChain = (req, resp) -> {
41 boolean reqEquals = Objects.equals(request, req);
42 boolean respEquals = Objects.equals(response, resp);
43 if (reqEquals == false || respEquals == false) {
44 logger.error("Illegal change was detected by valve - request {} or " +
45 "response {} was replaced by a filter. This is not supported by this valve",
46 reqEquals, respEquals);
47 throw new IllegalStateException("Request or response was replaced in a filter");
49 getNext().invoke(request, response);
51 filterProcessor.process(request, response, nextValveFilterChain);
55 * Called by Tomcat when configurationFile attribute is set.
56 * @param fileName path to xml file containing valve configuration
57 * @throws Exception exception
59 public void setConfigurationFile(String fileName) throws Exception {
60 File configurationFile = new File(fileName);
61 if (configurationFile.exists() == false || configurationFile.canRead() == false) {
62 throw new IllegalArgumentException(
63 "Cannot read 'configurationFile' of this valve defined in tomcat-server.xml: " + fileName);
67 xmlContent = FileUtils.readFileToString(configurationFile);
68 } catch (IOException e) {
69 logger.error("Cannot read {} of this valve defined in tomcat-server.xml", fileName, e);
70 throw new IllegalStateException("Cannot read " + fileName, e);
74 host = Parser.parse(xmlContent, fileName);
75 } catch (Exception e) {
76 logger.error("Cannot parse {} of this valve defined in tomcat-server.xml", fileName, e);
77 throw new IllegalStateException("Error while parsing " + fileName, e);
79 filterProcessor = new FilterProcessor(host);
83 * @see org.apache.catalina.valves.ValveBase#getInfo()
85 public String getInfo() {
86 return getClass() + "/1.0";