View Javadoc

1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  package org.apache.hadoop.hbase.http;
19  
20  import java.io.BufferedReader;
21  import java.io.IOException;
22  import java.io.InputStreamReader;
23  import java.net.URL;
24  import java.net.URLConnection;
25  import java.util.Set;
26  import java.util.TreeSet;
27  
28  import javax.servlet.Filter;
29  import javax.servlet.FilterChain;
30  import javax.servlet.FilterConfig;
31  import javax.servlet.ServletException;
32  import javax.servlet.ServletRequest;
33  import javax.servlet.ServletResponse;
34  import javax.servlet.http.HttpServletRequest;
35  
36  import org.apache.commons.logging.Log;
37  import org.apache.commons.logging.LogFactory;
38  import org.apache.hadoop.conf.Configuration;
39  import org.apache.hadoop.hbase.testclassification.SmallTests;
40  import org.apache.hadoop.net.NetUtils;
41  import org.junit.Test;
42  import org.junit.experimental.categories.Category;
43  
44  @Category(SmallTests.class)
45  public class TestPathFilter extends HttpServerFunctionalTest {
46    static final Log LOG = LogFactory.getLog(HttpServer.class);
47    static final Set<String> RECORDS = new TreeSet<String>(); 
48  
49    /** A very simple filter that records accessed uri's */
50    static public class RecordingFilter implements Filter {
51      private FilterConfig filterConfig = null;
52  
53      @Override
54      public void init(FilterConfig filterConfig) {
55        this.filterConfig = filterConfig;
56      }
57  
58      @Override
59      public void destroy() {
60        this.filterConfig = null;
61      }
62  
63      @Override
64      public void doFilter(ServletRequest request, ServletResponse response,
65          FilterChain chain) throws IOException, ServletException {
66        if (filterConfig == null)
67           return;
68  
69        String uri = ((HttpServletRequest)request).getRequestURI();
70        LOG.info("filtering " + uri);
71        RECORDS.add(uri);
72        chain.doFilter(request, response);
73      }
74  
75      /** Configuration for RecordingFilter */
76      static public class Initializer extends FilterInitializer {
77        public Initializer() {}
78  
79        @Override
80        public void initFilter(FilterContainer container, Configuration conf) {
81          container.addFilter("recording", RecordingFilter.class.getName(), null);
82        }
83      }
84    }
85    
86    
87    /** access a url, ignoring some IOException such as the page does not exist */
88    static void access(String urlstring) throws IOException {
89      LOG.warn("access " + urlstring);
90      URL url = new URL(urlstring);
91      
92      URLConnection connection = url.openConnection();
93      connection.connect();
94      
95      try {
96        BufferedReader in = new BufferedReader(new InputStreamReader(
97            connection.getInputStream()));
98        try {
99          for(; in.readLine() != null; );
100       } finally {
101         in.close();
102       }
103     } catch(IOException ioe) {
104       LOG.warn("urlstring=" + urlstring, ioe);
105     }
106   }
107 
108   @Test
109   public void testPathSpecFilters() throws Exception {
110     Configuration conf = new Configuration();
111     
112     //start a http server with CountingFilter
113     conf.set(HttpServer.FILTER_INITIALIZERS_PROPERTY,
114         RecordingFilter.Initializer.class.getName());
115     String[] pathSpecs = { "/path", "/path/*" };
116     HttpServer http = createTestServer(conf, pathSpecs);
117     http.start();
118 
119     final String baseURL = "/path";
120     final String baseSlashURL = "/path/";
121     final String addedURL = "/path/nodes";
122     final String addedSlashURL = "/path/nodes/";
123     final String longURL = "/path/nodes/foo/job";
124     final String rootURL = "/";
125     final String allURL = "/*";
126 
127     final String[] filteredUrls = {baseURL, baseSlashURL, addedURL, 
128         addedSlashURL, longURL};
129     final String[] notFilteredUrls = {rootURL, allURL};
130 
131     // access the urls and verify our paths specs got added to the 
132     // filters
133     final String prefix = "http://"
134         + NetUtils.getHostPortString(http.getConnectorAddress(0));
135     try {
136       for(int i = 0; i < filteredUrls.length; i++) {
137         access(prefix + filteredUrls[i]);
138       }
139       for(int i = 0; i < notFilteredUrls.length; i++) {
140         access(prefix + notFilteredUrls[i]);
141       }
142     } finally {
143       http.stop();
144     }
145 
146     LOG.info("RECORDS = " + RECORDS);
147     
148     //verify records
149     for(int i = 0; i < filteredUrls.length; i++) {
150       assertTrue(RECORDS.remove(filteredUrls[i]));
151     }
152     assertTrue(RECORDS.isEmpty());
153   }
154 }