You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by ro...@apache.org on 2017/10/18 23:25:35 UTC

[sling-org-apache-sling-startupfilter] branch master created (now 05de94c)

This is an automated email from the ASF dual-hosted git repository.

rombert pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-startupfilter.git.


      at 05de94c  SLING-7167 Adjust READMEs

This branch includes the following new commits:

     new 4d59e92  SLING-2347 - startup filter module, rejects requests with a 503 status during startup
     new ef6663b  SLING-2347 - use whiteboard pattern with StartupInfoProvider services
     new f75a947  SLING-2347 - startup filter disabler bundle added
     new cddef7a  SLING-2347 - set filter.order so that it runs first
     new 47adaa0  SLING-2347 - use response.setStatus to avoid triggering the container's error pages during startup
     new eb38504  Use latest parent pom in all projects
     new 3eb416b  Use latest parent pom everywhere
     new 23e1d12  SLING-2601 - more robust mechanism for disabling StartupFilter, based on the presence of a disabling service
     new 9e2aa62  Use latest releases and update to new parent pom
     new 2c27d8f  Update to latest parent pom and use latest releases in launchpad
     new b0d8006  Correct reactor pom and update to parent pom 16
     new 9064c6d  SLING-3119 - setup startup filter as a plain Filter instead of a Sling one. Contributed by Ben Peter, thanks!
     new d28e5d6  SLING-3119 - log filter pattern when activated
     new 60e2369  SLING-3119 - handle path-based bypass in doFilter instead of using regexp
     new 4608bde  SLING-4698 - Set parent.relativePath to empty for all modules
     new b11cf5d  Update to parent pom 28 and move to http whiteboard
     new bb29724  SLING-6100 - avoid NPE in StartupFilterImpl
     new cc0cc68  SLING-6141 : StartupFilter should use servlet path and request info
     new a01c0aa  use Sling Parent 30
     new 9781a60  add missing Felix SCR annotations
     new 05de94c  SLING-7167 Adjust READMEs

The 21 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


-- 
To stop receiving notification emails like this one, please contact
['"commits@sling.apache.org" <co...@sling.apache.org>'].

[sling-org-apache-sling-startupfilter] 14/21: SLING-3119 - handle path-based bypass in doFilter instead of using regexp

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-startupfilter.git

commit 60e23690d9fbd0fb0e73067c2ea3f25bbd4da8d0
Author: Bertrand Delacretaz <bd...@apache.org>
AuthorDate: Fri Sep 27 14:03:28 2013 +0000

    SLING-3119 - handle path-based bypass in doFilter instead of using regexp
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1526908 13f79535-47bb-0310-9956-ffa450edef68
---
 .../startupfilter/impl/StartupFilterImpl.java      | 15 ++++++++--
 .../startupfilter/impl/StartupFilterImplTest.java  | 32 +++++++++++++++++++++-
 2 files changed, 44 insertions(+), 3 deletions(-)

diff --git a/src/main/java/org/apache/sling/startupfilter/impl/StartupFilterImpl.java b/src/main/java/org/apache/sling/startupfilter/impl/StartupFilterImpl.java
index aeb88a2..1bfba9b 100644
--- a/src/main/java/org/apache/sling/startupfilter/impl/StartupFilterImpl.java
+++ b/src/main/java/org/apache/sling/startupfilter/impl/StartupFilterImpl.java
@@ -29,6 +29,7 @@ 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.Activate;
@@ -95,6 +96,16 @@ public class StartupFilterImpl implements StartupFilter, Filter {
             return;
         }
         
+        // Bypass for the managerRoot path
+        if(request instanceof HttpServletRequest) {
+            final String pathInfo = ((HttpServletRequest)request).getPathInfo();
+            if(managerRoot != null && managerRoot.length() > 0 && pathInfo.startsWith(managerRoot)) {
+                log.debug("Bypassing filter for path {} which starts with {}", pathInfo, managerRoot);
+                chain.doFilter(request, sr);
+                return;
+            }
+        }
+        
         updateProviders();
         
         final StringBuilder sb = new StringBuilder();
@@ -165,7 +176,7 @@ public class StartupFilterImpl implements StartupFilter, Filter {
         if(defaultFilterActive) {
             enable();
         }
-        log.info("Activated, enabled={}", isEnabled());
+        log.info("Activated, enabled={}, managerRoot={}", isEnabled(), managerRoot);
     }
     
     @Deactivate
@@ -179,7 +190,7 @@ public class StartupFilterImpl implements StartupFilter, Filter {
     
     public synchronized void enable() {
         if(filterServiceRegistration == null) {
-            final String pattern = "^(?!"+ managerRoot +")(.+)";
+            final String pattern = "/";
             final Hashtable<String, Object> params = new Hashtable<String, Object>();
             params.put(Constants.SERVICE_RANKING, 0x9000); // run before RequestLoggerFilter (0x8000)
             params.put("filter.scope", "REQUEST");
diff --git a/src/test/java/org/apache/sling/startupfilter/impl/StartupFilterImplTest.java b/src/test/java/org/apache/sling/startupfilter/impl/StartupFilterImplTest.java
index 9fd25c2..fb80d66 100644
--- a/src/test/java/org/apache/sling/startupfilter/impl/StartupFilterImplTest.java
+++ b/src/test/java/org/apache/sling/startupfilter/impl/StartupFilterImplTest.java
@@ -28,6 +28,8 @@ import java.util.concurrent.atomic.AtomicInteger;
 
 import javax.servlet.Filter;
 import javax.servlet.FilterChain;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
@@ -121,6 +123,8 @@ public class StartupFilterImplTest {
     private StringWriter messageWriter;
     private AtomicInteger activeFilterCount;
     private ServiceRegistration serviceRegistration;
+    private String requestPath;
+    private static final String CONSOLE_ROOT = "/test/system/console";
 
     @Before
     public void setup() {
@@ -131,6 +135,7 @@ public class StartupFilterImplTest {
         chain = mockery.mock(FilterChain.class);
         serviceRegistration = mockery.mock(ServiceRegistration.class);
         filter = new TestFilterImpl();
+        requestPath = "/NO_PATH_YET";
     }
     
     private void setProvider(final TestProvider provider) throws Exception {
@@ -170,7 +175,9 @@ public class StartupFilterImplTest {
             will(returnValue(providerRefs));
             allowing(bundleContext).getService(with(any(ServiceReference.class)));
             will(returnValue(provider));
-            allowing(bundleContext).getProperty(with(any(String.class)));
+            
+            allowing(bundleContext).getProperty(with("felix.webconsole.manager.root"));
+            will(returnValue(CONSOLE_ROOT));
 
             allowing(bundleContext).registerService(with(Filter.class.getName()), with(any(Object.class)), with(any(Dictionary.class)));
             will(new DoAllAction(
@@ -189,11 +196,20 @@ public class StartupFilterImplTest {
             
             allowing(serviceRegistration).unregister();
             will(new ChangeInteger(activeFilterCount, false));
+            
+            allowing(request).getPathInfo();
+            will(returnValue(getRequestPath()));
+            
+            allowing(chain).doFilter(with(any(ServletRequest.class)), with(any(ServletResponse.class)));
         }});
         
         filter.setup(componentContext);
     }
     
+    private String getRequestPath() {
+        return requestPath;
+    }
+    
     private void assertRequest(final int expectedStatus, final String expectedMessage) throws Exception {
         lastReturnedStatus = -1;
         
@@ -216,6 +232,20 @@ public class StartupFilterImplTest {
     }
 
     @Test
+    public void testBypassRoot() throws Exception {
+        requestPath = CONSOLE_ROOT;
+        setProvider(null);
+        assertRequest(-1, "");
+    }
+
+    @Test
+    public void testBypassSubpath() throws Exception {
+        requestPath = CONSOLE_ROOT + "/something";
+        setProvider(null);
+        assertRequest(-1, "");
+    }
+
+    @Test
     public void testDisabling() throws Exception {
         setProvider(null);
         assertEquals("Initially expecting one filter service", 1, activeFilterCount.get());

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-startupfilter] 07/21: Use latest parent pom everywhere

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-startupfilter.git

commit 3eb416b295c86aa55a4a6eaba136ca3d3ad4b89d
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Wed Aug 1 13:53:43 2012 +0000

    Use latest parent pom everywhere
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1367998 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pom.xml b/pom.xml
index 8cb7491..e00789b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -21,7 +21,7 @@
   <parent>
     <groupId>org.apache.sling</groupId>
     <artifactId>sling</artifactId>
-    <version>12</version>
+    <version>13</version>
     <relativePath>../../../parent/pom.xml</relativePath>
   </parent>
 

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-startupfilter] 21/21: SLING-7167 Adjust READMEs

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-startupfilter.git

commit 05de94c0921ff6c5e4b23ef044cad81fd432ffcf
Author: Oliver Lietz <ol...@apache.org>
AuthorDate: Tue Oct 3 09:30:37 2017 +0000

    SLING-7167 Adjust READMEs
    
    add missing README
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1810746 13f79535-47bb-0310-9956-ffa450edef68
---
 README.md | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/README.md b/README.md
new file mode 100644
index 0000000..326cad2
--- /dev/null
+++ b/README.md
@@ -0,0 +1,3 @@
+# Apache Sling Startup Filter
+
+This module is part of the [Apache Sling](https://sling.apache.org) project.

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-startupfilter] 15/21: SLING-4698 - Set parent.relativePath to empty for all modules

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-startupfilter.git

commit 4608bdec23856afb4e3a0c2958f8e3b88d5effa4
Author: Robert Munteanu <ro...@apache.org>
AuthorDate: Thu May 7 10:14:40 2015 +0000

    SLING-4698 - Set parent.relativePath to empty for all modules
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1678154 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pom.xml b/pom.xml
index e0a1265..eecd0cf 100644
--- a/pom.xml
+++ b/pom.xml
@@ -22,7 +22,7 @@
     <groupId>org.apache.sling</groupId>
     <artifactId>sling</artifactId>
     <version>16</version>
-    <relativePath>../../../parent/pom.xml</relativePath>
+    <relativePath/>
   </parent>
 
   <artifactId>org.apache.sling.startupfilter</artifactId>

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-startupfilter] 18/21: SLING-6141 : StartupFilter should use servlet path and request info

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-startupfilter.git

commit cc0cc6892e29893c830b6bb621a1616113cc1d35
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Wed Oct 12 14:49:27 2016 +0000

    SLING-6141 : StartupFilter should use servlet path and request info
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1764477 13f79535-47bb-0310-9956-ffa450edef68
---
 .../org/apache/sling/startupfilter/impl/StartupFilterImpl.java     | 7 ++++---
 .../org/apache/sling/startupfilter/impl/StartupFilterImplTest.java | 7 +++----
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/src/main/java/org/apache/sling/startupfilter/impl/StartupFilterImpl.java b/src/main/java/org/apache/sling/startupfilter/impl/StartupFilterImpl.java
index d0b367d..f6e126c 100644
--- a/src/main/java/org/apache/sling/startupfilter/impl/StartupFilterImpl.java
+++ b/src/main/java/org/apache/sling/startupfilter/impl/StartupFilterImpl.java
@@ -100,9 +100,10 @@ public class StartupFilterImpl implements StartupFilter, Filter {
 
         // Bypass for the managerRoot path
         if(request instanceof HttpServletRequest) {
-            final String pathInfo = ((HttpServletRequest)request).getPathInfo();
-            if(managerRoot != null && managerRoot.length() > 0 && pathInfo != null && pathInfo.startsWith(managerRoot)) {
-                log.debug("Bypassing filter for path {} which starts with {}", pathInfo, managerRoot);
+            final HttpServletRequest req = (HttpServletRequest)request;
+            final String path = req.getServletPath() + (req.getPathInfo() == null ? "" : req.getPathInfo());
+            if (managerRoot != null && managerRoot.length() > 0 && path.startsWith(managerRoot)) {
+                log.debug("Bypassing filter for path {} which starts with {}", path, managerRoot);
                 chain.doFilter(request, sr);
                 return;
             }
diff --git a/src/test/java/org/apache/sling/startupfilter/impl/StartupFilterImplTest.java b/src/test/java/org/apache/sling/startupfilter/impl/StartupFilterImplTest.java
index 7745cad..58d7f6c 100644
--- a/src/test/java/org/apache/sling/startupfilter/impl/StartupFilterImplTest.java
+++ b/src/test/java/org/apache/sling/startupfilter/impl/StartupFilterImplTest.java
@@ -202,6 +202,9 @@ public class StartupFilterImplTest {
             allowing(serviceRegistration).unregister();
             will(new ChangeInteger(activeFilterCount, false));
 
+            allowing(request).getServletPath();
+            will(returnValue(""));
+
             allowing(request).getPathInfo();
             will(returnValue(getPathInfo()));
 
@@ -211,10 +214,6 @@ public class StartupFilterImplTest {
         filter.setup(bundleContext, props);
     }
 
-    private String getRequestPath() {
-        return requestPath;
-    }
-
     private String getPathInfo() {
         return pathInfo;
     }

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-startupfilter] 04/21: SLING-2347 - set filter.order so that it runs first

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-startupfilter.git

commit cddef7a3d9c0c31f09a45d9068ed597c6fbeba8b
Author: Bertrand Delacretaz <bd...@apache.org>
AuthorDate: Fri Jan 6 22:17:04 2012 +0000

    SLING-2347 - set filter.order so that it runs first
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1228464 13f79535-47bb-0310-9956-ffa450edef68
---
 .../java/org/apache/sling/startupfilter/impl/StartupFilterImpl.java  | 5 +++--
 1 file changed, 3 insertions(+), 2 deletions(-)

diff --git a/src/main/java/org/apache/sling/startupfilter/impl/StartupFilterImpl.java b/src/main/java/org/apache/sling/startupfilter/impl/StartupFilterImpl.java
index 66f4beb..149fc84 100644
--- a/src/main/java/org/apache/sling/startupfilter/impl/StartupFilterImpl.java
+++ b/src/main/java/org/apache/sling/startupfilter/impl/StartupFilterImpl.java
@@ -145,8 +145,9 @@ public class StartupFilterImpl implements StartupFilter, Filter {
     
     public synchronized void enable() {
         if(filterServiceRegistration == null) {
-            final Hashtable<String, String> params = new Hashtable<String, String>();
+            final Hashtable<String, Object> params = new Hashtable<String, Object>();
             params.put("filter.scope", "REQUEST");
+            params.put("filter.order", Integer.MIN_VALUE);
             filterServiceRegistration = bundleContext.registerService(Filter.class.getName(), this, params);
             log.info("Registered {} as a Filter service", this);
         }
@@ -163,4 +164,4 @@ public class StartupFilterImpl implements StartupFilter, Filter {
     public synchronized boolean isEnabled() {
         return filterServiceRegistration != null;
     }
-}
\ No newline at end of file
+}

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-startupfilter] 02/21: SLING-2347 - use whiteboard pattern with StartupInfoProvider services

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-startupfilter.git

commit ef6663bd3e2ddb374263f09e8c8e8c053b1fde4d
Author: Bertrand Delacretaz <bd...@apache.org>
AuthorDate: Wed Jan 4 16:27:39 2012 +0000

    SLING-2347 - use whiteboard pattern with StartupInfoProvider services
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1227210 13f79535-47bb-0310-9956-ffa450edef68
---
 .../apache/sling/startupfilter/StartupFilter.java  |  39 ++-----
 .../sling/startupfilter/StartupInfoProvider.java   |  26 +++++
 .../startupfilter/impl/StartupFilterImpl.java      |  97 ++++++++++------
 .../OSGI-INF/metatype/metatype.properties          |   9 +-
 .../startupfilter/impl/StartupFilterImplTest.java  | 127 +++++++++++----------
 5 files changed, 175 insertions(+), 123 deletions(-)

diff --git a/src/main/java/org/apache/sling/startupfilter/StartupFilter.java b/src/main/java/org/apache/sling/startupfilter/StartupFilter.java
index 4878e09..d84faec 100644
--- a/src/main/java/org/apache/sling/startupfilter/StartupFilter.java
+++ b/src/main/java/org/apache/sling/startupfilter/StartupFilter.java
@@ -29,36 +29,17 @@ package org.apache.sling.startupfilter;
  */
 public interface StartupFilter {
     
-    String DEFAULT_STATUS_MESSAGE = "Startup in progress";
-    
-    /** Clients can supply objects implementing this
-     *  interface, to have the filter respond to HTTP
-     *  requests with the supplied information message.
-     */
-    public interface ProgressInfoProvider {
-        String getInfo();
-    }
-    
-    /** This ProgressInfoProvider is active by default, it 
-     *  must be removed for the filter to let requests pass through.
+    /** Enable the status filter, which outputs a default status message
+     *  and a concatenation of all status messages returned
+     *  by {@link StartupInfoProvider} services.
+     *  
+     *  The filter is initially enabled.   
      */
-    public static ProgressInfoProvider DEFAULT_INFO_PROVIDER = new ProgressInfoProvider() {
-        @Override
-        public String toString() {
-            return "Default ProgressInfoProvider";
-        }
-        public String getInfo() { 
-            return DEFAULT_STATUS_MESSAGE;
-        }
-    };
+    void enable();
     
-    /** Activate the supplied ProgressInfoProvider */
-    public void addProgressInfoProvider(ProgressInfoProvider pip);
+    /** Disable the status filter */
+    void disable();
     
-    /** Deactivate the supplied ProgressInfoProvider if it was
-     *  currently active.
-     *  Once all such providers are removed, the filter disables
-     *  itself and lets requests pass through.
-     */
-    public void removeProgressInfoProvider(ProgressInfoProvider pip);
+    /** True if currently enabled */
+    boolean isEnabled();
 }
\ No newline at end of file
diff --git a/src/main/java/org/apache/sling/startupfilter/StartupInfoProvider.java b/src/main/java/org/apache/sling/startupfilter/StartupInfoProvider.java
new file mode 100644
index 0000000..e4baf85
--- /dev/null
+++ b/src/main/java/org/apache/sling/startupfilter/StartupInfoProvider.java
@@ -0,0 +1,26 @@
+/*
+ * 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.startupfilter;
+
+public interface StartupInfoProvider {
+    /** Return startup progress information, which the startup
+     *  filter adds to its HTTP 503 response.  
+     */
+    String getProgressInfo();
+}
diff --git a/src/main/java/org/apache/sling/startupfilter/impl/StartupFilterImpl.java b/src/main/java/org/apache/sling/startupfilter/impl/StartupFilterImpl.java
index 5baeb6a..35f503e 100644
--- a/src/main/java/org/apache/sling/startupfilter/impl/StartupFilterImpl.java
+++ b/src/main/java/org/apache/sling/startupfilter/impl/StartupFilterImpl.java
@@ -19,8 +19,9 @@
 package org.apache.sling.startupfilter.impl;
 
 import java.io.IOException;
+import java.util.ArrayList;
 import java.util.Hashtable;
-import java.util.Stack;
+import java.util.List;
 
 import javax.servlet.Filter;
 import javax.servlet.FilterChain;
@@ -36,9 +37,12 @@ import org.apache.felix.scr.annotations.Deactivate;
 import org.apache.felix.scr.annotations.Property;
 import org.apache.felix.scr.annotations.Service;
 import org.apache.sling.startupfilter.StartupFilter;
+import org.apache.sling.startupfilter.StartupInfoProvider;
 import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
 import org.osgi.framework.ServiceRegistration;
 import org.osgi.service.component.ComponentContext;
+import org.osgi.util.tracker.ServiceTracker;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -52,25 +56,32 @@ public class StartupFilterImpl implements StartupFilter, Filter {
     private final Logger log = LoggerFactory.getLogger(getClass());
     private ServiceRegistration filterServiceRegistration;
     private BundleContext bundleContext;
-    private final Stack<ProgressInfoProvider> providers = new Stack<ProgressInfoProvider>();
+    private ServiceTracker providersTracker;
+    private int providersTrackerCount = -1;
+    
+    private final List<StartupInfoProvider> providers = new ArrayList<StartupInfoProvider>();
     
     @Property(boolValue=true)
-    public static final String DEFAULT_FILTER_ACTIVE_PROP = "default.filter.active";
+    public static final String ACTIVE_BY_DEFAULT_PROP = "active.by.default";
     private boolean defaultFilterActive;
     
+    public static final String DEFAULT_MESSAGE = "Startup in progress";
+    
+    @Property(value=DEFAULT_MESSAGE)
+    public static final String DEFAULT_MESSAGE_PROP = "default.message";
+    private String defaultMessage;
+    
     /** @inheritDoc */
     public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
-        ProgressInfoProvider pip = null;
-        synchronized (this) {
-            if(!providers.isEmpty()) {
-                pip = providers.peek();
-            }
-        }
-        if(pip != null) {
-            ((HttpServletResponse)response).sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE, pip.getInfo());
-        } else {
-            chain.doFilter(request, response);
+        updateProviders();
+        
+        final StringBuilder sb = new StringBuilder();
+        sb.append(defaultMessage);
+        for(StartupInfoProvider p : providers) {
+            sb.append('\n');
+            sb.append(p.getProgressInfo());
         }
+        ((HttpServletResponse)response).sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE, sb.toString());
     }
 
     /** @inheritDoc */
@@ -80,28 +91,54 @@ public class StartupFilterImpl implements StartupFilter, Filter {
     /** @inheritDoc */
     public void init(FilterConfig cfg) throws ServletException {
     }
+    
+    /** If needed, update our list of providers */
+    private void updateProviders() {
+        if(providersTracker.getTrackingCount() != providersTrackerCount) {
+            synchronized(this) {
+                if(providersTracker.getTrackingCount() != providersTrackerCount) {
+                    providers.clear();
+                    final ServiceReference [] refs = providersTracker.getServiceReferences();
+                    if(refs != null) {
+                        for(ServiceReference ref : refs) {
+                            providers.add((StartupInfoProvider)bundleContext.getService(ref));
+                        }
+                    }
+                }
+                providersTrackerCount = providersTracker.getTrackingCount();
+                log.info("Reloaded list of StartupInfoProvider: {}", providers);
+            }
+        }
+    }
 
     @Activate
     protected void activate(ComponentContext ctx) throws InterruptedException {
         bundleContext = ctx.getBundleContext();
-        defaultFilterActive = (Boolean)ctx.getProperties().get(DEFAULT_FILTER_ACTIVE_PROP);
+        
+        providersTracker = new ServiceTracker(bundleContext, StartupInfoProvider.class.getName(), null);
+        providersTracker.open();
+        
+        Object prop = ctx.getProperties().get(DEFAULT_MESSAGE_PROP);
+        defaultMessage = prop == null ? DEFAULT_MESSAGE : prop.toString();
+                
+        prop = ctx.getProperties().get(ACTIVE_BY_DEFAULT_PROP);
+        defaultFilterActive = (prop instanceof Boolean ? (Boolean)prop : false);
         if(defaultFilterActive) {
-            addProgressInfoProvider(DEFAULT_INFO_PROVIDER);
+            enable();
         }
-        log.info("Activated, defaultFilterActive={}", defaultFilterActive);
+        log.info("Activated, enabled={}", isEnabled());
     }
     
     @Deactivate
     protected void deactivate(ComponentContext ctx) throws InterruptedException {
-        unregisterFilter();
+        disable();
+        providersTracker.close();
+        providersTracker = null;
         bundleContext = null;
     }
     
     
-    /** @inheritDoc */
-    public synchronized void addProgressInfoProvider(ProgressInfoProvider pip) {
-        providers.push(pip);
-        log.info("Added {}", pip);
+    public synchronized void enable() {
         if(filterServiceRegistration == null) {
             final Hashtable<String, String> params = new Hashtable<String, String>();
             params.put("filter.scope", "REQUEST");
@@ -110,21 +147,15 @@ public class StartupFilterImpl implements StartupFilter, Filter {
         }
     }
     
-    /** @inheritDoc */
-    public synchronized void removeProgressInfoProvider(ProgressInfoProvider pip) {
-        providers.remove(pip);
-        log.info("Removed {}", pip);
-        if(providers.isEmpty()) {
-            log.info("No more ProgressInfoProviders, unregistering Filter service");
-            unregisterFilter();
-        }
-    }
-    
-    private synchronized void unregisterFilter() {
+    public synchronized void disable() {
         if(filterServiceRegistration != null) {
             filterServiceRegistration.unregister();
             filterServiceRegistration = null;
+            log.info("Filter service disabled");
         }
     }
-     
+    
+    public synchronized boolean isEnabled() {
+        return filterServiceRegistration != null;
+    }
 }
\ No newline at end of file
diff --git a/src/main/resources/OSGI-INF/metatype/metatype.properties b/src/main/resources/OSGI-INF/metatype/metatype.properties
index 7df6cfd..2e04d0f 100644
--- a/src/main/resources/OSGI-INF/metatype/metatype.properties
+++ b/src/main/resources/OSGI-INF/metatype/metatype.properties
@@ -27,6 +27,11 @@ org.apache.sling.startupfilter.impl.StartupFilterImpl.name=Sling Startup Filter
 org.apache.sling.startupfilter.impl.StartupFilterImpl.description=Rejects Sling requests \
   with a 503 error code during startup.
 
-default.filter.active.name=Default filter active?
-default.filter.active.description=If true, the filter is active as \
+active.by.default.name=Active by default?
+active.by.default.description=If true, the filter is active as \
   soon as the service starts.
+  
+default.message.name=Default message
+default.message.description=The default message is returned in the \
+  HTTP response of the filter, followed by any messages supplied \
+  by StartupInfoProvider services.
diff --git a/src/test/java/org/apache/sling/startupfilter/impl/StartupFilterImplTest.java b/src/test/java/org/apache/sling/startupfilter/impl/StartupFilterImplTest.java
index 5cd85b5..7d89f90 100644
--- a/src/test/java/org/apache/sling/startupfilter/impl/StartupFilterImplTest.java
+++ b/src/test/java/org/apache/sling/startupfilter/impl/StartupFilterImplTest.java
@@ -29,7 +29,7 @@ import javax.servlet.FilterChain;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
-import org.apache.sling.startupfilter.StartupFilter;
+import org.apache.sling.startupfilter.StartupInfoProvider;
 import org.hamcrest.Description;
 import org.jmock.Expectations;
 import org.jmock.Mockery;
@@ -38,24 +38,50 @@ import org.jmock.api.Invocation;
 import org.jmock.lib.action.DoAllAction;
 import org.junit.Before;
 import org.junit.Test;
+import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceListener;
+import org.osgi.framework.ServiceReference;
 import org.osgi.framework.ServiceRegistration;
 import org.osgi.service.component.ComponentContext;
 
 /** Test the StartupFilterImpl */
 public class StartupFilterImplTest {
-    static private class TestPip implements StartupFilter.ProgressInfoProvider {
-        String info;
+    static private class TestProvider implements StartupInfoProvider, ServiceReference {
+        private final String info;
         
-        TestPip(String s) {
+        TestProvider(String s) {
             info = s;
         }
         
-        public String getInfo() {
+        public String getProgressInfo() {
             return info;
         }
-    };
-    
+
+        public Object getProperty(String key) {
+            return null;
+        }
+
+        public String[] getPropertyKeys() {
+            return null;
+        }
+
+        public Bundle getBundle() {
+            return null;
+        }
+
+        public Bundle[] getUsingBundles() {
+            return null;
+        }
+
+        public boolean isAssignableTo(Bundle bundle, String className) {
+            return false;
+        }
+
+        public int compareTo(Object reference) {
+            return 0;
+        }
+    }
     static private class TestFilterImpl extends StartupFilterImpl {
         void setup(ComponentContext ctx) throws Exception {
             activate(ctx);
@@ -89,24 +115,25 @@ public class StartupFilterImplTest {
     private HttpServletRequest request; 
     private HttpServletResponse response;
     private FilterChain chain;
-    private AtomicInteger doChainCount;
     private int lastReturnedStatus;
     private String lastReturnedMessage;
     private AtomicInteger activeFilterCount;
     private ServiceRegistration serviceRegistration;
 
     @Before
-    public void setup() throws Exception {
-        doChainCount = new AtomicInteger();
+    public void setup() {
         activeFilterCount = new AtomicInteger();
         mockery = new Mockery();
-        final BundleContext bundleContext = mockery.mock(BundleContext.class); 
-        final ComponentContext componentContext = mockery.mock(ComponentContext.class); 
         request = mockery.mock(HttpServletRequest.class); 
         response = mockery.mock(HttpServletResponse.class);
         chain = mockery.mock(FilterChain.class);
         serviceRegistration = mockery.mock(ServiceRegistration.class);
         filter = new TestFilterImpl();
+    }
+    
+    private void setProvider(final TestProvider provider) throws Exception {
+        final BundleContext bundleContext = mockery.mock(BundleContext.class); 
+        final ComponentContext componentContext = mockery.mock(ComponentContext.class); 
         
         final Action storeResponse = new Action() {
             public void describeTo(Description d) {
@@ -121,8 +148,9 @@ public class StartupFilterImplTest {
         };
         
         final Dictionary<String, Object> props = new Hashtable<String, Object>();
-        props.put("default.filter.active", Boolean.TRUE);
+        props.put(StartupFilterImpl.ACTIVE_BY_DEFAULT_PROP, Boolean.TRUE);
         
+        final ServiceReference [] providerRefs = provider == null ? null : new ServiceReference[] { provider };
         mockery.checking(new Expectations() {{
             allowing(componentContext).getBundleContext();
             will(returnValue(bundleContext));
@@ -130,15 +158,21 @@ public class StartupFilterImplTest {
             allowing(componentContext).getProperties();
             will(returnValue(props));
             
+            allowing(bundleContext).createFilter(with(any(String.class)));
+            allowing(bundleContext).addServiceListener(with(any(ServiceListener.class)));
+            allowing(bundleContext).addServiceListener(with(any(ServiceListener.class)), with(any(String.class)));
+            
+            allowing(bundleContext).getServiceReferences(StartupInfoProvider.class.getName(), null);
+            will(returnValue(providerRefs));
+            allowing(bundleContext).getService(with(any(ServiceReference.class)));
+            will(returnValue(provider));
+            
             allowing(bundleContext).registerService(with(Filter.class.getName()), with(any(Object.class)), with(any(Dictionary.class)));
             will(new DoAllAction(
                     new ChangeInteger(activeFilterCount, true),
                     returnValue(serviceRegistration)
                     ));
             
-            allowing(chain).doFilter(request, response);
-            will(new ChangeInteger(doChainCount, true));
-            
             allowing(response).sendError(with(any(Integer.class)), with(any(String.class)));
             will(storeResponse);
             
@@ -152,67 +186,42 @@ public class StartupFilterImplTest {
     private void assertRequest(final int expectedStatus, final String expectedMessage) throws Exception {
         lastReturnedMessage = null;
         lastReturnedStatus = -1;
-        final int oldDoChainCount = doChainCount.get();
         
         filter.doFilter(request, response, chain);
         
         // status 0 means we expect the request to go through
-        if(expectedStatus == 0) {
-            assertEquals("Expecting doChain to have been be called once", 
-                    1, doChainCount.get() - oldDoChainCount);
-        } else {
-            assertEquals("Expecting status to match", 
-                    expectedStatus, lastReturnedStatus);
-            assertEquals("Expecting message to match", 
-                    expectedMessage, lastReturnedMessage);
-        }
+        assertEquals("Expecting status to match", 
+                expectedStatus, lastReturnedStatus);
+        assertEquals("Expecting message to match", 
+                expectedMessage, lastReturnedMessage);
     }
     
     @Test
     public void testInitialState() throws Exception {
-        assertEquals("Initially expecting one filter service", 1, activeFilterCount.get());
-        assertRequest(503, StartupFilter.DEFAULT_STATUS_MESSAGE);
+        setProvider(null);
+        assertEquals("Initially expecting the default status message", 1, activeFilterCount.get());
+        assertRequest(503, StartupFilterImpl.DEFAULT_MESSAGE);
     }
-    
+
     @Test
-    public void testDefaultFilterRemoved() throws Exception {
+    public void testDisabling() throws Exception {
+        setProvider(null);
         assertEquals("Initially expecting one filter service", 1, activeFilterCount.get());
-        filter.removeProgressInfoProvider(StartupFilter.DEFAULT_INFO_PROVIDER);
+        filter.disable();
         assertEquals("Expecting filter service to be gone", 0, activeFilterCount.get());
-        assertRequest(0, null);
     }
-    
+
     @Test
-    public void testSeveralProviders() throws Exception {
-        final StartupFilter.ProgressInfoProvider [] pips = {
-                new TestPip("one"),
-                new TestPip("two"),
-                new TestPip("three"),
-        };
+    public void testProviders() throws Exception {
+        final TestProvider p = new TestProvider("TEST");
         
+        setProvider(p);
         assertEquals("Initially expecting one filter service", 1, activeFilterCount.get());
         
-        // Last added provider must be active
-        for(StartupFilter.ProgressInfoProvider pip : pips) {
-            filter.addProgressInfoProvider(pip);
-            assertRequest(503, pip.getInfo());
-        }
-        
-        assertEquals("After adding several providers, expecting one filter service", 1, activeFilterCount.get());
-        
-        // When removing a provider the previous one becomes active
-        for(int i = pips.length - 1; i >= 0; i--) {
-            assertRequest(503, pips[i].getInfo());
-            filter.removeProgressInfoProvider(pips[i]);
-        }
-
-        // After removing all, default is active again
-        assertEquals("After removing providers, expecting one filter service", 1, activeFilterCount.get());
-        assertRequest(503, StartupFilter.DEFAULT_STATUS_MESSAGE);
+        final String expectedMessage = StartupFilterImpl.DEFAULT_MESSAGE + "\nTEST";
+        assertRequest(503, expectedMessage);
 
-        // Now remove default and check
-        filter.removeProgressInfoProvider(StartupFilter.DEFAULT_INFO_PROVIDER);
-        assertRequest(0, null);
+        filter.disable();
         assertEquals("Expecting filter service to be gone", 0, activeFilterCount.get());
     }
 }

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-startupfilter] 16/21: Update to parent pom 28 and move to http whiteboard

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-startupfilter.git

commit b11cf5d5b89aa9b704566cc09dea191c2a701b1e
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Wed Aug 31 08:23:44 2016 +0000

    Update to parent pom 28 and move to http whiteboard
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1758544 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml                                            | 147 ++++++++++-----------
 .../apache/sling/startupfilter/StartupFilter.java  |  17 ++-
 .../sling/startupfilter/StartupFilterDisabler.java |   3 +
 .../sling/startupfilter/StartupInfoProvider.java   |   5 +-
 .../startupfilter/impl/StartupFilterImpl.java      |  89 +++++++------
 ...tartupFilterDisabler.java => package-info.java} |   8 +-
 .../OSGI-INF/metatype/metatype.properties          |   2 +-
 .../startupfilter/impl/StartupFilterImplTest.java  |  94 ++++++-------
 8 files changed, 191 insertions(+), 174 deletions(-)

diff --git a/pom.xml b/pom.xml
index eecd0cf..edfd37d 100644
--- a/pom.xml
+++ b/pom.xml
@@ -17,85 +17,80 @@
 <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>16</version>
-    <relativePath/>
-  </parent>
+    <modelVersion>4.0.0</modelVersion>
+    <parent>
+        <groupId>org.apache.sling</groupId>
+        <artifactId>sling</artifactId>
+        <version>28</version>
+        <relativePath/>
+    </parent>
 
-  <artifactId>org.apache.sling.startupfilter</artifactId>
-  <version>0.0.1-SNAPSHOT</version>
-  <packaging>bundle</packaging>
+    <artifactId>org.apache.sling.startupfilter</artifactId>
+    <version>0.0.1-SNAPSHOT</version>
+    <packaging>bundle</packaging>
 
-  <name>Apache Sling Startup Filter</name>
-  <description> 
-    Servlet Filter that blocks access to Sling
-    while starting up.
-  </description>
+    <name>Apache Sling Startup Filter</name>
+    <description> 
+        Servlet Filter that blocks access to Sling while starting up.
+    </description>
 
-  <scm>
-    <connection>scm:svn:http://svn.apache.org/repos/asf/sling/trunk/contrib/extensions/startup-filter</connection>
-    <developerConnection>scm:svn:http://svn.apache.org/repos/asf/sling/trunk/contrib/extensions/startup-filter</developerConnection>
-    <url>http://svn.apache.org/repos/asf/sling/trunk/contrib/extensions/startup-filter</url>
-  </scm>
+    <scm>
+        <connection>scm:svn:http://svn.apache.org/repos/asf/sling/trunk/contrib/extensions/startup-filter</connection>
+        <developerConnection>scm:svn:http://svn.apache.org/repos/asf/sling/trunk/contrib/extensions/startup-filter</developerConnection>
+        <url>http://svn.apache.org/repos/asf/sling/trunk/contrib/extensions/startup-filter</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.startupfilter</Export-Package>
-            <Private-Package>org.apache.sling.startupfilter.impl.*</Private-Package>
-          </instructions>
-        </configuration>
-      </plugin>
-    </plugins>
-  </build>
+    <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>
+                        <Require-Capability>
+                            osgi.implementation;filter:="(&amp;(osgi.implementation=osgi.http)(version=1.0))"
+                        </Require-Capability>
+                    </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>javax.servlet</groupId>
-      <artifactId>servlet-api</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.slf4j</groupId>
-      <artifactId>slf4j-api</artifactId>
-    </dependency>
-    <dependency>
-      <groupId>org.slf4j</groupId>
-      <artifactId>slf4j-simple</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-      <groupId>junit</groupId>
-      <artifactId>junit</artifactId>
-      <scope>test</scope>
-    </dependency>
-    <dependency>
-        <groupId>org.jmock</groupId>
-        <artifactId>jmock-junit4</artifactId>
-        <scope>test</scope>
-    </dependency>
-  </dependencies>
+    <dependencies>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>osgi.core</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.osgi</groupId>
+            <artifactId>org.osgi.service.http.whiteboard</artifactId>
+            <version>1.0.0</version>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
+            <groupId>javax.servlet</groupId>
+            <artifactId>javax.servlet-api</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.slf4j</groupId>
+            <artifactId>slf4j-api</artifactId>
+        </dependency>
+        <dependency>
+           <groupId>org.slf4j</groupId>
+           <artifactId>slf4j-simple</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>junit</groupId>
+            <artifactId>junit</artifactId>
+        </dependency>
+        <dependency>
+            <groupId>org.jmock</groupId>
+            <artifactId>jmock-junit4</artifactId>
+        </dependency>
+    </dependencies>
 </project>
\ No newline at end of file
diff --git a/src/main/java/org/apache/sling/startupfilter/StartupFilter.java b/src/main/java/org/apache/sling/startupfilter/StartupFilter.java
index d84faec..93c5e3d 100644
--- a/src/main/java/org/apache/sling/startupfilter/StartupFilter.java
+++ b/src/main/java/org/apache/sling/startupfilter/StartupFilter.java
@@ -18,28 +18,31 @@
  */
 package org.apache.sling.startupfilter;
 
-/** Servlet Filter that blocks access to the Sling main 
+import org.osgi.annotation.versioning.ProviderType;
+
+/** Servlet Filter that blocks access to the Sling main
  *  servlet during startup, by returning an HTTP 503
  *  or other suitable status code.
- *  
+ *
  *  A typical use case is to start this filter before
  *  the Sling main servlet (by setting a lower start level
  *  on its bundle than on the Sling engine bundle), and
  *  deactivating once startup is finished.
  */
+@ProviderType
 public interface StartupFilter {
-    
+
     /** Enable the status filter, which outputs a default status message
      *  and a concatenation of all status messages returned
      *  by {@link StartupInfoProvider} services.
-     *  
-     *  The filter is initially enabled.   
+     *
+     *  The filter is initially enabled.
      */
     void enable();
-    
+
     /** Disable the status filter */
     void disable();
-    
+
     /** True if currently enabled */
     boolean isEnabled();
 }
\ No newline at end of file
diff --git a/src/main/java/org/apache/sling/startupfilter/StartupFilterDisabler.java b/src/main/java/org/apache/sling/startupfilter/StartupFilterDisabler.java
index 6cfd0f7..f44c90a 100644
--- a/src/main/java/org/apache/sling/startupfilter/StartupFilterDisabler.java
+++ b/src/main/java/org/apache/sling/startupfilter/StartupFilterDisabler.java
@@ -18,6 +18,9 @@
  */
 package org.apache.sling.startupfilter;
 
+import org.osgi.annotation.versioning.ConsumerType;
+
+@ConsumerType
 public interface StartupFilterDisabler {
     /** Indicate why the StartupFilter should be disabled */
     String getReason();
diff --git a/src/main/java/org/apache/sling/startupfilter/StartupInfoProvider.java b/src/main/java/org/apache/sling/startupfilter/StartupInfoProvider.java
index e4baf85..c1279e1 100644
--- a/src/main/java/org/apache/sling/startupfilter/StartupInfoProvider.java
+++ b/src/main/java/org/apache/sling/startupfilter/StartupInfoProvider.java
@@ -18,9 +18,12 @@
  */
 package org.apache.sling.startupfilter;
 
+import org.osgi.annotation.versioning.ConsumerType;
+
+@ConsumerType
 public interface StartupInfoProvider {
     /** Return startup progress information, which the startup
-     *  filter adds to its HTTP 503 response.  
+     *  filter adds to its HTTP 503 response.
      */
     String getProgressInfo();
 }
diff --git a/src/main/java/org/apache/sling/startupfilter/impl/StartupFilterImpl.java b/src/main/java/org/apache/sling/startupfilter/impl/StartupFilterImpl.java
index 1bfba9b..6f850ff 100644
--- a/src/main/java/org/apache/sling/startupfilter/impl/StartupFilterImpl.java
+++ b/src/main/java/org/apache/sling/startupfilter/impl/StartupFilterImpl.java
@@ -22,6 +22,7 @@ import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Hashtable;
 import java.util.List;
+import java.util.Map;
 
 import javax.servlet.Filter;
 import javax.servlet.FilterChain;
@@ -47,7 +48,7 @@ import org.osgi.framework.BundleContext;
 import org.osgi.framework.Constants;
 import org.osgi.framework.ServiceReference;
 import org.osgi.framework.ServiceRegistration;
-import org.osgi.service.component.ComponentContext;
+import org.osgi.service.http.whiteboard.HttpWhiteboardConstants;
 import org.osgi.util.tracker.ServiceTracker;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -60,42 +61,43 @@ import org.slf4j.LoggerFactory;
 public class StartupFilterImpl implements StartupFilter, Filter {
 
     private final Logger log = LoggerFactory.getLogger(getClass());
-    private ServiceRegistration filterServiceRegistration;
+    private ServiceRegistration<Filter> filterServiceRegistration;
     private BundleContext bundleContext;
-    private ServiceTracker providersTracker;
+    private ServiceTracker<StartupInfoProvider, StartupInfoProvider> providersTracker;
     private int providersTrackerCount = -1;
-    
+
     private final List<StartupInfoProvider> providers = new ArrayList<StartupInfoProvider>();
-    
+
     @Property(boolValue=true)
     public static final String ACTIVE_BY_DEFAULT_PROP = "active.by.default";
     private boolean defaultFilterActive;
-    
+
     public static final String DEFAULT_MESSAGE = "Startup in progress";
-    
+
     @Property(value=DEFAULT_MESSAGE)
     public static final String DEFAULT_MESSAGE_PROP = "default.message";
     private String defaultMessage;
 
     @Reference(cardinality=ReferenceCardinality.OPTIONAL_UNARY, policy=ReferencePolicy.DYNAMIC)
-    private StartupFilterDisabler startupFilterDisabler;
+    private volatile StartupFilterDisabler startupFilterDisabler;
 
     private static final String FRAMEWORK_PROP_MANAGER_ROOT = "felix.webconsole.manager.root";
     static final String DEFAULT_MANAGER_ROOT = "/system/console";
     private String managerRoot;
-    
+
     /** @inheritDoc */
+    @Override
     public void doFilter(ServletRequest request, ServletResponse sr, FilterChain chain) throws IOException, ServletException {
-        
+
         // Disable if a StartupFilterDisabler is present
         if(startupFilterDisabler!= null) {
-            log.info("StartupFilterDisabler service present, disabling StartupFilter ({})", 
+            log.info("StartupFilterDisabler service present, disabling StartupFilter ({})",
                     startupFilterDisabler.getReason());
             disable();
             chain.doFilter(request, sr);
             return;
         }
-        
+
         // Bypass for the managerRoot path
         if(request instanceof HttpServletRequest) {
             final String pathInfo = ((HttpServletRequest)request).getPathInfo();
@@ -105,9 +107,9 @@ public class StartupFilterImpl implements StartupFilter, Filter {
                 return;
             }
         }
-        
+
         updateProviders();
-        
+
         final StringBuilder sb = new StringBuilder();
         sb.append(defaultMessage);
         for(StartupInfoProvider p : providers) {
@@ -124,30 +126,32 @@ public class StartupFilterImpl implements StartupFilter, Filter {
         response.getWriter().write(sb.toString());
         response.getWriter().flush();
     }
-    
+
     @Override
     public String toString() {
-        return getClass().getSimpleName() + ": " + (isEnabled() ? "enabled" : "disabled"); 
+        return getClass().getSimpleName() + ": " + (isEnabled() ? "enabled" : "disabled");
     }
 
     /** @inheritDoc */
+    @Override
     public void destroy() {
     }
 
     /** @inheritDoc */
+    @Override
     public void init(FilterConfig cfg) throws ServletException {
     }
-    
+
     /** If needed, update our list of providers */
     private void updateProviders() {
         if(providersTracker.getTrackingCount() != providersTrackerCount) {
             synchronized(this) {
                 if(providersTracker.getTrackingCount() != providersTrackerCount) {
                     providers.clear();
-                    final ServiceReference [] refs = providersTracker.getServiceReferences();
+                    final ServiceReference<StartupInfoProvider> [] refs = providersTracker.getServiceReferences();
                     if(refs != null) {
-                        for(ServiceReference ref : refs) {
-                            providers.add((StartupInfoProvider)bundleContext.getService(ref));
+                        for(ServiceReference<StartupInfoProvider> ref : refs) {
+                            providers.add(bundleContext.getService(ref));
                         }
                     }
                 }
@@ -158,16 +162,16 @@ public class StartupFilterImpl implements StartupFilter, Filter {
     }
 
     @Activate
-    protected void activate(ComponentContext ctx) throws InterruptedException {
-        bundleContext = ctx.getBundleContext();
-        
-        providersTracker = new ServiceTracker(bundleContext, StartupInfoProvider.class.getName(), null);
+    protected void activate(final BundleContext ctx, final Map<String, Object> properties) throws InterruptedException {
+        bundleContext = ctx;
+
+        providersTracker = new ServiceTracker(bundleContext, StartupInfoProvider.class, null);
         providersTracker.open();
-        
-        Object prop = ctx.getProperties().get(DEFAULT_MESSAGE_PROP);
+
+        Object prop = properties.get(DEFAULT_MESSAGE_PROP);
         defaultMessage = prop == null ? DEFAULT_MESSAGE : prop.toString();
-                
-        prop = ctx.getProperties().get(ACTIVE_BY_DEFAULT_PROP);
+
+        prop = properties.get(ACTIVE_BY_DEFAULT_PROP);
         defaultFilterActive = (prop instanceof Boolean ? (Boolean)prop : false);
 
         prop = bundleContext.getProperty(FRAMEWORK_PROP_MANAGER_ROOT);
@@ -178,36 +182,41 @@ public class StartupFilterImpl implements StartupFilter, Filter {
         }
         log.info("Activated, enabled={}, managerRoot={}", isEnabled(), managerRoot);
     }
-    
+
     @Deactivate
-    protected void deactivate(ComponentContext ctx) throws InterruptedException {
+    protected void deactivate() throws InterruptedException {
         disable();
         providersTracker.close();
         providersTracker = null;
         bundleContext = null;
     }
-    
-    
+
+
+    @Override
     public synchronized void enable() {
-        if(filterServiceRegistration == null) {
+        if (filterServiceRegistration == null) {
             final String pattern = "/";
             final Hashtable<String, Object> params = new Hashtable<String, Object>();
             params.put(Constants.SERVICE_RANKING, 0x9000); // run before RequestLoggerFilter (0x8000)
-            params.put("filter.scope", "REQUEST");
-            params.put("pattern", pattern);
-            filterServiceRegistration = bundleContext.registerService(Filter.class.getName(), this, params);
-            log.info("Registered {} as a Filter service with pattern {}", this, pattern);
+            params.put("sling.filter.scope", "REQUEST");
+            params.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_SELECT,
+                    "(" + HttpWhiteboardConstants.HTTP_WHITEBOARD_CONTEXT_NAME + "=*)");
+            params.put(HttpWhiteboardConstants.HTTP_WHITEBOARD_FILTER_PATTERN, pattern);
+            filterServiceRegistration = bundleContext.registerService(Filter.class, this, params);
+            log.info("Registered {} as a servlet filter service with pattern {}", this, pattern);
         }
     }
-    
+
+    @Override
     public synchronized void disable() {
-        if(filterServiceRegistration != null) {
+        if (filterServiceRegistration != null) {
             filterServiceRegistration.unregister();
             filterServiceRegistration = null;
             log.info("Filter service disabled");
         }
     }
-    
+
+    @Override
     public synchronized boolean isEnabled() {
         return filterServiceRegistration != null;
     }
diff --git a/src/main/java/org/apache/sling/startupfilter/StartupFilterDisabler.java b/src/main/java/org/apache/sling/startupfilter/package-info.java
similarity index 86%
copy from src/main/java/org/apache/sling/startupfilter/StartupFilterDisabler.java
copy to src/main/java/org/apache/sling/startupfilter/package-info.java
index 6cfd0f7..2177642 100644
--- a/src/main/java/org/apache/sling/startupfilter/StartupFilterDisabler.java
+++ b/src/main/java/org/apache/sling/startupfilter/package-info.java
@@ -16,9 +16,9 @@
  * specific language governing permissions and limitations
  * under the License.
  */
+
+@Version("1.0.0")
 package org.apache.sling.startupfilter;
 
-public interface StartupFilterDisabler {
-    /** Indicate why the StartupFilter should be disabled */
-    String getReason();
-}
+import org.osgi.annotation.versioning.Version;
+
diff --git a/src/main/resources/OSGI-INF/metatype/metatype.properties b/src/main/resources/OSGI-INF/metatype/metatype.properties
index 2e04d0f..5f9bcb2 100644
--- a/src/main/resources/OSGI-INF/metatype/metatype.properties
+++ b/src/main/resources/OSGI-INF/metatype/metatype.properties
@@ -23,7 +23,7 @@
 # descriptions as used in the metatype.xml descriptor generated by the
 # the Sling SCR plugin
 
-org.apache.sling.startupfilter.impl.StartupFilterImpl.name=Sling Startup Filter
+org.apache.sling.startupfilter.impl.StartupFilterImpl.name=Apache Sling Startup Filter
 org.apache.sling.startupfilter.impl.StartupFilterImpl.description=Rejects Sling requests \
   with a 503 error code during startup.
 
diff --git a/src/test/java/org/apache/sling/startupfilter/impl/StartupFilterImplTest.java b/src/test/java/org/apache/sling/startupfilter/impl/StartupFilterImplTest.java
index fb80d66..46a2c5c 100644
--- a/src/test/java/org/apache/sling/startupfilter/impl/StartupFilterImplTest.java
+++ b/src/test/java/org/apache/sling/startupfilter/impl/StartupFilterImplTest.java
@@ -23,7 +23,8 @@ import static org.junit.Assert.assertEquals;
 import java.io.PrintWriter;
 import java.io.StringWriter;
 import java.util.Dictionary;
-import java.util.Hashtable;
+import java.util.HashMap;
+import java.util.Map;
 import java.util.concurrent.atomic.AtomicInteger;
 
 import javax.servlet.Filter;
@@ -47,63 +48,71 @@ import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceListener;
 import org.osgi.framework.ServiceReference;
 import org.osgi.framework.ServiceRegistration;
-import org.osgi.service.component.ComponentContext;
 
 /** Test the StartupFilterImpl */
 public class StartupFilterImplTest {
     static private class TestProvider implements StartupInfoProvider, ServiceReference {
         private final String info;
-        
+
         TestProvider(String s) {
             info = s;
         }
-        
+
+        @Override
         public String getProgressInfo() {
             return info;
         }
 
+        @Override
         public Object getProperty(String key) {
             return null;
         }
 
+        @Override
         public String[] getPropertyKeys() {
             return null;
         }
 
+        @Override
         public Bundle getBundle() {
             return null;
         }
 
+        @Override
         public Bundle[] getUsingBundles() {
             return null;
         }
 
+        @Override
         public boolean isAssignableTo(Bundle bundle, String className) {
             return false;
         }
 
+        @Override
         public int compareTo(Object reference) {
             return 0;
         }
     }
     static private class TestFilterImpl extends StartupFilterImpl {
-        void setup(ComponentContext ctx) throws Exception {
-            activate(ctx);
+        void setup(BundleContext ctx, Map<String, Object> props) throws Exception {
+            activate(ctx, props);
         }
     };
-    
+
     static private class ChangeInteger implements Action {
         private final boolean increment;
         private final AtomicInteger value;
-        
+
         ChangeInteger(AtomicInteger value, boolean increment) {
             this.increment = increment;
             this.value = value;
         }
+        @Override
         public void describeTo(Description d) {
             d.appendText(increment ? "increment" : "decrement");
             d.appendText(" an integer");
         }
+        @Override
         public Object invoke(Invocation invocation) throws Throwable {
             if(increment) {
                 value.incrementAndGet();
@@ -116,7 +125,7 @@ public class StartupFilterImplTest {
 
     private TestFilterImpl filter;
     private Mockery mockery;
-    private HttpServletRequest request; 
+    private HttpServletRequest request;
     private HttpServletResponse response;
     private FilterChain chain;
     private int lastReturnedStatus;
@@ -130,23 +139,24 @@ public class StartupFilterImplTest {
     public void setup() {
         activeFilterCount = new AtomicInteger();
         mockery = new Mockery();
-        request = mockery.mock(HttpServletRequest.class); 
+        request = mockery.mock(HttpServletRequest.class);
         response = mockery.mock(HttpServletResponse.class);
         chain = mockery.mock(FilterChain.class);
         serviceRegistration = mockery.mock(ServiceRegistration.class);
         filter = new TestFilterImpl();
         requestPath = "/NO_PATH_YET";
     }
-    
+
     private void setProvider(final TestProvider provider) throws Exception {
-        final BundleContext bundleContext = mockery.mock(BundleContext.class); 
-        final ComponentContext componentContext = mockery.mock(ComponentContext.class); 
-        
+        final BundleContext bundleContext = mockery.mock(BundleContext.class);
+
         final Action storeStatus = new Action() {
+            @Override
             public void describeTo(Description d) {
                 d.appendText("Store HTTP response values");
             }
 
+            @Override
             public Object invoke(Invocation invocation) throws Throwable {
                 lastReturnedStatus = (Integer)invocation.getParameter(0);
                 return null;
@@ -154,76 +164,70 @@ public class StartupFilterImplTest {
         };
 
         messageWriter = new StringWriter();
-        final PrintWriter responseWriter = new PrintWriter(messageWriter); 
-        
-        final Dictionary<String, Object> props = new Hashtable<String, Object>();
+        final PrintWriter responseWriter = new PrintWriter(messageWriter);
+
+        final Map<String, Object> props = new HashMap<String, Object>();
         props.put(StartupFilterImpl.ACTIVE_BY_DEFAULT_PROP, Boolean.TRUE);
-        
+
         final ServiceReference [] providerRefs = provider == null ? null : new ServiceReference[] { provider };
         mockery.checking(new Expectations() {{
-            allowing(componentContext).getBundleContext();
-            will(returnValue(bundleContext));
-            
-            allowing(componentContext).getProperties();
-            will(returnValue(props));
-            
             allowing(bundleContext).createFilter(with(any(String.class)));
             allowing(bundleContext).addServiceListener(with(any(ServiceListener.class)));
             allowing(bundleContext).addServiceListener(with(any(ServiceListener.class)), with(any(String.class)));
-            
+
             allowing(bundleContext).getServiceReferences(StartupInfoProvider.class.getName(), null);
             will(returnValue(providerRefs));
             allowing(bundleContext).getService(with(any(ServiceReference.class)));
             will(returnValue(provider));
-            
+
             allowing(bundleContext).getProperty(with("felix.webconsole.manager.root"));
             will(returnValue(CONSOLE_ROOT));
 
-            allowing(bundleContext).registerService(with(Filter.class.getName()), with(any(Object.class)), with(any(Dictionary.class)));
+            allowing(bundleContext).registerService(with(equal(Filter.class)), with(any(Filter.class)), with(any(Dictionary.class)));
             will(new DoAllAction(
                     new ChangeInteger(activeFilterCount, true),
                     returnValue(serviceRegistration)
                     ));
-            
+
             allowing(response).setStatus((with(any(Integer.class))));
             will(storeStatus);
-            
+
             allowing(response).setContentType("text/plain");
-            
+
             allowing(response).getWriter();
             will(returnValue(responseWriter));
             allowing(response).setCharacterEncoding(with(any(String.class)));
-            
+
             allowing(serviceRegistration).unregister();
             will(new ChangeInteger(activeFilterCount, false));
-            
+
             allowing(request).getPathInfo();
             will(returnValue(getRequestPath()));
-            
+
             allowing(chain).doFilter(with(any(ServletRequest.class)), with(any(ServletResponse.class)));
         }});
-        
-        filter.setup(componentContext);
+
+        filter.setup(bundleContext, props);
     }
-    
+
     private String getRequestPath() {
         return requestPath;
     }
-    
+
     private void assertRequest(final int expectedStatus, final String expectedMessage) throws Exception {
         lastReturnedStatus = -1;
-        
+
         filter.doFilter(request, response, chain);
-        
+
         final String responseText = messageWriter.toString();
-        
+
         // status 0 means we expect the request to go through
-        assertEquals("Expecting status to match", 
+        assertEquals("Expecting status to match",
                 expectedStatus, lastReturnedStatus);
-        assertEquals("Expecting message to match", 
+        assertEquals("Expecting message to match",
                 expectedMessage, responseText);
     }
-    
+
     @Test
     public void testInitialState() throws Exception {
         setProvider(null);
@@ -256,10 +260,10 @@ public class StartupFilterImplTest {
     @Test
     public void testProviders() throws Exception {
         final TestProvider p = new TestProvider("TEST");
-        
+
         setProvider(p);
         assertEquals("Initially expecting one filter service", 1, activeFilterCount.get());
-        
+
         final String expectedMessage = StartupFilterImpl.DEFAULT_MESSAGE + "\nTEST";
         assertRequest(503, expectedMessage);
 

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-startupfilter] 06/21: Use latest parent pom in all projects

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-startupfilter.git

commit eb3850427c5505fa8b0aa3f9c66d5b1d30e3e8cd
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Tue Apr 3 11:15:41 2012 +0000

    Use latest parent pom in all projects
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1308819 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pom.xml b/pom.xml
index ec1451f..8cb7491 100644
--- a/pom.xml
+++ b/pom.xml
@@ -21,7 +21,7 @@
   <parent>
     <groupId>org.apache.sling</groupId>
     <artifactId>sling</artifactId>
-    <version>11</version>
+    <version>12</version>
     <relativePath>../../../parent/pom.xml</relativePath>
   </parent>
 

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-startupfilter] 20/21: add missing Felix SCR annotations

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-startupfilter.git

commit 9781a600937175179119053c59f2524fbccb6d38
Author: Oliver Lietz <ol...@apache.org>
AuthorDate: Mon Mar 6 19:33:36 2017 +0000

    add missing Felix SCR annotations
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1785747 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/pom.xml b/pom.xml
index 71e1de3..00b18c8 100644
--- a/pom.xml
+++ b/pom.xml
@@ -73,6 +73,11 @@
             <scope>provided</scope>
         </dependency>
         <dependency>
+            <groupId>org.apache.felix</groupId>
+            <artifactId>org.apache.felix.scr.annotations</artifactId>
+            <scope>provided</scope>
+        </dependency>
+        <dependency>
             <groupId>javax.servlet</groupId>
             <artifactId>javax.servlet-api</artifactId>
         </dependency>

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-startupfilter] 05/21: SLING-2347 - use response.setStatus to avoid triggering the container's error pages during startup

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-startupfilter.git

commit 47adaa0aab50a2acc95a7745b7a53b0f2c9c2d85
Author: Bertrand Delacretaz <bd...@apache.org>
AuthorDate: Mon Jan 9 15:05:56 2012 +0000

    SLING-2347 - use response.setStatus to avoid triggering the container's error pages during startup
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1229187 13f79535-47bb-0310-9956-ffa450edef68
---
 .../startupfilter/impl/StartupFilterImpl.java      | 12 ++++++++--
 .../startupfilter/impl/StartupFilterImplTest.java  | 27 +++++++++++++++-------
 2 files changed, 29 insertions(+), 10 deletions(-)

diff --git a/src/main/java/org/apache/sling/startupfilter/impl/StartupFilterImpl.java b/src/main/java/org/apache/sling/startupfilter/impl/StartupFilterImpl.java
index 149fc84..a26395f 100644
--- a/src/main/java/org/apache/sling/startupfilter/impl/StartupFilterImpl.java
+++ b/src/main/java/org/apache/sling/startupfilter/impl/StartupFilterImpl.java
@@ -72,7 +72,7 @@ public class StartupFilterImpl implements StartupFilter, Filter {
     private String defaultMessage;
     
     /** @inheritDoc */
-    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
+    public void doFilter(ServletRequest request, ServletResponse sr, FilterChain chain) throws IOException, ServletException {
         updateProviders();
         
         final StringBuilder sb = new StringBuilder();
@@ -81,7 +81,15 @@ public class StartupFilterImpl implements StartupFilter, Filter {
             sb.append('\n');
             sb.append(p.getProgressInfo());
         }
-        ((HttpServletResponse)response).sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE, sb.toString());
+
+        // Do not use setError to avoid triggering the container's error page,
+        // as that might cascade other errors during startup
+        final HttpServletResponse response = (HttpServletResponse)sr;
+        response.setStatus(HttpServletResponse.SC_SERVICE_UNAVAILABLE);
+        response.setContentType("text/plain");
+        response.setCharacterEncoding("UTF-8");
+        response.getWriter().write(sb.toString());
+        response.getWriter().flush();
     }
     
     @Override
diff --git a/src/test/java/org/apache/sling/startupfilter/impl/StartupFilterImplTest.java b/src/test/java/org/apache/sling/startupfilter/impl/StartupFilterImplTest.java
index 7d89f90..329dae8 100644
--- a/src/test/java/org/apache/sling/startupfilter/impl/StartupFilterImplTest.java
+++ b/src/test/java/org/apache/sling/startupfilter/impl/StartupFilterImplTest.java
@@ -20,6 +20,8 @@ package org.apache.sling.startupfilter.impl;
 
 import static org.junit.Assert.assertEquals;
 
+import java.io.PrintWriter;
+import java.io.StringWriter;
 import java.util.Dictionary;
 import java.util.Hashtable;
 import java.util.concurrent.atomic.AtomicInteger;
@@ -116,7 +118,7 @@ public class StartupFilterImplTest {
     private HttpServletResponse response;
     private FilterChain chain;
     private int lastReturnedStatus;
-    private String lastReturnedMessage;
+    private StringWriter messageWriter;
     private AtomicInteger activeFilterCount;
     private ServiceRegistration serviceRegistration;
 
@@ -135,17 +137,19 @@ public class StartupFilterImplTest {
         final BundleContext bundleContext = mockery.mock(BundleContext.class); 
         final ComponentContext componentContext = mockery.mock(ComponentContext.class); 
         
-        final Action storeResponse = new Action() {
+        final Action storeStatus = new Action() {
             public void describeTo(Description d) {
                 d.appendText("Store HTTP response values");
             }
 
             public Object invoke(Invocation invocation) throws Throwable {
                 lastReturnedStatus = (Integer)invocation.getParameter(0);
-                lastReturnedMessage = (String)invocation.getParameter(1);
                 return null;
             }
         };
+
+        messageWriter = new StringWriter();
+        final PrintWriter responseWriter = new PrintWriter(messageWriter); 
         
         final Dictionary<String, Object> props = new Hashtable<String, Object>();
         props.put(StartupFilterImpl.ACTIVE_BY_DEFAULT_PROP, Boolean.TRUE);
@@ -173,8 +177,14 @@ public class StartupFilterImplTest {
                     returnValue(serviceRegistration)
                     ));
             
-            allowing(response).sendError(with(any(Integer.class)), with(any(String.class)));
-            will(storeResponse);
+            allowing(response).setStatus((with(any(Integer.class))));
+            will(storeStatus);
+            
+            allowing(response).setContentType("text/plain");
+            
+            allowing(response).getWriter();
+            will(returnValue(responseWriter));
+            allowing(response).setCharacterEncoding(with(any(String.class)));
             
             allowing(serviceRegistration).unregister();
             will(new ChangeInteger(activeFilterCount, false));
@@ -184,16 +194,17 @@ public class StartupFilterImplTest {
     }
     
     private void assertRequest(final int expectedStatus, final String expectedMessage) throws Exception {
-        lastReturnedMessage = null;
         lastReturnedStatus = -1;
         
         filter.doFilter(request, response, chain);
         
+        final String responseText = messageWriter.toString();
+        
         // status 0 means we expect the request to go through
         assertEquals("Expecting status to match", 
                 expectedStatus, lastReturnedStatus);
         assertEquals("Expecting message to match", 
-                expectedMessage, lastReturnedMessage);
+                expectedMessage, responseText);
     }
     
     @Test
@@ -224,4 +235,4 @@ public class StartupFilterImplTest {
         filter.disable();
         assertEquals("Expecting filter service to be gone", 0, activeFilterCount.get());
     }
-}
+}
\ No newline at end of file

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-startupfilter] 11/21: Correct reactor pom and update to parent pom 16

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-startupfilter.git

commit b0d8006372fdac585b7e8215ce2d0b120e0e5ab9
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Sun May 5 14:38:24 2013 +0000

    Correct reactor pom and update to parent pom 16
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1479333 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pom.xml b/pom.xml
index 91583f1..e0a1265 100644
--- a/pom.xml
+++ b/pom.xml
@@ -21,7 +21,7 @@
   <parent>
     <groupId>org.apache.sling</groupId>
     <artifactId>sling</artifactId>
-    <version>15</version>
+    <version>16</version>
     <relativePath>../../../parent/pom.xml</relativePath>
   </parent>
 

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-startupfilter] 08/21: SLING-2601 - more robust mechanism for disabling StartupFilter, based on the presence of a disabling service

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-startupfilter.git

commit 23e1d12f28fa857f71b351478e4b831bb82f4747
Author: Bertrand Delacretaz <bd...@apache.org>
AuthorDate: Tue Sep 18 06:58:25 2012 +0000

    SLING-2601 - more robust mechanism for disabling StartupFilter, based on the presence of a disabling service
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1387008 13f79535-47bb-0310-9956-ffa450edef68
---
 .../sling/startupfilter/StartupFilterDisabler.java | 24 ++++++++++++++++++++++
 .../startupfilter/impl/StartupFilterImpl.java      | 17 +++++++++++++++
 2 files changed, 41 insertions(+)

diff --git a/src/main/java/org/apache/sling/startupfilter/StartupFilterDisabler.java b/src/main/java/org/apache/sling/startupfilter/StartupFilterDisabler.java
new file mode 100644
index 0000000..6cfd0f7
--- /dev/null
+++ b/src/main/java/org/apache/sling/startupfilter/StartupFilterDisabler.java
@@ -0,0 +1,24 @@
+/*
+ * 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.startupfilter;
+
+public interface StartupFilterDisabler {
+    /** Indicate why the StartupFilter should be disabled */
+    String getReason();
+}
diff --git a/src/main/java/org/apache/sling/startupfilter/impl/StartupFilterImpl.java b/src/main/java/org/apache/sling/startupfilter/impl/StartupFilterImpl.java
index a26395f..d1ed6dd 100644
--- a/src/main/java/org/apache/sling/startupfilter/impl/StartupFilterImpl.java
+++ b/src/main/java/org/apache/sling/startupfilter/impl/StartupFilterImpl.java
@@ -35,8 +35,12 @@ 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.ReferenceCardinality;
+import org.apache.felix.scr.annotations.ReferencePolicy;
 import org.apache.felix.scr.annotations.Service;
 import org.apache.sling.startupfilter.StartupFilter;
+import org.apache.sling.startupfilter.StartupFilterDisabler;
 import org.apache.sling.startupfilter.StartupInfoProvider;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.ServiceReference;
@@ -71,8 +75,21 @@ public class StartupFilterImpl implements StartupFilter, Filter {
     public static final String DEFAULT_MESSAGE_PROP = "default.message";
     private String defaultMessage;
     
+    @Reference(cardinality=ReferenceCardinality.OPTIONAL_UNARY, policy=ReferencePolicy.DYNAMIC)
+    private StartupFilterDisabler startupFilterDisabler;
+    
     /** @inheritDoc */
     public void doFilter(ServletRequest request, ServletResponse sr, FilterChain chain) throws IOException, ServletException {
+        
+        // Disable if a StartupFilterDisabler is present
+        if(startupFilterDisabler!= null) {
+            log.info("StartupFilterDisabler service present, disabling StartupFilter ({})", 
+                    startupFilterDisabler.getReason());
+            disable();
+            chain.doFilter(request, sr);
+            return;
+        }
+        
         updateProviders();
         
         final StringBuilder sb = new StringBuilder();

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-startupfilter] 10/21: Update to latest parent pom and use latest releases in launchpad

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-startupfilter.git

commit 2c27d8f2915d1072b1797fb6e48f6ad71fa6977d
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Mon Feb 18 08:38:52 2013 +0000

    Update to latest parent pom and use latest releases in launchpad
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1447147 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pom.xml b/pom.xml
index b5a05e2..91583f1 100644
--- a/pom.xml
+++ b/pom.xml
@@ -21,7 +21,7 @@
   <parent>
     <groupId>org.apache.sling</groupId>
     <artifactId>sling</artifactId>
-    <version>14</version>
+    <version>15</version>
     <relativePath>../../../parent/pom.xml</relativePath>
   </parent>
 

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-startupfilter] 13/21: SLING-3119 - log filter pattern when activated

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-startupfilter.git

commit d28e5d657f78cf5ce9f77eeff32992d0be848a65
Author: Bertrand Delacretaz <bd...@apache.org>
AuthorDate: Fri Sep 27 13:21:00 2013 +0000

    SLING-3119 - log filter pattern when activated
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1526893 13f79535-47bb-0310-9956-ffa450edef68
---
 .../org/apache/sling/startupfilter/impl/StartupFilterImpl.java     | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

diff --git a/src/main/java/org/apache/sling/startupfilter/impl/StartupFilterImpl.java b/src/main/java/org/apache/sling/startupfilter/impl/StartupFilterImpl.java
index a56cfb2..aeb88a2 100644
--- a/src/main/java/org/apache/sling/startupfilter/impl/StartupFilterImpl.java
+++ b/src/main/java/org/apache/sling/startupfilter/impl/StartupFilterImpl.java
@@ -79,7 +79,7 @@ public class StartupFilterImpl implements StartupFilter, Filter {
     @Reference(cardinality=ReferenceCardinality.OPTIONAL_UNARY, policy=ReferencePolicy.DYNAMIC)
     private StartupFilterDisabler startupFilterDisabler;
 
-    private final String FRAMEWORK_PROP_MANAGER_ROOT = "felix.webconsole.manager.root";
+    private static final String FRAMEWORK_PROP_MANAGER_ROOT = "felix.webconsole.manager.root";
     static final String DEFAULT_MANAGER_ROOT = "/system/console";
     private String managerRoot;
     
@@ -179,12 +179,13 @@ public class StartupFilterImpl implements StartupFilter, Filter {
     
     public synchronized void enable() {
         if(filterServiceRegistration == null) {
+            final String pattern = "^(?!"+ managerRoot +")(.+)";
             final Hashtable<String, Object> params = new Hashtable<String, Object>();
             params.put(Constants.SERVICE_RANKING, 0x9000); // run before RequestLoggerFilter (0x8000)
             params.put("filter.scope", "REQUEST");
-            params.put("pattern", "^(?!"+ managerRoot +")(.+)");
+            params.put("pattern", pattern);
             filterServiceRegistration = bundleContext.registerService(Filter.class.getName(), this, params);
-            log.info("Registered {} as a Filter service", this);
+            log.info("Registered {} as a Filter service with pattern {}", this, pattern);
         }
     }
     

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-startupfilter] 19/21: use Sling Parent 30

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-startupfilter.git

commit a01c0aa57cc3aee23ba882758d104fd2c600a426
Author: Oliver Lietz <ol...@apache.org>
AuthorDate: Mon Mar 6 10:31:22 2017 +0000

    use Sling Parent 30
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1785622 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/pom.xml b/pom.xml
index edfd37d..71e1de3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -21,7 +21,7 @@
     <parent>
         <groupId>org.apache.sling</groupId>
         <artifactId>sling</artifactId>
-        <version>28</version>
+        <version>30</version>
         <relativePath/>
     </parent>
 
@@ -93,4 +93,4 @@
             <artifactId>jmock-junit4</artifactId>
         </dependency>
     </dependencies>
-</project>
\ No newline at end of file
+</project>

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-startupfilter] 17/21: SLING-6100 - avoid NPE in StartupFilterImpl

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-startupfilter.git

commit bb2972447e71de1de65904e3e545300f237e3886
Author: Bertrand Delacretaz <bd...@apache.org>
AuthorDate: Wed Oct 5 10:56:58 2016 +0000

    SLING-6100 - avoid NPE in StartupFilterImpl
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1763407 13f79535-47bb-0310-9956-ffa450edef68
---
 .../sling/startupfilter/impl/StartupFilterImpl.java   |  2 +-
 .../startupfilter/impl/StartupFilterImplTest.java     | 19 ++++++++++++++++---
 2 files changed, 17 insertions(+), 4 deletions(-)

diff --git a/src/main/java/org/apache/sling/startupfilter/impl/StartupFilterImpl.java b/src/main/java/org/apache/sling/startupfilter/impl/StartupFilterImpl.java
index 6f850ff..d0b367d 100644
--- a/src/main/java/org/apache/sling/startupfilter/impl/StartupFilterImpl.java
+++ b/src/main/java/org/apache/sling/startupfilter/impl/StartupFilterImpl.java
@@ -101,7 +101,7 @@ public class StartupFilterImpl implements StartupFilter, Filter {
         // Bypass for the managerRoot path
         if(request instanceof HttpServletRequest) {
             final String pathInfo = ((HttpServletRequest)request).getPathInfo();
-            if(managerRoot != null && managerRoot.length() > 0 && pathInfo.startsWith(managerRoot)) {
+            if(managerRoot != null && managerRoot.length() > 0 && pathInfo != null && pathInfo.startsWith(managerRoot)) {
                 log.debug("Bypassing filter for path {} which starts with {}", pathInfo, managerRoot);
                 chain.doFilter(request, sr);
                 return;
diff --git a/src/test/java/org/apache/sling/startupfilter/impl/StartupFilterImplTest.java b/src/test/java/org/apache/sling/startupfilter/impl/StartupFilterImplTest.java
index 46a2c5c..7745cad 100644
--- a/src/test/java/org/apache/sling/startupfilter/impl/StartupFilterImplTest.java
+++ b/src/test/java/org/apache/sling/startupfilter/impl/StartupFilterImplTest.java
@@ -133,6 +133,7 @@ public class StartupFilterImplTest {
     private AtomicInteger activeFilterCount;
     private ServiceRegistration serviceRegistration;
     private String requestPath;
+    private String pathInfo;
     private static final String CONSOLE_ROOT = "/test/system/console";
 
     @Before
@@ -202,7 +203,7 @@ public class StartupFilterImplTest {
             will(new ChangeInteger(activeFilterCount, false));
 
             allowing(request).getPathInfo();
-            will(returnValue(getRequestPath()));
+            will(returnValue(getPathInfo()));
 
             allowing(chain).doFilter(with(any(ServletRequest.class)), with(any(ServletResponse.class)));
         }});
@@ -214,6 +215,10 @@ public class StartupFilterImplTest {
         return requestPath;
     }
 
+    private String getPathInfo() {
+        return pathInfo;
+    }
+
     private void assertRequest(final int expectedStatus, final String expectedMessage) throws Exception {
         lastReturnedStatus = -1;
 
@@ -237,14 +242,22 @@ public class StartupFilterImplTest {
 
     @Test
     public void testBypassRoot() throws Exception {
-        requestPath = CONSOLE_ROOT;
+        requestPath = pathInfo = CONSOLE_ROOT;
         setProvider(null);
         assertRequest(-1, "");
     }
 
     @Test
+    public void testNullPathInfo() throws Exception {
+        requestPath = pathInfo = CONSOLE_ROOT;
+        pathInfo = null;
+        setProvider(null);
+        assertRequest(503, "Startup in progress");
+    }
+
+    @Test
     public void testBypassSubpath() throws Exception {
-        requestPath = CONSOLE_ROOT + "/something";
+        requestPath = pathInfo = CONSOLE_ROOT + "/something";
         setProvider(null);
         assertRequest(-1, "");
     }

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-startupfilter] 03/21: SLING-2347 - startup filter disabler bundle added

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-startupfilter.git

commit f75a9472c9fc4cf03010dc8986e6e17812d03a60
Author: Bertrand Delacretaz <bd...@apache.org>
AuthorDate: Wed Jan 4 16:45:04 2012 +0000

    SLING-2347 - startup filter disabler bundle added
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1227218 13f79535-47bb-0310-9956-ffa450edef68
---
 .../java/org/apache/sling/startupfilter/impl/StartupFilterImpl.java  | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/src/main/java/org/apache/sling/startupfilter/impl/StartupFilterImpl.java b/src/main/java/org/apache/sling/startupfilter/impl/StartupFilterImpl.java
index 35f503e..66f4beb 100644
--- a/src/main/java/org/apache/sling/startupfilter/impl/StartupFilterImpl.java
+++ b/src/main/java/org/apache/sling/startupfilter/impl/StartupFilterImpl.java
@@ -83,6 +83,11 @@ public class StartupFilterImpl implements StartupFilter, Filter {
         }
         ((HttpServletResponse)response).sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE, sb.toString());
     }
+    
+    @Override
+    public String toString() {
+        return getClass().getSimpleName() + ": " + (isEnabled() ? "enabled" : "disabled"); 
+    }
 
     /** @inheritDoc */
     public void destroy() {

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-startupfilter] 09/21: Use latest releases and update to new parent pom

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-startupfilter.git

commit 9e2aa62ad9cb9c48e80a26bd78c3bb968027bf3a
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Sun Dec 23 06:53:35 2012 +0000

    Use latest releases and update to new parent pom
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1425425 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/pom.xml b/pom.xml
index e00789b..b5a05e2 100644
--- a/pom.xml
+++ b/pom.xml
@@ -21,7 +21,7 @@
   <parent>
     <groupId>org.apache.sling</groupId>
     <artifactId>sling</artifactId>
-    <version>13</version>
+    <version>14</version>
     <relativePath>../../../parent/pom.xml</relativePath>
   </parent>
 

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-startupfilter] 01/21: SLING-2347 - startup filter module, rejects requests with a 503 status during startup

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-startupfilter.git

commit 4d59e92c076d18fed60870b14b49e60e48b8e39e
Author: Bertrand Delacretaz <bd...@apache.org>
AuthorDate: Fri Dec 30 16:55:12 2011 +0000

    SLING-2347 - startup filter module, rejects requests with a 503 status during startup
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1225861 13f79535-47bb-0310-9956-ffa450edef68
---
 pom.xml                                            | 101 ++++++++++
 .../apache/sling/startupfilter/StartupFilter.java  |  64 ++++++
 .../startupfilter/impl/StartupFilterImpl.java      | 130 ++++++++++++
 .../OSGI-INF/metatype/metatype.properties          |  32 +++
 .../startupfilter/impl/StartupFilterImplTest.java  | 218 +++++++++++++++++++++
 5 files changed, 545 insertions(+)

diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..ec1451f
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,101 @@
+<?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>11</version>
+    <relativePath>../../../parent/pom.xml</relativePath>
+  </parent>
+
+  <artifactId>org.apache.sling.startupfilter</artifactId>
+  <version>0.0.1-SNAPSHOT</version>
+  <packaging>bundle</packaging>
+
+  <name>Apache Sling Startup Filter</name>
+  <description> 
+    Servlet Filter that blocks access to Sling
+    while starting up.
+  </description>
+
+  <scm>
+    <connection>scm:svn:http://svn.apache.org/repos/asf/sling/trunk/contrib/extensions/startup-filter</connection>
+    <developerConnection>scm:svn:http://svn.apache.org/repos/asf/sling/trunk/contrib/extensions/startup-filter</developerConnection>
+    <url>http://svn.apache.org/repos/asf/sling/trunk/contrib/extensions/startup-filter</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.startupfilter</Export-Package>
+            <Private-Package>org.apache.sling.startupfilter.impl.*</Private-Package>
+          </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>javax.servlet</groupId>
+      <artifactId>servlet-api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-api</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-simple</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+        <groupId>org.jmock</groupId>
+        <artifactId>jmock-junit4</artifactId>
+        <scope>test</scope>
+    </dependency>
+  </dependencies>
+</project>
\ No newline at end of file
diff --git a/src/main/java/org/apache/sling/startupfilter/StartupFilter.java b/src/main/java/org/apache/sling/startupfilter/StartupFilter.java
new file mode 100644
index 0000000..4878e09
--- /dev/null
+++ b/src/main/java/org/apache/sling/startupfilter/StartupFilter.java
@@ -0,0 +1,64 @@
+/*
+ * 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.startupfilter;
+
+/** Servlet Filter that blocks access to the Sling main 
+ *  servlet during startup, by returning an HTTP 503
+ *  or other suitable status code.
+ *  
+ *  A typical use case is to start this filter before
+ *  the Sling main servlet (by setting a lower start level
+ *  on its bundle than on the Sling engine bundle), and
+ *  deactivating once startup is finished.
+ */
+public interface StartupFilter {
+    
+    String DEFAULT_STATUS_MESSAGE = "Startup in progress";
+    
+    /** Clients can supply objects implementing this
+     *  interface, to have the filter respond to HTTP
+     *  requests with the supplied information message.
+     */
+    public interface ProgressInfoProvider {
+        String getInfo();
+    }
+    
+    /** This ProgressInfoProvider is active by default, it 
+     *  must be removed for the filter to let requests pass through.
+     */
+    public static ProgressInfoProvider DEFAULT_INFO_PROVIDER = new ProgressInfoProvider() {
+        @Override
+        public String toString() {
+            return "Default ProgressInfoProvider";
+        }
+        public String getInfo() { 
+            return DEFAULT_STATUS_MESSAGE;
+        }
+    };
+    
+    /** Activate the supplied ProgressInfoProvider */
+    public void addProgressInfoProvider(ProgressInfoProvider pip);
+    
+    /** Deactivate the supplied ProgressInfoProvider if it was
+     *  currently active.
+     *  Once all such providers are removed, the filter disables
+     *  itself and lets requests pass through.
+     */
+    public void removeProgressInfoProvider(ProgressInfoProvider pip);
+}
\ No newline at end of file
diff --git a/src/main/java/org/apache/sling/startupfilter/impl/StartupFilterImpl.java b/src/main/java/org/apache/sling/startupfilter/impl/StartupFilterImpl.java
new file mode 100644
index 0000000..5baeb6a
--- /dev/null
+++ b/src/main/java/org/apache/sling/startupfilter/impl/StartupFilterImpl.java
@@ -0,0 +1,130 @@
+/*
+ * 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.startupfilter.impl;
+
+import java.io.IOException;
+import java.util.Hashtable;
+import java.util.Stack;
+
+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.HttpServletResponse;
+
+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.Service;
+import org.apache.sling.startupfilter.StartupFilter;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.component.ComponentContext;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/** StartupFilter implementation. Initially registered
+ *  as a StartupFilter only, the Filter registration
+ *  is dynamic, on-demand. */
+@Component(immediate=true, metatype=true)
+@Service(value=StartupFilter.class)
+public class StartupFilterImpl implements StartupFilter, Filter {
+
+    private final Logger log = LoggerFactory.getLogger(getClass());
+    private ServiceRegistration filterServiceRegistration;
+    private BundleContext bundleContext;
+    private final Stack<ProgressInfoProvider> providers = new Stack<ProgressInfoProvider>();
+    
+    @Property(boolValue=true)
+    public static final String DEFAULT_FILTER_ACTIVE_PROP = "default.filter.active";
+    private boolean defaultFilterActive;
+    
+    /** @inheritDoc */
+    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
+        ProgressInfoProvider pip = null;
+        synchronized (this) {
+            if(!providers.isEmpty()) {
+                pip = providers.peek();
+            }
+        }
+        if(pip != null) {
+            ((HttpServletResponse)response).sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE, pip.getInfo());
+        } else {
+            chain.doFilter(request, response);
+        }
+    }
+
+    /** @inheritDoc */
+    public void destroy() {
+    }
+
+    /** @inheritDoc */
+    public void init(FilterConfig cfg) throws ServletException {
+    }
+
+    @Activate
+    protected void activate(ComponentContext ctx) throws InterruptedException {
+        bundleContext = ctx.getBundleContext();
+        defaultFilterActive = (Boolean)ctx.getProperties().get(DEFAULT_FILTER_ACTIVE_PROP);
+        if(defaultFilterActive) {
+            addProgressInfoProvider(DEFAULT_INFO_PROVIDER);
+        }
+        log.info("Activated, defaultFilterActive={}", defaultFilterActive);
+    }
+    
+    @Deactivate
+    protected void deactivate(ComponentContext ctx) throws InterruptedException {
+        unregisterFilter();
+        bundleContext = null;
+    }
+    
+    
+    /** @inheritDoc */
+    public synchronized void addProgressInfoProvider(ProgressInfoProvider pip) {
+        providers.push(pip);
+        log.info("Added {}", pip);
+        if(filterServiceRegistration == null) {
+            final Hashtable<String, String> params = new Hashtable<String, String>();
+            params.put("filter.scope", "REQUEST");
+            filterServiceRegistration = bundleContext.registerService(Filter.class.getName(), this, params);
+            log.info("Registered {} as a Filter service", this);
+        }
+    }
+    
+    /** @inheritDoc */
+    public synchronized void removeProgressInfoProvider(ProgressInfoProvider pip) {
+        providers.remove(pip);
+        log.info("Removed {}", pip);
+        if(providers.isEmpty()) {
+            log.info("No more ProgressInfoProviders, unregistering Filter service");
+            unregisterFilter();
+        }
+    }
+    
+    private synchronized void unregisterFilter() {
+        if(filterServiceRegistration != null) {
+            filterServiceRegistration.unregister();
+            filterServiceRegistration = null;
+        }
+    }
+     
+}
\ No newline at end of file
diff --git a/src/main/resources/OSGI-INF/metatype/metatype.properties b/src/main/resources/OSGI-INF/metatype/metatype.properties
new file mode 100644
index 0000000..7df6cfd
--- /dev/null
+++ b/src/main/resources/OSGI-INF/metatype/metatype.properties
@@ -0,0 +1,32 @@
+#
+#  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 Sling SCR plugin
+
+org.apache.sling.startupfilter.impl.StartupFilterImpl.name=Sling Startup Filter
+org.apache.sling.startupfilter.impl.StartupFilterImpl.description=Rejects Sling requests \
+  with a 503 error code during startup.
+
+default.filter.active.name=Default filter active?
+default.filter.active.description=If true, the filter is active as \
+  soon as the service starts.
diff --git a/src/test/java/org/apache/sling/startupfilter/impl/StartupFilterImplTest.java b/src/test/java/org/apache/sling/startupfilter/impl/StartupFilterImplTest.java
new file mode 100644
index 0000000..5cd85b5
--- /dev/null
+++ b/src/test/java/org/apache/sling/startupfilter/impl/StartupFilterImplTest.java
@@ -0,0 +1,218 @@
+/*
+ * 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.startupfilter.impl;
+
+import static org.junit.Assert.assertEquals;
+
+import java.util.Dictionary;
+import java.util.Hashtable;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.sling.startupfilter.StartupFilter;
+import org.hamcrest.Description;
+import org.jmock.Expectations;
+import org.jmock.Mockery;
+import org.jmock.api.Action;
+import org.jmock.api.Invocation;
+import org.jmock.lib.action.DoAllAction;
+import org.junit.Before;
+import org.junit.Test;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceRegistration;
+import org.osgi.service.component.ComponentContext;
+
+/** Test the StartupFilterImpl */
+public class StartupFilterImplTest {
+    static private class TestPip implements StartupFilter.ProgressInfoProvider {
+        String info;
+        
+        TestPip(String s) {
+            info = s;
+        }
+        
+        public String getInfo() {
+            return info;
+        }
+    };
+    
+    static private class TestFilterImpl extends StartupFilterImpl {
+        void setup(ComponentContext ctx) throws Exception {
+            activate(ctx);
+        }
+    };
+    
+    static private class ChangeInteger implements Action {
+        private final boolean increment;
+        private final AtomicInteger value;
+        
+        ChangeInteger(AtomicInteger value, boolean increment) {
+            this.increment = increment;
+            this.value = value;
+        }
+        public void describeTo(Description d) {
+            d.appendText(increment ? "increment" : "decrement");
+            d.appendText(" an integer");
+        }
+        public Object invoke(Invocation invocation) throws Throwable {
+            if(increment) {
+                value.incrementAndGet();
+            } else {
+                value.decrementAndGet();
+            }
+            return null;
+        }
+    };
+
+    private TestFilterImpl filter;
+    private Mockery mockery;
+    private HttpServletRequest request; 
+    private HttpServletResponse response;
+    private FilterChain chain;
+    private AtomicInteger doChainCount;
+    private int lastReturnedStatus;
+    private String lastReturnedMessage;
+    private AtomicInteger activeFilterCount;
+    private ServiceRegistration serviceRegistration;
+
+    @Before
+    public void setup() throws Exception {
+        doChainCount = new AtomicInteger();
+        activeFilterCount = new AtomicInteger();
+        mockery = new Mockery();
+        final BundleContext bundleContext = mockery.mock(BundleContext.class); 
+        final ComponentContext componentContext = mockery.mock(ComponentContext.class); 
+        request = mockery.mock(HttpServletRequest.class); 
+        response = mockery.mock(HttpServletResponse.class);
+        chain = mockery.mock(FilterChain.class);
+        serviceRegistration = mockery.mock(ServiceRegistration.class);
+        filter = new TestFilterImpl();
+        
+        final Action storeResponse = new Action() {
+            public void describeTo(Description d) {
+                d.appendText("Store HTTP response values");
+            }
+
+            public Object invoke(Invocation invocation) throws Throwable {
+                lastReturnedStatus = (Integer)invocation.getParameter(0);
+                lastReturnedMessage = (String)invocation.getParameter(1);
+                return null;
+            }
+        };
+        
+        final Dictionary<String, Object> props = new Hashtable<String, Object>();
+        props.put("default.filter.active", Boolean.TRUE);
+        
+        mockery.checking(new Expectations() {{
+            allowing(componentContext).getBundleContext();
+            will(returnValue(bundleContext));
+            
+            allowing(componentContext).getProperties();
+            will(returnValue(props));
+            
+            allowing(bundleContext).registerService(with(Filter.class.getName()), with(any(Object.class)), with(any(Dictionary.class)));
+            will(new DoAllAction(
+                    new ChangeInteger(activeFilterCount, true),
+                    returnValue(serviceRegistration)
+                    ));
+            
+            allowing(chain).doFilter(request, response);
+            will(new ChangeInteger(doChainCount, true));
+            
+            allowing(response).sendError(with(any(Integer.class)), with(any(String.class)));
+            will(storeResponse);
+            
+            allowing(serviceRegistration).unregister();
+            will(new ChangeInteger(activeFilterCount, false));
+        }});
+        
+        filter.setup(componentContext);
+    }
+    
+    private void assertRequest(final int expectedStatus, final String expectedMessage) throws Exception {
+        lastReturnedMessage = null;
+        lastReturnedStatus = -1;
+        final int oldDoChainCount = doChainCount.get();
+        
+        filter.doFilter(request, response, chain);
+        
+        // status 0 means we expect the request to go through
+        if(expectedStatus == 0) {
+            assertEquals("Expecting doChain to have been be called once", 
+                    1, doChainCount.get() - oldDoChainCount);
+        } else {
+            assertEquals("Expecting status to match", 
+                    expectedStatus, lastReturnedStatus);
+            assertEquals("Expecting message to match", 
+                    expectedMessage, lastReturnedMessage);
+        }
+    }
+    
+    @Test
+    public void testInitialState() throws Exception {
+        assertEquals("Initially expecting one filter service", 1, activeFilterCount.get());
+        assertRequest(503, StartupFilter.DEFAULT_STATUS_MESSAGE);
+    }
+    
+    @Test
+    public void testDefaultFilterRemoved() throws Exception {
+        assertEquals("Initially expecting one filter service", 1, activeFilterCount.get());
+        filter.removeProgressInfoProvider(StartupFilter.DEFAULT_INFO_PROVIDER);
+        assertEquals("Expecting filter service to be gone", 0, activeFilterCount.get());
+        assertRequest(0, null);
+    }
+    
+    @Test
+    public void testSeveralProviders() throws Exception {
+        final StartupFilter.ProgressInfoProvider [] pips = {
+                new TestPip("one"),
+                new TestPip("two"),
+                new TestPip("three"),
+        };
+        
+        assertEquals("Initially expecting one filter service", 1, activeFilterCount.get());
+        
+        // Last added provider must be active
+        for(StartupFilter.ProgressInfoProvider pip : pips) {
+            filter.addProgressInfoProvider(pip);
+            assertRequest(503, pip.getInfo());
+        }
+        
+        assertEquals("After adding several providers, expecting one filter service", 1, activeFilterCount.get());
+        
+        // When removing a provider the previous one becomes active
+        for(int i = pips.length - 1; i >= 0; i--) {
+            assertRequest(503, pips[i].getInfo());
+            filter.removeProgressInfoProvider(pips[i]);
+        }
+
+        // After removing all, default is active again
+        assertEquals("After removing providers, expecting one filter service", 1, activeFilterCount.get());
+        assertRequest(503, StartupFilter.DEFAULT_STATUS_MESSAGE);
+
+        // Now remove default and check
+        filter.removeProgressInfoProvider(StartupFilter.DEFAULT_INFO_PROVIDER);
+        assertRequest(0, null);
+        assertEquals("Expecting filter service to be gone", 0, activeFilterCount.get());
+    }
+}

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.

[sling-org-apache-sling-startupfilter] 12/21: SLING-3119 - setup startup filter as a plain Filter instead of a Sling one. Contributed by Ben Peter, thanks!

Posted by ro...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

rombert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/sling-org-apache-sling-startupfilter.git

commit 9064c6d3a136eed512bec59e8180f9cbd1b577b4
Author: Bertrand Delacretaz <bd...@apache.org>
AuthorDate: Fri Sep 27 13:16:36 2013 +0000

    SLING-3119 - setup startup filter as a plain Filter instead of a Sling one. Contributed by Ben Peter, thanks!
    
    git-svn-id: https://svn.apache.org/repos/asf/sling/trunk@1526891 13f79535-47bb-0310-9956-ffa450edef68
---
 .../apache/sling/startupfilter/impl/StartupFilterImpl.java | 14 ++++++++++++--
 .../sling/startupfilter/impl/StartupFilterImplTest.java    |  3 ++-
 2 files changed, 14 insertions(+), 3 deletions(-)

diff --git a/src/main/java/org/apache/sling/startupfilter/impl/StartupFilterImpl.java b/src/main/java/org/apache/sling/startupfilter/impl/StartupFilterImpl.java
index d1ed6dd..a56cfb2 100644
--- a/src/main/java/org/apache/sling/startupfilter/impl/StartupFilterImpl.java
+++ b/src/main/java/org/apache/sling/startupfilter/impl/StartupFilterImpl.java
@@ -43,6 +43,7 @@ import org.apache.sling.startupfilter.StartupFilter;
 import org.apache.sling.startupfilter.StartupFilterDisabler;
 import org.apache.sling.startupfilter.StartupInfoProvider;
 import org.osgi.framework.BundleContext;
+import org.osgi.framework.Constants;
 import org.osgi.framework.ServiceReference;
 import org.osgi.framework.ServiceRegistration;
 import org.osgi.service.component.ComponentContext;
@@ -74,9 +75,13 @@ public class StartupFilterImpl implements StartupFilter, Filter {
     @Property(value=DEFAULT_MESSAGE)
     public static final String DEFAULT_MESSAGE_PROP = "default.message";
     private String defaultMessage;
-    
+
     @Reference(cardinality=ReferenceCardinality.OPTIONAL_UNARY, policy=ReferencePolicy.DYNAMIC)
     private StartupFilterDisabler startupFilterDisabler;
+
+    private final String FRAMEWORK_PROP_MANAGER_ROOT = "felix.webconsole.manager.root";
+    static final String DEFAULT_MANAGER_ROOT = "/system/console";
+    private String managerRoot;
     
     /** @inheritDoc */
     public void doFilter(ServletRequest request, ServletResponse sr, FilterChain chain) throws IOException, ServletException {
@@ -153,6 +158,10 @@ public class StartupFilterImpl implements StartupFilter, Filter {
                 
         prop = ctx.getProperties().get(ACTIVE_BY_DEFAULT_PROP);
         defaultFilterActive = (prop instanceof Boolean ? (Boolean)prop : false);
+
+        prop = bundleContext.getProperty(FRAMEWORK_PROP_MANAGER_ROOT);
+        managerRoot = prop == null ? DEFAULT_MANAGER_ROOT : prop.toString();
+
         if(defaultFilterActive) {
             enable();
         }
@@ -171,8 +180,9 @@ public class StartupFilterImpl implements StartupFilter, Filter {
     public synchronized void enable() {
         if(filterServiceRegistration == null) {
             final Hashtable<String, Object> params = new Hashtable<String, Object>();
+            params.put(Constants.SERVICE_RANKING, 0x9000); // run before RequestLoggerFilter (0x8000)
             params.put("filter.scope", "REQUEST");
-            params.put("filter.order", Integer.MIN_VALUE);
+            params.put("pattern", "^(?!"+ managerRoot +")(.+)");
             filterServiceRegistration = bundleContext.registerService(Filter.class.getName(), this, params);
             log.info("Registered {} as a Filter service", this);
         }
diff --git a/src/test/java/org/apache/sling/startupfilter/impl/StartupFilterImplTest.java b/src/test/java/org/apache/sling/startupfilter/impl/StartupFilterImplTest.java
index 329dae8..9fd25c2 100644
--- a/src/test/java/org/apache/sling/startupfilter/impl/StartupFilterImplTest.java
+++ b/src/test/java/org/apache/sling/startupfilter/impl/StartupFilterImplTest.java
@@ -170,7 +170,8 @@ public class StartupFilterImplTest {
             will(returnValue(providerRefs));
             allowing(bundleContext).getService(with(any(ServiceReference.class)));
             will(returnValue(provider));
-            
+            allowing(bundleContext).getProperty(with(any(String.class)));
+
             allowing(bundleContext).registerService(with(Filter.class.getName()), with(any(Object.class)), with(any(Dictionary.class)));
             will(new DoAllAction(
                     new ChangeInteger(activeFilterCount, true),

-- 
To stop receiving notification emails like this one, please contact
"commits@sling.apache.org" <co...@sling.apache.org>.