Revision created by MOE tool push_codebase.
[gae.git] / java / src / main / com / google / appengine / tools / development / LocalApiProxyServletFilter.java
blobf6919d7d53f70cdee3219c5a493a9a1de9b00c89
1 // Copyright 2008 Google Inc. All Rights Reserved.
3 package com.google.appengine.tools.development;
5 import com.google.apphosting.api.ApiProxy;
6 import com.google.apphosting.utils.config.AppEngineWebXml;
7 import com.google.apphosting.utils.config.AppEngineWebXmlReader;
8 import com.google.apphosting.utils.config.WebModule;
10 import java.io.File;
11 import java.io.IOException;
12 import java.io.InputStream;
13 import java.util.logging.Logger;
15 import javax.servlet.Filter;
16 import javax.servlet.FilterChain;
17 import javax.servlet.FilterConfig;
18 import javax.servlet.ServletContext;
19 import javax.servlet.ServletException;
20 import javax.servlet.ServletRequest;
21 import javax.servlet.ServletResponse;
22 import javax.servlet.http.HttpServletRequest;
24 /**
25 * This filter is not currently used. It was originally written for
26 * IBM so they could see how to use our API's from their own webserver.
27 * We kept it around because we'd ultimately like to use this ourselves but
28 * we don't currently have a way to ensure that this filter runs before any
29 * other filters get initialized.
31 * {@code LocalApiProxyServletFilter} is a servlet {@link Filter} that
32 * sets up {@link ApiProxy} for use with the stub API implementations.
34 * <p>There are two parts to this:<ul>
36 * <li>At initialization, this filter installs a {@link
37 * ApiProxy.Delegate} instance that locates any API stub
38 * implementations on the classpath and registers them for use by
39 * future requests. It also looks for an App Engine-specific
40 * deployment descriptor ({@code WEB-INF/appengine-web.xml}) and
41 * parses it to obtain some metadata about the application
42 * (e.g. application identifier).</li>
44 * <li>Around each request, a {@link ApiProxy.Environment} instance is
45 * installed into a {@link ThreadLocal} managed by {@link ApiProxy}.
46 * This environment instance contains the application metadata that
47 * was extracted earlier, and also provides access to the
48 * authentication data maintained by the stub implementation of the
49 * Users API.</li> </ul>
52 public class LocalApiProxyServletFilter implements Filter {
53 private static final Logger logger = Logger.getLogger(LocalApiProxyServletFilter.class.getName());
54 private static final String AE_WEB_XML = "/WEB-INF/appengine-web.xml";
56 private AppEngineWebXml appEngineWebXml;
58 /**
59 * Register a custom {@link ApiProxy.Delegate instance}.
61 @Override
62 public void init(FilterConfig config) {
63 logger.info("Filter initialization invoked -- registering ApiProxy delegate.");
64 ApiProxyLocalFactory factory = new ApiProxyLocalFactory();
65 ApiProxy.setDelegate(factory.create(getLocalServerEnvironment(config)));
67 logger.info("Parsing custom deployment descriptor (" + AE_WEB_XML + ").");
68 ServletAppEngineWebXmlReader reader =
69 new ServletAppEngineWebXmlReader(config.getServletContext());
70 appEngineWebXml = reader.readAppEngineWebXml();
71 logger.info("Application identifier is: " + appEngineWebXml.getAppId());
74 private LocalServerEnvironment getLocalServerEnvironment(final FilterConfig config) {
75 return new LocalServerEnvironment() {
77 @Override
78 public File getAppDir() {
79 return new File(".");
82 @Override
83 public String getAddress() {
84 throw new UnsupportedOperationException();
87 @Override
88 public int getPort() {
89 throw new UnsupportedOperationException();
92 @Override
93 public String getHostName() {
94 throw new UnsupportedOperationException();
97 @Override
98 public void waitForServerToStart() { }
100 @Override
101 public boolean simulateProductionLatencies() {
102 return true;
105 @Override
106 public boolean enforceApiDeadlines() {
107 return false;
113 * Remove the custom {@link ApiProxy.Delegate} instance.
115 @Override
116 public void destroy() {
117 logger.info("Filter destruction invoked -- removing delegate.");
118 ApiProxy.setDelegate(null);
122 * Wrap the request with calls to the environment-management method
123 * on {@link ApiProxy}.
125 @Override
126 public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
127 throws IOException, ServletException {
128 HttpServletRequest httpRequest = (HttpServletRequest) request;
130 logger.fine("Filter received a request, setting environment ThreadLocal.");
131 ApiProxy.setEnvironmentForCurrentThread(new LocalHttpRequestEnvironment(
132 appEngineWebXml.getAppId(), WebModule.getServerName(appEngineWebXml),
133 appEngineWebXml.getMajorVersionId(), LocalEnvironment.MAIN_INSTANCE,
134 httpRequest, null, null));
135 try {
136 chain.doFilter(request, response);
137 } finally {
138 logger.fine("Request has completed. Removing environment ThreadLocal.");
139 ApiProxy.clearEnvironmentForCurrentThread();
144 * {@code ServletAppEngineWebXmlReader} is a specialization of
145 * {@link AppEngineWebXmlReader} that reads the custom deployment
146 * descriptor ({@code WEB-INF/appengine-web.xml}) from a {@link
147 * ServletContext} rather than looking for an actual file on the
148 * filesystem.
150 private static class ServletAppEngineWebXmlReader extends AppEngineWebXmlReader {
151 private final ServletContext context;
153 public ServletAppEngineWebXmlReader(ServletContext context) {
154 super("");
155 this.context = context;
158 @Override
159 protected InputStream getInputStream() {
160 return context.getResourceAsStream(AE_WEB_XML);