Author: bdelacretaz
Date: Wed Aug 4 13:43:44 2010
New Revision: 982249
URL: http://svn.apache.org/viewvc?rev=982249&view=rev
Log:
SLING-550 - provide RuntimeState in a request attribute so that servlets can
report progress
Added:
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/JobProgressInfo.java
(with props)
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/RuntimeState.java
(with props)
Modified:
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/JobStatus.java
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/BackgroundRequestExecutionJob.java
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/SuspendableOutputStream.java
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/servlets/BackgroundTestServlet.java
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/storage/NodeJobStatusFactoryImpl.java
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/webconsole/JobConsolePlugin.java
Added:
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/JobProgressInfo.java
URL:
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/JobProgressInfo.java?rev=982249&view=auto
==============================================================================
---
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/JobProgressInfo.java
(added)
+++
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/JobProgressInfo.java
Wed Aug 4 13:43:44 2010
@@ -0,0 +1,34 @@
+/*
+ * 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;
+
+import java.util.Date;
+
+/** Provides Job progress information */
+public interface JobProgressInfo {
+
+ /** Return the job's ETA if available.
+ * @return null if the job didn't provide an ETA, or if
+ * it is done.
+ */
+ Date getEstimatedCompletionTime();
+
+ /** Return a single line of progress information */
+ String getProgressMessage();
+}
Propchange:
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/JobProgressInfo.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/JobProgressInfo.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev URL
Modified:
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/JobStatus.java
URL:
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/JobStatus.java?rev=982249&r1=982248&r2=982249&view=diff
==============================================================================
---
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/JobStatus.java
(original)
+++
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/JobStatus.java
Wed Aug 4 13:43:44 2010
@@ -46,4 +46,7 @@ public interface JobStatus {
/** Full Path of the job's stream, including extension */
String getStreamPath();
+
+ /** Return the job's progress info */
+ JobProgressInfo getProgressInfo();
}
\ No newline at end of file
Added:
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/RuntimeState.java
URL:
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/RuntimeState.java?rev=982249&view=auto
==============================================================================
---
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/RuntimeState.java
(added)
+++
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/RuntimeState.java
Wed Aug 4 13:43:44 2010
@@ -0,0 +1,36 @@
+/*
+ * 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;
+
+import java.util.Date;
+
+/** Interface used by a running job to exchange state
+ * information with the execution engine.
+ */
+public interface RuntimeState {
+ /** Set the progress message that is returned
+ * by {...@link JobProgressInfo}
+ */
+ void setProgressMessage(String str);
+
+ /** Set the ETA that is returned
+ * by {...@link JobProgressInfo}
+ */
+ void setEstimatedCompletionTime(Date d);
+}
Propchange:
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/RuntimeState.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/RuntimeState.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev URL
Modified:
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/BackgroundRequestExecutionJob.java
URL:
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/BackgroundRequestExecutionJob.java?rev=982249&r1=982248&r2=982249&view=diff
==============================================================================
---
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/BackgroundRequestExecutionJob.java
(original)
+++
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/BackgroundRequestExecutionJob.java
Wed Aug 4 13:43:44 2010
@@ -32,8 +32,10 @@ import org.apache.sling.api.resource.Res
import org.apache.sling.bgservlets.BackgroundHttpServletRequest;
import org.apache.sling.bgservlets.BackgroundHttpServletResponse;
import org.apache.sling.bgservlets.JobData;
+import org.apache.sling.bgservlets.JobProgressInfo;
import org.apache.sling.bgservlets.JobStatus;
import org.apache.sling.bgservlets.JobStorage;
+import org.apache.sling.bgservlets.RuntimeState;
import org.apache.sling.commons.auth.spi.AuthenticationInfo;
import org.apache.sling.engine.SlingServlet;
import org.slf4j.Logger;
@@ -43,7 +45,7 @@ import org.slf4j.LoggerFactory;
* Runnable that executes a FilterChain, using a ServletResponseWrapper to
* capture the output.
*/
-class BackgroundRequestExecutionJob implements Runnable, JobStatus {
+class BackgroundRequestExecutionJob implements Runnable, JobStatus,
RuntimeState, JobProgressInfo {
private final Logger log = LoggerFactory.getLogger(getClass());
private final HttpServletRequest request;
private final BackgroundHttpServletResponse response;
@@ -53,6 +55,8 @@ class BackgroundRequestExecutionJob impl
private final String path;
private final String streamPath;
private final Date creationTime;
+ private Date estimatedCompletionTime;
+ private String progressMessage;
BackgroundRequestExecutionJob(SlingServlet slingServlet,
ResourceResolverFactory rrf, JobStorage storage,
SlingHttpServletRequest request,
@@ -61,6 +65,9 @@ class BackgroundRequestExecutionJob impl
this.request = new BackgroundHttpServletRequest(request,
parametersToRemove);
this.slingServlet = slingServlet;
+
+ // Provide this as the RuntimeState for the background servlet
+ this.request.setAttribute(RuntimeState.class.getName(), this);
// Need a new ResourceResolver with the same credentials as the
// current request, for the background request.
@@ -129,4 +136,24 @@ class BackgroundRequestExecutionJob impl
public Date getCreationTime() {
return creationTime;
}
+
+ public JobProgressInfo getProgressInfo() {
+ return this;
+ }
+
+ public String getProgressMessage() {
+ return progressMessage;
+ }
+
+ public Date getEstimatedCompletionTime() {
+ return estimatedCompletionTime;
+ }
+
+ public void setEstimatedCompletionTime(Date d) {
+ estimatedCompletionTime = d;
+ }
+
+ public void setProgressMessage(String str) {
+ progressMessage = str;
+ }
}
Modified:
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/SuspendableOutputStream.java
URL:
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/SuspendableOutputStream.java?rev=982249&r1=982248&r2=982249&view=diff
==============================================================================
---
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/SuspendableOutputStream.java
(original)
+++
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/SuspendableOutputStream.java
Wed Aug 4 13:43:44 2010
@@ -23,6 +23,7 @@ import java.io.IOException;
import java.io.OutputStream;
import java.util.Date;
+import org.apache.sling.bgservlets.JobProgressInfo;
import org.apache.sling.bgservlets.JobStatus;
/**
@@ -178,4 +179,15 @@ public class SuspendableOutputStream ext
throw new UnsupportedOperationException(
"getCreationTime() is not applicable to this class");
}
+
+ /**
+ * Not implemented
+ * @throws UnsupportedOperationException
+ */
+ public JobProgressInfo getProgressInfo() {
+ throw new UnsupportedOperationException(
+ "getProgressInfo() is not applicable to this class");
+ }
+
+
}
Modified:
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/servlets/BackgroundTestServlet.java
URL:
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/servlets/BackgroundTestServlet.java?rev=982249&r1=982248&r2=982249&view=diff
==============================================================================
---
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/servlets/BackgroundTestServlet.java
(original)
+++
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/servlets/BackgroundTestServlet.java
Wed Aug 4 13:43:44 2010
@@ -30,6 +30,7 @@ import org.apache.felix.scr.annotations.
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.servlets.SlingSafeMethodsServlet;
+import org.apache.sling.bgservlets.RuntimeState;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -55,6 +56,14 @@ public class BackgroundTestServlet exten
final int cycles = getIntParam(request, "cycles", 10);
final int interval = getIntParam(request, "interval", 1000);
final int flushEvery = getIntParam(request, "flushEvery", 2);
+
+ // Use supplied RuntimeState if available
+ final RuntimeState runtimeState =
(RuntimeState)request.getAttribute(RuntimeState.class.getName());
+ if(runtimeState == null) {
+ log.warn("No RuntimeState attribute provided, won't report
progress");
+ } else {
+ runtimeState.setEstimatedCompletionTime(new
Date(System.currentTimeMillis() + cycles * interval));
+ }
w.println("Start at " + new Date());
try {
@@ -63,7 +72,15 @@ public class BackgroundTestServlet exten
w.println("Flushing output<br/>");
w.flush();
}
- w.printf("Cycle %d of %d\n<br/>", i, cycles);
+
+ final String msg = String.format("Cycle %d of %d", i, cycles);
+ w.printf(msg);
+ w.print("\n<br/>");
+
+ if(runtimeState != null) {
+ runtimeState.setProgressMessage(msg);
+ }
+
try {
Thread.sleep(interval);
} catch (InterruptedException iex) {
Modified:
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/storage/NodeJobStatusFactoryImpl.java
URL:
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/storage/NodeJobStatusFactoryImpl.java?rev=982249&r1=982248&r2=982249&view=diff
==============================================================================
---
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/storage/NodeJobStatusFactoryImpl.java
(original)
+++
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/storage/NodeJobStatusFactoryImpl.java
Wed Aug 4 13:43:44 2010
@@ -28,6 +28,7 @@ import org.apache.felix.scr.annotations.
import org.apache.felix.scr.annotations.Service;
import org.apache.sling.bgservlets.ExecutionEngine;
import org.apache.sling.bgservlets.JobData;
+import org.apache.sling.bgservlets.JobProgressInfo;
import org.apache.sling.bgservlets.JobStatus;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -96,6 +97,25 @@ public class NodeJobStatusFactoryImpl im
}
return null;
}
+
+ public JobProgressInfo getProgressInfo() {
+ // If job is active, return its info, else
+ // return info from our job node
+ final JobStatus active = getActiveJob();
+ if(active != null) {
+ return active.getProgressInfo();
+ } else {
+ return new JobProgressInfo() {
+ public String getProgressMessage() {
+ return getState().toString();
+ }
+
+ public Date getEstimatedCompletionTime() {
+ return null;
+ }
+ };
+ }
+ }
};
public JobStatus getJobStatus(Node n) throws RepositoryException {
Modified:
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/webconsole/JobConsolePlugin.java
URL:
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/webconsole/JobConsolePlugin.java?rev=982249&r1=982248&r2=982249&view=diff
==============================================================================
---
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/webconsole/JobConsolePlugin.java
(original)
+++
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/webconsole/JobConsolePlugin.java
Wed Aug 4 13:43:44 2010
@@ -20,6 +20,7 @@ package org.apache.sling.bgservlets.impl
import java.io.IOException;
import java.io.PrintWriter;
+import java.util.Date;
import java.util.Dictionary;
import java.util.Hashtable;
import java.util.Iterator;
@@ -178,6 +179,8 @@ public class JobConsolePlugin {
pw.println("<tr class='content'>");
pw.println("<th class='content container'>Controls</th>");
pw.println("<th class='content container'>State</th>");
+ pw.println("<th class='content container'>ETA</th>");
+ pw.println("<th class='content container'>Progress</th>");
pw.println("<th class='content container'>Path</th>");
pw.println("</tr>");
pw.println("</thead>");
@@ -216,16 +219,43 @@ public class JobConsolePlugin {
+ job.getPath() + "'/> ");
pw.println("</form></td>");
pw.println("<td>");
- pw.println(job.getState());
+ pw.println(escape(job.getState().toString()));
+ pw.println("</td>");
+ pw.println("<td>");
+ final Date eta =
job.getProgressInfo().getEstimatedCompletionTime();
+ pw.println(eta == null ? "-" : eta.toString());
+ pw.println("</td>");
+ pw.println("<td>");
+ pw.println(escape(job.getProgressInfo().getProgressMessage()));
pw.println("</td>");
pw.print("<td>\n<a href='");
- pw.print(console.getJobStatusPagePath(request, job,
STATUS_EXTENSION));
+ pw.print(escape(console.getJobStatusPagePath(request, job,
STATUS_EXTENSION)));
pw.print("'>");
- pw.print(job.getPath());
+ pw.print(escape(job.getPath()));
pw.println("</a>");
pw.println("</td>");
pw.println("</tr>");
}
+
+ static String escape(String str) {
+ if(str == null) {
+ return null;
+ }
+ final StringBuilder sb = new StringBuilder();
+ for(int i=0; i < str.length(); i++) {
+ final char c = str.charAt(i);
+ if(c == '<') {
+ sb.append("<");
+ } else if(c== '>') {
+ sb.append(">");
+ } else if(c == '&') {
+ sb.append("&");
+ } else {
+ sb.append(c);
+ }
+ }
+ return sb.toString();
+ }
}
}
\ No newline at end of file