Author: bdelacretaz
Date: Fri Jul 23 15:18:22 2010
New Revision: 967128
URL: http://svn.apache.org/viewvc?rev=967128&view=rev
Log:
SLING-550 - refactored job data storage
Added:
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/JobData.java
(with props)
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/JobStorage.java
(with props)
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/DeepNodeCreator.java
(with props)
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/storage/
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/storage/JobDataImpl.java
(with props)
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/storage/JobStorageException.java
(with props)
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/storage/JobStorageImpl.java
(with props)
sling/trunk/contrib/extensions/bgservlets/src/main/resources/
sling/trunk/contrib/extensions/bgservlets/src/main/resources/SLING-INF/
sling/trunk/contrib/extensions/bgservlets/src/main/resources/SLING-INF/nodetypes/
sling/trunk/contrib/extensions/bgservlets/src/main/resources/SLING-INF/nodetypes/jobdata.cnd
(with props)
sling/trunk/contrib/extensions/bgservlets/src/test/java/org/apache/sling/bgservlets/impl/DeepNodeCreatorTest.java
(with props)
Modified:
sling/trunk/contrib/extensions/bgservlets/pom.xml
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/OutputReplayServlet.java
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/nodestream/NodeInputStream.java
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/nodestream/NodeOutputStream.java
Modified: sling/trunk/contrib/extensions/bgservlets/pom.xml
URL:
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/bgservlets/pom.xml?rev=967128&r1=967127&r2=967128&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/bgservlets/pom.xml (original)
+++ sling/trunk/contrib/extensions/bgservlets/pom.xml Fri Jul 23 15:18:22 2010
@@ -57,6 +57,7 @@
<Private-Package>org.apache.sling.bgservlets.impl.*</Private-Package>
<DynamicImport-Package>org.apache.felix.webconsole</DynamicImport-Package>
<Bundle-Activator>org.apache.sling.bgservlets.impl.Activator</Bundle-Activator>
+ <Sling-Nodetypes>SLING-INF/nodetypes/jobdata.cnd</Sling-Nodetypes>
</instructions>
</configuration>
</plugin>
Added:
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=967128&view=auto
==============================================================================
---
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/JobData.java
(added)
+++
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/JobData.java
Fri Jul 23 15:18:22 2010
@@ -0,0 +1,43 @@
+/*
+ * 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.io.InputStream;
+import java.io.OutputStream;
+
+/** Wraps a JCR Node to store and retrieve information
+ * about a background Job
+ */
+public interface JobData {
+ String JOB_DATA_MIXIN = "sling:bgJobData";
+
+ /** Return unique path of this data item */
+ String getPath();
+
+ /** OutputStream used to write the job's output,
+ * stored permanently under the job node.
+ */
+ OutputStream getOutputStream();
+
+ /** Input stream used to replay data stored
+ * in the stream provided by {#link getOutputStream}
+ * @return null if no stream stored yet
+ */
+ InputStream getInputStream();
+}
Propchange:
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/JobData.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/JobData.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev URL
Added:
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/JobStorage.java
URL:
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/JobStorage.java?rev=967128&view=auto
==============================================================================
---
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/JobStorage.java
(added)
+++
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/JobStorage.java
Fri Jul 23 15:18:22 2010
@@ -0,0 +1,31 @@
+/*
+ * 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 javax.jcr.Node;
+import javax.jcr.Session;
+
+/** Store and retrieve job data persistently */
+public interface JobStorage {
+ /** Create a JobData object for a new job */
+ JobData createJobData(Session s);
+
+ /** Retrieve an existing JobData object */
+ JobData getJobData(Node ns);
+}
Propchange:
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/JobStorage.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/JobStorage.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=967128&r1=967127&r2=967128&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
Fri Jul 23 15:18:22 2010
@@ -20,8 +20,6 @@ package org.apache.sling.bgservlets.impl
import java.io.IOException;
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -31,8 +29,9 @@ import org.apache.sling.api.resource.Res
import org.apache.sling.api.resource.ResourceResolverFactory;
import org.apache.sling.bgservlets.BackgroundHttpServletRequest;
import org.apache.sling.bgservlets.BackgroundHttpServletResponse;
+import org.apache.sling.bgservlets.JobData;
import org.apache.sling.bgservlets.JobStatus;
-import org.apache.sling.bgservlets.impl.nodestream.NodeOutputStream;
+import org.apache.sling.bgservlets.JobStorage;
import org.apache.sling.commons.auth.spi.AuthenticationInfo;
import org.apache.sling.engine.SlingServlet;
import org.slf4j.Logger;
@@ -52,14 +51,13 @@ class BackgroundRequestExecutionJob impl
private final String path;
BackgroundRequestExecutionJob(SlingServlet slingServlet,
- ResourceResolverFactory rrf, HttpServletRequest request,
+ ResourceResolverFactory rrf, JobStorage storage,
HttpServletRequest request,
HttpServletResponse hsr, String[] parametersToRemove)
throws IOException, LoginException {
this.request = new BackgroundHttpServletRequest(request,
parametersToRemove);
this.slingServlet = slingServlet;
- // TODO we might
// In a normal request the ResourceResolver is added to the request
// attributes
// by the authentication service, need to do the same here as we can't
@@ -72,31 +70,16 @@ class BackgroundRequestExecutionJob impl
"Missing AuthenticationInfo attribute");
}
resourceResolver = rrf.getResourceResolver(aa);
-
- // Save servlet output to the repository
+
+ // Get JobData, defines path and used to save servlet output to the
repository
final Session s = resourceResolver.adaptTo(Session.class);
if(s == null) {
throw new IOException("Unable to get Session from ResourceResolver
" + resourceResolver);
}
-
- // TODO configurable path
- try {
- final String outputRootPath = "/" + getClass().getSimpleName();
- Node outputRoot = null;
- if(s.itemExists(outputRootPath)) {
- outputRoot = (Node)s.getItem(outputRootPath);
- } else {
- outputRoot =
s.getRootNode().addNode(outputRootPath.substring(1));
- }
- final Node output = outputRoot.addNode("out_" +
System.currentTimeMillis());
- s.save();
- final NodeOutputStream nos = new NodeOutputStream(output);
- path = output.getPath();
- stream = new SuspendableOutputStream(nos);
- response = new BackgroundHttpServletResponse(hsr, stream);
- } catch(RepositoryException re) {
- throw new IOException("RepositoryException in
BackgroundRequestExecutionJob", re);
- }
+ final JobData d = storage.createJobData(s);
+ path = d.getPath();
+ stream = new SuspendableOutputStream(d.getOutputStream());
+ response = new BackgroundHttpServletResponse(hsr, stream);
}
public String toString() {
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=967128&r1=967127&r2=967128&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
Fri Jul 23 15:18:22 2010
@@ -37,6 +37,7 @@ import org.apache.felix.scr.annotations.
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.resource.ResourceResolverFactory;
import org.apache.sling.bgservlets.ExecutionEngine;
+import org.apache.sling.bgservlets.JobStorage;
import org.apache.sling.engine.SlingServlet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -63,6 +64,9 @@ public class BackgroundServletStarterFil
@Reference
private ResourceResolverFactory resourceResolverFactory;
+
+ @Reference
+ private JobStorage jobStorage;
/**
* Request runs in the background if this request parameter is present TODO
@@ -91,8 +95,8 @@ public class BackgroundServletStarterFil
if (Boolean.valueOf(bgParam)) {
try {
final BackgroundRequestExecutionJob job = new
BackgroundRequestExecutionJob(
- slingServlet, resourceResolverFactory, request,
- response, PARAM_TO_REMOVE);
+ slingServlet, resourceResolverFactory, jobStorage,
+ request, response, PARAM_TO_REMOVE);
log.debug("{} parameter true, running request in the
background ({})",
BG_PARAM, job);
if (slingRequest != null) {
Added:
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/DeepNodeCreator.java
URL:
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/DeepNodeCreator.java?rev=967128&view=auto
==============================================================================
---
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/DeepNodeCreator.java
(added)
+++
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/DeepNodeCreator.java
Fri Jul 23 15:18:22 2010
@@ -0,0 +1,76 @@
+/*
+ * 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 javax.jcr.Item;
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+/**
+ * Deep-creation of nodes: parent nodes are created if needed.
+ * TOO replace with the version of JCR-2687 once that's released.
+ */
+public class DeepNodeCreator {
+
+ /** Create a node, also creating parent nodes as needed
+ * @param path Path of the node to create
+ * @param session Used to create nodes
+ * @param nodeType Node type of created nodes, can be
+ * overridden via {...@link #getNodeType}
+ * @return The created node
+ * @throws RepositoryException In case of problems
+ */
+ public Node deepCreateNode(String path, Session session, String nodeType)
+ throws RepositoryException {
+ Node result = null;
+ if (session.itemExists(path)) {
+ final Item it = session.getItem(path);
+ if (it.isNode()) {
+ result = (Node) it;
+ }
+ } else {
+ final int slashPos = path.lastIndexOf("/");
+ String parentPath = path.substring(0, slashPos);
+ if(parentPath.length() == 0) {
+ parentPath = "/";
+ }
+ final String childPath = path.substring(slashPos + 1);
+ final Node parent = deepCreateNode(parentPath, session, nodeType);
+ result = parent.addNode(childPath, getNodeType(parent, childPath,
nodeType));
+ nodeCreated(result);
+ session.save();
+ }
+ return result;
+ }
+
+ /** Can be overridden to return a specific nodetype to use at a given path.
+ * @param parent the parent of the node that is being created
+ * @param childPath the path of the child that is being created
+ * @param suggestedNodeType the nodeType value passed to {...@link
deepCreateNode}
+ * @return suggestedNodeType by default
+ */
+ protected String getNodeType(Node parent, String childPath, String
suggestedNodeType)
+ throws RepositoryException {
+ return suggestedNodeType;
+ }
+
+ /** Can be overridden to customize the created nodes, add mixins etc. */
+ protected void nodeCreated(Node n) throws RepositoryException {
+ }
+}
Propchange:
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/DeepNodeCreator.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/DeepNodeCreator.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev URL
Modified:
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/OutputReplayServlet.java
URL:
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/OutputReplayServlet.java?rev=967128&r1=967127&r2=967128&view=diff
==============================================================================
---
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/OutputReplayServlet.java
(original)
+++
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/OutputReplayServlet.java
Fri Jul 23 15:18:22 2010
@@ -19,6 +19,7 @@
package org.apache.sling.bgservlets.impl;
import java.io.IOException;
+import java.io.InputStream;
import java.io.OutputStream;
import javax.jcr.Node;
@@ -28,11 +29,13 @@ import javax.servlet.http.HttpServletRes
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Properties;
import org.apache.felix.scr.annotations.Property;
+import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.Service;
import org.apache.sling.api.SlingHttpServletRequest;
import org.apache.sling.api.SlingHttpServletResponse;
import org.apache.sling.api.servlets.SlingSafeMethodsServlet;
-import org.apache.sling.bgservlets.impl.nodestream.NodeInputStream;
+import org.apache.sling.bgservlets.JobData;
+import org.apache.sling.bgservlets.JobStorage;
/** Servlet that replays the output of servlets executed in
* the background.
@@ -46,6 +49,9 @@ import org.apache.sling.bgservlets.impl.
})
public class OutputReplayServlet extends SlingSafeMethodsServlet {
+ @Reference
+ private JobStorage jobStorage;
+
@Override
protected void doGet(SlingHttpServletRequest request,
SlingHttpServletResponse response)
throws ServletException, IOException {
@@ -55,19 +61,20 @@ public class OutputReplayServlet extends
"Resource does not adapt to a Node: " +
request.getResource().getPath());
}
- // TODO content-type, length etc
- final NodeInputStream nis = new NodeInputStream(n);
+ // TODO content-type, length etc.
+ final JobData d = jobStorage.getJobData(n);
+ final InputStream is = d.getInputStream();
try {
final OutputStream os = response.getOutputStream();
final byte [] buffer = new byte[32768];
int count = 0;
- while((count = nis.read(buffer, 0, buffer.length)) > 0) {
+ while((count = is.read(buffer, 0, buffer.length)) > 0) {
os.write(buffer, 0, count);
}
os.flush();
} finally {
- if(nis != null) {
- nis.close();
+ if(is != null) {
+ is.close();
}
}
}
Modified:
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/nodestream/NodeInputStream.java
URL:
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/nodestream/NodeInputStream.java?rev=967128&r1=967127&r2=967128&view=diff
==============================================================================
---
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/nodestream/NodeInputStream.java
(original)
+++
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/nodestream/NodeInputStream.java
Fri Jul 23 15:18:22 2010
@@ -54,6 +54,7 @@ public class NodeInputStream extends Inp
/** Select next property to read from and open its stream */
private void selectNextStream() throws IOException {
counter++;
+ // TODO use hierarchy to allow for arbitrary number of flush calls
final String name = NodeOutputStream.STREAM_PROPERTY_NAME_PREFIX +
counter;
try {
if(node.hasProperty(name)) {
Modified:
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/nodestream/NodeOutputStream.java
URL:
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/nodestream/NodeOutputStream.java?rev=967128&r1=967127&r2=967128&view=diff
==============================================================================
---
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/nodestream/NodeOutputStream.java
(original)
+++
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/nodestream/NodeOutputStream.java
Fri Jul 23 15:18:22 2010
@@ -80,6 +80,7 @@ public class NodeOutputStream extends Ou
@Override
public void flush() throws IOException {
counter++;
+ // TODO use hierarchy to allow for arbitrary number of flush calls
final String name = NodeOutputStream.STREAM_PROPERTY_NAME_PREFIX +
counter;
try {
if(!node.getSession().isLive()) {
Added:
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=967128&view=auto
==============================================================================
---
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/storage/JobDataImpl.java
(added)
+++
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/storage/JobDataImpl.java
Fri Jul 23 15:18:22 2010
@@ -0,0 +1,72 @@
+/*
+ * 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 java.io.InputStream;
+import java.io.OutputStream;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+
+import org.apache.sling.bgservlets.JobData;
+import org.apache.sling.bgservlets.impl.nodestream.NodeInputStream;
+import org.apache.sling.bgservlets.impl.nodestream.NodeOutputStream;
+
+class JobDataImpl implements JobData {
+
+ private final Node node;
+ private final String path;
+
+ public static final String STREAM_PATH = "outputStream";
+
+ /** Build a JobDataImpl on supplied node, which must exists */
+ JobDataImpl(Node n) throws RepositoryException {
+ node = n;
+ path = n.getPath();
+ }
+
+ public InputStream getInputStream() {
+ try {
+ if(node.hasNode(STREAM_PATH)) {
+ return new NodeInputStream(node.getNode(STREAM_PATH));
+ }
+ } catch(Exception e) {
+ throw new JobStorageException("Exception in getInputStream()",
e);
+ }
+ return null;
+ }
+
+ public OutputStream getOutputStream() {
+ try {
+ if(node.hasNode(STREAM_PATH)) {
+ throw new IllegalArgumentException("Stream node already
exists: "
+ + node.getPath() + "/" + STREAM_PATH);
+ }
+ final Node stream = node.addNode(STREAM_PATH);
+ node.save();
+ return new NodeOutputStream(stream);
+ } catch(Exception e) {
+ throw new JobStorageException("Exception in getOutputStream()", e);
+ }
+ }
+
+ public String getPath() {
+ return path;
+ }
+}
Propchange:
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/storage/JobDataImpl.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/storage/JobDataImpl.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev URL
Added:
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=967128&view=auto
==============================================================================
---
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/storage/JobStorageException.java
(added)
+++
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/storage/JobStorageException.java
Fri Jul 23 15:18:22 2010
@@ -0,0 +1,35 @@
+/*
+ * 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 org.apache.sling.api.SlingException;
+
+/** Exception thrown by this package. Unchecked, meant
+ * for non-recoverable problems.
+ */
+...@suppresswarnings("serial")
+class JobStorageException extends SlingException {
+ public JobStorageException(String reason) {
+ super(reason);
+ }
+
+ public JobStorageException(String reason, Throwable cause) {
+ super(reason, cause);
+ }
+}
Propchange:
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/storage/JobStorageException.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/storage/JobStorageException.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev URL
Added:
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/storage/JobStorageImpl.java
URL:
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/storage/JobStorageImpl.java?rev=967128&view=auto
==============================================================================
---
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/storage/JobStorageImpl.java
(added)
+++
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/storage/JobStorageImpl.java
Fri Jul 23 15:18:22 2010
@@ -0,0 +1,80 @@
+/*
+ * 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 java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+import org.apache.felix.scr.annotations.Component;
+import org.apache.felix.scr.annotations.Service;
+import org.apache.sling.bgservlets.JobData;
+import org.apache.sling.bgservlets.JobStorage;
+import org.apache.sling.bgservlets.impl.DeepNodeCreator;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/** Default JobStorage implementation */
+...@component
+...@service
+public class JobStorageImpl implements JobStorage {
+
+ private Logger log = LoggerFactory.getLogger(getClass());
+
+ /** TODO configurable */
+ public static final String JOBS_PATH = "/var/bg/jobs";
+ public static final String PATH_FORMAT = "/yyyy/MM/dd/HH/mm";
+ public static final String JOB_NODETYPE = "nt:unstructured";
+
+ private int counter;
+ private static final DateFormat pathFormat = new
SimpleDateFormat(PATH_FORMAT);
+
+ public JobData createJobData(Session s) {
+ try {
+ return getJobData(createNewJobNode(s));
+ } catch(Exception e) {
+ throw new JobStorageException("Unable to create new JobDataImpl",
e);
+ }
+ }
+
+ public JobData getJobData(Node n) {
+ try {
+ return new JobDataImpl(n);
+ } catch(Exception e) {
+ throw new JobStorageException("Unable to create JobDataImpl", e);
+ }
+ }
+
+ Node createNewJobNode(Session s) throws RepositoryException {
+ String path = null;
+ synchronized (this) {
+ counter++;
+ path = JOBS_PATH + pathFormat.format(new Date()) + "/" +
counter;
+ }
+ final Node result = new DeepNodeCreator().deepCreateNode(path, s,
JOB_NODETYPE);
+ result.addMixin(JobData.JOB_DATA_MIXIN);
+ result.save();
+ log.debug("Job node {} created", result.getPath());
+ return result;
+ }
+}
Propchange:
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/storage/JobStorageImpl.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
sling/trunk/contrib/extensions/bgservlets/src/main/java/org/apache/sling/bgservlets/impl/storage/JobStorageImpl.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev URL
Added:
sling/trunk/contrib/extensions/bgservlets/src/main/resources/SLING-INF/nodetypes/jobdata.cnd
URL:
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/bgservlets/src/main/resources/SLING-INF/nodetypes/jobdata.cnd?rev=967128&view=auto
==============================================================================
---
sling/trunk/contrib/extensions/bgservlets/src/main/resources/SLING-INF/nodetypes/jobdata.cnd
(added)
+++
sling/trunk/contrib/extensions/bgservlets/src/main/resources/SLING-INF/nodetypes/jobdata.cnd
Fri Jul 23 15:18:22 2010
@@ -0,0 +1,25 @@
+//
+// 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.
+//
+
+<sling = 'http://sling.apache.org/jcr/sling/1.0'>
+
+//-----------------------------------------------------------------------------
+// Marker mixin node type for Sling JobData nodes
+[sling:bgJobData]
+ mixin
Propchange:
sling/trunk/contrib/extensions/bgservlets/src/main/resources/SLING-INF/nodetypes/jobdata.cnd
------------------------------------------------------------------------------
svn:eol-style = native
Added:
sling/trunk/contrib/extensions/bgservlets/src/test/java/org/apache/sling/bgservlets/impl/DeepNodeCreatorTest.java
URL:
http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/bgservlets/src/test/java/org/apache/sling/bgservlets/impl/DeepNodeCreatorTest.java?rev=967128&view=auto
==============================================================================
---
sling/trunk/contrib/extensions/bgservlets/src/test/java/org/apache/sling/bgservlets/impl/DeepNodeCreatorTest.java
(added)
+++
sling/trunk/contrib/extensions/bgservlets/src/test/java/org/apache/sling/bgservlets/impl/DeepNodeCreatorTest.java
Fri Jul 23 15:18:22 2010
@@ -0,0 +1,161 @@
+/*
+ * 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 static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+import javax.jcr.Node;
+import javax.jcr.RepositoryException;
+import javax.jcr.Session;
+
+import org.jmock.Expectations;
+import org.jmock.Mockery;
+import org.junit.Test;
+
+/** Test the DeepNodeCreator class
+ * TOO replace with the version of JCR-2687 once that's released.
+ * */
+public class DeepNodeCreatorTest {
+
+ @Test
+ public void testExistingNode() throws Exception {
+ final Mockery mockery = new Mockery();
+ final DeepNodeCreator c = new DeepNodeCreator();
+ final String path = "/foo/bar";
+ final Session s = mockery.mock(Session.class);
+ final Node n = mockery.mock(Node.class);
+
+ mockery.checking(new Expectations() {{
+ allowing(s).itemExists(path);
+ will(returnValue(true));
+
+ allowing(s).getItem(path);
+ will(returnValue(n));
+
+ allowing(n).isNode();
+ will(returnValue(true));
+ }});
+
+ final Node result = c.deepCreateNode(path, s, null);
+ assertTrue("Expecting deepCreate to return existing node", result ==
n);
+ }
+
+ public void testCreateFromRoot() throws Exception {
+ final Mockery mockery = new Mockery();
+ final DeepNodeCreator c = new DeepNodeCreator();
+ final String rootPath = "/";
+ final String fooPath = "/foo";
+ final String barPath = "/foo/bar";
+ final Session s = mockery.mock(Session.class);
+ final Node root = mockery.mock(Node.class, rootPath);
+ final Node foo = mockery.mock(Node.class, fooPath);
+ final Node bar = mockery.mock(Node.class, barPath);
+ final String testNodeType = "NT_TEST";
+
+ mockery.checking(new Expectations() {{
+ allowing(s).itemExists(barPath);
+ will(returnValue(false));
+
+ allowing(s).itemExists(fooPath);
+ will(returnValue(false));
+
+ allowing(s).itemExists(rootPath);
+ will(returnValue(true));
+
+ allowing(s).getItem(rootPath);
+ will(returnValue(root));
+
+ allowing(root).isNode();
+ will(returnValue(true));
+
+ allowing(root).addNode("foo", testNodeType);
+ will(returnValue(foo));
+
+ allowing(foo).addNode("bar", testNodeType);
+ will(returnValue(bar));
+
+ allowing(s).save();
+ }});
+
+ final Node result = c.deepCreateNode(barPath, s, testNodeType);
+ assertTrue("Expecting deepCreate to return create node", result ==
bar);
+ }
+
+ public void testCreateWithVariousTypes() throws Exception {
+ final Mockery mockery = new Mockery();
+
+ final String fooPath = "/foo";
+ final String barPath = "/foo/bar";
+ final String wiiPath = "/foo/bar/wii";
+ final Session s = mockery.mock(Session.class);
+ final Node foo = mockery.mock(Node.class, fooPath);
+ final Node bar = mockery.mock(Node.class, barPath);
+ final Node wii = mockery.mock(Node.class, wiiPath);
+
+ mockery.checking(new Expectations() {{
+ allowing(s).itemExists(wiiPath);
+ will(returnValue(false));
+
+ allowing(s).itemExists(barPath);
+ will(returnValue(false));
+
+ allowing(s).itemExists(fooPath);
+ will(returnValue(true));
+
+ allowing(s).getItem(fooPath);
+ will(returnValue(foo));
+
+ allowing(foo).isNode();
+ will(returnValue(true));
+
+ allowing(foo).getPath();
+ will(returnValue(fooPath));
+
+ allowing(foo).addNode("bar", "NT_/foo.bar");
+ will(returnValue(bar));
+
+ allowing(bar).getPath();
+ will(returnValue(barPath));
+
+ allowing(bar).addNode("wii", "NT_/foo/bar.wii");
+ will(returnValue(wii));
+
+ allowing(s).save();
+ }});
+
+ final AtomicInteger counter = new AtomicInteger();
+ final DeepNodeCreator c = new DeepNodeCreator() {
+
+ @Override
+ protected String getNodeType(Node parent, String childPath, String
suggestedNodeType)
+ throws RepositoryException {
+ return "NT_" + parent.getPath() + "." + childPath;
+ }
+
+ @Override
+ protected void nodeCreated(Node n) throws RepositoryException {
+ counter.addAndGet(1);
+ }
+ };
+ final Node result = c.deepCreateNode(wiiPath, s, null);
+ assertTrue("Expecting deepCreate to return created node", result ==
wii);
+ assertEquals("Expecting correct count of nodeCreated calls", 2,
counter.get());
+ }
+}
Propchange:
sling/trunk/contrib/extensions/bgservlets/src/test/java/org/apache/sling/bgservlets/impl/DeepNodeCreatorTest.java
------------------------------------------------------------------------------
svn:eol-style = native
Propchange:
sling/trunk/contrib/extensions/bgservlets/src/test/java/org/apache/sling/bgservlets/impl/DeepNodeCreatorTest.java
------------------------------------------------------------------------------
svn:keywords = Author Date Id Revision Rev URL