001 /** 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018 019 package org.apache.hadoop.lib.servlet; 020 021 import org.apache.hadoop.fs.FileSystem; 022 import org.apache.hadoop.lib.service.FileSystemAccess; 023 024 import javax.servlet.Filter; 025 import javax.servlet.FilterChain; 026 import javax.servlet.FilterConfig; 027 import javax.servlet.ServletException; 028 import javax.servlet.ServletRequest; 029 import javax.servlet.ServletResponse; 030 import java.io.IOException; 031 032 /** 033 * The <code>FileSystemReleaseFilter</code> releases back to the 034 * {@link FileSystemAccess} service a <code>FileSystem</code> instance. 035 * <p/> 036 * This filter is useful in situations where a servlet request 037 * is streaming out HDFS data and the corresponding filesystem 038 * instance have to be closed after the streaming completes. 039 */ 040 public abstract class FileSystemReleaseFilter implements Filter { 041 private static final ThreadLocal<FileSystem> FILE_SYSTEM_TL = new ThreadLocal<FileSystem>(); 042 043 /** 044 * Initializes the filter. 045 * <p/> 046 * This implementation is a NOP. 047 * 048 * @param filterConfig filter configuration. 049 * 050 * @throws ServletException thrown if the filter could not be initialized. 051 */ 052 @Override 053 public void init(FilterConfig filterConfig) throws ServletException { 054 } 055 056 /** 057 * It delegates the incoming request to the <code>FilterChain</code>, and 058 * at its completion (in a finally block) releases the filesystem instance 059 * back to the {@link FileSystemAccess} service. 060 * 061 * @param servletRequest servlet request. 062 * @param servletResponse servlet response. 063 * @param filterChain filter chain. 064 * 065 * @throws IOException thrown if an IO error occurrs. 066 * @throws ServletException thrown if a servet error occurrs. 067 */ 068 @Override 069 public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) 070 throws IOException, ServletException { 071 try { 072 filterChain.doFilter(servletRequest, servletResponse); 073 } finally { 074 FileSystem fs = FILE_SYSTEM_TL.get(); 075 if (fs != null) { 076 FILE_SYSTEM_TL.remove(); 077 getFileSystemAccess().releaseFileSystem(fs); 078 } 079 } 080 } 081 082 /** 083 * Destroys the filter. 084 * <p/> 085 * This implementation is a NOP. 086 */ 087 @Override 088 public void destroy() { 089 } 090 091 /** 092 * Static method that sets the <code>FileSystem</code> to release back to 093 * the {@link FileSystemAccess} service on servlet request completion. 094 * 095 * @param fs fileystem instance. 096 */ 097 public static void setFileSystem(FileSystem fs) { 098 FILE_SYSTEM_TL.set(fs); 099 } 100 101 /** 102 * Abstract method to be implemetned by concrete implementations of the 103 * filter that return the {@link FileSystemAccess} service to which the filesystem 104 * will be returned to. 105 * 106 * @return the FileSystemAccess service. 107 */ 108 protected abstract FileSystemAccess getFileSystemAccess(); 109 110 }