You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@sling.apache.org by Justin Edelson <ju...@gmail.com> on 2010/07/13 15:11:20 UTC
Re: svn commit: r963686 - in /sling/trunk/contrib/extensions/bgservlets:
./ src/ src/main/ src/main/java/ src/main/java/org/ src/main/java/org/apache/
src/main/java/org/apache/sling/ src/main/java/org/apache/sling/bgservlets/
src/main/java/org/apache/sling...
This looks pretty cool. I like the idea of using the Servlet interface
instead of Callable/Runnable.
I have two comments:
1) The request/response pair passed to the servlet should be entirely
synthetic. This is true in general AFAIK[1]; in Sling it is especially
true because request.getResourceResolver() will return a closed resource
resolver.
2) Even with synthetic request/response objects, I suspect that not all
servlets are going to work in the background (or s/going to/should/).
Thus, what about using a marker interface on the servlet to declare that
it should be run in the background. Or... to declare that it can be run
in the background.
Justin
[1] that is, the ServletRequest and ServletResponse objects are not
meant to be used outside of the request thread owned by the servlet
container.
On 7/13/10 7:58 AM, bdelacretaz@apache.org wrote:
> Author: bdelacretaz
> Date: Tue Jul 13 11:58:51 2010
> New Revision: 963686
>
> URL: http://svn.apache.org/viewvc?rev=963686&view=rev
> Log:
> SLING-550 - first shot at background servlets engine, works for some simple cases, no job control yet
>
> Added:
> sling/trunk/contrib/extensions/bgservlets/ (with props)
> sling/trunk/contrib/extensions/bgservlets/pom.xml (with props)
> sling/trunk/contrib/extensions/bgservlets/src/
> sling/trunk/contrib/extensions/bgservlets/src/main/
> sling/trunk/contrib/extensions/bgservlets/src/main/java/
> sling/trunk/contrib/extensions/bgservlets/src/main/java/org/
> sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/
> sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/
> sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/
> sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/ExecutionEngine.java (with props)
> sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/
> sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/BackgroundServletStarterFilter.java (with props)
> sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/BackgroundTestServlet.java (with props)
> sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/ExecutionEngineImpl.java (with props)
> sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/FilterChainExecutionJob.java (with props)
> sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/ServletResponseWrapper.java (with props)
>
> Propchange: sling/trunk/contrib/extensions/bgservlets/
> ------------------------------------------------------------------------------
> --- svn:ignore (added)
> +++ svn:ignore Tue Jul 13 11:58:51 2010
> @@ -0,0 +1,13 @@
> +target
> +bin
> +derby.log
> +*.iml
> +*.ipr
> +*.iws
> +.settings
> +.project
> +.classpath
> +.externalToolBuilders
> +maven-eclipse.xml
> +
> +
>
> Added: sling/trunk/contrib/extensions/bgservlets/pom.xml
> URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/bgservlets/pom.xml?rev=963686&view=auto
> ==============================================================================
> --- sling/trunk/contrib/extensions/bgservlets/pom.xml (added)
> +++ sling/trunk/contrib/extensions/bgservlets/pom.xml Tue Jul 13 11:58:51 2010
> @@ -0,0 +1,94 @@
> +<?xml version="1.0" encoding="UTF-8"?>
> + <!--
> + Licensed to the Apache Software Foundation (ASF) under one or more
> + contributor license agreements. See the NOTICE file distributed with
> + this work for additional information regarding copyright ownership.
> + The ASF licenses this file to you 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.
> + -->
> +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
> + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
> +
> + <modelVersion>4.0.0</modelVersion>
> + <parent>
> + <groupId>org.apache.sling</groupId>
> + <artifactId>sling</artifactId>
> + <version>9</version>
> + <relativePath>../../../parent/pom.xml</relativePath>
> + </parent>
> +
> + <artifactId>org.apache.sling.bgservlets</artifactId>
> + <version>0.0.1-SNAPSHOT</version>
> + <packaging>bundle</packaging>
> +
> + <name>Apache Sling Background Servlets Engine</name>
> + <description>
> + Allows scripts and servlets to run as background tasks
> + which can be suspended, resumed, stopped and restarted.
> + </description>
> +
> + <scm>
> + <connection>scm:svn:http://svn.apache.org/repos/asf/sling/trunk/contrib/extensions/bgservlets</connection>
> + <developerConnection>scm:svn:https://svn.apache.org/repos/asf/sling/trunk/contrib/extensions/bgservlets</developerConnection>
> + <url>http://svn.apache.org/repos/asf/sling/trunk/contrib/extensions/bgservlets</url>
> + </scm>
> +
> + <build>
> + <plugins>
> + <plugin>
> + <groupId>org.apache.felix</groupId>
> + <artifactId>maven-scr-plugin</artifactId>
> + </plugin>
> + <plugin>
> + <groupId>org.apache.felix</groupId>
> + <artifactId>maven-bundle-plugin</artifactId>
> + <extensions>true</extensions>
> + <configuration>
> + <instructions>
> + <Export-Package>org.apache.sling.bgservlets</Export-Package>
> + <Private-Package>org.apache.sling.bgservlets.impl.*</Private-Package>
> + </instructions>
> + </configuration>
> + </plugin>
> + </plugins>
> + </build>
> +
> + <dependencies>
> + <dependency>
> + <groupId>org.osgi</groupId>
> + <artifactId>org.osgi.core</artifactId>
> + </dependency>
> + <dependency>
> + <groupId>org.osgi</groupId>
> + <artifactId>org.osgi.compendium</artifactId>
> + </dependency>
> + <dependency>
> + <groupId>org.apache.felix</groupId>
> + <artifactId>org.apache.felix.scr.annotations</artifactId>
> + <version>1.2.0</version>
> + <scope>compile</scope>
> + </dependency>
> + <dependency>
> + <groupId>org.apache.sling</groupId>
> + <artifactId>org.apache.sling.api</artifactId>
> + <version>2.0.8</version>
> + <scope>provided</scope>
> + </dependency>
> + <dependency>
> + <groupId>javax.servlet</groupId>
> + <artifactId>servlet-api</artifactId>
> + </dependency>
> + <dependency>
> + <groupId>org.slf4j</groupId>
> + <artifactId>slf4j-api</artifactId>
> + </dependency>
> + </dependencies>
> +</project>
> \ No newline at end of file
>
> Propchange: sling/trunk/contrib/extensions/bgservlets/pom.xml
> ------------------------------------------------------------------------------
> svn:eol-style = native
>
> Added: sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/ExecutionEngine.java
> URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/ExecutionEngine.java?rev=963686&view=auto
> ==============================================================================
> --- sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/ExecutionEngine.java (added)
> +++ sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/ExecutionEngine.java Tue Jul 13 11:58:51 2010
> @@ -0,0 +1,28 @@
> +/*
> + * Licensed to the Apache Software Foundation (ASF) under one
> + * or more contributor license agreements. See the NOTICE file
> + * distributed with this work for additional information
> + * regarding copyright ownership. The ASF licenses this file
> + * to you 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.apache.sling.bgservlets;
> +
> +/** Service that executes Runnables, will later allow
> + * them to be suspended, resumed, stopped and restarted.
> + */
> +public interface ExecutionEngine {
> +
> + /** Add a job to the execution queue */
> + void queueForExecution(Runnable job);
> +}
> \ No newline at end of file
>
> Propchange: sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/ExecutionEngine.java
> ------------------------------------------------------------------------------
> svn:eol-style = native
>
> Propchange: sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/ExecutionEngine.java
> ------------------------------------------------------------------------------
> svn:keywords = Author Date Id Revision Rev URL
>
> Added: sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/BackgroundServletStarterFilter.java
> URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/BackgroundServletStarterFilter.java?rev=963686&view=auto
> ==============================================================================
> --- sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/BackgroundServletStarterFilter.java (added)
> +++ sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/BackgroundServletStarterFilter.java Tue Jul 13 11:58:51 2010
> @@ -0,0 +1,91 @@
> +/*
> + * Licensed to the Apache Software Foundation (ASF) under one
> + * or more contributor license agreements. See the NOTICE file
> + * distributed with this work for additional information
> + * regarding copyright ownership. The ASF licenses this file
> + * to you 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.apache.sling.bgservlets.impl;
> +
> +import java.io.IOException;
> +
> +import javax.servlet.Filter;
> +import javax.servlet.FilterChain;
> +import javax.servlet.FilterConfig;
> +import javax.servlet.ServletException;
> +import javax.servlet.ServletRequest;
> +import javax.servlet.ServletResponse;
> +import javax.servlet.http.HttpServletRequest;
> +import javax.servlet.http.HttpServletResponse;
> +
> +import org.apache.felix.scr.annotations.Component;
> +import org.apache.felix.scr.annotations.Properties;
> +import org.apache.felix.scr.annotations.Property;
> +import org.apache.felix.scr.annotations.Reference;
> +import org.apache.felix.scr.annotations.Service;
> +import org.apache.sling.bgservlets.ExecutionEngine;
> +import org.slf4j.Logger;
> +import org.slf4j.LoggerFactory;
> +
> +/** Filter that runs the current request in the background
> + * if specific request parameters are set.
> + * TODO: define the position of this filter in the chain,
> + * and how do we enforce it?
> + */
> +@Component
> +@Service
> +@Properties({
> + @Property(name="filter.scope", value="request"),
> + @Property(name="filter.order", intValue=java.lang.Integer.MIN_VALUE)
> +})
> +public class BackgroundServletStarterFilter implements Filter{
> +
> + private final Logger log = LoggerFactory.getLogger(getClass());
> +
> + @Reference
> + private ExecutionEngine executionEngine;
> +
> + /**
> + * Request runs in the background if this request parameter is present
> + * TODO should be configurable, and maybe use other decision methods */
> + public static final String BG_PARAM = "sling:bg";
> +
> + public void doFilter(final ServletRequest sreq, final ServletResponse sresp,
> + final FilterChain chain) throws IOException, ServletException {
> + if(!(sreq instanceof HttpServletRequest)) {
> + throw new ServletException("request is not an HttpServletRequest: " + sresp.getClass().getName());
> + }
> + if(!(sresp instanceof HttpServletResponse)) {
> + throw new ServletException("response is not an HttpServletResponse: " + sresp.getClass().getName());
> + }
> + final HttpServletRequest request = (HttpServletRequest)sreq;
> + final HttpServletResponse response = (HttpServletResponse)sresp;
> + if(sreq.getParameter(BG_PARAM) != null) {
> + final FilterChainExecutionJob job = new FilterChainExecutionJob(chain, request, response);
> + log.debug("{} request parameter present, running request in the background using {}", BG_PARAM, job);
> + executionEngine.queueForExecution(job);
> +
> + // TODO not really an error, should send a nicer message
> + response.sendError(HttpServletResponse.SC_ACCEPTED, "Running request in the background using " + job);
> + } else {
> + chain.doFilter(sreq, sresp);
> + }
> + }
> +
> + public void destroy() {
> + }
> +
> + public void init(FilterConfig cfg) throws ServletException {
> + }
> +}
> \ No newline at end of file
>
> Propchange: sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/BackgroundServletStarterFilter.java
> ------------------------------------------------------------------------------
> svn:eol-style = native
>
> Propchange: sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/BackgroundServletStarterFilter.java
> ------------------------------------------------------------------------------
> svn:keywords = Author Date Id Revision Rev URL
>
> Added: sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/BackgroundTestServlet.java
> URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/BackgroundTestServlet.java?rev=963686&view=auto
> ==============================================================================
> --- sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/BackgroundTestServlet.java (added)
> +++ sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/BackgroundTestServlet.java Tue Jul 13 11:58:51 2010
> @@ -0,0 +1,78 @@
> +/*
> + * Licensed to the Apache Software Foundation (ASF) under one
> + * or more contributor license agreements. See the NOTICE file
> + * distributed with this work for additional information
> + * regarding copyright ownership. The ASF licenses this file
> + * to you 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.apache.sling.bgservlets.impl;
> +
> +import java.io.IOException;
> +import java.io.PrintWriter;
> +
> +import javax.servlet.ServletException;
> +
> +import org.apache.felix.scr.annotations.Component;
> +import org.apache.felix.scr.annotations.Property;
> +import org.apache.felix.scr.annotations.Service;
> +import org.apache.sling.api.SlingHttpServletRequest;
> +import org.apache.sling.api.SlingHttpServletResponse;
> +import org.apache.sling.api.servlets.SlingSafeMethodsServlet;
> +
> +/** Servlet used for interactive testing of the background
> + * servlets engine.
> + * TODO remove once we have better tests.
> + */
> +@Component
> +@Service
> +@SuppressWarnings("serial")
> +@Property(name="sling.servlet.paths", value="/system/bgservlets/test")
> +public class BackgroundTestServlet extends SlingSafeMethodsServlet {
> +
> + @Override
> + protected void doGet(SlingHttpServletRequest request,
> + SlingHttpServletResponse response) throws ServletException,
> + IOException {
> + response.setContentType("text/plain");
> + final PrintWriter w = response.getWriter();
> +
> + final int cycles = getIntParam(request, "cycles", 10);
> + final int interval = getIntParam(request, "interval", 1);
> + final int flushEvery = getIntParam(request, "flushEvery", 2);
> +
> + for(int i=1; i <= cycles; i++) {
> + if(i % flushEvery == 0) {
> + w.println("Flushing output");
> + w.flush();
> + }
> + w.printf("Cycle %d of %d\n", i, cycles);
> + try {
> + Thread.sleep(interval * 1000);
> + } catch(InterruptedException iex) {
> + throw new ServletException("InterruptedException", iex);
> + }
> + }
> + w.println("All done.");
> + w.flush();
> + }
> +
> + private int getIntParam(SlingHttpServletRequest request, String name, int defaultValue) {
> + int result = defaultValue;
> + final String str = request.getParameter(name);
> + if(str != null) {
> + result = Integer.parseInt(str);
> + }
> + return result;
> + }
> +}
>
> Propchange: sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/BackgroundTestServlet.java
> ------------------------------------------------------------------------------
> svn:eol-style = native
>
> Propchange: sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/BackgroundTestServlet.java
> ------------------------------------------------------------------------------
> svn:keywords = Author Date Id Revision Rev URL
>
> Added: sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/ExecutionEngineImpl.java
> URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/ExecutionEngineImpl.java?rev=963686&view=auto
> ==============================================================================
> --- sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/ExecutionEngineImpl.java (added)
> +++ sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/ExecutionEngineImpl.java Tue Jul 13 11:58:51 2010
> @@ -0,0 +1,74 @@
> +/*
> + * Licensed to the Apache Software Foundation (ASF) under one
> + * or more contributor license agreements. See the NOTICE file
> + * distributed with this work for additional information
> + * regarding copyright ownership. The ASF licenses this file
> + * to you 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.apache.sling.bgservlets.impl;
> +
> +import java.util.concurrent.ArrayBlockingQueue;
> +import java.util.concurrent.BlockingQueue;
> +import java.util.concurrent.Executor;
> +import java.util.concurrent.RejectedExecutionHandler;
> +import java.util.concurrent.ThreadPoolExecutor;
> +import java.util.concurrent.TimeUnit;
> +
> +import org.apache.felix.scr.annotations.Component;
> +import org.apache.felix.scr.annotations.Service;
> +import org.apache.sling.api.SlingException;
> +import org.apache.sling.bgservlets.ExecutionEngine;
> +import org.osgi.service.component.ComponentContext;
> +
> +/** Simple ExecutionEngine
> + * TODO should use Sling's thread pool, and check synergies
> + * with scheduler services */
> +@Component
> +@Service
> +public class ExecutionEngineImpl implements ExecutionEngine {
> +
> + private Executor executor;
> +
> + @SuppressWarnings("serial")
> + public static class QueueFullException extends SlingException {
> + QueueFullException(Runnable r) {
> + super("Execution queue is full, cannot execute " + r);
> + }
> + }
> +
> + public void activate(ComponentContext context) {
> + // TODO configurable!
> + final int corePoolSize = 2;
> + int maximumPoolSize = 2;
> + long keepAliveTime = 30;
> + TimeUnit unit = TimeUnit.SECONDS;
> + BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<Runnable>(4);
> + RejectedExecutionHandler handler = new RejectedExecutionHandler() {
> + public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
> + throw new QueueFullException(r);
> + }
> + };
> + executor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, handler);
> + }
> +
> + public void deactivate(ComponentContext context) {
> + // TODO how to shutdown executor?
> + executor = null;
> + }
> +
> + public void queueForExecution(Runnable job) {
> + // TODO wrap job in our own Runnable to detect start/end etc.
> + executor.execute(job);
> + }
> +}
>
> Propchange: sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/ExecutionEngineImpl.java
> ------------------------------------------------------------------------------
> svn:eol-style = native
>
> Propchange: sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/ExecutionEngineImpl.java
> ------------------------------------------------------------------------------
> svn:keywords = Author Date Id Revision Rev URL
>
> Added: sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/FilterChainExecutionJob.java
> URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/FilterChainExecutionJob.java?rev=963686&view=auto
> ==============================================================================
> --- sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/FilterChainExecutionJob.java (added)
> +++ sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/FilterChainExecutionJob.java Tue Jul 13 11:58:51 2010
> @@ -0,0 +1,68 @@
> +/*
> + * Licensed to the Apache Software Foundation (ASF) under one
> + * or more contributor license agreements. See the NOTICE file
> + * distributed with this work for additional information
> + * regarding copyright ownership. The ASF licenses this file
> + * to you 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.apache.sling.bgservlets.impl;
> +
> +import java.io.IOException;
> +
> +import javax.servlet.FilterChain;
> +import javax.servlet.http.HttpServletRequest;
> +import javax.servlet.http.HttpServletResponse;
> +
> +import org.slf4j.Logger;
> +import org.slf4j.LoggerFactory;
> +
> +/** Runnable that executes a FilterChain, using
> + * a ServletResponseWrapper to capture the output.
> + */
> +class FilterChainExecutionJob implements Runnable {
> + private final Logger log = LoggerFactory.getLogger(getClass());
> + private final FilterChain chain;
> + private final ServletResponseWrapper response;
> +
> + // TODO is it ok to keep a reference to the request until run() is called??
> + private final HttpServletRequest request;
> +
> + FilterChainExecutionJob(FilterChain chain, HttpServletRequest request, HttpServletResponse hsr) throws IOException {
> + this.chain = chain;
> + this.request = request;
> + response = new ServletResponseWrapper(hsr);
> + }
> +
> + public String toString() {
> + return "Background request job: " + response;
> + }
> +
> + public void run() {
> + log.info("{} execution starts", this);
> + try {
> + chain.doFilter(request, response);
> + } catch(Exception e) {
> + // TODO report errors in the background job's output
> + log.error("chain.doFilter failed", e);
> + } finally {
> + try {
> + response.cleanup();
> + } catch(IOException ioe) {
> + // TODO report errors in the background job's output
> + log.error("ServletResponseWrapper cleanup failed", ioe);
> + }
> + }
> + log.info("{} execution ends", this);
> + }
> +}
>
> Propchange: sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/FilterChainExecutionJob.java
> ------------------------------------------------------------------------------
> svn:eol-style = native
>
> Propchange: sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/FilterChainExecutionJob.java
> ------------------------------------------------------------------------------
> svn:keywords = Author Date Id Revision Rev URL
>
> Added: sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/ServletResponseWrapper.java
> URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/ServletResponseWrapper.java?rev=963686&view=auto
> ==============================================================================
> --- sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/ServletResponseWrapper.java (added)
> +++ sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/ServletResponseWrapper.java Tue Jul 13 11:58:51 2010
> @@ -0,0 +1,93 @@
> +/*
> + * Licensed to the Apache Software Foundation (ASF) under one
> + * or more contributor license agreements. See the NOTICE file
> + * distributed with this work for additional information
> + * regarding copyright ownership. The ASF licenses this file
> + * to you 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.apache.sling.bgservlets.impl;
> +
> +import java.io.File;
> +import java.io.FileOutputStream;
> +import java.io.IOException;
> +import java.io.OutputStream;
> +import java.io.OutputStreamWriter;
> +import java.io.PrintWriter;
> +
> +import javax.servlet.ServletOutputStream;
> +import javax.servlet.http.HttpServletResponse;
> +import javax.servlet.http.HttpServletResponseWrapper;
> +
> +/** Wraps an HttpServletResponse for background processing */
> +class ServletResponseWrapper extends HttpServletResponseWrapper {
> +
> + private final String outputPath;
> + private final ServletOutputStream stream;
> + private final PrintWriter writer;
> +
> + static class CustomOutputStream extends ServletOutputStream {
> +
> + private final OutputStream os;
> +
> + CustomOutputStream(OutputStream os) {
> + this.os = os;
> + }
> +
> + @Override
> + public void write(int b) throws IOException {
> + os.write(b);
> + }
> +
> + @Override
> + public void close() throws IOException {
> + os.close();
> + }
> +
> + @Override
> + public void flush() throws IOException {
> + os.flush();
> + }
> +
> + }
> +
> + ServletResponseWrapper(HttpServletResponse response) throws IOException {
> + super(response);
> + // TODO write output to the Sling repository. For now: just a temp file
> + final File output = File.createTempFile(getClass().getSimpleName(), ".data");
> + output.deleteOnExit();
> + outputPath = output.getAbsolutePath();
> + stream = new CustomOutputStream(new FileOutputStream(output));
> + writer = new PrintWriter(new OutputStreamWriter(stream));
> + }
> +
> + public String toString() {
> + return getClass().getName() + ":" + outputPath;
> + }
> +
> + void cleanup() throws IOException {
> + stream.flush();
> + stream.close();
> + }
> +
> + @Override
> + public ServletOutputStream getOutputStream() throws IOException {
> + return stream;
> + }
> +
> + @Override
> + public PrintWriter getWriter() throws IOException {
> + return writer;
> + }
> +
> +}
> \ No newline at end of file
>
> Propchange: sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/ServletResponseWrapper.java
> ------------------------------------------------------------------------------
> svn:eol-style = native
>
> Propchange: sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/ServletResponseWrapper.java
> ------------------------------------------------------------------------------
> svn:keywords = Author Date Id Revision Rev URL
>
>