Author: bdelacretaz
Date: Tue Jul 27 14:41:16 2010
New Revision: 979727
URL: http://svn.apache.org/viewvc?rev=979727&view=rev
Log:
SLING-550 - JobConsole backend added, gets job data from persistent storage
Added:
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/JobConsole.java
(with props)
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/JobConsoleImpl.java
(with props)
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/storage/NodeJobStatusFactory.java
(with props)
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/storage/NodeJobStatusFactoryImpl.java
(with props)
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/webconsole/JobConsolePlugin.java
- copied, changed from r979652,
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/webconsole/ExecutionEngineConsolePlugin.java
Removed:
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/webconsole/ExecutionEngineConsolePlugin.java
Modified:
sling/trunk/contrib/extensions/bgservlets/pom.xml
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/JobData.java
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/Activator.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/BackgroundServletStarterFilter.java
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/ExecutionEngineImpl.java
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/servlets/JobInfoServlet.java
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/storage/JobDataImpl.java
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/storage/JobStorageException.java
Modified: sling/trunk/contrib/extensions/bgservlets/pom.xml
URL:
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/bgservlets/pom.xml?rev=979727&r1=979726&r2=979727&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/bgservlets/pom.xml (original)
+++ sling/trunk/contrib/extensions/bgservlets/pom.xml Tue Jul 27 14:41:16 2010
@@ -109,6 +109,11 @@
<version>2.0.4-incubator</version>
</dependency>
<dependency>
+ <groupId>org.apache.sling</groupId>
+ <artifactId>org.apache.sling.jcr.api</artifactId>
+ <version>2.0.6</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/JobConsole.java
URL:
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/JobConsole.java?rev=979727&view=auto
==============================================================================
---
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/JobConsole.java
(added)
+++
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/JobConsole.java
Tue Jul 27 14:41:16 2010
@@ -0,0 +1,50 @@
+/*
+ * 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.Iterator;
+
+import javax.jcr.Session;
+import javax.servlet.http.HttpServletRequest;
+
+/** Back-end for management consoles that
+ * give access to background jobs.
+ */
+public interface JobConsole {
+ /** Return Iterator on JobStatus, in descending order of
+ * creation date.
+ *
+ * @param session not used if activeOnly = true
+ * @param activeOnly if true, only jobs that are currently
+ * active in the ExecutionEngine are returned.
+ */
+ Iterator<JobStatus> getJobStatus(Session session, boolean activeOnly);
+
+ /** Return a single JobStatus, null if not found.
+ *
+ * @param session Session to use if reading from persistent storage
+ * @param path the job path
+ */
+ JobStatus getJobStatus(Session session, String path);
+
+ /** Return the full path, including extension, to use to display
+ * the given job status' page.
+ */
+ String getJobStatusPagePath(HttpServletRequest request, JobStatus
jobStatus, String extension);
+}
Propchange:
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/JobConsole.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/JobConsole.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev URL
Modified:
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/JobData.java
URL:
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/JobData.java?rev=979727&r1=979726&r2=979727&view=diff
==============================================================================
---
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/JobData.java
(original)
+++
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/JobData.java
Tue Jul 27 14:41:16 2010
@@ -26,6 +26,7 @@ import java.io.OutputStream;
*/
public interface JobData {
String JOB_DATA_MIXIN = "sling:bgJobData";
+ String PROP_EXTENSION = "sling;jobExtension";
/** Return unique path of this data item */
String getPath();
@@ -40,4 +41,10 @@ public interface JobData {
* @return null if no stream stored yet
*/
InputStream getInputStream();
+
+ /** Set a named property */
+ void setProperty(String name, String value);
+
+ /** Get a named property, null if non-existent */
+ String getProperty(String name);
}
Modified:
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/Activator.java
URL:
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/Activator.java?rev=979727&r1=979726&r2=979727&view=diff
==============================================================================
---
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/Activator.java
(original)
+++
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/Activator.java
Tue Jul 27 14:41:16 2010
@@ -18,7 +18,7 @@
*/
package org.apache.sling.bgservlets.impl;
-import
org.apache.sling.bgservlets.impl.webconsole.ExecutionEngineConsolePlugin;
+import org.apache.sling.bgservlets.impl.webconsole.JobConsolePlugin;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
import org.slf4j.Logger;
@@ -33,7 +33,7 @@ public class Activator implements Bundle
*/
public void start(BundleContext context) throws Exception {
try {
- ExecutionEngineConsolePlugin.initPlugin(context);
+ JobConsolePlugin.initPlugin(context);
} catch (Throwable ignore) {
// Happens for example if the webconsole is not installed
log.debug("Exception in start()", ignore);
@@ -45,7 +45,7 @@ public class Activator implements Bundle
*/
public void stop(BundleContext context) throws Exception {
try {
- ExecutionEngineConsolePlugin.destroyPlugin();
+ JobConsolePlugin.destroyPlugin();
} catch (Throwable ignore) {
log.debug("Exception in stop()", ignore);
}
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=979727&r1=979726&r2=979727&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
Tue Jul 27 14:41:16 2010
@@ -24,6 +24,7 @@ import javax.jcr.Session;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.resource.LoginException;
import org.apache.sling.api.resource.ResourceResolver;
import org.apache.sling.api.resource.ResourceResolverFactory;
@@ -51,7 +52,7 @@ class BackgroundRequestExecutionJob impl
private final String path;
BackgroundRequestExecutionJob(SlingServlet slingServlet,
- ResourceResolverFactory rrf, JobStorage storage,
HttpServletRequest request,
+ ResourceResolverFactory rrf, JobStorage storage,
SlingHttpServletRequest request,
HttpServletResponse hsr, String[] parametersToRemove)
throws IOException, LoginException {
this.request = new BackgroundHttpServletRequest(request,
@@ -77,6 +78,10 @@ class BackgroundRequestExecutionJob impl
throw new IOException("Unable to get Session from ResourceResolver
" + resourceResolver);
}
final JobData d = storage.createJobData(s);
+ final String ext = request.getRequestPathInfo().getExtension();
+ if(ext != null) {
+ d.setProperty(JobData.PROP_EXTENSION, ext);
+ }
path = d.getPath();
stream = new SuspendableOutputStream(d.getOutputStream());
response = new BackgroundHttpServletResponse(hsr, stream);
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=979727&r1=979726&r2=979727&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
Tue Jul 27 14:41:16 2010
@@ -88,15 +88,15 @@ public class BackgroundServletStarterFil
+ sresp.getClass().getName());
}
final HttpServletRequest request = (HttpServletRequest) sreq;
- final SlingHttpServletRequest slingRequest = (request instanceof
SlingHttpServletRequest ? (SlingHttpServletRequest) request
- : null);
+ final SlingHttpServletRequest slingRequest =
+ (request instanceof SlingHttpServletRequest ?
(SlingHttpServletRequest) request : null);
final HttpServletResponse response = (HttpServletResponse) sresp;
final String bgParam = sreq.getParameter(BG_PARAM);
if (Boolean.valueOf(bgParam)) {
try {
final BackgroundRequestExecutionJob job = new
BackgroundRequestExecutionJob(
slingServlet, resourceResolverFactory, jobStorage,
- request, response, PARAM_TO_REMOVE);
+ slingRequest, response, PARAM_TO_REMOVE);
log.debug("{} parameter true, running request in the
background ({})",
BG_PARAM, job);
if (slingRequest != null) {
Modified:
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=979727&r1=979726&r2=979727&view=diff
==============================================================================
---
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/ExecutionEngineImpl.java
(original)
+++
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/ExecutionEngineImpl.java
Tue Jul 27 14:41:16 2010
@@ -18,6 +18,7 @@
*/
package org.apache.sling.bgservlets.impl;
+import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
@@ -48,7 +49,7 @@ public class ExecutionEngineImpl impleme
private final Logger log = LoggerFactory.getLogger(getClass());
private Executor executor;
- private final Map<String, JobStatus> jobs = new HashMap<String,
JobStatus>();
+ private final Map<String, JobStatus> jobs =
Collections.synchronizedMap(new HashMap<String, JobStatus>());
private class RunnableWrapper implements Runnable {
private final Runnable inputJob;
@@ -70,7 +71,9 @@ public class ExecutionEngineImpl impleme
inputJob.run();
} finally {
if (jobStatus != null) {
+ log.debug("Job is done, cleaning up {}",
jobStatus.getPath());
jobStatus.requestStateChange(JobStatus.State.DONE);
+ jobs.remove(jobStatus.getPath());
}
}
log.info("Done running job {}", inputJob);
@@ -126,7 +129,6 @@ public class ExecutionEngineImpl impleme
final RunnableWrapper w = new RunnableWrapper(inputJob);
if (w.getJobStatus() != null) {
w.getJobStatus().requestStateChange(JobStatus.State.QUEUED);
- // TODO when to cleanup?
jobs.put(w.getJobStatus().getPath(), w.getJobStatus());
}
executor.execute(w);
Added:
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/JobConsoleImpl.java
URL:
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/JobConsoleImpl.java?rev=979727&view=auto
==============================================================================
---
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/JobConsoleImpl.java
(added)
+++
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/JobConsoleImpl.java
Tue Jul 27 14:41:16 2010
@@ -0,0 +1,123 @@
+/*
+ * 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.Iterator;
+
+import javax.jcr.Item;
+import javax.jcr.Node;
+import javax.jcr.NodeIterator;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+import javax.jcr.query.Query;
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.Service;
+import org.apache.sling.bgservlets.ExecutionEngine;
+import org.apache.sling.bgservlets.JobConsole;
+import org.apache.sling.bgservlets.JobStatus;
+import org.apache.sling.bgservlets.impl.storage.JobStorageException;
+import org.apache.sling.bgservlets.impl.storage.NodeJobStatusFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/** JobConsole implementation */
+...@component
+...@service
+public class JobConsoleImpl implements JobConsole {
+
+ private final Logger log = LoggerFactory.getLogger(getClass());
+
+ public static final String JOB_QUERY = "select * from sling:bgJobData
order by jcr:created desc";
+
+ @Reference
+ private ExecutionEngine executionEngine;
+
+ @Reference
+ private NodeJobStatusFactory jobStatusFactory;
+
+ public Iterator<JobStatus> getJobStatus(Session session, boolean
activeOnly) {
+ if(activeOnly) {
+ log.debug("activeOnly is set, getting jobs from ExecutionEngine");
+ return getEngineJobs();
+ } else {
+ log.debug("activeOnly is set, getting jobs from repository query");
+ try {
+ return getStoredJobs(session);
+ } catch(RepositoryException re) {
+ throw new JobStorageException("RepositoryException in
getJobStatus(query)", re);
+ }
+ }
+ }
+
+ public JobStatus getJobStatus(Session session, String path) {
+ // Try ExecutionEngine first, persistent storage if not found
+ JobStatus result = executionEngine.getJobStatus(path);
+ if(result == null) {
+ try {
+ if(session.itemExists(path)) {
+ final Item i = session.getItem(path);
+ if(i.isNode()) {
+ result = jobStatusFactory.getJobStatus((Node)i);
+ }
+ }
+ } catch(RepositoryException re) {
+ throw new JobStorageException("RepositoryException in
getJobStatus(path)", re);
+ }
+ }
+ return result;
+ }
+
+ private Iterator<JobStatus> getEngineJobs() {
+ return executionEngine.getMatchingJobStatus(null);
+ }
+
+ private Iterator<JobStatus> getStoredJobs(Session s) throws
RepositoryException {
+ final Query q =
s.getWorkspace().getQueryManager().createQuery(JOB_QUERY, Query.SQL);
+ final NodeIterator it = q.execute().getNodes();
+ return new Iterator<JobStatus>() {
+
+ public boolean hasNext() {
+ return it.hasNext();
+ }
+
+ public JobStatus next() {
+ try {
+ return jobStatusFactory.getJobStatus(it.nextNode());
+ } catch(RepositoryException re) {
+ throw new JobStorageException("RepositoryException in
next()", re);
+ }
+ }
+
+ public void remove() {
+ throw new UnsupportedOperationException();
+ }
+
+ };
+ }
+
+ public String getJobStatusPagePath(HttpServletRequest request, JobStatus
jobStatus, String extension) {
+ if(!extension.startsWith(".")) {
+ extension = "." + extension;
+ }
+ return request.getContextPath() + jobStatus.getPath() + extension;
+ }
+}
Propchange:
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/JobConsoleImpl.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/JobConsoleImpl.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev URL
Modified:
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=979727&r1=979726&r2=979727&view=diff
==============================================================================
---
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/servlets/JobInfoServlet.java
(original)
+++
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/servlets/JobInfoServlet.java
Tue Jul 27 14:41:16 2010
@@ -23,16 +23,20 @@ import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Map;
+import javax.jcr.Node;
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.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;
import org.apache.sling.commons.json.JSONException;
import org.apache.sling.commons.json.io.JSONWriter;
@@ -56,13 +60,16 @@ public class JobInfoServlet extends Slin
renderers.put("json", new JsonRenderer());
}
+ @Reference
+ private JobStorage jobStorage;
+
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("Background execution: job output available at ");
pw.println(streamPath);
}
}
@@ -72,9 +79,9 @@ public class JobInfoServlet extends Slin
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("<h1>Background job information</h1>");
pw.println("Job output available at");
- pw.println("<a href='" + streamPath + "'>" + streamResource +
"</a>.");
+ pw.println("<a href='" + streamPath + "'>" + streamResource +
"</a>");
pw.println("</body>");
}
}
@@ -85,7 +92,7 @@ public class JobInfoServlet extends Slin
try {
w.object();
w.key("info");
- w.value("Background job scheduled");
+ w.value("Background job information");
w.key("jobStreamPath");
w.value(streamPath);
w.endObject();
@@ -99,7 +106,14 @@ public class JobInfoServlet extends Slin
protected void doGet(SlingHttpServletRequest request,
SlingHttpServletResponse response) throws ServletException,
IOException {
- final String streamResource = request.getResource().getPath() +
"/stream." + request.getRequestPathInfo().getExtension();
+ final JobData j =
jobStorage.getJobData(request.getResource().adaptTo(Node.class));
+ String jobExt = j.getProperty(JobData.PROP_EXTENSION);
+ if(jobExt == null || jobExt.length() == 0) {
+ jobExt = "";
+ } else {
+ jobExt = "." + jobExt;
+ }
+ final String streamResource = request.getResource().getPath() +
"/stream" + jobExt;
final String streamPath = request.getContextPath() + streamResource;
final String ext = request.getRequestPathInfo().getExtension();
Renderer r = renderers.get(ext);
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=979727&r1=979726&r2=979727&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
Tue Jul 27 14:41:16 2010
@@ -75,4 +75,25 @@ class JobDataImpl implements JobData {
public String getPath() {
return path;
}
+
+ public String getProperty(String name) {
+ String result = null;
+ try {
+ if(node.hasProperty(name)) {
+ result = node.getProperty(name).getValue().getString();
+ }
+ } catch(RepositoryException re) {
+ throw new JobStorageException("RepositoryException in
getProperty", re);
+ }
+ return result;
+ }
+
+ public void setProperty(String name, String value) {
+ try {
+ node.setProperty(name, value);
+ node.save();
+ } catch(RepositoryException re) {
+ throw new JobStorageException("RepositoryException in
setProperty", re);
+ }
+ }
}
Modified:
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/storage/JobStorageException.java
URL:
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/storage/JobStorageException.java?rev=979727&r1=979726&r2=979727&view=diff
==============================================================================
---
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/storage/JobStorageException.java
(original)
+++
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/storage/JobStorageException.java
Tue Jul 27 14:41:16 2010
@@ -20,11 +20,11 @@ package org.apache.sling.bgservlets.impl
import org.apache.sling.api.SlingException;
-/** Exception thrown by this package. Unchecked, meant
+/** Exception related to job storage. Unchecked, meant
* for non-recoverable problems.
*/
@SuppressWarnings("serial")
-class JobStorageException extends SlingException {
+public class JobStorageException extends SlingException {
public JobStorageException(String reason) {
super(reason);
}
Added:
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/storage/NodeJobStatusFactory.java
URL:
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/storage/NodeJobStatusFactory.java?rev=979727&view=auto
==============================================================================
---
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/storage/NodeJobStatusFactory.java
(added)
+++
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/storage/NodeJobStatusFactory.java
Tue Jul 27 14:41:16 2010
@@ -0,0 +1,29 @@
+/*
+ * 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.storage;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+
+import org.apache.sling.bgservlets.JobStatus;
+
+/** Builds JobStatus objects out of Nodes */
+public interface NodeJobStatusFactory {
+ public JobStatus getJobStatus(Node n) throws RepositoryException;
+}
Propchange:
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/storage/NodeJobStatusFactory.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/storage/NodeJobStatusFactory.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev URL
Added:
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=979727&view=auto
==============================================================================
---
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/storage/NodeJobStatusFactoryImpl.java
(added)
+++
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/storage/NodeJobStatusFactoryImpl.java
Tue Jul 27 14:41:16 2010
@@ -0,0 +1,84 @@
+/*
+ * 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.storage;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Reference;
+import org.apache.felix.scr.annotations.Service;
+import org.apache.sling.bgservlets.ExecutionEngine;
+import org.apache.sling.bgservlets.JobStatus;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/** JobStatus that gets its data from a Node created
+ * by the JobDataImpl class. The state of such a job
+ * can be changed only if the job is currently active
+ * in the ExecutionEngine. */
+...@component
+...@service
+public class NodeJobStatusFactoryImpl implements NodeJobStatusFactory {
+
+ private Logger log = LoggerFactory.getLogger(getClass());
+
+ @Reference
+ private ExecutionEngine executionEngine;
+
+ private class NodeJobStatus implements JobStatus {
+ private final String path;
+
+ public NodeJobStatus(Node n) throws RepositoryException {
+ path = n.getPath();
+ }
+
+ public String getPath() {
+ return path;
+ }
+
+ public State getState() {
+ final JobStatus j = getActiveJob();
+ if(j == null) {
+ log.debug("Job {} not found by getActiveJob, assuming
status==DONE", path);
+ return State.DONE;
+ }
+ return j.getState();
+ }
+
+ public void requestStateChange(State s) {
+ final JobStatus j = getActiveJob();
+ if(j == null) {
+ throw new JobStorageException("Job is not active, cannot
change state, path=" + path);
+ }
+ j.requestStateChange(s);
+ }
+
+ private JobStatus getActiveJob() {
+ if(executionEngine != null) {
+ return executionEngine.getJobStatus(path);
+ }
+ return null;
+ }
+ };
+
+ public JobStatus getJobStatus(Node n) throws RepositoryException {
+ return new NodeJobStatus(n);
+ }
+}
Propchange:
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/storage/NodeJobStatusFactoryImpl.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/storage/NodeJobStatusFactoryImpl.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev URL
Copied:
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/webconsole/JobConsolePlugin.java
(from r979652,
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/webconsole/ExecutionEngineConsolePlugin.java)
URL:
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/webconsole/JobConsolePlugin.java?p2=sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/webconsole/JobConsolePlugin.java&p1=sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/webconsole/ExecutionEngineConsolePlugin.java&r1=979652&r2=979727&rev=979727&view=diff
==============================================================================
---
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/webconsole/ExecutionEngineConsolePlugin.java
(original)
+++
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/webconsole/JobConsolePlugin.java
Tue Jul 27 14:41:16 2010
@@ -24,14 +24,17 @@ import java.util.Dictionary;
import java.util.Hashtable;
import java.util.Iterator;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.felix.webconsole.AbstractWebConsolePlugin;
import org.apache.felix.webconsole.WebConsoleConstants;
-import org.apache.sling.bgservlets.ExecutionEngine;
+import org.apache.sling.bgservlets.JobConsole;
import org.apache.sling.bgservlets.JobStatus;
+import org.apache.sling.jcr.api.SlingRepository;
import org.osgi.framework.BundleContext;
import org.osgi.framework.Constants;
import org.osgi.framework.ServiceRegistration;
@@ -40,12 +43,12 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** Felix OSGi console plugin for the ExecutionEngine */
-public class ExecutionEngineConsolePlugin {
- private static final Logger log = LoggerFactory
- .getLogger(ExecutionEngineConsolePlugin.class);
+public class JobConsolePlugin {
+ private static final Logger log =
LoggerFactory.getLogger(JobConsolePlugin.class);
private static Plugin plugin;
public static final String LABEL = "bgservlets";
public static final String TITLE = "Background Servlets & Jobs";
+ public static final String STATUS_EXTENSION = "html";
public static void initPlugin(BundleContext context) {
if (plugin == null) {
@@ -70,26 +73,26 @@ public class ExecutionEngineConsolePlugi
@SuppressWarnings("serial")
public static final class Plugin extends AbstractWebConsolePlugin {
private ServiceRegistration serviceRegistration;
- private ServiceTracker executionEngineTracker;
+ private ServiceTracker jobConsoleTracker;
+ private ServiceTracker repositoryTracker;
public void activate(BundleContext ctx) {
super.activate(ctx);
- executionEngineTracker = new ServiceTracker(ctx,
- ExecutionEngine.class.getName(), null);
- executionEngineTracker.open();
+ jobConsoleTracker = new ServiceTracker(ctx,
JobConsole.class.getName(), null);
+ jobConsoleTracker.open();
+ repositoryTracker = new ServiceTracker(ctx,
SlingRepository.class.getName(), null);
+ repositoryTracker.open();
Dictionary<String, Object> props = new Hashtable<String, Object>();
- props
- .put(Constants.SERVICE_DESCRIPTION,
- "Web Console Plugin to display Background servlets
and ExecutionEngine status");
+ props.put(Constants.SERVICE_DESCRIPTION,
+ "Web Console Plugin to display Background servlets and
ExecutionEngine status");
props.put(Constants.SERVICE_VENDOR,
"The Apache Software Foundation");
props.put(Constants.SERVICE_PID, getClass().getName());
props.put(WebConsoleConstants.PLUGIN_LABEL, LABEL);
- serviceRegistration = ctx.registerService(
- WebConsoleConstants.SERVICE_NAME, this, props);
+ serviceRegistration =
ctx.registerService(WebConsoleConstants.SERVICE_NAME, this, props);
}
public void deactivate() {
@@ -97,9 +100,13 @@ public class ExecutionEngineConsolePlugi
serviceRegistration.unregister();
serviceRegistration = null;
}
- if (executionEngineTracker != null) {
- executionEngineTracker.close();
- executionEngineTracker = null;
+ if (jobConsoleTracker != null) {
+ jobConsoleTracker.close();
+ jobConsoleTracker = null;
+ }
+ if (repositoryTracker != null) {
+ repositoryTracker.close();
+ repositoryTracker = null;
}
super.deactivate();
}
@@ -118,17 +125,37 @@ public class ExecutionEngineConsolePlugi
protected void renderContent(HttpServletRequest req,
HttpServletResponse res) throws ServletException, IOException {
final PrintWriter pw = res.getWriter();
- final ExecutionEngine ee = (ExecutionEngine) executionEngineTracker
- .getService();
- if (ee == null) {
- pw.println("No ExecutionEngine service found");
+
+ // Access required services
+ final JobConsole console =
(JobConsole)jobConsoleTracker.getService();
+ if (console == null) {
+ pw.println("No JobConsole service found");
return;
}
-
+ final SlingRepository repository =
(SlingRepository)repositoryTracker.getService();
+ if(repository == null) {
+ pw.println("No SlingRepository service found");
+ return;
+ }
+ Session s = null;
+ try {
+ s =
repository.loginAdministrative(repository.getDefaultWorkspace());
+ processCommands(req, pw, s, console);
+ renderJobs(req, pw, s, console);
+ } catch(RepositoryException re) {
+ throw new ServletException("RepositoryExceptio in
renderContent()", re);
+ } finally {
+ if(s != null) {
+ s.logout();
+ }
+ }
+ }
+
+ private void processCommands(HttpServletRequest req, PrintWriter pw,
Session s, JobConsole console) {
// TODO should use POST
final String jobPath = req.getParameter("jobPath");
if (jobPath != null) {
- final JobStatus job = ee.getJobStatus(jobPath);
+ final JobStatus job = console.getJobStatus(s, jobPath);
if (job != null) {
final String action = req.getParameter("action");
if ("suspend".equals(action)) {
@@ -140,12 +167,13 @@ public class ExecutionEngineConsolePlugi
}
}
}
+ }
+
+ private void renderJobs(HttpServletRequest req, PrintWriter pw,
Session s, JobConsole console) {
+ pw.println("TODO: action buttons look bad<br/>");
+ pw.println("TODO: options for max. number of jobs displayed +
active only<br/>");
- pw.println("TODO: provide a way to cleanup old jobs<br/>");
- pw.println("TODO: optionally list active jobs only<br/>");
-
- pw
- .println("<table class='content' cellpadding='0'
cellspacing='0' width='100%'>");
+ pw.println("<table class='content' cellpadding='0' cellspacing='0'
width='100%'>");
pw.println("<thead>");
pw.println("<tr class='content'>");
pw.println("<th class='content container'>Controls</th>");
@@ -155,19 +183,28 @@ public class ExecutionEngineConsolePlugi
pw.println("</thead>");
pw.println("<tbody>");
- final Iterator<JobStatus> it = ee.getMatchingJobStatus(null);
+ final int maxJobsDisplayed = 100;
+ boolean truncated = false;
+ final boolean activeOnly = false;
+ final Iterator<JobStatus> it = console.getJobStatus(s, activeOnly);
int count = 0;
while (it.hasNext()) {
- renderJobStatus(pw, it.next());
+ renderJobStatus(req, pw, console, it.next());
count++;
+ if(count > maxJobsDisplayed) {
+ truncated = true;
+ break;
+ }
}
pw.println("</tbody>");
pw.println("</table>");
pw.println("Total <b>" + count + "</b> jobs.<br />");
+ if(truncated) {
+ pw.println("(List truncated after " + maxJobsDisplayed + "
jobs)<br />");
+ }
}
- private void renderJobStatus(PrintWriter pw, JobStatus job) {
- // TODO should use POST
+ private void renderJobStatus(HttpServletRequest request, PrintWriter
pw, JobConsole console, JobStatus job) {
pw.println("<tr class='content'>");
pw.println("<td><form action='./" + LABEL + "' method='GET'>");
final String[] actions = { "suspend", "resume", "stop" };
@@ -181,8 +218,11 @@ public class ExecutionEngineConsolePlugi
pw.println("<td>");
pw.println(job.getState());
pw.println("</td>");
- pw.println("<td>");
- pw.println(job.getPath());
+ pw.print("<td>\n<a href='");
+ pw.print(console.getJobStatusPagePath(request, job,
STATUS_EXTENSION));
+ pw.print("'>");
+ pw.print(job.getPath());
+ pw.println("</a>");
pw.println("</td>");
pw.println("</tr>");
}