incubator-sling-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bdelacre...@apache.org
Subject svn commit: r979727 - in /sling/trunk/contrib/extensions/bgservlets: ./ src/main/java/org/apache/sling/bgservlets/ src/main/java/org/apache/sling/bgservlets/impl/ src/main/java/org/apache/sling/bgservlets/impl/servlets/ src/main/java/org/apache/sling/b...
Date Tue, 27 Jul 2010 14:41:17 GMT
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>");
         }



Mime
View raw message