You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by bd...@apache.org on 2016/02/23 16:45:12 UTC
svn commit: r1731890 - in /sling/trunk/contrib/extensions/bgservlets:
engine/ engine/src/main/java/org/apache/sling/bgservlets/impl/
engine/src/main/java/org/apache/sling/bgservlets/impl/servlets/
engine/src/main/resources/OSGI-INF/metatype/ engine/src...
Author: bdelacretaz
Date: Tue Feb 23 15:45:12 2016
New Revision: 1731890
URL: http://svn.apache.org/viewvc?rev=1731890&view=rev
Log:
SLING-5553 - Start background servlet jobs for POST, PUT and DELETE only by default
Added:
sling/trunk/contrib/extensions/bgservlets/engine/src/test/java/org/apache/sling/bgservlets/impl/BackgroundServletStarterFilterTest.java
Modified:
sling/trunk/contrib/extensions/bgservlets/engine/pom.xml
sling/trunk/contrib/extensions/bgservlets/engine/src/main/java/org/apache/sling/bgservlets/impl/BackgroundServletStarterFilter.java
sling/trunk/contrib/extensions/bgservlets/engine/src/main/java/org/apache/sling/bgservlets/impl/servlets/BackgroundTestServlet.java
sling/trunk/contrib/extensions/bgservlets/engine/src/main/resources/OSGI-INF/metatype/metatype.properties
sling/trunk/contrib/extensions/bgservlets/testing/src/main/provisioning/test-model.txt
sling/trunk/contrib/extensions/bgservlets/testing/src/test/java/org/apache/sling/bgservlets/it/BackgroundRequestIT.java
sling/trunk/contrib/extensions/bgservlets/testing/src/test/java/org/apache/sling/bgservlets/it/JobConsoleIT.java
Modified: sling/trunk/contrib/extensions/bgservlets/engine/pom.xml
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/bgservlets/engine/pom.xml?rev=1731890&r1=1731889&r2=1731890&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/bgservlets/engine/pom.xml (original)
+++ sling/trunk/contrib/extensions/bgservlets/engine/pom.xml Tue Feb 23 15:45:12 2016
@@ -112,6 +112,11 @@
</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>
Modified: sling/trunk/contrib/extensions/bgservlets/engine/src/main/java/org/apache/sling/bgservlets/impl/BackgroundServletStarterFilter.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/bgservlets/engine/src/main/java/org/apache/sling/bgservlets/impl/BackgroundServletStarterFilter.java?rev=1731890&r1=1731889&r2=1731890&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/bgservlets/engine/src/main/java/org/apache/sling/bgservlets/impl/BackgroundServletStarterFilter.java (original)
+++ sling/trunk/contrib/extensions/bgservlets/engine/src/main/java/org/apache/sling/bgservlets/impl/BackgroundServletStarterFilter.java Tue Feb 23 15:45:12 2016
@@ -19,6 +19,9 @@
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;
@@ -37,6 +40,7 @@ import org.apache.felix.scr.annotations.
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;
@@ -67,25 +71,56 @@ public class BackgroundServletStarterFil
@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="sling:bg")
+ @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 = (String)ctx.getProperties().get(PROP_BG_PARAM);
- if(bgParamName == null || bgParamName.length() == 0) {
- throw new IllegalStateException("Missing " + PROP_BG_PARAM + " in ComponentContext");
+ 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", bgParamName);
+
+ 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 {
@@ -102,8 +137,7 @@ public class BackgroundServletStarterFil
final SlingHttpServletRequest slingRequest =
(request instanceof SlingHttpServletRequest ? (SlingHttpServletRequest) request : null);
final HttpServletResponse response = (HttpServletResponse) sresp;
- final String bgParam = sreq.getParameter(bgParamName);
- if (Boolean.valueOf(bgParam)) {
+ if (startBackgroundRequest(request)) {
try {
final BackgroundRequestExecutionJob job = new BackgroundRequestExecutionJob(
slingRequestProcessor, jobStorage, slingRequest, response,
Modified: sling/trunk/contrib/extensions/bgservlets/engine/src/main/java/org/apache/sling/bgservlets/impl/servlets/BackgroundTestServlet.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/bgservlets/engine/src/main/java/org/apache/sling/bgservlets/impl/servlets/BackgroundTestServlet.java?rev=1731890&r1=1731889&r2=1731890&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/bgservlets/engine/src/main/java/org/apache/sling/bgservlets/impl/servlets/BackgroundTestServlet.java (original)
+++ sling/trunk/contrib/extensions/bgservlets/engine/src/main/java/org/apache/sling/bgservlets/impl/servlets/BackgroundTestServlet.java Tue Feb 23 15:45:12 2016
@@ -29,7 +29,7 @@ import org.apache.felix.scr.annotations.
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.api.servlets.SlingAllMethodsServlet;
import org.apache.sling.bgservlets.RuntimeState;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -42,11 +42,18 @@ import org.slf4j.LoggerFactory;
@Service
@SuppressWarnings("serial")
@Property(name = "sling.servlet.paths", value = "/system/bgservlets/test")
-public class BackgroundTestServlet extends SlingSafeMethodsServlet {
+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 {
@@ -92,7 +99,7 @@ public class BackgroundTestServlet exten
w.println("All done.");
w.flush();
} catch (Throwable t) {
- log.info("Exception in doGet", t);
+ log.info("Exception in service method", t);
}
}
Modified: sling/trunk/contrib/extensions/bgservlets/engine/src/main/resources/OSGI-INF/metatype/metatype.properties
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/bgservlets/engine/src/main/resources/OSGI-INF/metatype/metatype.properties?rev=1731890&r1=1731889&r2=1731890&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/bgservlets/engine/src/main/resources/OSGI-INF/metatype/metatype.properties (original)
+++ sling/trunk/contrib/extensions/bgservlets/engine/src/main/resources/OSGI-INF/metatype/metatype.properties Tue Feb 23 15:45:12 2016
@@ -57,4 +57,9 @@ max.pool.size.name = Maximum ThreadPoolE
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.
\ No newline at end of file
+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
Added: sling/trunk/contrib/extensions/bgservlets/engine/src/test/java/org/apache/sling/bgservlets/impl/BackgroundServletStarterFilterTest.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/bgservlets/engine/src/test/java/org/apache/sling/bgservlets/impl/BackgroundServletStarterFilterTest.java?rev=1731890&view=auto
==============================================================================
--- sling/trunk/contrib/extensions/bgservlets/engine/src/test/java/org/apache/sling/bgservlets/impl/BackgroundServletStarterFilterTest.java (added)
+++ sling/trunk/contrib/extensions/bgservlets/engine/src/test/java/org/apache/sling/bgservlets/impl/BackgroundServletStarterFilterTest.java Tue Feb 23 15:45:12 2016
@@ -0,0 +1,92 @@
+/*
+ * 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
Modified: sling/trunk/contrib/extensions/bgservlets/testing/src/main/provisioning/test-model.txt
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/bgservlets/testing/src/main/provisioning/test-model.txt?rev=1731890&r1=1731889&r2=1731890&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/bgservlets/testing/src/main/provisioning/test-model.txt (original)
+++ sling/trunk/contrib/extensions/bgservlets/testing/src/main/provisioning/test-model.txt Tue Feb 23 15:45:12 2016
@@ -20,7 +20,8 @@
# Dependencies
[artifacts]
org.apache.sling/org.apache.sling.launchpad/8/slingstart
- org.apache.sling/org.apache.sling.bgservlets/1.0.3-SNAPSHOT
+ org.apache.sling/org.apache.sling.extensions.webconsolesecurityprovider/1.1.6
+ org.apache.sling/org.apache.sling.bgservlets/1.0.5-SNAPSHOT
# additional configuration for testing
[configurations]
Modified: sling/trunk/contrib/extensions/bgservlets/testing/src/test/java/org/apache/sling/bgservlets/it/BackgroundRequestIT.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/bgservlets/testing/src/test/java/org/apache/sling/bgservlets/it/BackgroundRequestIT.java?rev=1731890&r1=1731889&r2=1731890&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/bgservlets/testing/src/test/java/org/apache/sling/bgservlets/it/BackgroundRequestIT.java (original)
+++ sling/trunk/contrib/extensions/bgservlets/testing/src/test/java/org/apache/sling/bgservlets/it/BackgroundRequestIT.java Tue Feb 23 15:45:12 2016
@@ -63,10 +63,15 @@ public class BackgroundRequestIT {
}
@Test
+ public void testGetRequestFails() throws IOException,InterruptedException, JSONException {
+ T.assertHttpStatus(HttpTest.HTTP_BASE_URL + "/tmp.json?sling:bg=true", 500);
+ }
+
+ @Test
public void testTmpRequestCreatesJob() throws IOException,InterruptedException, JSONException {
final int initialJobs = countStoredJobs();
- T.getContent(HttpTest.HTTP_BASE_URL + "/tmp.json?sling:bg=true", "application/json");
-
+ T.assertPostStatus(HttpTest.HTTP_BASE_URL + "/tmp.json?sling:bg=true", 302, null, null);
+
// Request must have created a job
final long timeout = System.currentTimeMillis() + 10000L;
while(true) {
Modified: sling/trunk/contrib/extensions/bgservlets/testing/src/test/java/org/apache/sling/bgservlets/it/JobConsoleIT.java
URL: http://svn.apache.org/viewvc/sling/trunk/contrib/extensions/bgservlets/testing/src/test/java/org/apache/sling/bgservlets/it/JobConsoleIT.java?rev=1731890&r1=1731889&r2=1731890&view=diff
==============================================================================
--- sling/trunk/contrib/extensions/bgservlets/testing/src/test/java/org/apache/sling/bgservlets/it/JobConsoleIT.java (original)
+++ sling/trunk/contrib/extensions/bgservlets/testing/src/test/java/org/apache/sling/bgservlets/it/JobConsoleIT.java Tue Feb 23 15:45:12 2016
@@ -23,7 +23,6 @@ import static org.junit.Assert.fail;
import java.io.IOException;
import java.util.regex.Pattern;
-import org.apache.sling.commons.json.JSONException;
import org.apache.sling.commons.testing.integration.HttpTest;
import org.junit.Before;
import org.junit.Test;
@@ -38,9 +37,9 @@ public class JobConsoleIT {
}
@Test
- public void testJobConsoleOutput() throws IOException,InterruptedException, JSONException {
+ public void testJobConsoleOutput() throws IOException,InterruptedException {
// Create a job
- T.getContent(HttpTest.HTTP_BASE_URL + "/tmp.json?sling:bg=true", "application/json");
+ T.assertPostStatus(HttpTest.HTTP_BASE_URL + "/tmp.json?sling:bg=true", 302, null, null);
// Request must have created a job
final long timeout = System.currentTimeMillis() + 10000L;