Move engine under the correct tag
git-svn-id: https://svn.apache.org/repos/asf/sling/tags/org.apache.sling.bgservlets-1.0.6-BAD@1732137 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/engine/pom.xml b/engine/pom.xml
deleted file mode 100644
index c1196e1..0000000
--- a/engine/pom.xml
+++ /dev/null
@@ -1,159 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
- <!--
- 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.
- -->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
-
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.apache.sling</groupId>
- <artifactId>sling</artifactId>
- <version>22</version>
- <relativePath />
- </parent>
-
- <artifactId>org.apache.sling.bgservlets</artifactId>
- <version>1.0.6</version>
- <packaging>bundle</packaging>
-
- <name>Apache Sling Background Servlets Engine</name>
- <description>
- Allows scripts and servlets to run as background tasks
- which can be suspended, resumed, stopped and restarted.
- </description>
-
- <scm>
- <connection>scm:svn:http://svn.apache.org/repos/asf/sling/tags/org.apache.sling.bgservlets-1.0.6</connection>
- <developerConnection>scm:svn:https://svn.apache.org/repos/asf/sling/tags/org.apache.sling.bgservlets-1.0.6</developerConnection>
- <url>http://svn.apache.org/repos/asf/sling/tags/org.apache.sling.bgservlets-1.0.6</url>
- </scm>
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-scr-plugin</artifactId>
- </plugin>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <extensions>true</extensions>
- <configuration>
- <instructions>
- <Export-Package>org.apache.sling.bgservlets</Export-Package>
- <Private-Package>org.apache.sling.bgservlets.impl.*</Private-Package>
- <DynamicImport-Package>org.apache.felix.webconsole</DynamicImport-Package>
- <Sling-Nodetypes>SLING-INF/nodetypes/jobdata.cnd</Sling-Nodetypes>
- </instructions>
- </configuration>
- </plugin>
- </plugins>
- </build>
-
- <dependencies>
- <dependency>
- <groupId>org.osgi</groupId>
- <artifactId>org.osgi.core</artifactId>
- </dependency>
- <dependency>
- <groupId>org.osgi</groupId>
- <artifactId>org.osgi.compendium</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.felix</groupId>
- <artifactId>org.apache.felix.scr.annotations</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.sling</groupId>
- <artifactId>org.apache.sling.api</artifactId>
- <version>2.8.0</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.sling</groupId>
- <artifactId>org.apache.sling.engine</artifactId>
- <version>2.2.0</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.sling</groupId>
- <artifactId>org.apache.sling.settings</artifactId>
- <version>1.0.0</version>
- <scope>provided</scope>
- </dependency>
- <dependency>
- <groupId>org.apache.sling</groupId>
- <artifactId>org.apache.sling.commons.testing</artifactId>
- <version>2.0.6</version>
- <scope>test</scope>
- <exclusions>
- <exclusion>
- <groupId>junit</groupId>
- <artifactId>junit-dep</artifactId>
- </exclusion>
- </exclusions>
- </dependency>
- <dependency>
- <groupId>org.apache.sling</groupId>
- <artifactId>org.apache.sling.commons.json</artifactId>
- <version>2.0.4-incubator</version>
- </dependency>
- <dependency>
- <groupId>org.apache.sling</groupId>
- <artifactId>org.apache.sling.commons.osgi</artifactId>
- <version>2.1.0</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>
- <dependency>
- <groupId>javax.jcr</groupId>
- <artifactId>jcr</artifactId>
- <version>2.0</version>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- </dependency>
- <dependency>
- <groupId>org.apache.felix</groupId>
- <artifactId>org.apache.felix.webconsole</artifactId>
- <version>3.0.0</version>
- </dependency>
- <dependency>
- <groupId>org.mockito</groupId>
- <artifactId>mockito-core</artifactId>
- <version>1.9.5</version>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <scope>test</scope>
- </dependency>
- <dependency>
- <groupId>junit-addons</groupId>
- <artifactId>junit-addons</artifactId>
- <version>1.4</version>
- <scope>test</scope>
- </dependency>
- </dependencies>
-</project>
diff --git a/engine/src/main/java/org/apache/sling/bgservlets/BackgroundHttpServletRequest.java b/engine/src/main/java/org/apache/sling/bgservlets/BackgroundHttpServletRequest.java
deleted file mode 100644
index 05d24dd..0000000
--- a/engine/src/main/java/org/apache/sling/bgservlets/BackgroundHttpServletRequest.java
+++ /dev/null
@@ -1,481 +0,0 @@
-/*
- * 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.BufferedReader;
-import java.io.ByteArrayInputStream;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.net.URLDecoder;
-import java.net.URLEncoder;
-import java.security.Principal;
-import java.util.Enumeration;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Locale;
-import java.util.Map;
-
-import javax.servlet.RequestDispatcher;
-import javax.servlet.ServletInputStream;
-import javax.servlet.http.Cookie;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpSession;
-
-import org.apache.sling.api.SlingException;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/** Minimal HttpServletRequest for background processing */
-public class BackgroundHttpServletRequest implements HttpServletRequest {
-
- private static final Logger log = LoggerFactory.getLogger(BackgroundHttpServletRequest.class);
-
- private final String contextPath;
- private final String method;
- private final String pathInfo;
- private final String servletPath;
- private final String queryString;
- private final String requestURI;
- private final StringBuffer requestURL;
- private String characterEncoding;
- private final int contentLength;
- private final String contentType;
- private final Locale locale;
- private final String protocol;
- private final String remoteAddr;
- private final String remoteHost;
- private final int remotePort;
- private final int serverPort;
- private final String scheme;
- private final String remoteUser;
- private final String serverName;
-
- private final Map<String, Object> attributes;
- private final Map<String, ?> parameters;
-
- static class IteratorEnumeration<T> implements Enumeration<T> {
- private final Iterator<T> it;
-
- IteratorEnumeration(Iterator<T> it) {
- this.it = it;
- }
-
- public boolean hasMoreElements() {
- return it.hasNext();
- }
-
- public T nextElement() {
- return it.next();
- }
- }
-
- /**
- * We throw this for any method for which we do not have data that's safe to
- * use outside of the container's request/response cycle. Start by throwing
- * this everywhere and implement methods as needed, if their data is safe to
- * use.
- */
- @SuppressWarnings("serial")
- class UnsupportedBackgroundOperationException extends
- UnsupportedOperationException {
- UnsupportedBackgroundOperationException() {
- super("This operation is not supported for background requests");
- }
- }
-
- @SuppressWarnings("unchecked")
- public BackgroundHttpServletRequest(HttpServletRequest r,
- String[] parametersToRemove) {
-
- // Store objects which are safe to use outside
- // of the container's request/response cycle - the
- // goal is to release r once this request starts
- // executing in the background
- contextPath = r.getContextPath();
- method = r.getMethod();
- pathInfo = r.getPathInfo();
- servletPath = r.getServletPath();
- queryString = filterQueryString(r.getQueryString(), parametersToRemove);
- requestURI = r.getRequestURI();
- requestURL = r.getRequestURL();
- characterEncoding = r.getCharacterEncoding();
- contentLength = r.getContentLength();
- contentType = r.getContentType();
- locale = r.getLocale();
- protocol = r.getProtocol();
- remoteAddr = r.getRemoteAddr();
- remoteHost = r.getRemoteHost();
- remotePort = r.getRemotePort();
- serverPort = r.getServerPort();
- scheme = r.getScheme();
- remoteUser = r.getRemoteUser();
- serverName = r.getServerName();
-
- attributes = new HashMap<String, Object>();
- //
- // Don't copy attributes, we consider this to be a "fresh" request final
- // Enumeration<?> e = r.getAttributeNames(); while(e.hasMoreElements())
- // { final String key = (String)e.nextElement(); attributes.put(key,
- // r.getAttribute(key)); }
- //
-
- parameters = new HashMap<String, String>();
- parameters.putAll(r.getParameterMap());
- for (String key : parametersToRemove) {
- parameters.remove(key);
- }
- }
-
- private String filterQueryString(String original, String [] parametersToRemove) {
- if(original == null) {
- return null;
- }
-
- final String encoding = "UTF-8"; // recommended as per URLDecoder javadocs
- final StringBuilder sb = new StringBuilder(original.length());
- final String SEP = "&";
- final String [] params = original.split(SEP);
- for(String param : params) {
- String name = null;
- try {
- name = URLDecoder.decode(param.split("=")[0].trim(), encoding);
- } catch(UnsupportedEncodingException uee) {
- throw new SlingException("Unexpected UnsupportedEncodingException for " + encoding, uee);
- }
- boolean ignore = false;
- for(String p : parametersToRemove) {
- if(name.equals(p)) {
- ignore=true;
- break;
- }
- }
- if(!ignore) {
- sb.append(param).append(SEP);
- }
- }
- final String result = sb.toString();
- log.debug("Filtered query string to '{}'", result);
- return result;
- }
-
- public String getAuthType() {
- return null;
- }
-
- public String getContextPath() {
- return contextPath;
- }
-
- public Cookie[] getCookies() {
- return null;
- }
-
- public long getDateHeader(String arg0) {
- return 0;
- }
-
- public String getHeader(String arg0) {
- return null;
- }
-
- public Enumeration<?> getHeaderNames() {
- return null;
- }
-
- public Enumeration<?> getHeaders(String name) {
- return null;
- }
-
- public int getIntHeader(String name) {
- return 0;
- }
-
- public String getMethod() {
- return method;
- }
-
- public String getPathInfo() {
- return pathInfo;
- }
-
- public String getPathTranslated() {
- throw new UnsupportedBackgroundOperationException();
- }
-
- public String getQueryString() {
- return queryString;
- }
-
- public String getRemoteUser() {
- return remoteUser;
- }
-
- public String getRequestedSessionId() {
- throw new UnsupportedBackgroundOperationException();
- }
-
- public String getRequestURI() {
- return requestURI;
- }
-
- public StringBuffer getRequestURL() {
- return requestURL;
- }
-
- public String getServletPath() {
- return servletPath;
- }
-
- public HttpSession getSession() {
- throw new UnsupportedBackgroundOperationException();
- }
-
- public HttpSession getSession(boolean arg0) {
- throw new UnsupportedBackgroundOperationException();
- }
-
- public Principal getUserPrincipal() {
- throw new UnsupportedBackgroundOperationException();
- }
-
- public boolean isRequestedSessionIdFromCookie() {
- throw new UnsupportedBackgroundOperationException();
- }
-
- public boolean isRequestedSessionIdFromUrl() {
- throw new UnsupportedBackgroundOperationException();
- }
-
- public boolean isRequestedSessionIdFromURL() {
- throw new UnsupportedBackgroundOperationException();
- }
-
- public boolean isRequestedSessionIdValid() {
- throw new UnsupportedBackgroundOperationException();
- }
-
- public boolean isUserInRole(String arg0) {
- throw new UnsupportedBackgroundOperationException();
- }
-
- public Object getAttribute(String name) {
- return attributes.get(name);
- }
-
- public Enumeration<?> getAttributeNames() {
- return new IteratorEnumeration<String>(attributes.keySet().iterator());
- }
-
- public String getCharacterEncoding() {
- return characterEncoding;
- }
-
- public int getContentLength() {
- return contentLength;
- }
-
- public String getContentType() {
- return contentType;
- }
-
- private static final String encode(final String value) {
- try {
- return URLEncoder.encode(value, "UTF-8");
- } catch ( final UnsupportedEncodingException uee) {
- return value;
- }
- }
-
- private boolean append(final StringBuilder sb, final String key, final String val, final boolean first) {
- if ( !first ) {
- sb.append('&');
- }
- sb.append(key);
- sb.append('=');
- sb.append(encode(val));
- return false;
- }
-
- public ServletInputStream getInputStream() throws IOException {
- // create byte array of all parameters
- boolean first = true;
- final StringBuilder sb = new StringBuilder();
- for(final Map.Entry<String, ?> entry : this.parameters.entrySet()) {
- if ( entry.getValue() instanceof String[] ) {
- for(final String val : (String[])entry.getValue()) {
- first = append(sb, entry.getKey(), val, first);
- }
- } else {
- first = append(sb, entry.getKey(), (String)entry.getValue(), first);
- }
- }
- return new ByteArrayServletInputStream(new ByteArrayInputStream(sb.toString().getBytes(this.characterEncoding)));
- }
-
- private static final class ByteArrayServletInputStream extends ServletInputStream {
-
- private final ByteArrayInputStream stream;
-
- public ByteArrayServletInputStream(final ByteArrayInputStream stream) {
- this.stream = stream;
- }
-
- @Override
- public int available() throws IOException {
- return this.stream.available();
- }
-
- @Override
- public void close() throws IOException {
- this.stream.close();
- }
-
- @Override
- public synchronized void mark(final int arg0) {
- this.stream.mark(arg0);
- }
-
- @Override
- public boolean markSupported() {
- return this.stream.markSupported();
- }
-
- @Override
- public int read() throws IOException {
- return this.stream.read();
- }
-
- @Override
- public int read(final byte[] arg0, final int arg1, final int arg2) throws IOException {
- return this.stream.read(arg0, arg1, arg2);
- }
-
- @Override
- public int read(final byte[] arg0) throws IOException {
- return this.stream.read(arg0);
- }
-
- @Override
- public synchronized void reset() throws IOException {
- this.stream.reset();
- }
-
- @Override
- public long skip(final long arg0) throws IOException {
- return this.stream.skip(arg0);
- }
- }
-
- public String getLocalAddr() {
- throw new UnsupportedBackgroundOperationException();
- }
-
- public Locale getLocale() {
- return locale;
- }
-
- public Enumeration<?> getLocales() {
- throw new UnsupportedBackgroundOperationException();
- }
-
- public String getLocalName() {
- throw new UnsupportedBackgroundOperationException();
- }
-
- public int getLocalPort() {
- throw new UnsupportedBackgroundOperationException();
- }
-
- public String getParameter(String name) {
- final Object obj = parameters.get(name);
- if (obj instanceof String[]) {
- return ((String[]) obj)[0];
- }
- return (String) obj;
- }
-
- public Map<?, ?> getParameterMap() {
- return parameters;
- }
-
- public Enumeration<?> getParameterNames() {
- return new IteratorEnumeration<String>(parameters.keySet().iterator());
- }
-
- public String[] getParameterValues(String key) {
- throw new UnsupportedBackgroundOperationException();
- }
-
- public String getProtocol() {
- return protocol;
- }
-
- public BufferedReader getReader() throws IOException {
- throw new UnsupportedBackgroundOperationException();
- }
-
- public String getRealPath(String arg0) {
- throw new UnsupportedBackgroundOperationException();
- }
-
- public String getRemoteAddr() {
- return remoteAddr;
- }
-
- public String getRemoteHost() {
- return remoteHost;
- }
-
- public int getRemotePort() {
- return remotePort;
- }
-
- public RequestDispatcher getRequestDispatcher(String arg0) {
- throw new UnsupportedBackgroundOperationException();
- }
-
- public String getScheme() {
- return scheme;
- }
-
- public String getServerName() {
- return serverName;
- }
-
- public int getServerPort() {
- return serverPort;
- }
-
- public boolean isSecure() {
- return false;
- }
-
- public void removeAttribute(String name) {
- attributes.remove(name);
- }
-
- public void setAttribute(String key, Object value) {
- attributes.put(key, value);
- }
-
- public void setCharacterEncoding(final String encoding)
- throws UnsupportedEncodingException {
- this.characterEncoding = encoding;
- }
-}
diff --git a/engine/src/main/java/org/apache/sling/bgservlets/BackgroundHttpServletResponse.java b/engine/src/main/java/org/apache/sling/bgservlets/BackgroundHttpServletResponse.java
deleted file mode 100644
index 4095d65..0000000
--- a/engine/src/main/java/org/apache/sling/bgservlets/BackgroundHttpServletResponse.java
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * 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.IOException;
-import java.io.OutputStream;
-import java.io.OutputStreamWriter;
-import java.io.PrintWriter;
-import java.util.Locale;
-
-import javax.servlet.ServletOutputStream;
-import javax.servlet.http.Cookie;
-import javax.servlet.http.HttpServletResponse;
-
-/** Minimal HttpServletResponse for background processing */
-public class BackgroundHttpServletResponse implements HttpServletResponse {
-
- private final ServletOutputStream stream;
- private final PrintWriter writer;
-
- static class ServletOutputStreamWrapper extends ServletOutputStream {
-
- private final OutputStream os;
-
- ServletOutputStreamWrapper(OutputStream os) {
- this.os = os;
- }
-
- @Override
- public void write(int b) throws IOException {
- os.write(b);
- }
-
- @Override
- public void close() throws IOException {
- os.close();
- }
-
- @Override
- public void flush() throws IOException {
- os.flush();
- }
-
- }
-
- public BackgroundHttpServletResponse(HttpServletResponse hsr, OutputStream os)
- throws IOException {
- stream = new ServletOutputStreamWrapper(os);
- writer = new PrintWriter(new OutputStreamWriter(stream));
- }
-
- public void cleanup() throws IOException {
- stream.flush();
- stream.close();
- }
-
- public ServletOutputStream getOutputStream() throws IOException {
- return stream;
- }
-
- public PrintWriter getWriter() throws IOException {
- return writer;
- }
-
- public void addCookie(Cookie arg0) {
- }
-
- public void addDateHeader(String arg0, long arg1) {
- }
-
- public void addHeader(String arg0, String arg1) {
- }
-
- public void addIntHeader(String arg0, int arg1) {
- }
-
- public boolean containsHeader(String arg0) {
- return false;
- }
-
- public String encodeRedirectUrl(String arg0) {
- return null;
- }
-
- public String encodeRedirectURL(String arg0) {
- return null;
- }
-
- public String encodeUrl(String arg0) {
- return null;
- }
-
- public String encodeURL(String arg0) {
- return null;
- }
-
- public void sendError(int arg0, String arg1) throws IOException {
- // TODO
- }
-
- public void sendError(int arg0) throws IOException {
- // TODO
- }
-
- public void sendRedirect(String arg0) throws IOException {
- // TODO
- }
-
- public void setDateHeader(String arg0, long arg1) {
- }
-
- public void setHeader(String arg0, String arg1) {
- }
-
- public void setIntHeader(String arg0, int arg1) {
- }
-
- public void setStatus(int arg0, String arg1) {
- // TODO
- }
-
- public void setStatus(int arg0) {
- // TODO
- }
-
- public void flushBuffer() throws IOException {
- stream.flush();
- }
-
- public int getBufferSize() {
- return 0;
- }
-
- public String getCharacterEncoding() {
- return null;
- }
-
- public String getContentType() {
- return null;
- }
-
- public Locale getLocale() {
- return null;
- }
-
- public boolean isCommitted() {
- return false;
- }
-
- public void reset() {
- }
-
- public void resetBuffer() {
- }
-
- public void setBufferSize(int arg0) {
- }
-
- public void setCharacterEncoding(String arg0) {
- }
-
- public void setContentLength(int arg0) {
- }
-
- public void setContentType(String arg0) {
- }
-
- public void setLocale(Locale arg0) {
- }
-}
\ No newline at end of file
diff --git a/engine/src/main/java/org/apache/sling/bgservlets/BackgroundServletConstants.java b/engine/src/main/java/org/apache/sling/bgservlets/BackgroundServletConstants.java
deleted file mode 100644
index 36edf64..0000000
--- a/engine/src/main/java/org/apache/sling/bgservlets/BackgroundServletConstants.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sling.bgservlets;
-
-public class BackgroundServletConstants {
- /** Resource type for the Job node */
- public static final String JOB_RESOURCE_TYPE = "sling/bg/job";
-
- /** Resource type for the stream node */
- public static final String STREAM_RESOURCE_TYPE = "sling/bg/stream";
-
- /** Property name used to store job nodes creation times */
- public static final String CREATION_TIME_PROPERTY = "jcr:created";
-}
diff --git a/engine/src/main/java/org/apache/sling/bgservlets/ExecutionEngine.java b/engine/src/main/java/org/apache/sling/bgservlets/ExecutionEngine.java
deleted file mode 100644
index 894ed2e..0000000
--- a/engine/src/main/java/org/apache/sling/bgservlets/ExecutionEngine.java
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * 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;
-
-/**
- * Service that executes Runnables, will later allow them to be suspended,
- * resumed, stopped and restarted.
- */
-public interface ExecutionEngine {
-
- /** Add a job to the execution queue */
- void queueForExecution(Runnable job);
-
- /** Get JobStatus by path */
- JobStatus getJobStatus(String path);
-
- /**
- * Enumerate JobStatus that match supplied predicate
- *
- * @param p
- * if null, returns all known JobStatus.
- */
- Iterator<JobStatus> getMatchingJobStatus(Predicate<JobStatus> p);
-}
\ No newline at end of file
diff --git a/engine/src/main/java/org/apache/sling/bgservlets/JobConsole.java b/engine/src/main/java/org/apache/sling/bgservlets/JobConsole.java
deleted file mode 100644
index 83a748c..0000000
--- a/engine/src/main/java/org/apache/sling/bgservlets/JobConsole.java
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * 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 the job's status page. */
- String getJobStatusPagePath(HttpServletRequest request, JobStatus jobStatus, String extension);
-
- /** Return the full path, including extension, to the job's stream */
- String getJobStreamPath(HttpServletRequest request, JobStatus jobStatus);
-}
diff --git a/engine/src/main/java/org/apache/sling/bgservlets/JobData.java b/engine/src/main/java/org/apache/sling/bgservlets/JobData.java
deleted file mode 100644
index 4d8ab16..0000000
--- a/engine/src/main/java/org/apache/sling/bgservlets/JobData.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * 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;
-import java.util.Date;
-
-/** Wraps a JCR Node to store and retrieve information
- * about a background Job
- */
-public interface JobData {
- String JOB_DATA_MIXIN = "sling:bgJobData";
- String PROP_EXTENSION = "sling:jobExtension";
-
- /** 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();
-
- /** Set a named property */
- void setProperty(String name, String value);
-
- /** Get a named property, null if non-existent */
- String getProperty(String name);
-
- /** Return this item's creation time */
- Date getCreationTime();
-}
diff --git a/engine/src/main/java/org/apache/sling/bgservlets/JobProgressInfo.java b/engine/src/main/java/org/apache/sling/bgservlets/JobProgressInfo.java
deleted file mode 100644
index fef8630..0000000
--- a/engine/src/main/java/org/apache/sling/bgservlets/JobProgressInfo.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sling.bgservlets;
-
-import java.util.Date;
-
-/** Provides Job progress information */
-public interface JobProgressInfo {
-
- /** Return the job's ETA if available.
- * @return null if the job didn't provide an ETA, or if
- * it is done.
- */
- Date getEstimatedCompletionTime();
-
- /** Return a single line of progress information */
- String getProgressMessage();
-}
diff --git a/engine/src/main/java/org/apache/sling/bgservlets/JobStatus.java b/engine/src/main/java/org/apache/sling/bgservlets/JobStatus.java
deleted file mode 100644
index 2b4f6fa..0000000
--- a/engine/src/main/java/org/apache/sling/bgservlets/JobStatus.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sling.bgservlets;
-
-import java.util.Date;
-
-/** Provides info about a job */
-public interface JobStatus {
- enum State {
- NEW, QUEUED, REJECTED, RUNNING, SUSPEND_REQUESTED, SUSPENDED, STOP_REQUESTED, STOPPED, DONE
- }
-
- /** Suffix used to build the job's stream path */
- String STREAM_PATH_SUFFIX = "/stream";
-
- /** Return the job's current state */
- State getState();
-
- /** Return the job's creation time */
- Date getCreationTime();
-
- /**
- * Request a change in the job's state, which might not take effect
- * immediately, or even be ignored.
- */
- void requestStateChange(State s);
-
- /** Indicate which state changes a human user can currently request,
- * based on our state. For a human user, the only states that make sense
- * to be requested are RUNNING, SUSPENDED and STOPPED, or a subset
- * of those based on current state.
- * @return empty array if no state change allowed
- */
- State [] getAllowedHumanStateChanges();
-
- /** Path of the Resource that describes this job */
- String getPath();
-
- /** Full Path of the job's stream, including extension */
- String getStreamPath();
-
- /** Return the job's progress info */
- JobProgressInfo getProgressInfo();
-}
\ No newline at end of file
diff --git a/engine/src/main/java/org/apache/sling/bgservlets/JobStorage.java b/engine/src/main/java/org/apache/sling/bgservlets/JobStorage.java
deleted file mode 100644
index 08f3fbd..0000000
--- a/engine/src/main/java/org/apache/sling/bgservlets/JobStorage.java
+++ /dev/null
@@ -1,31 +0,0 @@
-/*
- * 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);
-}
diff --git a/engine/src/main/java/org/apache/sling/bgservlets/Predicate.java b/engine/src/main/java/org/apache/sling/bgservlets/Predicate.java
deleted file mode 100644
index 7247020..0000000
--- a/engine/src/main/java/org/apache/sling/bgservlets/Predicate.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * 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;
-
-/** Simple typed predicate */
-public interface Predicate<T> {
- boolean isTrue(T subject);
-}
diff --git a/engine/src/main/java/org/apache/sling/bgservlets/RuntimeState.java b/engine/src/main/java/org/apache/sling/bgservlets/RuntimeState.java
deleted file mode 100644
index 7242c81..0000000
--- a/engine/src/main/java/org/apache/sling/bgservlets/RuntimeState.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sling.bgservlets;
-
-import java.util.Date;
-
-/** Interface used by a running job to exchange state
- * information with the execution engine.
- */
-public interface RuntimeState {
- /** Set the progress message that is returned
- * by {@link JobProgressInfo}
- */
- void setProgressMessage(String str);
-
- /** Set the ETA that is returned
- * by {@link JobProgressInfo}
- */
- void setEstimatedCompletionTime(Date d);
-}
diff --git a/engine/src/main/java/org/apache/sling/bgservlets/impl/BackgroundRequestExecutionJob.java b/engine/src/main/java/org/apache/sling/bgservlets/impl/BackgroundRequestExecutionJob.java
deleted file mode 100644
index e45f24b..0000000
--- a/engine/src/main/java/org/apache/sling/bgservlets/impl/BackgroundRequestExecutionJob.java
+++ /dev/null
@@ -1,174 +0,0 @@
-/*
- * 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.io.IOException;
-import java.util.Date;
-
-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.bgservlets.BackgroundHttpServletRequest;
-import org.apache.sling.bgservlets.BackgroundHttpServletResponse;
-import org.apache.sling.bgservlets.JobData;
-import org.apache.sling.bgservlets.JobProgressInfo;
-import org.apache.sling.bgservlets.JobStatus;
-import org.apache.sling.bgservlets.JobStorage;
-import org.apache.sling.bgservlets.RuntimeState;
-import org.apache.sling.engine.SlingRequestProcessor;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Runnable that executes a FilterChain, using a ServletResponseWrapper to
- * capture the output.
- */
-class BackgroundRequestExecutionJob implements Runnable, JobStatus, RuntimeState, JobProgressInfo {
- private final Logger log = LoggerFactory.getLogger(getClass());
- private final HttpServletRequest request;
- private final BackgroundHttpServletResponse response;
- private final SuspendableOutputStream stream;
-
- /** ResourceResolver used for the job processing */
- private final ResourceResolver processingResourceResolver;
-
- /** ResourceResolver used for the stats and to save the processing output */
- private final ResourceResolver outputResourceResolver;
- private final SlingRequestProcessor slingRequestProcessor;
- private final String path;
- private final String streamPath;
- private final Date creationTime;
- private Date estimatedCompletionTime;
- private String progressMessage;
-
- BackgroundRequestExecutionJob(SlingRequestProcessor slingRequestProcessor,
- JobStorage storage, SlingHttpServletRequest request,
- HttpServletResponse hsr, String[] parametersToRemove)
- throws IOException, LoginException {
- this.request = new BackgroundHttpServletRequest(request,
- parametersToRemove);
- this.slingRequestProcessor = slingRequestProcessor;
-
- // Provide this as the RuntimeState for the background servlet
- this.request.setAttribute(RuntimeState.class.getName(), this);
-
- // Need a new ResourceResolver with the same credentials as the
- // current request, for the background request.
- processingResourceResolver = request.getResourceResolver().clone(null);
-
- // And a dedicated session for the response object
- outputResourceResolver = request.getResourceResolver().clone(null);
-
- // Get JobData, defines path and used to save servlet output to the repository
- final Session outputSession = outputResourceResolver.adaptTo(Session.class);
- if(outputSession == null) {
- throw new IOException("Unable to get Session from ResourceResolver " + processingResourceResolver);
- }
- final JobData d = storage.createJobData(outputSession);
- final String ext = request.getRequestPathInfo().getExtension();
- if(ext != null) {
- d.setProperty(JobData.PROP_EXTENSION, ext);
- }
- path = d.getPath();
- creationTime = d.getCreationTime();
- streamPath = d.getPath() + STREAM_PATH_SUFFIX + (ext == null ? "" : "." + ext);
- stream = new SuspendableOutputStream(d.getOutputStream());
- response = new BackgroundHttpServletResponse(hsr, stream);
- }
-
- public String toString() {
- return getClass().getSimpleName() + ", state=" + getState() + ", path="
- + path;
- }
-
- public void run() {
- try {
- slingRequestProcessor.processRequest(request, response, processingResourceResolver);
- } catch (Exception e) {
- // TODO report errors in the background job's output
- log.error("Exception in background request processing", e);
- } finally {
- try {
- response.cleanup();
- } catch (IOException ioe) {
- // TODO report errors in the background job's output
- log.error("ServletResponseWrapper cleanup failed", ioe);
- }
-
- // cleanup the resource resolvers
- processingResourceResolver.close();
- outputResourceResolver.close();
- }
- }
-
- /** @inheritDoc */
- public String getPath() {
- return path;
- }
-
- /** @inheritDoc */
- public State getState() {
- return stream.getState();
- }
-
- /** @inheritDoc */
- public void requestStateChange(State s) {
- stream.requestStateChange(s);
- }
-
- /** @inheritDoc */
- public State[] getAllowedHumanStateChanges() {
- return stream.getAllowedHumanStateChanges();
- }
-
- public String getStreamPath() {
- return streamPath;
- }
-
- public Date getCreationTime() {
- return creationTime;
- }
-
- /** @inheritDoc */
- public JobProgressInfo getProgressInfo() {
- return this;
- }
-
- /** @inheritDoc */
- public String getProgressMessage() {
- return progressMessage;
- }
-
- /** @inheritDoc */
- public Date getEstimatedCompletionTime() {
- return estimatedCompletionTime;
- }
-
- public void setEstimatedCompletionTime(Date d) {
- estimatedCompletionTime = d;
- }
-
- public void setProgressMessage(String str) {
- progressMessage = str;
- }
-}
\ No newline at end of file
diff --git a/engine/src/main/java/org/apache/sling/bgservlets/impl/BackgroundServletStarterFilter.java b/engine/src/main/java/org/apache/sling/bgservlets/impl/BackgroundServletStarterFilter.java
deleted file mode 100644
index a8e18ba..0000000
--- a/engine/src/main/java/org/apache/sling/bgservlets/impl/BackgroundServletStarterFilter.java
+++ /dev/null
@@ -1,178 +0,0 @@
-/*
- * 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.io.IOException;
-import java.util.Arrays;
-import java.util.HashSet;
-import java.util.Set;
-
-import javax.servlet.Filter;
-import javax.servlet.FilterChain;
-import javax.servlet.FilterConfig;
-import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.apache.felix.scr.annotations.Component;
-import org.apache.felix.scr.annotations.Properties;
-import org.apache.felix.scr.annotations.Property;
-import org.apache.felix.scr.annotations.Reference;
-import org.apache.felix.scr.annotations.Service;
-import org.apache.sling.api.SlingHttpServletRequest;
-import org.apache.sling.bgservlets.ExecutionEngine;
-import org.apache.sling.bgservlets.JobStorage;
-import org.apache.sling.commons.osgi.PropertiesUtil;
-import org.apache.sling.engine.SlingRequestProcessor;
-import org.osgi.service.component.ComponentContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Filter that runs the current request in the background if specific request
- * parameters are set. Must be placed early in the filter chain.
- */
-@Component(
- metatype=true,
- label="%BackgroundServletStarterFilter.label",
- description="%BackgroundServletStarterFilter.description")
-@Service
-@Properties( {
- @Property(name = "filter.scope", value = "request", propertyPrivate=true),
- @Property(name = "filter.order", intValue = -1000000000, propertyPrivate=true )})
-public class BackgroundServletStarterFilter implements Filter {
-
- private final Logger log = LoggerFactory.getLogger(getClass());
-
- @Reference
- private ExecutionEngine executionEngine;
-
- @Reference
- private SlingRequestProcessor slingRequestProcessor;
-
- @Reference
- private JobStorage jobStorage;
-
- /** Default value of the "put in background" parameter */
- public static final String DEFAULT_BG_PARAM = "sling:bg";
-
- /** Name of the property that defines the request parameter name to
- * use to start a servlet in the background.
- */
- @Property(value=DEFAULT_BG_PARAM)
- public static final String PROP_BG_PARAM = "background.parameter.name";
-
- /** Default list of HTTP method names that can trigger background requests */
- public static final String [] DEFAULT_ALLOWED_METHODS = {"POST", "PUT", "DELETE"};
-
- /** Name of the property that defines the list of allowed HTTP methods
- * to trigger background jobs
- */
- @Property()
- public static final String PROP_ALLOWED_METHODS = "allowed.http.methods";
-
- private Set<String> allowedHttpMethods;
-
- /**
- * Request runs in the background if this request parameter is present
- */
- private String bgParamName;
-
- protected void activate(ComponentContext ctx) {
- bgParamName = PropertiesUtil.toString(ctx.getProperties().get(PROP_BG_PARAM), DEFAULT_BG_PARAM);
-
- final String [] cfgMethods = PropertiesUtil.toStringArray(ctx.getProperties().get(PROP_ALLOWED_METHODS), DEFAULT_ALLOWED_METHODS);
- allowedHttpMethods = new HashSet<String>();
- allowedHttpMethods.addAll(Arrays.asList(cfgMethods));
-
- if(allowedHttpMethods.isEmpty()) {
- log.error("{} defines no allowed HTTP methods, background servlets cannot be started", PROP_ALLOWED_METHODS);
- }
-
- log.info(
- "Request parameter {} will run servlets in the background for HTTP methods {}",
- bgParamName,
- allowedHttpMethods);
- }
-
- private boolean startBackgroundRequest(HttpServletRequest req) throws ServletException {
- boolean result = Boolean.valueOf(req.getParameter(bgParamName));
- if(result && ! allowedHttpMethods.contains(req.getMethod())) {
- throw new ServletException("Background requests cannot be started with a " + req.getMethod() + " request");
- }
- return result;
- }
-
- public void doFilter(final ServletRequest sreq,
- final ServletResponse sresp, final FilterChain chain)
- throws IOException, ServletException {
- if (!(sreq instanceof HttpServletRequest)) {
- throw new ServletException("request is not an HttpServletRequest: "
- + sresp.getClass().getName());
- }
- if (!(sresp instanceof HttpServletResponse)) {
- throw new ServletException(
- "response is not an HttpServletResponse: "
- + sresp.getClass().getName());
- }
- final HttpServletRequest request = (HttpServletRequest) sreq;
- final SlingHttpServletRequest slingRequest =
- (request instanceof SlingHttpServletRequest ? (SlingHttpServletRequest) request : null);
- final HttpServletResponse response = (HttpServletResponse) sresp;
- if (startBackgroundRequest(request)) {
- try {
- final BackgroundRequestExecutionJob job = new BackgroundRequestExecutionJob(
- slingRequestProcessor, jobStorage, slingRequest, response,
- new String[] { bgParamName });
- log.debug("{} parameter true, running request in the background ({})",
- bgParamName, job);
- if (slingRequest != null) {
- slingRequest.getRequestProgressTracker().log(
- bgParamName
- + " parameter true, running request in background ("
- + job + ")");
- }
- executionEngine.queueForExecution(job);
-
- // Redirect to the job's status page, using same extension
- // as this request
- String ext = slingRequest.getRequestPathInfo().getExtension();
- if(ext == null) {
- ext = "";
- } else if(ext.length() > 0) {
- ext = "." + ext;
- }
- final String path = request.getContextPath() + job.getPath() + ext;
- response.sendRedirect(path);
- } catch (org.apache.sling.api.resource.LoginException e) {
- throw new ServletException("LoginException in doFilter", e);
- }
- } else {
- chain.doFilter(sreq, sresp);
- }
- }
-
- public void destroy() {
- }
-
- public void init(FilterConfig cfg) throws ServletException {
- }
-}
\ No newline at end of file
diff --git a/engine/src/main/java/org/apache/sling/bgservlets/impl/DeepNodeCreator.java b/engine/src/main/java/org/apache/sling/bgservlets/impl/DeepNodeCreator.java
deleted file mode 100644
index ac1b575..0000000
--- a/engine/src/main/java/org/apache/sling/bgservlets/impl/DeepNodeCreator.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * 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);
- Node parent = null;
- if(parentPath.length() == 0) {
- // reached the root
- parent = session.getRootNode();
- } else {
- parent = deepCreateNode(parentPath, session, nodeType);
- }
- final String childPath = path.substring(slashPos + 1);
- 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 {
- }
-}
diff --git a/engine/src/main/java/org/apache/sling/bgservlets/impl/ExecutionEngineImpl.java b/engine/src/main/java/org/apache/sling/bgservlets/impl/ExecutionEngineImpl.java
deleted file mode 100644
index 13920b5..0000000
--- a/engine/src/main/java/org/apache/sling/bgservlets/impl/ExecutionEngineImpl.java
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * 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.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.concurrent.ArrayBlockingQueue;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.Executor;
-import java.util.concurrent.RejectedExecutionHandler;
-import java.util.concurrent.ThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
-
-import org.apache.felix.scr.annotations.Component;
-import org.apache.felix.scr.annotations.Property;
-import org.apache.felix.scr.annotations.Service;
-import org.apache.sling.api.SlingException;
-import org.apache.sling.bgservlets.ExecutionEngine;
-import org.apache.sling.bgservlets.JobStatus;
-import org.apache.sling.bgservlets.Predicate;
-import org.osgi.service.component.ComponentContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Simple ExecutionEngine TODO should use Sling's thread pool, and check
- * synergies with scheduler services
- */
-@Component(
- metatype=true,
- label="%ExecutionEngineImpl.label",
- description="%ExecutionEngineImpl.description")
-@Service
-public class ExecutionEngineImpl implements ExecutionEngine {
-
- private final Logger log = LoggerFactory.getLogger(getClass());
- private Executor executor;
- private final Map<String, JobStatus> jobs = Collections.synchronizedMap(new HashMap<String, JobStatus>());
-
- @Property(intValue=10)
- public static final String PROP_CORE_POOL_SIZE = "core.pool.size";
- private int corePoolSize;
-
- @Property(intValue=20)
- public static final String PROP_MAX_POOL_SIZE = "max.pool.size";
- private int maximumPoolSize;
-
- @Property(intValue=30)
- public static final String PROP_KEEP_ALIVE_TIME = "keep.alive.time.seconds";
- private int keepAliveTimeSeconds;
-
- private class RunnableWrapper implements Runnable {
- private final Runnable inputJob;
- private final JobStatus jobStatus;
-
- RunnableWrapper(Runnable inputJob) {
- this.inputJob = inputJob;
- jobStatus = (inputJob instanceof JobStatus ? (JobStatus) inputJob
- : null);
- }
-
- public void run() {
- if (jobStatus != null) {
- jobStatus.requestStateChange(JobStatus.State.RUNNING);
- }
- log.info("Starting job {}", inputJob);
- try {
- // TODO save Exceptions in job?
- 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);
- }
-
- JobStatus getJobStatus() {
- return jobStatus;
- }
- };
-
- @SuppressWarnings("serial")
- public static class QueueFullException extends SlingException {
- QueueFullException(Runnable r) {
- super("Execution queue is full, cannot execute " + r);
- }
- }
-
- private int getIntegerProperty(ComponentContext ctx, String name) {
- final Integer value = (Integer)ctx.getProperties().get(name);
- if(value == null) {
- throw new IllegalStateException("Missing ComponentContext property: " + name);
- }
- return value.intValue();
- }
-
- protected void activate(ComponentContext context) {
- corePoolSize = getIntegerProperty(context, PROP_CORE_POOL_SIZE);
- maximumPoolSize = getIntegerProperty(context, PROP_MAX_POOL_SIZE);
- keepAliveTimeSeconds = getIntegerProperty(context, PROP_KEEP_ALIVE_TIME);
- TimeUnit unit = TimeUnit.SECONDS;
- BlockingQueue<Runnable> workQueue = new ArrayBlockingQueue<Runnable>(4);
- RejectedExecutionHandler handler = new RejectedExecutionHandler() {
- public void rejectedExecution(Runnable r,
- ThreadPoolExecutor executor) {
- onJobRejected(r);
- }
- };
- log.info("ThreadPoolExecutor configuration: corePoolSize = {}, maxPoolSize={}, keepAliveTimeSeconds={}",
- new Object[] { corePoolSize, maximumPoolSize, keepAliveTimeSeconds });
- executor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize,
- keepAliveTimeSeconds, unit, workQueue, handler);
- }
-
- protected void deactivate(ComponentContext context) {
- // TODO how to shutdown executor?
- executor = null;
-
- // TODO cleanup jobs??
- }
-
- private void onJobRejected(Runnable r) {
- final RunnableWrapper w = (RunnableWrapper) r;
- if (w.getJobStatus() != null) {
- w.getJobStatus().requestStateChange(JobStatus.State.REJECTED);
- }
- log.info("Rejected job {}", r);
- throw new QueueFullException(r);
- }
-
- public void queueForExecution(final Runnable inputJob) {
- // Wrap job in our own Runnable to change its state as we execute it
- final RunnableWrapper w = new RunnableWrapper(inputJob);
- if (w.getJobStatus() != null) {
- w.getJobStatus().requestStateChange(JobStatus.State.QUEUED);
- jobs.put(w.getJobStatus().getPath(), w.getJobStatus());
- }
- executor.execute(w);
- }
-
- public JobStatus getJobStatus(String path) {
- return jobs.get(path);
- }
-
- public Iterator<JobStatus> getMatchingJobStatus(Predicate<JobStatus> p) {
- // TODO take predicate into account
- // TODO sort by submission/execution time?
- return jobs.values().iterator();
- }
-}
\ No newline at end of file
diff --git a/engine/src/main/java/org/apache/sling/bgservlets/impl/JobConsoleImpl.java b/engine/src/main/java/org/apache/sling/bgservlets/impl/JobConsoleImpl.java
deleted file mode 100644
index a461b31..0000000
--- a/engine/src/main/java/org/apache/sling/bgservlets/impl/JobConsoleImpl.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * 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.Activate;
-import org.apache.felix.scr.annotations.Component;
-import org.apache.felix.scr.annotations.Deactivate;
-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.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.apache.sling.bgservlets.impl.webconsole.JobConsolePlugin;
-import org.osgi.service.component.ComponentContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/** JobConsole implementation */
-@Component(
- metatype=true,
- label="%JobConsoleImpl.label",
- description="%JobConsoleImpl.description")
-@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;
-
- @Property(boolValue=true)
- private final static String PROP_CONSOLE_PLUGIN_ACTIVE = "console.plugin.active";
-
- 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);
- }
- }
- }
-
- @Activate
- protected void activate(ComponentContext ctx) {
- final Object obj = ctx.getProperties().get(PROP_CONSOLE_PLUGIN_ACTIVE);
- final boolean pluginActive = (obj instanceof Boolean ? (Boolean)obj : true);
- if(pluginActive) {
- JobConsolePlugin.initPlugin(ctx.getBundleContext(), this);
- } else {
- log.info("{} is false, not activating JobConsolePlugin", PROP_CONSOLE_PLUGIN_ACTIVE);
- }
- }
-
- @Deactivate
- protected void deactivate(ComponentContext ctx) {
- JobConsolePlugin.destroyPlugin();
- }
-
- 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;
- }
-
- public String getJobStreamPath(HttpServletRequest request, JobStatus jobStatus) {
- return request.getContextPath() + jobStatus.getStreamPath();
- }
-}
diff --git a/engine/src/main/java/org/apache/sling/bgservlets/impl/SuspendableOutputStream.java b/engine/src/main/java/org/apache/sling/bgservlets/impl/SuspendableOutputStream.java
deleted file mode 100644
index 44102e7..0000000
--- a/engine/src/main/java/org/apache/sling/bgservlets/impl/SuspendableOutputStream.java
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- * 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.io.FilterOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-import java.util.Date;
-
-import org.apache.sling.bgservlets.JobProgressInfo;
-import org.apache.sling.bgservlets.JobStatus;
-
-/**
- * Wraps an OutputStream with controls for suspending it or throwing an
- * IOException next time it is written to. Used to suspend background servlets
- * (by blocking the stream) or stop them (by throwing an exception).
- */
-public class SuspendableOutputStream extends FilterOutputStream implements
- JobStatus {
- private State state = State.NEW;
- private boolean closed = false;
-
- @SuppressWarnings("serial")
- public static class StreamStoppedException extends RuntimeException {
- StreamStoppedException() {
- super("Stopped by " + SuspendableOutputStream.class.getSimpleName());
- }
- }
-
- public SuspendableOutputStream(OutputStream os) {
- super(os);
- }
-
- @Override
- public void write(byte[] b, int off, int len) throws IOException {
- checkWritePermission();
- super.write(b, off, len);
- }
-
- @Override
- public void write(byte[] b) throws IOException {
- checkWritePermission();
- super.write(b);
- }
-
- @Override
- public void write(int b) throws IOException {
- checkWritePermission();
- super.write(b);
- }
-
- @Override
- public void close() throws IOException {
- super.close();
- state = State.DONE;
- closed = true;
- }
-
- private void checkWritePermission() throws IOException {
- if (closed) {
- throw new IOException("Attempt to write to closed stream");
- }
-
- if (state == State.STOP_REQUESTED || state == State.STOPPED) {
- state = State.STOPPED;
- // stopped: throw exception to stop stream user
- flush();
- throw new StreamStoppedException();
-
- } else if (state == State.SUSPEND_REQUESTED || state == State.SUSPENDED) {
- synchronized (this) {
- if (state == State.SUSPEND_REQUESTED
- || state == State.SUSPENDED)
- state = State.SUSPENDED;
- try {
- // suspended: block until resumed
- while (state == State.SUSPENDED) {
- wait();
- }
- } catch (InterruptedException e) {
- throw (IOException)new IOException(
- "InterruptedException in checkWritePermission()").initCause(e);
- }
- }
- }
- }
-
- public State getState() {
- return state;
- }
-
- /** Only SUSPENDED, STOP, and RUNNING make sense here */
- public synchronized void requestStateChange(State s) {
- boolean illegal = false;
-
- if (state == State.DONE) {
- // ignore changes
- } else if (s == State.SUSPENDED) {
- if (state == State.NEW || state == State.QUEUED
- || state == State.RUNNING) {
- state = State.SUSPEND_REQUESTED;
- notify();
- } else if (state == State.SUSPEND_REQUESTED
- || state == State.SUSPENDED) {
- // ignore change
- } else {
- illegal = true;
- }
-
- } else if (s == State.STOPPED) {
- if (state == State.NEW || state == State.QUEUED
- || state == State.RUNNING
- || state == State.SUSPEND_REQUESTED
- || state == State.SUSPENDED) {
- state = State.STOP_REQUESTED;
- notify();
- } else if (state == State.STOP_REQUESTED || state == State.STOPPED) {
- // ignore change
- } else {
- illegal = true;
- }
-
- } else if (s == State.RUNNING) {
- if (state == State.QUEUED
- || state == State.SUSPEND_REQUESTED
- || state == State.SUSPENDED) {
- state = State.RUNNING;
- notify();
- }
-
- } else {
- state = s;
- notify();
- }
-
- if (illegal) {
- throw new IllegalStateException("Illegal state change:" + state
- + " -> " + s);
- }
- }
-
- /** @inheritDoc */
- public State [] getAllowedHumanStateChanges() {
- return getAllowedStates(state);
- }
-
- static State [] getAllowedStates(State s) {
- State [] result = new State[] {};
- if(s == State.RUNNING) {
- result = new State[] { State.SUSPENDED, State.STOPPED };
- } else if(s == State.SUSPEND_REQUESTED || s == State.SUSPENDED) {
- result = new State[] { State.RUNNING, State.STOPPED };
- }
- return result;
- }
-
- /**
- * Not implemented
- * @throws UnsupportedOperationException
- */
- public String getPath() {
- throw new UnsupportedOperationException(
- "getPath() is not applicable to this class");
- }
-
- /**
- * Not implemented
- * @throws UnsupportedOperationException
- */
- public String getStreamPath() {
- throw new UnsupportedOperationException(
- "getStreamPath() is not applicable to this class");
- }
-
- /**
- * Not implemented
- * @throws UnsupportedOperationException
- */
- public Date getCreationTime() {
- throw new UnsupportedOperationException(
- "getCreationTime() is not applicable to this class");
- }
-
- /**
- * Not implemented
- * @throws UnsupportedOperationException
- */
- public JobProgressInfo getProgressInfo() {
- throw new UnsupportedOperationException(
- "getProgressInfo() is not applicable to this class");
- }
-
-
-}
diff --git a/engine/src/main/java/org/apache/sling/bgservlets/impl/nodestream/NodeInputStream.java b/engine/src/main/java/org/apache/sling/bgservlets/impl/nodestream/NodeInputStream.java
deleted file mode 100644
index 88e6e5a..0000000
--- a/engine/src/main/java/org/apache/sling/bgservlets/impl/nodestream/NodeInputStream.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * 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.nodestream;
-
-import java.io.IOException;
-import java.io.InputStream;
-
-import javax.jcr.Node;
-import javax.jcr.Property;
-import javax.jcr.RepositoryException;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/** Reads data stored by a {@link NodeOutputStream}
- * and rebuilds a continuous stream out of the
- * multiple Properties that it creates.
- */
-public class NodeInputStream extends InputStream {
-
- private final Logger log = LoggerFactory.getLogger(getClass());
-
- /** The Node under which we read our data */
- private final Node node;
-
- /** Computes path for stream storage */
- private final NodeStreamPath streamPath;
-
- /** Current stream that we are reading */
- private InputStream currentStream;
-
- public NodeInputStream(Node n) throws IOException {
- node = n;
- streamPath = new NodeStreamPath();
- selectNextStream();
- }
-
- /** Select next property to read from and open its stream */
- private void selectNextStream() throws IOException {
- streamPath.selectNextPath();
- final String propertyPath = streamPath.getNodePath() + "/" + NodeStreamPath.PROPERTY_NAME;
- try {
- if(node.hasProperty(propertyPath)) {
- final Property p = node.getProperty(propertyPath);
- currentStream = p.getStream();
- log.debug("Switched to the InputStream of Property {}", p.getPath());
- } else {
- currentStream = null;
- log.debug("Property {} not found, end of stream", node.getPath() + "/" + propertyPath);
- }
- } catch(RepositoryException re) {
- throw (IOException)new IOException("RepositoryException in selectNextProperty()").initCause(re);
- }
- }
-
- @Override
- public int available() throws IOException {
- return currentStream == null ? 0 : currentStream.available();
- }
-
- @Override
- public void close() throws IOException {
- if(currentStream != null) {
- currentStream.close();
- }
- super.close();
- }
-
- @Override
- public int read() throws IOException {
- if(currentStream == null) {
- return -1;
- }
- int result = currentStream.read();
- if(result == -1) {
- selectNextStream();
- return read();
- }
- return result;
- }
-
- @Override
- public int read(byte[] b, int off, int len) throws IOException {
- if(currentStream == null) {
- return 0;
- }
- int result = currentStream.read(b, off, len);
- if(result <= 0) {
- selectNextStream();
- return read(b, off, len);
- }
- return result;
- }
-
- @Override
- public int read(byte[] b) throws IOException {
- return read(b, 0, b.length);
- }
-}
diff --git a/engine/src/main/java/org/apache/sling/bgservlets/impl/nodestream/NodeOutputStream.java b/engine/src/main/java/org/apache/sling/bgservlets/impl/nodestream/NodeOutputStream.java
deleted file mode 100644
index 3b825a2..0000000
--- a/engine/src/main/java/org/apache/sling/bgservlets/impl/nodestream/NodeOutputStream.java
+++ /dev/null
@@ -1,131 +0,0 @@
-/*
- * 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.nodestream;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-
-import org.apache.sling.bgservlets.impl.DeepNodeCreator;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-
-/** An OutputStream stored in properties under
- * a JCR node. The content is persisted on
- * each flush() call, using sequentially-named
- * properties so that {@link NodeInputStream} can
- * reconstruct the stream from permanent storage.
- * flush() is also called automatically every
- * BUFFER_SWITCH_SIZE bytes, to keep our memory
- * requirements low.
- *
- * Meant to be used when running background servlets:
- * we want to save their output in a way that
- * survives system restart.
- */
-public class NodeOutputStream extends OutputStream {
-
- private final Logger log = LoggerFactory.getLogger(getClass());
-
- /** Node type for our stream nodes */
- public static final String STREAM_NODE_TYPE = "nt:unstructured";
-
- /** The Node under which we write our data */
- private final Node node;
-
- /** Computes path for stream storage */
- private final NodeStreamPath streamPath;
-
- /** Buffer to hold data before writing it to a Property */
- private final ByteArrayOutputStream buffer = new ByteArrayOutputStream(BUFFER_SIZE);
-
- public static final int BUFFER_SIZE = 32768;
- public static final int BUFFER_SWITCH_SIZE = BUFFER_SIZE * 100 / 90;
-
- public NodeOutputStream(Node n) {
- node = n;
- streamPath = new NodeStreamPath();
- }
-
- /** Calls flush to persist our stream, before closing */
- @Override
- public void close() throws IOException {
- flush();
- buffer.close();
- }
-
- /** Store the contents of our buffer to a new Property under our
- * node, numbered sequentially.
- */
- @Override
- public void flush() throws IOException {
-
- streamPath.selectNextPath();
-
- try {
- if(!node.getSession().isLive()) {
- log.warn("Session closed, unable to flush stream");
- } else {
- // Create node that will store the stream
- final String streamNodePath = node.getPath() + "/" + streamPath.getNodePath();
- final Node streamNode = new DeepNodeCreator().deepCreateNode(streamNodePath,
- node.getSession(), STREAM_NODE_TYPE);
-
- streamNode.setProperty(NodeStreamPath.PROPERTY_NAME,
- new ByteArrayInputStream(buffer.toByteArray()));
- log.debug("Saved {} bytes to Property {}", buffer.size(),
- streamNode.getProperty(NodeStreamPath.PROPERTY_NAME).getPath());
- node.save();
- buffer.reset();
- }
- } catch(RepositoryException re) {
- throw (IOException)new IOException("RepositoryException in flush()").initCause(re);
- }
- }
-
- private void flushIfNeeded() throws IOException {
- if(buffer.size() >= BUFFER_SWITCH_SIZE) {
- log.debug("Buffer size {} reached switch level {}, flushing", buffer.size(), BUFFER_SWITCH_SIZE);
- flush();
- }
- }
-
- @Override
- public void write(byte[] b, int off, int len) throws IOException {
- buffer.write(b, off, len);
- flushIfNeeded();
- }
-
- @Override
- public void write(byte[] b) throws IOException {
- buffer.write(b);
- flushIfNeeded();
- }
-
- @Override
- public void write(int b) throws IOException {
- buffer.write(b);
- flushIfNeeded();
- }
-}
diff --git a/engine/src/main/java/org/apache/sling/bgservlets/impl/nodestream/NodeStreamPath.java b/engine/src/main/java/org/apache/sling/bgservlets/impl/nodestream/NodeStreamPath.java
deleted file mode 100644
index 773b53e..0000000
--- a/engine/src/main/java/org/apache/sling/bgservlets/impl/nodestream/NodeStreamPath.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * 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.nodestream;
-
-
-/** Builds sequential hierachical paths to store node
- * streams: increment a counter and build path using
- * CHARS_PER_LEVEL characters of the String value of
- * the counter per path level.
- */
-class NodeStreamPath {
- private int counter;
- private String path;
- private final int CHARS_PER_LEVEL = 2;
-
- /** Property name to use for streams */
- static final String PROPERTY_NAME = "stream";
-
- /** Select the next path to use, must be
- * called before using getPath().
- * Not thread-safe. */
- void selectNextPath() {
- counter++;
- final StringBuilder sb = new StringBuilder();
- final String str = String.valueOf(counter);
- for(int i = 0; i < str.length(); i++) {
- if(i> 0 && i % CHARS_PER_LEVEL == 0) {
- sb.append('/');
- }
- sb.append(str.charAt(i));
- }
- path = sb.toString();
- }
-
- /** Return the last path computed by selectNextPath() */
- String getNodePath() {
- return path;
- }
-}
diff --git a/engine/src/main/java/org/apache/sling/bgservlets/impl/servlets/BackgroundTestServlet.java b/engine/src/main/java/org/apache/sling/bgservlets/impl/servlets/BackgroundTestServlet.java
deleted file mode 100644
index 0818828..0000000
--- a/engine/src/main/java/org/apache/sling/bgservlets/impl/servlets/BackgroundTestServlet.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sling.bgservlets.impl.servlets;
-
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.util.Date;
-
-import javax.servlet.ServletException;
-
-import org.apache.felix.scr.annotations.Component;
-import org.apache.felix.scr.annotations.Property;
-import org.apache.felix.scr.annotations.Service;
-import org.apache.sling.api.SlingHttpServletRequest;
-import org.apache.sling.api.SlingHttpServletResponse;
-import org.apache.sling.api.servlets.SlingAllMethodsServlet;
-import org.apache.sling.bgservlets.RuntimeState;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Servlet used for interactive testing of the background servlets engine. TODO
- * remove once we have better tests.
- */
-@Component
-@Service
-@SuppressWarnings("serial")
-@Property(name = "sling.servlet.paths", value = "/system/bgservlets/test")
-public class BackgroundTestServlet extends SlingAllMethodsServlet {
-
- private final Logger log = LoggerFactory.getLogger(getClass());
-
- @Override
- protected void doPost(SlingHttpServletRequest request,
- SlingHttpServletResponse response) throws ServletException,
- IOException {
- doGet(request, response);
- }
-
- @Override
- protected void doGet(SlingHttpServletRequest request,
- SlingHttpServletResponse response) throws ServletException,
- IOException {
- response.setContentType("text/plain");
- final PrintWriter w = response.getWriter();
-
- final int cycles = getIntParam(request, "cycles", 10);
- final int interval = getIntParam(request, "interval", 1000);
- final int flushEvery = getIntParam(request, "flushEvery", 2);
-
- // Use supplied RuntimeState if available
- final RuntimeState runtimeState = (RuntimeState)request.getAttribute(RuntimeState.class.getName());
- if(runtimeState == null) {
- log.warn("No RuntimeState attribute provided, won't report progress");
- } else {
- runtimeState.setEstimatedCompletionTime(new Date(System.currentTimeMillis() + cycles * interval));
- }
-
- w.println("Start at " + new Date());
- try {
- for (int i = 1; i <= cycles; i++) {
- if (i % flushEvery == 0) {
- w.println("Flushing output<br/>");
- w.flush();
- }
-
- final String msg = String.format("Cycle %d of %d", i, cycles);
- w.printf(msg);
- w.print("\n<br/>");
-
- if(runtimeState != null) {
- runtimeState.setProgressMessage(msg);
- final int remainingCycles = cycles - i;
- runtimeState.setEstimatedCompletionTime(new Date(System.currentTimeMillis() + remainingCycles * interval));
- }
-
- try {
- Thread.sleep(interval);
- } catch (InterruptedException iex) {
- throw new ServletException("InterruptedException", iex);
- }
- }
- w.println("All done.");
- w.flush();
- } catch (Throwable t) {
- log.info("Exception in service method", t);
- }
- }
-
- private int getIntParam(SlingHttpServletRequest request, String name,
- int defaultValue) {
- int result = defaultValue;
- final String str = request.getParameter(name);
- if (str != null) {
- result = Integer.parseInt(str);
- }
- return result;
- }
-}
diff --git a/engine/src/main/java/org/apache/sling/bgservlets/impl/servlets/JobInfoServlet.java b/engine/src/main/java/org/apache/sling/bgservlets/impl/servlets/JobInfoServlet.java
deleted file mode 100644
index 2c754e8..0000000
--- a/engine/src/main/java/org/apache/sling/bgservlets/impl/servlets/JobInfoServlet.java
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sling.bgservlets.impl.servlets;
-
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.util.HashMap;
-import java.util.Map;
-
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletResponse;
-
-import org.apache.felix.scr.annotations.Component;
-import org.apache.felix.scr.annotations.Properties;
-import org.apache.felix.scr.annotations.Property;
-import org.apache.felix.scr.annotations.Reference;
-import org.apache.felix.scr.annotations.Service;
-import org.apache.sling.api.SlingHttpServletRequest;
-import org.apache.sling.api.SlingHttpServletResponse;
-import org.apache.sling.api.servlets.SlingSafeMethodsServlet;
-import org.apache.sling.bgservlets.BackgroundServletConstants;
-import org.apache.sling.bgservlets.JobConsole;
-import org.apache.sling.bgservlets.JobData;
-import org.apache.sling.bgservlets.JobStatus;
-import org.apache.sling.commons.json.JSONException;
-import org.apache.sling.commons.json.io.JSONWriter;
-
-/** Default rendering of a job node in various formats,
- * meant to be displayed when the job is started.
- */
-@Component
-@Service
-@Properties({
- @Property(name = "sling.servlet.resourceTypes", value = BackgroundServletConstants.JOB_RESOURCE_TYPE),
- @Property(name = "sling.servlet.methods", value="GET")
-})
-@SuppressWarnings("serial")
-public class JobInfoServlet extends SlingSafeMethodsServlet {
-
- public static final String DEFAULT_ENCODING = "UTF-8";
- public static final String DEFAULT_EXT = "txt";
-
- private static final Map<String, Renderer> renderers;
- static {
- renderers = new HashMap<String, Renderer>();
- renderers.put("txt", new TextRenderer());
- renderers.put("html", new HtmlRenderer());
- renderers.put("json", new JsonRenderer());
- }
-
- @Reference
- private JobConsole jobConsole;
-
- 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: job output available at ");
- pw.println(streamPath);
- }
- }
-
- private static class HtmlRenderer implements Renderer {
- public void render(PrintWriter pw, String streamPath, String streamResource) {
- pw.println("<html><head><title>Background job</title>");
- pw.println("<link rel='stream' href='" + streamPath + "'/>");
- pw.println("</head><body>");
- pw.println("<h1>Background job information</h1>");
- pw.println("Job output available at");
- pw.println("<a href='" + streamPath + "'>" + streamResource + "</a>");
- pw.println("</body>");
- }
- }
-
- private static class JsonRenderer implements Renderer {
- public void render(PrintWriter pw, String streamPath, String streamResource) throws IOException {
- JSONWriter w = new JSONWriter(pw);
- try {
- w.object();
- w.key("info");
- w.value("Background job information");
- w.key("jobStreamPath");
- w.value(streamPath);
- w.endObject();
- } catch (JSONException e) {
- throw (IOException)new IOException("JSONException in " + getClass().getSimpleName()).initCause(e);
- }
- }
- }
-
- @Override
- protected void doGet(SlingHttpServletRequest request,
- SlingHttpServletResponse response) throws ServletException,
- IOException {
- try {
- final Node n = request.getResource().adaptTo(Node.class);
- final JobStatus j = jobConsole.getJobStatus(n.getSession(), n.getPath());
- final String streamPath = j.getStreamPath();
- final String fullStreamPath = request.getContextPath() + streamPath;
- final String ext = request.getRequestPathInfo().getExtension();
- Renderer r = renderers.get(ext);
- if(r == null) {
- r = renderers.get(DEFAULT_EXT);
- }
- if(r == null) {
- response.sendError(HttpServletResponse.SC_BAD_REQUEST, "No JobRenderer available for extension '" + ext + "'");
- }
- response.setContentType(request.getResponseContentType());
- response.setCharacterEncoding(DEFAULT_ENCODING);
- r.render(response.getWriter(), fullStreamPath, streamPath);
- } catch(RepositoryException re) {
- throw new ServletException("RepositoryException in doGet", re);
- }
- }
-}
diff --git a/engine/src/main/java/org/apache/sling/bgservlets/impl/servlets/JobStateChangeServlet.java b/engine/src/main/java/org/apache/sling/bgservlets/impl/servlets/JobStateChangeServlet.java
deleted file mode 100644
index 4d5f374..0000000
--- a/engine/src/main/java/org/apache/sling/bgservlets/impl/servlets/JobStateChangeServlet.java
+++ /dev/null
@@ -1,98 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sling.bgservlets.impl.servlets;
-
-import java.io.IOException;
-
-import javax.jcr.Session;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletResponse;
-
-import org.apache.felix.scr.annotations.Component;
-import org.apache.felix.scr.annotations.Properties;
-import org.apache.felix.scr.annotations.Property;
-import org.apache.felix.scr.annotations.Reference;
-import org.apache.felix.scr.annotations.Service;
-import org.apache.sling.api.SlingHttpServletRequest;
-import org.apache.sling.api.SlingHttpServletResponse;
-import org.apache.sling.api.servlets.SlingAllMethodsServlet;
-import org.apache.sling.bgservlets.BackgroundServletConstants;
-import org.apache.sling.bgservlets.JobConsole;
-import org.apache.sling.bgservlets.JobStatus;
-import org.apache.sling.commons.json.JSONException;
-import org.apache.sling.commons.json.io.JSONWriter;
-
-/** Handles POST to a job node, to request a job
- * state change.
- */
-@Component
-@Service
-@Properties({
- @Property(name = "sling.servlet.resourceTypes", value = BackgroundServletConstants.JOB_RESOURCE_TYPE),
- @Property(name = "sling.servlet.methods", value="POST")
-})
-@SuppressWarnings("serial")
-public class JobStateChangeServlet extends SlingAllMethodsServlet {
-
- public static final String PARAM_STATE = "desiredState";
-
- @Reference
- private JobConsole jobConsole;
-
- @Override
- protected void doPost(SlingHttpServletRequest request, SlingHttpServletResponse response)
- throws ServletException, IOException {
- final String str = request.getParameter(PARAM_STATE);
- if(str == null) {
- response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Missing parameter:" + PARAM_STATE);
- }
- JobStatus.State desiredState = JobStatus.State.NEW;
- try {
- desiredState = JobStatus.State.valueOf(str);
- } catch(Exception e) {
- response.sendError(HttpServletResponse.SC_BAD_REQUEST, "Invalid " + PARAM_STATE + ": " + str);
- return;
- }
-
- final Session session = request.getResourceResolver().adaptTo(Session.class);
- if(session == null) {
- response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "ResourceResolver does not adapt to a Session");
- return;
- }
- final JobStatus j = jobConsole.getJobStatus(session, request.getResource().getPath());
- final JobStatus.State oldState = j.getState();
- j.requestStateChange(desiredState);
- final JobStatus.State newState = j.getState();
-
- response.setContentType("application/json");
- response.setCharacterEncoding("UTF-8");
- final JSONWriter w = new JSONWriter(response.getWriter());
- try {
- w.object();
- w.key("info").value("Requested state change");
- w.key(PARAM_STATE).value(desiredState.toString());
- w.key("path").value(j.getPath());
- w.key("currentState").value(newState);
- w.key("stateChanged").value(newState != oldState);
- w.endObject();
- } catch(JSONException je) {
- throw new ServletException("JSONException in doPost", je);
- }
- }
-}
diff --git a/engine/src/main/java/org/apache/sling/bgservlets/impl/servlets/JobStreamServlet.java b/engine/src/main/java/org/apache/sling/bgservlets/impl/servlets/JobStreamServlet.java
deleted file mode 100644
index d45084e..0000000
--- a/engine/src/main/java/org/apache/sling/bgservlets/impl/servlets/JobStreamServlet.java
+++ /dev/null
@@ -1,84 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.sling.bgservlets.impl.servlets;
-
-import java.io.IOException;
-import java.io.InputStream;
-import java.io.OutputStream;
-
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletResponse;
-
-import org.apache.felix.scr.annotations.Component;
-import org.apache.felix.scr.annotations.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;
-
-/** Default rendering of the job's stream node: replays the
- * stored stream.
- */
-@Component
-@Service
-@SuppressWarnings("serial")
-@Property(name = "sling.servlet.resourceTypes", value = BackgroundServletConstants.STREAM_RESOURCE_TYPE)
-public class JobStreamServlet extends SlingSafeMethodsServlet {
-
- @Reference
- private JobStorage jobStorage;
-
- @Override
- protected void doGet(SlingHttpServletRequest request, SlingHttpServletResponse response)
- throws ServletException, IOException {
- final Node n = request.getResource().adaptTo(Node.class);
- if(n == null) {
- response.sendError(HttpServletResponse.SC_NOT_FOUND,
- "Resource does not adapt to a Node: " + request.getResource().getPath());
- }
-
- // The stream is a child of the job node
- try {
- final JobData d = jobStorage.getJobData(n.getParent());
- final InputStream is = d.getInputStream();
- try {
- response.setContentType(request.getResponseContentType());
- final OutputStream os = response.getOutputStream();
- final byte [] buffer = new byte[32768];
- int count = 0;
- while((count = is.read(buffer, 0, buffer.length)) > 0) {
- os.write(buffer, 0, count);
- }
- os.flush();
- } finally {
- if(is != null) {
- is.close();
- }
- }
- } catch(RepositoryException re) {
- throw new ServletException("RepositoryException in doGet()", re);
- }
- }
-}
diff --git a/engine/src/main/java/org/apache/sling/bgservlets/impl/storage/JobDataImpl.java b/engine/src/main/java/org/apache/sling/bgservlets/impl/storage/JobDataImpl.java
deleted file mode 100644
index e6f8388..0000000
--- a/engine/src/main/java/org/apache/sling/bgservlets/impl/storage/JobDataImpl.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * 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 java.util.Calendar;
-import java.util.Date;
-
-import javax.jcr.Node;
-import javax.jcr.RepositoryException;
-
-import org.apache.sling.api.SlingConstants;
-import org.apache.sling.bgservlets.BackgroundServletConstants;
-import org.apache.sling.bgservlets.JobData;
-import org.apache.sling.bgservlets.JobStatus;
-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;
- private final Calendar creationTime;
-
- public static final String STREAM_PATH = JobStatus.STREAM_PATH_SUFFIX.substring(1);
-
- public static final String RT_PROP = SlingConstants.NAMESPACE_PREFIX + ":" + SlingConstants.PROPERTY_RESOURCE_TYPE;
-
- /** Build a JobDataImpl on supplied node, which must exists */
- JobDataImpl(Node n) throws RepositoryException {
- node = n;
- path = node.getPath();
- if(node.hasProperty(BackgroundServletConstants.CREATION_TIME_PROPERTY)) {
- creationTime = node.getProperty(BackgroundServletConstants.CREATION_TIME_PROPERTY).getDate();
- } else {
- // Set fake date if not found
- creationTime = Calendar.getInstance();
- creationTime.set(1900, 1, 1);
- }
- }
-
- 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);
- }
- node.setProperty(RT_PROP, BackgroundServletConstants.JOB_RESOURCE_TYPE);
- final Node stream = node.addNode(STREAM_PATH);
- stream.setProperty(RT_PROP, BackgroundServletConstants.STREAM_RESOURCE_TYPE);
- node.save();
- return new NodeOutputStream(stream);
- } catch(Exception e) {
- throw new JobStorageException("Exception in getOutputStream()", e);
- }
- }
-
- 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);
- }
- }
-
- public Date getCreationTime() {
- return creationTime.getTime();
- }
-}
diff --git a/engine/src/main/java/org/apache/sling/bgservlets/impl/storage/JobStorageException.java b/engine/src/main/java/org/apache/sling/bgservlets/impl/storage/JobStorageException.java
deleted file mode 100644
index 9445666..0000000
--- a/engine/src/main/java/org/apache/sling/bgservlets/impl/storage/JobStorageException.java
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * 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 related to job storage. Unchecked, meant
- * for non-recoverable problems.
- */
-@SuppressWarnings("serial")
-public class JobStorageException extends SlingException {
- public JobStorageException(String reason) {
- super(reason);
- }
-
- public JobStorageException(String reason, Throwable cause) {
- super(reason, cause);
- }
-}
diff --git a/engine/src/main/java/org/apache/sling/bgservlets/impl/storage/JobStorageImpl.java b/engine/src/main/java/org/apache/sling/bgservlets/impl/storage/JobStorageImpl.java
deleted file mode 100644
index ec5bd5b..0000000
--- a/engine/src/main/java/org/apache/sling/bgservlets/impl/storage/JobStorageImpl.java
+++ /dev/null
@@ -1,119 +0,0 @@
-/*
- * 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.Calendar;
-import java.util.Date;
-import java.util.concurrent.atomic.AtomicInteger;
-
-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.Property;
-import org.apache.felix.scr.annotations.Reference;
-import org.apache.felix.scr.annotations.Service;
-import org.apache.sling.bgservlets.BackgroundServletConstants;
-import org.apache.sling.bgservlets.JobData;
-import org.apache.sling.bgservlets.JobStorage;
-import org.apache.sling.bgservlets.impl.DeepNodeCreator;
-import org.apache.sling.settings.SlingSettingsService;
-import org.osgi.service.component.ComponentContext;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/** Default JobStorage implementation */
-@Component(
- metatype=true,
- label="%JobStorage.label",
- description="%JobStorage.description")
-@Service
-public class JobStorageImpl implements JobStorage {
-
- private Logger log = LoggerFactory.getLogger(getClass());
-
- /** Configurable base path for storing job data */
- @Property(value="/var/bg/jobs")
- public static final String PROP_JOB_STORAGE_PATH = "job.storage.path";
-
- /** Need Sling Settings to get the instance ID */
- @Reference
- private SlingSettingsService slingSettings;
-
- public static final String PATH_FORMAT = "/yyyy/MM/dd/HH/mm";
- public static final String JOB_NODETYPE = "nt:unstructured";
-
- private String jobStoragePath;
- private AtomicInteger counter = new AtomicInteger();
- private static final DateFormat pathFormat = new SimpleDateFormat(PATH_FORMAT);
- private String slingInstanceId;
-
- protected void activate(ComponentContext ctx) {
- jobStoragePath = (String)ctx.getProperties().get(PROP_JOB_STORAGE_PATH);
- if(jobStoragePath == null || jobStoragePath.length() == 0) {
- throw new IllegalStateException("Missing " + PROP_JOB_STORAGE_PATH + " in ComponentContext");
- }
- if(!jobStoragePath.startsWith("/")) {
- jobStoragePath = "/" + jobStoragePath;
- }
- if(jobStoragePath.endsWith("/")) {
- jobStoragePath = jobStoragePath.substring(0, jobStoragePath.length() - 1);
- }
- slingInstanceId = slingSettings.getSlingId();
- log.info("Jobs will be stored under {}/{}", jobStoragePath, slingInstanceId);
- }
-
- 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);
- }
- }
-
- String getNextPath() {
- final StringBuilder sb = new StringBuilder();
- sb.append(jobStoragePath);
- sb.append("/").append(slingInstanceId);
- sb.append(pathFormat.format(new Date())).append("/");
- sb.append(counter.incrementAndGet());
- return sb.toString();
- }
-
- Node createNewJobNode(Session s) throws RepositoryException {
- final String path = getNextPath();
- final Node result = new DeepNodeCreator().deepCreateNode(path, s, JOB_NODETYPE);
- result.addMixin(JobData.JOB_DATA_MIXIN);
- result.setProperty(BackgroundServletConstants.CREATION_TIME_PROPERTY, Calendar.getInstance());
- result.getSession().save();
- log.debug("Job node {} created", result.getPath());
- return result;
- }
-}
diff --git a/engine/src/main/java/org/apache/sling/bgservlets/impl/storage/NodeJobStatusFactory.java b/engine/src/main/java/org/apache/sling/bgservlets/impl/storage/NodeJobStatusFactory.java
deleted file mode 100644
index 6765f19..0000000
--- a/engine/src/main/java/org/apache/sling/bgservlets/impl/storage/NodeJobStatusFactory.java
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * 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;
-}
diff --git a/engine/src/main/java/org/apache/sling/bgservlets/impl/storage/NodeJobStatusFactoryImpl.java b/engine/src/main/java/org/apache/sling/bgservlets/impl/storage/NodeJobStatusFactoryImpl.java
deleted file mode 100644
index 032fa48..0000000
--- a/engine/src/main/java/org/apache/sling/bgservlets/impl/storage/NodeJobStatusFactoryImpl.java
+++ /dev/null
@@ -1,135 +0,0 @@
-/*
- * 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.util.Date;
-
-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.JobData;
-import org.apache.sling.bgservlets.JobProgressInfo;
-import org.apache.sling.bgservlets.JobStatus;
-import org.apache.sling.bgservlets.JobStatus.State;
-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;
- private final String streamPath;
- private final Date creationTime;
-
- public NodeJobStatus(Node n) throws RepositoryException {
- path = n.getPath();
- if(n.hasProperty(JobData.PROP_EXTENSION)) {
- streamPath = path + JobStatus.STREAM_PATH_SUFFIX + "."
- + n.getProperty(JobData.PROP_EXTENSION).getString();
- } else {
- streamPath = path + JobStatus.STREAM_PATH_SUFFIX;
- }
- creationTime = new JobDataImpl(n).getCreationTime();
- }
-
- public String getPath() {
- return path;
- }
-
- public String getStreamPath() {
- return streamPath;
- }
-
- public Date getCreationTime() {
- return creationTime;
- }
-
- 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) {
- log.debug("Job {} is not active, cannot change state", path);
- } else {
- j.requestStateChange(s);
- }
- }
-
- /** @inheritDoc */
- public State [] getAllowedHumanStateChanges() {
- final JobStatus j = getActiveJob();
- if(j == null) {
- return new State[] {};
- }
- return j.getAllowedHumanStateChanges();
- }
-
- private JobStatus getActiveJob() {
- if(executionEngine != null) {
- return executionEngine.getJobStatus(path);
- }
- return null;
- }
-
- public JobProgressInfo getProgressInfo() {
- // If job is active, return its info, else
- // return info from our job node
- final JobStatus active = getActiveJob();
- if(active != null) {
- return active.getProgressInfo();
- } else {
- return new JobProgressInfo() {
- public String getProgressMessage() {
- return getState().toString();
- }
-
- public Date getEstimatedCompletionTime() {
- return null;
- }
- };
- }
- }
- };
-
- public JobStatus getJobStatus(Node n) throws RepositoryException {
- return new NodeJobStatus(n);
- }
-}
diff --git a/engine/src/main/java/org/apache/sling/bgservlets/impl/webconsole/JobConsolePlugin.java b/engine/src/main/java/org/apache/sling/bgservlets/impl/webconsole/JobConsolePlugin.java
deleted file mode 100644
index 4e6b7b7..0000000
--- a/engine/src/main/java/org/apache/sling/bgservlets/impl/webconsole/JobConsolePlugin.java
+++ /dev/null
@@ -1,284 +0,0 @@
-/*
- * 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.webconsole;
-
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.util.Date;
-import java.util.Dictionary;
-import java.util.Hashtable;
-import java.util.Iterator;
-
-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.api.resource.ResourceResolver;
-import org.apache.sling.api.resource.ResourceResolverFactory;
-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;
-import org.osgi.util.tracker.ServiceTracker;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/** Felix OSGi console plugin for the ExecutionEngine */
-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, JobConsole jobConsole) {
- if (plugin == null) {
- Plugin tmp = new Plugin(jobConsole);
- tmp.activate(context);
- plugin = tmp;
- log.info("{} activated", plugin);
- }
- }
-
- public static void destroyPlugin() {
- if (plugin != null) {
- try {
- plugin.deactivate();
- log.info("{} deactivated", plugin);
- } finally {
- plugin = null;
- }
- }
- }
-
- @SuppressWarnings("serial")
- public static final class Plugin extends AbstractWebConsolePlugin {
- private ServiceRegistration serviceRegistration;
- private final JobConsole jobConsole;
- private ServiceTracker repositoryTracker;
- private ServiceTracker resourceResolverFactoryTracker;
-
- public Plugin(JobConsole console) {
- jobConsole = console;
- }
-
- public void activate(BundleContext ctx) {
- super.activate(ctx);
-
- repositoryTracker = new ServiceTracker(ctx, SlingRepository.class.getName(), null);
- repositoryTracker.open();
-
- resourceResolverFactoryTracker = new ServiceTracker(ctx, ResourceResolverFactory.class.getName(), null);
- resourceResolverFactoryTracker.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_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);
- }
-
- public void deactivate() {
- if (serviceRegistration != null) {
- serviceRegistration.unregister();
- serviceRegistration = null;
- }
- if (repositoryTracker != null) {
- repositoryTracker.close();
- repositoryTracker = null;
- }
- if (resourceResolverFactoryTracker != null) {
- resourceResolverFactoryTracker.close();
- resourceResolverFactoryTracker = null;
- }
- super.deactivate();
- }
-
- @Override
- public String getLabel() {
- return LABEL;
- }
-
- @Override
- public String getTitle() {
- return TITLE;
- }
-
- /** Return the JCR session of the current request's user */
- private Session getRequestSession() throws ServletException {
- Session result = null;
- final ResourceResolverFactory f = (ResourceResolverFactory)resourceResolverFactoryTracker.getService();
- if(f == null) {
- throw new ServletException("Unable to acquire ResourceResolverFactory service");
- }
-
- final ResourceResolver r = f.getThreadResourceResolver();
- if(r == null) {
- throw new ServletException(
- "Unable to acquire ResourceResolver from ResourceResolverFactory service. "
- + "This usually happens if the webconsole does not use the Sling Security Provider."
- );
- }
-
- result = r.adaptTo(Session.class);
-
- if(result == null) {
- throw new ServletException("ResourceResolver does not adapt to Session");
- }
- return result;
- }
-
- @Override
- protected void renderContent(HttpServletRequest req,
- HttpServletResponse res) throws ServletException, IOException {
- final PrintWriter pw = res.getWriter();
-
- // Access required services
- final SlingRepository repository = (SlingRepository)repositoryTracker.getService();
- if(repository == null) {
- pw.println("No SlingRepository service found");
- return;
- }
- renderJobs(req, pw, getRequestSession(), jobConsole);
- }
-
- @Override
- protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
- final PrintWriter pw = resp.getWriter();
-
- // Access required services
- final SlingRepository repository = (SlingRepository)repositoryTracker.getService();
- if(repository == null) {
- pw.println("No SlingRepository service found");
- return;
- }
- final Session s = getRequestSession();
- final String jobPath = req.getParameter("jobPath");
- if (jobPath != null) {
- final JobStatus job = jobConsole.getJobStatus(s, jobPath);
- if (job != null) {
- final String action = req.getParameter("action");
- if ("suspend".equals(action)) {
- job.requestStateChange(JobStatus.State.SUSPENDED);
- } else if ("stop".equals(action)) {
- job.requestStateChange(JobStatus.State.STOPPED);
- } else if ("resume".equals(action)) {
- job.requestStateChange(JobStatus.State.RUNNING);
- }
- }
- }
-
- resp.sendRedirect(req.getServletPath() + req.getPathInfo());
- }
-
- private void renderJobs(HttpServletRequest req, PrintWriter pw, Session s, JobConsole console) {
- 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>");
- pw.println("<th class='content container'>State</th>");
- pw.println("<th class='content container'>ETA</th>");
- pw.println("<th class='content container'>Progress</th>");
- pw.println("<th class='content container'>Path</th>");
- pw.println("</tr>");
- pw.println("</thead>");
- pw.println("<tbody>");
-
- 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(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(HttpServletRequest request, PrintWriter pw, JobConsole console, JobStatus job) {
- pw.println("<tr class='content'>");
- pw.println("<td><form action='./" + LABEL + "' method='POST'>");
- final String[] actions = { "suspend", "resume", "stop" };
- for (String action : actions) {
- pw.println("<input type='submit' name='action' value='"
- + action + "'/> ");
- }
- pw.println("<input type='hidden' name='jobPath' value='"
- + job.getPath() + "'/> ");
- pw.println("</form></td>");
- pw.println("<td>");
- pw.println(escape(job.getState().toString()));
- pw.println("</td>");
- pw.println("<td>");
- final Date eta = job.getProgressInfo().getEstimatedCompletionTime();
- pw.println(eta == null ? "-" : eta.toString());
- pw.println("</td>");
- pw.println("<td>");
- pw.println(escape(job.getProgressInfo().getProgressMessage()));
- pw.println("</td>");
- pw.print("<td>\n<a href='");
- pw.print(escape(console.getJobStatusPagePath(request, job, STATUS_EXTENSION)));
- pw.print("'>");
- pw.print(escape(job.getPath()));
- pw.println("</a>");
- pw.println("</td>");
- pw.println("</tr>");
- }
-
- static String escape(String str) {
- if(str == null) {
- return null;
- }
- final StringBuilder sb = new StringBuilder();
- for(int i=0; i < str.length(); i++) {
- final char c = str.charAt(i);
- if(c == '<') {
- sb.append("<");
- } else if(c== '>') {
- sb.append(">");
- } else if(c == '&') {
- sb.append("&");
- } else {
- sb.append(c);
- }
- }
- return sb.toString();
- }
-
- }
-}
\ No newline at end of file
diff --git a/engine/src/main/resources/OSGI-INF/metatype/metatype.properties b/engine/src/main/resources/OSGI-INF/metatype/metatype.properties
deleted file mode 100644
index 024831d..0000000
--- a/engine/src/main/resources/OSGI-INF/metatype/metatype.properties
+++ /dev/null
@@ -1,65 +0,0 @@
-#
-# 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.
-#
-
-
-#
-# This file contains localization strings for configuration labels and
-# descriptions as used in the metatype.xml descriptor generated by the
-# the SCR plugin
-
-BackgroundServletStarterFilter.label = Apache Sling Background Requests Filter
-BackgroundServletStarterFilter.description = ServletFilter that runs \
- requests in the background if a specific request parameter is set \
- to true.
-
-JobConsoleImpl.label = Apache Sling Background Jobs Console
-JobConsoleImpl.description = Provides a simple API to manage background jobs.
-
-console.plugin.active.name = Console plugin active?
-console.plugin.active.description = Turn the Felix Web Console JobConsole \
- plugin on or off.
-
-background.parameter.name.name = Background request parameter name
-background.parameter.name.description = Requests run in the background \
- if this request parameter is set to true.
-
-JobStorage.label = Apache Sling Background Requests Job Storage Service
-JobStorage.description = Stores job state and output for requests running \
- in the background.
-
-job.storage.path.name = Job Storage Base Path
-job.storage.path.description = Path under which job state is stored in \
- the repository.
-
-ExecutionEngineImpl.label = Apache Sling Execution Engine for Background Requests
-ExecutionEngineImpl.description = Used to run requests in the background
-
-core.pool.size.name = Core ThreadPoolExecutor size
-core.pool.size.description = See ThreadPoolExecutor documentation for more info.
-
-max.pool.size.name = Maximum ThreadPoolExecutor size
-max.pool.size.description = See ThreadPoolExecutor documentation for more info.
-
-keep.alive.time.seconds.name = Keep alive time for ThreadPoolExecutor (seconds)
-keep.alive.time.seconds.description = See ThreadPoolExecutor documentation for more info.
-
-allowed.http.methods.name = HTTP methods that can start background jobs
-allowed.http.methods.description = List of allowed HTTP methods for starting background \
- jobs. Including GET and HEAD is not recommended, background jobs are not meant to be \
- used for this "safe" category of HTTP methods.
\ No newline at end of file
diff --git a/engine/src/main/resources/SLING-INF/nodetypes/jobdata.cnd b/engine/src/main/resources/SLING-INF/nodetypes/jobdata.cnd
deleted file mode 100644
index f701fb2..0000000
--- a/engine/src/main/resources/SLING-INF/nodetypes/jobdata.cnd
+++ /dev/null
@@ -1,25 +0,0 @@
-//
-// 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
diff --git a/engine/src/test/java/org/apache/sling/bgservlets/QueryStringFilterTest.java b/engine/src/test/java/org/apache/sling/bgservlets/QueryStringFilterTest.java
deleted file mode 100644
index 444510d..0000000
--- a/engine/src/test/java/org/apache/sling/bgservlets/QueryStringFilterTest.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * 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 static org.junit.Assert.assertEquals;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-import javax.servlet.http.HttpServletRequest;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.Parameterized;
-import org.junit.runners.Parameterized.Parameters;
-import org.mockito.Mockito;
-
-@RunWith(Parameterized.class)
-public class QueryStringFilterTest {
-
- private final String slingBgParamName;
-
- @Parameters(name="{0}")
- public static List<Object[]> data() {
- final List<Object[]> result = new ArrayList<Object[]>();
- result.add(new Object[] { "sling:bg" });
- result.add(new Object[] { "sling%3Abg" });
- return result;
- }
-
- public QueryStringFilterTest(String slingBgParamName) {
- this.slingBgParamName = slingBgParamName;
- }
-
- private void assertFilter(String [] toRemove, String orig, String expected) {
- final HttpServletRequest mock = Mockito.mock(HttpServletRequest.class);
- Mockito.when(mock.getQueryString()).thenReturn(orig);
- final BackgroundHttpServletRequest r = new BackgroundHttpServletRequest(mock, toRemove);
- final String result = r.getQueryString();
- assertEquals("Expecting correct queryString after removal of " + Arrays.asList(toRemove), expected, result);
-
- }
-
- @Test
- public void testNothingToRemove() {
- final String [] toRemove = {};
- assertFilter(toRemove, null, null);
- assertFilter(toRemove, slingBgParamName + "=true", slingBgParamName + "=true&");
- assertFilter(toRemove, "a=b&" + slingBgParamName + "=true", "a=b&" + slingBgParamName + "=true&");
- assertFilter(toRemove, "sling:bg=true&c=d", "sling:bg=true&c=d&");
- assertFilter(toRemove, "a=b&sling:bg=true&c=d", "a=b&sling:bg=true&c=d&");
- }
-
- @Test
- public void testRemoveOne() {
- final String [] toRemove = { "sling:bg" };
- assertFilter(toRemove, null, null);
- assertFilter(toRemove, slingBgParamName + "=true", "");
- assertFilter(toRemove, "a=b&" + slingBgParamName + "=true", "a=b&");
- assertFilter(toRemove, slingBgParamName + "=true&c=d", "c=d&");
- assertFilter(toRemove, "a=b&" + slingBgParamName + "=true&c=d", "a=b&c=d&");
- assertFilter(toRemove, "a=b&" + slingBgParamName + " = true+with+spaces&c=d", "a=b&c=d&");
- }
-
- @Test
- public void testRemoveTwo() {
- final String [] toRemove = { "sling:bg", "some_other_param" };
- assertFilter(toRemove, null, null);
- assertFilter(toRemove, slingBgParamName + "=true", "");
- assertFilter(toRemove, "a=b&" + slingBgParamName + "=true", "a=b&");
- assertFilter(toRemove, slingBgParamName + "=true&c=d", "c=d&");
- assertFilter(toRemove, "a=b&" + slingBgParamName + "=true&c=d", "a=b&c=d&");
- assertFilter(toRemove, "a=b&" + slingBgParamName + " = true+with+spaces&c=d", "a=b&c=d&");
- assertFilter(toRemove, "a=b&" + slingBgParamName + " = true+with+spaces&c=d&some_other_param=foo", "a=b&c=d&");
- assertFilter(toRemove, slingBgParamName + "=true&some_other_param=foo", "");
- assertFilter(toRemove, slingBgParamName + "=true&some_other_param=foo&", "");
- }
-}
diff --git a/engine/src/test/java/org/apache/sling/bgservlets/impl/BackgroundServletStarterFilterTest.java b/engine/src/test/java/org/apache/sling/bgservlets/impl/BackgroundServletStarterFilterTest.java
deleted file mode 100644
index c2bc322..0000000
--- a/engine/src/test/java/org/apache/sling/bgservlets/impl/BackgroundServletStarterFilterTest.java
+++ /dev/null
@@ -1,92 +0,0 @@
-/*
- * 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.io.IOException;
-import java.util.Dictionary;
-import java.util.Hashtable;
-
-import javax.servlet.FilterChain;
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletResponse;
-
-import org.apache.sling.api.SlingHttpServletRequest;
-import org.jmock.Expectations;
-import org.jmock.Mockery;
-import org.junit.Before;
-import org.junit.Test;
-import org.osgi.service.component.ComponentContext;
-
-public class BackgroundServletStarterFilterTest {
- private BackgroundServletStarterFilter filter;
- private Mockery mockery;
- private SlingHttpServletRequest request;
- private HttpServletResponse response;
- private FilterChain chain;
-
- @SuppressWarnings("serial")
- static class BackgroundJobIsStarting extends RuntimeException {
- }
-
- @Before
- public void setup() {
- mockery = new Mockery();
- request = mockery.mock(SlingHttpServletRequest.class);
- response = mockery.mock(HttpServletResponse.class);
- chain = mockery.mock(FilterChain.class);
-
- final ComponentContext ctx = mockery.mock(ComponentContext.class);
- final Dictionary<String, Object> props = new Hashtable<String, Object>();
-
- filter = new BackgroundServletStarterFilter();
-
- mockery.checking(new Expectations() {{
- allowing(request).getParameter("sling:bg");
- will(returnValue("true"));
-
- // If this method is called it means the BackgroundHttpServletRequest
- // is being created to start a background job, that's all we need to know
- allowing(request).getContextPath();
- will(throwException(new BackgroundJobIsStarting()));
-
- allowing(ctx).getProperties();
- will(returnValue(props));
- }});
-
- filter.activate(ctx);
- }
-
- private void testWithMethod(final String method) throws IOException, ServletException {
- mockery.checking(new Expectations() {{
- allowing(request).getMethod();
- will(returnValue(method));
- }});
- filter.doFilter(request, response, chain);
- }
-
- @Test(expected=ServletException.class)
- public void testGetRequest() throws IOException, ServletException {
- testWithMethod("GET");
- }
-
- @Test(expected=BackgroundJobIsStarting.class)
- public void testPostRequest() throws IOException, ServletException {
- testWithMethod("POST");
- }
-}
\ No newline at end of file
diff --git a/engine/src/test/java/org/apache/sling/bgservlets/impl/DeepNodeCreatorTest.java b/engine/src/test/java/org/apache/sling/bgservlets/impl/DeepNodeCreatorTest.java
deleted file mode 100644
index d2066fc..0000000
--- a/engine/src/test/java/org/apache/sling/bgservlets/impl/DeepNodeCreatorTest.java
+++ /dev/null
@@ -1,210 +0,0 @@
-/*
- * 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 static org.junit.Assert.fail;
-
-import java.util.concurrent.atomic.AtomicInteger;
-
-import javax.jcr.ItemExistsException;
-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 **/
-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);
- }
-
- @Test
- 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).getRootNode();
- will(returnValue(root));
-
- allowing(s).save();
- }});
-
- final Node result = c.deepCreateNode(barPath, s, testNodeType);
- assertTrue("Expecting deepCreate to return created node", result == bar);
- }
-
- @Test
- 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).getRootNode();
-
- 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());
- }
-
- @Test
- public void testCannotReadFoo() throws Exception {
- final Mockery mockery = new Mockery();
- final Session s = mockery.mock(Session.class);
- final String fooPath = "/foo";
- final Node foo = mockery.mock(Node.class, fooPath);
- final String barPath = "/foo/bar";
- final Node bar = mockery.mock(Node.class, barPath);
- final Node root = mockery.mock(Node.class, "/");
-
- mockery.checking(new Expectations() {{
- allowing(s).itemExists(with(any(String.class)));
- will(returnValue(false));
-
- allowing(s).itemExists(barPath);
- will(returnValue(true));
-
- allowing(s).getItem(fooPath);
- will(returnValue(foo));
-
- allowing(s).getItem(barPath);
- will(returnValue(bar));
-
- allowing(s).getRootNode();
- will(returnValue(root));
-
- allowing(root).addNode(with(any(String.class)), with(any(String.class)));
- will(throwException(new ItemExistsException("As if the child node was not readable")));
-
- allowing(s).save();
- }});
-
- final DeepNodeCreator c = new DeepNodeCreator();
-
- try {
- c.deepCreateNode("/foo/bar/something", s, "nt:unstructured");
- fail("Expecting an exception as /foo is not accessible");
- } catch(ItemExistsException asExpected) {
- // all is good
- }
- }
-}
\ No newline at end of file
diff --git a/engine/src/test/java/org/apache/sling/bgservlets/impl/SuspendableOutputStreamTest.java b/engine/src/test/java/org/apache/sling/bgservlets/impl/SuspendableOutputStreamTest.java
deleted file mode 100644
index 81af563..0000000
--- a/engine/src/test/java/org/apache/sling/bgservlets/impl/SuspendableOutputStreamTest.java
+++ /dev/null
@@ -1,188 +0,0 @@
-/*
- * 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.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertTrue;
-import static org.junit.Assert.fail;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.OutputStream;
-
-import org.apache.sling.bgservlets.JobStatus;
-import org.junit.Test;
-
-public class SuspendableOutputStreamTest {
- public final static String TEST = "0123456789abcdefghijklmnopqrstuvwxyz";
-
- static class WriterThread extends Thread {
- private final OutputStream os;
- private final byte[] toWrite = "TEST".getBytes();
- private Exception runException;
- final static int WRITE_DELAY = 50;
-
- WriterThread(OutputStream os) {
- this.os = os;
- }
-
- @Override
- public void run() {
- try {
- while (true) {
- os.write(toWrite);
- Thread.sleep(WRITE_DELAY);
- }
- } catch (Exception e) {
- runException = e;
- }
- }
- }
-
- @Test
- public void testNoSuspend() throws IOException {
- final ByteArrayOutputStream bos = new ByteArrayOutputStream();
- final SuspendableOutputStream f = new SuspendableOutputStream(bos);
- f.write(TEST.getBytes());
- f.flush();
- assertEquals("String should be fully written", TEST, bos.toString());
- }
-
- @Test
- public void testStop() throws IOException {
- final ByteArrayOutputStream bos = new ByteArrayOutputStream();
- final SuspendableOutputStream f = new SuspendableOutputStream(bos);
- assertEquals("Expecting NEW state first", JobStatus.State.NEW, f
- .getState());
- f.requestStateChange(JobStatus.State.RUNNING);
- f.write(TEST.getBytes());
- f.flush();
-
- f.requestStateChange(JobStatus.State.STOPPED);
- assertEquals("Expecting STOP_REQUESTED state before write",
- JobStatus.State.STOP_REQUESTED, f.getState());
- try {
- f.write("nothing".getBytes());
- fail("Expected StreamStoppedException when writing to STOPPED stream");
- } catch (SuspendableOutputStream.StreamStoppedException asExpected) {
- }
-
- assertEquals("Expecting STOPPED state after write",
- JobStatus.State.STOPPED, f.getState());
- }
-
- @Test
- public void testSuspend() throws Exception {
- final ByteArrayOutputStream bos = new ByteArrayOutputStream();
- final SuspendableOutputStream f = new SuspendableOutputStream(bos);
- f.requestStateChange(JobStatus.State.RUNNING);
- final WriterThread t = new WriterThread(f);
- t.setDaemon(true);
- t.start();
-
- final long delay = WriterThread.WRITE_DELAY * 3;
- Thread.sleep(delay);
- assertTrue("Expecting data to be written by WriterThread",
- bos.size() > 0);
-
- f.requestStateChange(JobStatus.State.SUSPENDED);
- Thread.sleep(delay);
- assertEquals("Expecting SUSPEND state after a few writes",
- JobStatus.State.SUSPENDED, f.getState());
-
- final int count = bos.size();
- Thread.sleep(delay);
- assertEquals("Expecting no writes in SUSPEND state", count, bos.size());
-
- f.requestStateChange(JobStatus.State.RUNNING);
- Thread.sleep(delay);
- assertEquals("Expecting RUNNING state", JobStatus.State.RUNNING, f
- .getState());
- assertTrue("Expecting data to be written after resuming",
- bos.size() > count);
-
- f.close();
- Thread.sleep(delay);
- assertFalse("Expecting WriterThread to end after closing stream", t
- .isAlive());
- assertNotNull("Expecting non-null Exception in WriterThread",
- t.runException);
- assertTrue("Expecting IOException in WriterThread",
- t.runException instanceof IOException);
- }
-
- @Test
- public void testSuspendThenStop() throws Exception {
- final ByteArrayOutputStream bos = new ByteArrayOutputStream();
- final SuspendableOutputStream f = new SuspendableOutputStream(bos);
- assertEquals("Expecting NEW state first", JobStatus.State.NEW, f
- .getState());
- final WriterThread t = new WriterThread(f);
- t.setDaemon(true);
- t.start();
-
- f.requestStateChange(JobStatus.State.SUSPENDED);
-
- final long delay = WriterThread.WRITE_DELAY * 3;
- Thread.sleep(delay);
- assertEquals("Expecting SUSPEND state after a few writes",
- JobStatus.State.SUSPENDED, f.getState());
-
- f.requestStateChange(JobStatus.State.STOPPED);
- assertEquals("Expecting STOP_REQUESTED state before write",
- JobStatus.State.STOP_REQUESTED, f.getState());
- try {
- f.write("nothing".getBytes());
- fail("Expected StreamStoppedException when writing to STOPPED stream");
- } catch (SuspendableOutputStream.StreamStoppedException asExpected) {
- }
-
- assertEquals("Expecting STOPPED state after write",
- JobStatus.State.STOPPED, f.getState());
- f.close();
- }
-
- @Test
- public void testDone() {
- final ByteArrayOutputStream bos = new ByteArrayOutputStream();
- final SuspendableOutputStream f = new SuspendableOutputStream(bos);
- f.requestStateChange(JobStatus.State.DONE);
- assertEquals("Expecting DONE state (1)", JobStatus.State.DONE, f
- .getState());
- f.requestStateChange(JobStatus.State.SUSPENDED);
- assertEquals("Expecting DONE state (2)", JobStatus.State.DONE, f
- .getState());
- f.requestStateChange(JobStatus.State.STOPPED);
- assertEquals("Expecting DONE state (3)", JobStatus.State.DONE, f
- .getState());
- }
-
- @Test
- public void testCreationToRunningState() {
- final ByteArrayOutputStream bos = new ByteArrayOutputStream();
- final SuspendableOutputStream f = new SuspendableOutputStream(bos);
- assertEquals("Expecting NEW state initially", JobStatus.State.NEW, f.getState());
- f.requestStateChange(JobStatus.State.QUEUED);
- assertEquals("Expecting QUEUED state as requests", JobStatus.State.QUEUED, f.getState());
- f.requestStateChange(JobStatus.State.RUNNING);
- assertEquals("Expecting RUNNING state as requested", JobStatus.State.RUNNING, f.getState());
- }
-}
diff --git a/engine/src/test/java/org/apache/sling/bgservlets/impl/nodestream/NodeStreamPathTest.java b/engine/src/test/java/org/apache/sling/bgservlets/impl/nodestream/NodeStreamPathTest.java
deleted file mode 100644
index c89f69b..0000000
--- a/engine/src/test/java/org/apache/sling/bgservlets/impl/nodestream/NodeStreamPathTest.java
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * 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.nodestream;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNull;
-
-import org.junit.Test;
-
-public class NodeStreamPathTest {
-
- @Test
- public void testNullOnFirstCall() {
- final NodeStreamPath nsp = new NodeStreamPath();
- assertNull(nsp.getNodePath());
- }
-
- @Test
- public void testPaths() {
- final String [] data = {
- "1", "1",
- "9", "9",
- "99", "99",
- "100", "10/0",
- "199", "19/9",
- "200", "20/0",
- "1234", "12/34",
- };
-
- for(int i=0; i < data.length; i += 2) {
- final NodeStreamPath nsp = new NodeStreamPath();
- for(int j = 0; j < Integer.parseInt(data[i]); j++) {
- nsp.selectNextPath();
- }
- final String exp = data[i+1];
- assertEquals("At index " + i + ", expected " + exp, exp, nsp.getNodePath());
- }
- }
-}
diff --git a/engine/src/test/java/org/apache/sling/bgservlets/impl/nodestream/NodeStreamTest.java b/engine/src/test/java/org/apache/sling/bgservlets/impl/nodestream/NodeStreamTest.java
deleted file mode 100644
index aa5ca6a..0000000
--- a/engine/src/test/java/org/apache/sling/bgservlets/impl/nodestream/NodeStreamTest.java
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * 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.nodestream;
-
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.InputStream;
-import java.util.Random;
-
-import javax.jcr.Node;
-import javax.jcr.NodeIterator;
-import javax.jcr.RepositoryException;
-
-import org.apache.sling.commons.testing.jcr.RepositoryTestBase;
-
-public class NodeStreamTest extends RepositoryTestBase {
-
- public static final String ASCII_DATA = "0123456789abcdefgjijklmnoprqstuvwxyz";
- public static final byte [] BINARY_DATA = getBinaryData();
- public static final String NAME_PREFIX = "testNode";
- public static final int BIG_FACTOR = 15;
- public static final byte [] BIG_DATA = bigData(BINARY_DATA, BIG_FACTOR);
- private int counter;
-
- private void assertStream(InputStream expected, InputStream actual) {
- int offset = 0;
- try {
- while(true) {
- final int exp = expected.read();
- if(exp == -1) {
- assertEquals("Expecting end of actual stream at offset " + offset, -1, actual.read());
- break;
- } else {
- final int act = actual.read();
- assertEquals("Expecting same data at offset " + offset, exp, act);
- }
- offset++;
- }
- } catch(Exception e) {
- fail("Exception at offset " + offset + ": " + e);
- }
- }
-
- public void testAsciiWriteAndRead() throws Exception {
- final Node testNode = getTestRootNode().addNode(NAME_PREFIX + counter++);
- testNode.getSession().save();
- final NodeOutputStream nos = new NodeOutputStream(testNode);
- nos.write(ASCII_DATA.getBytes());
- nos.close();
- final NodeInputStream nis = new NodeInputStream(testNode);
- assertStream(new ByteArrayInputStream(ASCII_DATA.getBytes()), nis);
- }
-
- public void testBinaryWriteAndRead() throws Exception {
- final Node testNode = getTestRootNode().addNode(NAME_PREFIX + counter++);
- testNode.getSession().save();
- final NodeOutputStream nos = new NodeOutputStream(testNode);
- nos.write(BINARY_DATA);
- nos.close();
- final NodeInputStream nis = new NodeInputStream(testNode);
- assertStream(new ByteArrayInputStream(BINARY_DATA), nis);
- }
-
- public void testBigBinaryWriteAndRead() throws Exception {
- final Node testNode = getTestRootNode().addNode(NAME_PREFIX + counter++);
- testNode.getSession().save();
- final NodeOutputStream nos = new NodeOutputStream(testNode);
- nos.write(BIG_DATA);
- nos.close();
-
- assertFalse("Expecting no pending changes in testNode session", testNode.getSession().hasPendingChanges());
-
- final NodeInputStream nis = new NodeInputStream(testNode);
- assertStream(new ByteArrayInputStream(BIG_DATA), nis);
- }
-
- public void testMultipleBinaryWrites() throws Exception {
- final Node testNode = getTestRootNode().addNode(NAME_PREFIX + counter++);
- testNode.getSession().save();
- final NodeOutputStream nos = new NodeOutputStream(testNode);
- for(int i=0; i < BIG_FACTOR; i++) {
- nos.write(BINARY_DATA);
- }
- nos.close();
-
- assertFalse("Expecting no pending changes in testNode session", testNode.getSession().hasPendingChanges());
-
- // Stream must be stored in a hierarchy under testNode, to
- // avoid limitations if flush() is called many times
- final int childCount = getChildCount(testNode);
- final int expect = 10;
- assertTrue("Expecting > " + expect + " child nodes under testNode, got " + childCount, childCount > expect);
-
- final NodeInputStream nis = new NodeInputStream(testNode);
- assertStream(new ByteArrayInputStream(BIG_DATA), nis);
- }
-
- private int getChildCount(Node n) throws RepositoryException {
- int result = 0;
- final NodeIterator it = n.getNodes();
- while(it.hasNext()) {
- result++;
- final Node kid = it.nextNode();
- result += getChildCount(kid);
- }
- return result;
- }
-
- public void testWriteWithOffset() throws Exception {
- final Node testNode = getTestRootNode().addNode(NAME_PREFIX + counter++);
- testNode.getSession().save();
-
- final NodeOutputStream nos = new NodeOutputStream(testNode);
- int offset = 0;
- int step = 1271;
- while(offset < BIG_DATA.length && step > 0) {
- step = Math.min(step, BIG_DATA.length - offset);
- nos.write(BIG_DATA, offset, step);
- offset += step;
- }
- nos.close();
-
- final NodeInputStream nis = new NodeInputStream(testNode);
- assertStream(new ByteArrayInputStream(BIG_DATA), nis);
- }
-
- public void testChunkedRead() throws Exception {
- final Node testNode = getTestRootNode().addNode(NAME_PREFIX + counter++);
- testNode.getSession().save();
-
- final NodeOutputStream nos = new NodeOutputStream(testNode);
- try {
- nos.write(BIG_DATA);
- } finally {
- nos.close();
- }
-
- final ByteArrayOutputStream actual = new ByteArrayOutputStream(BIG_DATA.length);
- final byte [] buffer = new byte[7432];
- final NodeInputStream nis = new NodeInputStream(testNode);
- try {
- int count = 0;
- while((count = nis.read(buffer, 0, buffer.length)) > 0) {
- actual.write(buffer, 0, count);
- }
- } finally {
- nis.close();
- }
-
- assertStream(new ByteArrayInputStream(BIG_DATA), new ByteArrayInputStream(actual.toByteArray()));
- }
-
- private static byte[] bigData(byte [] data, int multiplier) {
- final byte [] result = new byte[data.length * multiplier];
- int destPos = 0;
- for(int i=0; i < multiplier; i++) {
- System.arraycopy(data, 0, result, destPos, data.length);
- destPos += data.length;
- }
- return result;
- }
-
- private static byte [] getBinaryData() {
- final ByteArrayOutputStream os = new ByteArrayOutputStream();
- final Random random = new Random();
- for(int i=0;i < 66000; i++) {
- os.write(random.nextInt());
- }
- return os.toByteArray();
- }
-}
diff --git a/engine/src/test/java/org/apache/sling/bgservlets/impl/storage/JobStorageImplTest.java b/engine/src/test/java/org/apache/sling/bgservlets/impl/storage/JobStorageImplTest.java
deleted file mode 100644
index a6ae984..0000000
--- a/engine/src/test/java/org/apache/sling/bgservlets/impl/storage/JobStorageImplTest.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * 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 static org.junit.Assert.fail;
-
-import java.util.Hashtable;
-import java.util.UUID;
-import java.util.regex.Pattern;
-
-import junitx.util.PrivateAccessor;
-
-import org.apache.sling.settings.SlingSettingsService;
-import org.jmock.Expectations;
-import org.jmock.Mockery;
-import org.junit.Before;
-import org.junit.Test;
-import org.osgi.service.component.ComponentContext;
-
-public class JobStorageImplTest {
- private JobStorageImpl storage;
- private final Mockery mockery = new Mockery();
- private final String instanceId = UUID.randomUUID().toString();
-
- @Before
- public void setup() throws NoSuchFieldException {
- storage = new JobStorageImpl();
-
- final Hashtable<String, Object> props = new Hashtable<String, Object>();
- props.put("job.storage.path", "/var/test");
-
- final ComponentContext ctx = mockery.mock(ComponentContext.class);
- mockery.checking(new Expectations() {{
- allowing(ctx).getProperties();
- will(returnValue(props));
- }});
-
- final SlingSettingsService sss = mockery.mock(SlingSettingsService.class);
- mockery.checking(new Expectations() {{
- allowing(sss).getSlingId();
- will(returnValue(instanceId));
- }});
-
- PrivateAccessor.setField(storage, "slingSettings", sss);
- storage.activate(ctx);
- }
-
- private void assertPath(String regex, String actual) {
- if(!Pattern.compile(regex).matcher(actual).matches()) {
- fail("Path " + actual + " does not match expected regex " + regex);
- }
- }
-
- @Test
- public void testNextPath() {
- for(int i=1 ; i<10; i++) {
- assertPath("/var/test/" + instanceId + "/2.*/" + i + "$", storage.getNextPath());
- }
- }
-}
\ No newline at end of file