Author: bdelacretaz
Date: Mon Jul 26 16:31:49 2010
New Revision: 979347
URL: http://svn.apache.org/viewvc?rev=979347&view=rev
Log:
SLING-505 - servlet-based rendering of job and stream nodes, meant to be
overridden with custom scripts.
Added:
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/BackgroundServletConstants.java
(with props)
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/servlets/
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/servlets/BackgroundTestServlet.java
- copied, changed from r979260,
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/BackgroundTestServlet.java
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/servlets/JobInfoServlet.java
(with props)
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/servlets/JobStreamServlet.java
- copied, changed from r979209,
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/OutputReplayServlet.java
Removed:
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/BackgroundTestServlet.java
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/OutputReplayServlet.java
Modified:
sling/trunk/contrib/extensions/bgservlets/pom.xml
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/BackgroundServletStarterFilter.java
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/nodestream/NodeOutputStream.java
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/storage/JobDataImpl.java
Modified: sling/trunk/contrib/extensions/bgservlets/pom.xml
URL:
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/bgservlets/pom.xml?rev=979347&r1=979346&r2=979347&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/bgservlets/pom.xml (original)
+++ sling/trunk/contrib/extensions/bgservlets/pom.xml Mon Jul 26 16:31:49 2010
@@ -104,6 +104,11 @@
<scope>test</scope>
</dependency>
<dependency>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>org.apache.sling.commons.json</artifactId>
+ <version>2.0.4-incubator</version>
+ </dependency>
+ <dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
</dependency>
Added:
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/BackgroundServletConstants.java
URL:
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/BackgroundServletConstants.java?rev=979347&view=auto
==============================================================================
---
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/BackgroundServletConstants.java
(added)
+++
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/BackgroundServletConstants.java
Mon Jul 26 16:31:49 2010
@@ -0,0 +1,27 @@
+/*
+ * 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;
+
+public class BackgroundServletConstants {
+ /** Resource type for the Job node */
+ public static final String JOB_RESOURCE_TYPE = "sling/bg/job";
+
+ /** Resource type for the stream node */
+ public static final String STREAM_RESOURCE_TYPE = "sling/bg/stream";
+}
Propchange:
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/BackgroundServletConstants.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/BackgroundServletConstants.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev URL
Modified:
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=979347&r1=979346&r2=979347&view=diff
==============================================================================
---
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/BackgroundServletStarterFilter.java
(original)
+++
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/BackgroundServletStarterFilter.java
Mon Jul 26 16:31:49 2010
@@ -107,9 +107,16 @@ public class BackgroundServletStarterFil
}
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);
+ // Redirect to the job's status page, using same extension
+ // as this request
+ String ext = slingRequest.getRequestPathInfo().getExtension();
+ if(ext == null) {
+ ext = "";
+ } else if(ext.length() > 0) {
+ ext = "." + ext;
+ }
+ final String path = request.getContextPath() + job.getPath() +
ext;
+ response.sendRedirect(path);
} catch (org.apache.sling.api.resource.LoginException e) {
throw new ServletException("LoginException in doFilter", e);
}
Modified:
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/nodestream/NodeOutputStream.java
URL:
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/nodestream/NodeOutputStream.java?rev=979347&r1=979346&r2=979347&view=diff
==============================================================================
---
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/nodestream/NodeOutputStream.java
(original)
+++
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/nodestream/NodeOutputStream.java
Mon Jul 26 16:31:49 2010
@@ -48,9 +48,6 @@ public class NodeOutputStream extends Ou
private final Logger log = LoggerFactory.getLogger(getClass());
- /** Prefix for Property names used to store our streams */
- public static final String STREAM_PROPERTY_NAME_PREFIX = "_NODE_STREAM_";
-
/** Node type for our stream nodes */
public static final String STREAM_NODE_TYPE = "nt:unstructured";
Copied:
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/servlets/BackgroundTestServlet.java
(from r979260,
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/servlets/BackgroundTestServlet.java?p2=sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/servlets/BackgroundTestServlet.java&p1=sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/BackgroundTestServlet.java&r1=979260&r2=979347&rev=979347&view=diff
==============================================================================
---
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/BackgroundTestServlet.java
(original)
+++
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/servlets/BackgroundTestServlet.java
Mon Jul 26 16:31:49 2010
@@ -16,7 +16,7 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.sling.bgservlets.impl;
+package org.apache.sling.bgservlets.impl.servlets;
import java.io.IOException;
import java.io.PrintWriter;
@@ -60,10 +60,10 @@ public class BackgroundTestServlet exten
try {
for (int i = 1; i <= cycles; i++) {
if (i % flushEvery == 0) {
- w.println("Flushing output");
+ w.println("Flushing output<br/>");
w.flush();
}
- w.printf("Cycle %d of %d\n", i, cycles);
+ w.printf("Cycle %d of %d\n<br/>", i, cycles);
try {
Thread.sleep(interval);
} catch (InterruptedException iex) {
Added:
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/servlets/JobInfoServlet.java
URL:
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/servlets/JobInfoServlet.java?rev=979347&view=auto
==============================================================================
---
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/servlets/JobInfoServlet.java
(added)
+++
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/servlets/JobInfoServlet.java
Mon Jul 26 16:31:49 2010
@@ -0,0 +1,116 @@
+/*
+ * 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.servlets;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletResponse;
+
+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;
+import org.apache.sling.bgservlets.BackgroundServletConstants;
+import org.apache.sling.commons.json.JSONException;
+import org.apache.sling.commons.json.io.JSONWriter;
+
+/** Default rendering of a job node in various formats,
+ * meant to be displayed when the job is started.
+ */
+...@component
+...@service
+...@property(name = "sling.servlet.resourceTypes", value =
BackgroundServletConstants.JOB_RESOURCE_TYPE)
+...@suppresswarnings("serial")
+public class JobInfoServlet extends SlingSafeMethodsServlet {
+
+ public static final String DEFAULT_ENCODING = "UTF-8";
+ public static final String DEFAULT_EXT = "txt";
+
+ private static final Map<String, Renderer> renderers;
+ static {
+ renderers = new HashMap<String, Renderer>();
+ renderers.put("txt", new TextRenderer());
+ renderers.put("html", new HtmlRenderer());
+ renderers.put("json", new JsonRenderer());
+ }
+
+ static interface Renderer {
+ void render(PrintWriter pw, String streamPath, String streamResource)
throws IOException;
+ }
+
+ private static class TextRenderer implements Renderer {
+ public void render(PrintWriter pw, String streamPath, String
streamResource) {
+ pw.println("Background execution scheduled, job output available
at ");
+ pw.println(streamPath);
+ }
+ }
+
+ private static class HtmlRenderer implements Renderer {
+ public void render(PrintWriter pw, String streamPath, String
streamResource) {
+ pw.println("<html><head><title>Background job</title>");
+ pw.println("<link rel='stream' href='" + streamPath + "'/>");
+ pw.println("</head><body>");
+ pw.println("<h1>Background job scheduled</h1>");
+ pw.println("Job output available at");
+ pw.println("<a href='" + streamPath + "'>" + streamResource +
"</a>.");
+ pw.println("</body>");
+ }
+ }
+
+ private static class JsonRenderer implements Renderer {
+ public void render(PrintWriter pw, String streamPath, String
streamResource) throws IOException {
+ JSONWriter w = new JSONWriter(pw);
+ try {
+ w.object();
+ w.key("info");
+ w.value("Background job scheduled");
+ w.key("jobStreamPath");
+ w.value(streamPath);
+ w.endObject();
+ } catch (JSONException e) {
+ throw new IOException("JSONException in " +
getClass().getSimpleName(), e);
+ }
+ }
+ }
+
+ @Override
+ protected void doGet(SlingHttpServletRequest request,
+ SlingHttpServletResponse response) throws ServletException,
+ IOException {
+ final String streamResource = request.getResource().getPath() +
"/stream." + request.getRequestPathInfo().getExtension();
+ final String streamPath = request.getContextPath() + streamResource;
+ final String ext = request.getRequestPathInfo().getExtension();
+ Renderer r = renderers.get(ext);
+ if(r == null) {
+ r = renderers.get(DEFAULT_EXT);
+ }
+ if(r == null) {
+ response.sendError(HttpServletResponse.SC_BAD_REQUEST, "No
JobRenderer available for extension '" + ext + "'");
+ }
+ response.setContentType(request.getResponseContentType());
+ response.setCharacterEncoding(DEFAULT_ENCODING);
+ r.render(response.getWriter(), streamPath, streamResource);
+ }
+}
Propchange:
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/servlets/JobInfoServlet.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/servlets/JobInfoServlet.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev URL
Copied:
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/servlets/JobStreamServlet.java
(from r979209,
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/OutputReplayServlet.java)
URL:
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/servlets/JobStreamServlet.java?p2=sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/servlets/JobStreamServlet.java&p1=sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/OutputReplayServlet.java&r1=979209&r2=979347&rev=979347&view=diff
==============================================================================
---
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/OutputReplayServlet.java
(original)
+++
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/servlets/JobStreamServlet.java
Mon Jul 26 16:31:49 2010
@@ -16,38 +16,36 @@
* specific language governing permissions and limitations
* under the License.
*/
-package org.apache.sling.bgservlets.impl;
+package org.apache.sling.bgservlets.impl.servlets;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.jcr.Node;
+import javax.jcr.RepositoryException;
import javax.servlet.ServletException;
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.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.servlets.SlingSafeMethodsServlet;
+import org.apache.sling.bgservlets.BackgroundServletConstants;
import org.apache.sling.bgservlets.JobData;
import org.apache.sling.bgservlets.JobStorage;
-/** Servlet that replays the output of servlets executed in
- * the background.
+/** Default rendering of the job's stream node: replays the
+ * stored stream.
*/
@Component
@Service
@SuppressWarnings("serial")
-...@properties ( {
- @Property(name="sling.servlet.resourceTypes",
value="sling/servlet/default"),
- @Property(name="sling.servlet.extensions", value="bgreplay")
-})
-public class OutputReplayServlet extends SlingSafeMethodsServlet {
+...@property(name = "sling.servlet.resourceTypes", value =
BackgroundServletConstants.STREAM_RESOURCE_TYPE)
+public class JobStreamServlet extends SlingSafeMethodsServlet {
@Reference
private JobStorage jobStorage;
@@ -60,22 +58,27 @@ public class OutputReplayServlet extends
response.sendError(HttpServletResponse.SC_NOT_FOUND,
"Resource does not adapt to a Node: " +
request.getResource().getPath());
}
-
- // TODO content-type, length etc.
- final JobData d = jobStorage.getJobData(n);
- final InputStream is = d.getInputStream();
+
+ // The stream is a child of the job node
try {
- final OutputStream os = response.getOutputStream();
- final byte [] buffer = new byte[32768];
- int count = 0;
- while((count = is.read(buffer, 0, buffer.length)) > 0) {
- os.write(buffer, 0, count);
- }
- os.flush();
- } finally {
- if(is != null) {
- is.close();
+ final JobData d = jobStorage.getJobData(n.getParent());
+ final InputStream is = d.getInputStream();
+ try {
+ response.setContentType(request.getResponseContentType());
+ final OutputStream os = response.getOutputStream();
+ final byte [] buffer = new byte[32768];
+ int count = 0;
+ while((count = is.read(buffer, 0, buffer.length)) > 0) {
+ os.write(buffer, 0, count);
+ }
+ os.flush();
+ } finally {
+ if(is != null) {
+ is.close();
+ }
}
+ } catch(RepositoryException re) {
+ throw new ServletException("RepositoryException in doGet()", re);
}
}
}
Modified:
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/storage/JobDataImpl.java
URL:
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/storage/JobDataImpl.java?rev=979347&r1=979346&r2=979347&view=diff
==============================================================================
---
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/storage/JobDataImpl.java
(original)
+++
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/storage/JobDataImpl.java
Mon Jul 26 16:31:49 2010
@@ -24,6 +24,8 @@ import java.io.OutputStream;
import javax.jcr.Node;
import javax.jcr.RepositoryException;
+import org.apache.sling.api.SlingConstants;
+import org.apache.sling.bgservlets.BackgroundServletConstants;
import org.apache.sling.bgservlets.JobData;
import org.apache.sling.bgservlets.impl.nodestream.NodeInputStream;
import org.apache.sling.bgservlets.impl.nodestream.NodeOutputStream;
@@ -33,12 +35,14 @@ class JobDataImpl implements JobData {
private final Node node;
private final String path;
- public static final String STREAM_PATH = "outputStream";
+ public static final String STREAM_PATH = "stream";
+ public static final String RT_PROP = SlingConstants.NAMESPACE_PREFIX + ":"
+ SlingConstants.PROPERTY_RESOURCE_TYPE;
+
/** Build a JobDataImpl on supplied node, which must exists */
JobDataImpl(Node n) throws RepositoryException {
node = n;
- path = n.getPath();
+ path = node.getPath();
}
public InputStream getInputStream() {
@@ -58,7 +62,9 @@ class JobDataImpl implements JobData {
throw new IllegalArgumentException("Stream node already
exists: "
+ node.getPath() + "/" + STREAM_PATH);
}
+ node.setProperty(RT_PROP,
BackgroundServletConstants.JOB_RESOURCE_TYPE);
final Node stream = node.addNode(STREAM_PATH);
+ stream.setProperty(RT_PROP,
BackgroundServletConstants.STREAM_RESOURCE_TYPE);
node.save();
return new NodeOutputStream(stream);
} catch(Exception e) {