You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sling.apache.org by jo...@apache.org on 2024/12/19 14:59:26 UTC

(sling-org-apache-sling-servlets-resolver) branch master updated: SLING-12571 add option to relax the HC conditions (#51)

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

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


The following commit(s) were added to refs/heads/master by this push:
     new d0e0054  SLING-12571 add option to relax the HC conditions (#51)
d0e0054 is described below

commit d0e005492abe2a5c9a7e08f6f65a882e605f24d1
Author: Jörg Hoh <jo...@users.noreply.github.com>
AuthorDate: Thu Dec 19 15:59:20 2024 +0100

    SLING-12571 add option to relax the HC conditions (#51)
    
    * SLING-12571 add option to relax the HC conditions
---
 .../internal/bundle/BundledScriptTracker.java      | 47 +++++++++++++++++-----
 .../internal/bundle/BundledScriptTrackerTest.java  | 26 ++++++++++++
 2 files changed, 63 insertions(+), 10 deletions(-)

diff --git a/src/main/java/org/apache/sling/servlets/resolver/internal/bundle/BundledScriptTracker.java b/src/main/java/org/apache/sling/servlets/resolver/internal/bundle/BundledScriptTracker.java
index 89baa45..ca83566 100644
--- a/src/main/java/org/apache/sling/servlets/resolver/internal/bundle/BundledScriptTracker.java
+++ b/src/main/java/org/apache/sling/servlets/resolver/internal/bundle/BundledScriptTracker.java
@@ -130,6 +130,7 @@ public class BundledScriptTracker implements BundleTrackerCustomizer<List<Servic
     
     private Set<String> registeredBundles = new HashSet<>();
     private Set<String> expectedBundles = new HashSet<>();
+    private boolean ignoreNonExistingBundles = false;
     
     private ServiceRegistration<HealthCheck> healthCheckRegistration = null;
 
@@ -142,9 +143,10 @@ public class BundledScriptTracker implements BundleTrackerCustomizer<List<Servic
         bt.open();
         if (config.mandatoryBundles() != null) {
             expectedBundles.addAll(Arrays.asList(config.mandatoryBundles()));
+            ignoreNonExistingBundles = config.ignoreNonExistingBundles();
             healthCheckRegistration = registerHealthCheck(config.tags());
-            LOGGER.info("Healthcheck configured with mandatory bundles {} for tags {}", 
-                    Arrays.toString(config.mandatoryBundles()), Arrays.toString(config.tags()));
+            LOGGER.info("Healthcheck configured with mandatory bundles {} for tags {}, ignoreNonExistingBundles = {}",
+                    Arrays.toString(config.mandatoryBundles()), Arrays.toString(config.tags()), ignoreNonExistingBundles);
         }
     }
 
@@ -591,23 +593,46 @@ public class BundledScriptTracker implements BundleTrackerCustomizer<List<Servic
         refreshDispatcher(Collections.emptyList());
         registeredBundles.remove(bundle.getSymbolicName());
     }
-    
+
     @Override
     public Result execute() {
-        
+
         if (expectedBundles == null) {
             return new Result(Result.Status.OK,"Health check is not configured.");
         }
-        
-        if (registeredBundles.containsAll(expectedBundles)) {
+
+        Set<String> mandatoryAvailableBundles;
+        if (ignoreNonExistingBundles) {
+            // Filter the provided symbolic names if a bundle with that name actually exists
+            mandatoryAvailableBundles = filterForExistingBundles(bundleContext.get(), expectedBundles);
+        } else {
+            mandatoryAvailableBundles = expectedBundles;
+        }
+
+        if (registeredBundles.containsAll(mandatoryAvailableBundles)) {
             return new Result(Result.Status.OK,"All expected bundles have registered their scripts.");
         } else {
             FormattingResultLog log = new FormattingResultLog();
-            log.warn("Expected bundles : {}, registered bundles: {}", expectedBundles, registeredBundles);
+            log.warn("Expected bundles : {}, registered bundles: {}", mandatoryAvailableBundles, registeredBundles);
             return new Result(log);
         }
     }
 
+    /**
+     * Return the symbolic names of bundles which are provided via {{code expectedBundles}} and present
+     * @param bundleContext a bundleContext
+     * @param expectedBundles the symbolic names of bundles to check for
+     * @return the symbolic names of present bundles
+     */
+    protected static Set<String> filterForExistingBundles(BundleContext bundleContext,
+            Set<String> expectedBundles) {
+            List<Bundle> allBundles = Arrays.asList(bundleContext.getBundles());
+            return allBundles.stream()
+                .map(Bundle::getSymbolicName)
+                .filter(s -> expectedBundles.contains(s))
+                .collect(Collectors.toSet());
+    }
+
     private class DispatcherServlet extends GenericServlet {
         private static final long serialVersionUID = -1917128676758775458L;
         private final Set<String> resourceType;
@@ -806,14 +831,16 @@ public class BundledScriptTracker implements BundleTrackerCustomizer<List<Servic
         return newSet;
     }
 
-
     @ObjectClassDefinition
     public @interface BundledScriptTrackerConfig {
-        
+
         @AttributeDefinition(name="Mandatory Bundles", description="A list of symbolic bundle names for which the "
                 + "script registration process must have been successfully completed for the health check to report ok.")
         String[] mandatoryBundles();
-        
+
+        @AttributeDefinition(name="Check for bundle presence", description="If disabled, bundles listed as mandatory are ignored if no bundle with that symbolic name is present")
+        boolean ignoreNonExistingBundles() default false;
+
         @AttributeDefinition(name="healthcheck tags", description="the tags under which the healthcheck should be registered")
         String[] tags() default "systemready";
     }
diff --git a/src/test/java/org/apache/sling/servlets/resolver/internal/bundle/BundledScriptTrackerTest.java b/src/test/java/org/apache/sling/servlets/resolver/internal/bundle/BundledScriptTrackerTest.java
index 47f7329..c0ddf30 100644
--- a/src/test/java/org/apache/sling/servlets/resolver/internal/bundle/BundledScriptTrackerTest.java
+++ b/src/test/java/org/apache/sling/servlets/resolver/internal/bundle/BundledScriptTrackerTest.java
@@ -18,15 +18,21 @@
  */
 package org.apache.sling.servlets.resolver.internal.bundle;
 
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
 import static org.mockito.Mockito.mock;
 import static org.mockito.Mockito.verify;
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Set;
 
 import javax.servlet.Servlet;
 
 import org.junit.Test;
+import org.mockito.Mockito;
+import org.mockito.internal.util.collections.Sets;
 import org.osgi.framework.Bundle;
 import org.osgi.framework.BundleContext;
 import org.osgi.framework.BundleEvent;
@@ -45,4 +51,24 @@ public class BundledScriptTrackerTest {
         tracker.removedBundle(mock(Bundle.class), mock(BundleEvent.class), registrations);
         verify(registration).unregister();
     }
+
+    @Test
+    public void test_filterForExistingBundles() {
+        BundleContext bc = Mockito.mock(BundleContext.class);
+        Mockito.doReturn(new Bundle[] {mockBundle("a"),mockBundle("b"),
+                mockBundle("c"),mockBundle("d"),mockBundle("e")}).when(bc).getBundles();
+
+        Set<String> expectedSymbolicNames = Sets.newSet("a","b","z");
+        Set<String> res = BundledScriptTracker.filterForExistingBundles(bc,expectedSymbolicNames);
+        assertNotNull(res);
+        assertEquals(2,res.size());
+        assertTrue(res.contains("a"));
+        assertTrue(res.contains("b"));
+    }
+
+    private static Bundle mockBundle (String symbolicName) {
+        Bundle b = Mockito.mock(Bundle.class);
+        Mockito.when(b.getSymbolicName()).thenReturn(symbolicName);
+        return b;
+    }
 }