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

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


The following commit(s) were added to refs/heads/master by this push:
     new 9e84d835 SLING-12900: improve test coverage for VP bg init vs events, 
minor refactoring (#193)
9e84d835 is described below

commit 9e84d8353728bd4fc06c52cdd9c9ea8c49eb6013
Author: Julian Reschke <[email protected]>
AuthorDate: Thu Aug 21 16:33:14 2025 +0200

    SLING-12900: improve test coverage for VP bg init vs events, minor 
refactoring (#193)
---
 .../resourceresolver/impl/mapping/MapEntries.java  | 32 +++++++++--------
 .../impl/mapping/VanityPathMapEntriesTest.java     | 40 ++++++++++++++++++++++
 2 files changed, 57 insertions(+), 15 deletions(-)

diff --git 
a/src/main/java/org/apache/sling/resourceresolver/impl/mapping/MapEntries.java 
b/src/main/java/org/apache/sling/resourceresolver/impl/mapping/MapEntries.java
index c8e47673..ddda5586 100644
--- 
a/src/main/java/org/apache/sling/resourceresolver/impl/mapping/MapEntries.java
+++ 
b/src/main/java/org/apache/sling/resourceresolver/impl/mapping/MapEntries.java
@@ -35,6 +35,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
 import java.util.Optional;
+import java.util.Set;
 import java.util.SortedMap;
 import java.util.TreeMap;
 import java.util.TreeSet;
@@ -426,8 +427,11 @@ public class MapEntries implements MapEntriesHandler, 
ResourceChangeListener, Ex
 
     // ---------- ResourceChangeListener interface
 
+    private final Set<ResourceChange.ChangeType> RELEVANT_CHANGE_TYPES = 
Set.of(
+            ResourceChange.ChangeType.ADDED, 
ResourceChange.ChangeType.CHANGED, ResourceChange.ChangeType.REMOVED);
+
     /**
-     * Handles the change to any of the node properties relevant for vanity URL
+     * Handles the change to any of the node properties relevant for vanity 
paths
      * mappings. The {@link #MapEntries(MapConfigurationProvider, 
BundleContext, EventAdmin, StringInterpolationProvider, Optional)}
      * constructor makes sure the event listener is registered to only get
      * appropriate events.
@@ -450,28 +454,26 @@ public class MapEntries implements MapEntriesHandler, 
ResourceChangeListener, Ex
             final ResourceChange.ChangeType type = rc.getType();
             final String path = rc.getPath();
 
-            log.debug("onChange, type={}, path={}", rc.getType(), path);
+            log.debug("onChange, type={}, path={}", type, path);
 
             // don't care for system area
             if (path.startsWith(JCR_SYSTEM_PREFIX)) {
                 continue;
             }
 
+            boolean queued = false;
+
             // during startup: just enqueue the events
-            if (inStartup) {
-                if (type == ResourceChange.ChangeType.REMOVED
-                        || type == ResourceChange.ChangeType.ADDED
-                        || type == ResourceChange.ChangeType.CHANGED) {
-                    Map.Entry<String, ResourceChange.ChangeType> entry = new 
SimpleEntry<>(path, type);
-                    log.trace("enqueue: {}", entry);
-                    resourceChangeQueue.add(entry);
-                }
-            } else {
-                boolean changed = handleResourceChange(type, path, 
resolverRefreshed, hasReloadedConfig);
 
-                if (changed) {
-                    sendEvent = true;
-                }
+            if (inStartup && RELEVANT_CHANGE_TYPES.contains(type)) {
+                Map.Entry<String, ResourceChange.ChangeType> entry = new 
SimpleEntry<>(path, type);
+                log.trace("enqueue: {}", entry);
+                resourceChangeQueue.add(entry);
+                queued = true;
+            }
+
+            if (!queued) {
+                sendEvent |= handleResourceChange(type, path, 
resolverRefreshed, hasReloadedConfig);
             }
         }
 
diff --git 
a/src/test/java/org/apache/sling/resourceresolver/impl/mapping/VanityPathMapEntriesTest.java
 
b/src/test/java/org/apache/sling/resourceresolver/impl/mapping/VanityPathMapEntriesTest.java
index d8a97a73..d5b04a90 100644
--- 
a/src/test/java/org/apache/sling/resourceresolver/impl/mapping/VanityPathMapEntriesTest.java
+++ 
b/src/test/java/org/apache/sling/resourceresolver/impl/mapping/VanityPathMapEntriesTest.java
@@ -32,6 +32,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Optional;
 import java.util.Set;
+import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.atomic.AtomicBoolean;
@@ -52,6 +53,7 @@ import org.apache.sling.api.wrappers.ValueMapDecorator;
 import org.apache.sling.resourceresolver.impl.ResourceResolverMetrics;
 import 
org.apache.sling.resourceresolver.impl.mapping.MapConfigurationProvider.VanityPathConfig;
 import org.junit.After;
+import org.junit.Assume;
 import org.junit.Before;
 import org.junit.Test;
 import org.junit.runner.RunWith;
@@ -1273,6 +1275,44 @@ public class VanityPathMapEntriesTest extends 
AbstractMappingMapEntriesTest {
         assertTrue(finalVanityMap.get("/eventTest").contains("/baa"));
     }
 
+    @Test
+    public void test_remove_vanity_path_during_bg_init() {
+        Assume.assumeTrue(
+                "simulation of resource removal during bg init only meaningful 
in 'bg init' case",
+                resourceResolverFactory.isVanityPathCacheInitInBackground());
+
+        Resource root = createMockedResource("/");
+        Resource foo = createMockedResource(root, "foo");
+        Resource leaf = createMockedResource(foo, "leaf");
+
+        when(leaf.getValueMap()).thenReturn(buildValueMap("sling:vanityPath", 
"/bar"));
+
+        CountDownLatch greenLight = new CountDownLatch(1);
+
+        when(resourceResolver.findResources(anyString(), eq("JCR-SQL2")))
+                .thenAnswer((Answer<Iterator<Resource>>) invocation -> {
+                    greenLight.await();
+                    return Set.of(leaf).iterator();
+                });
+
+        VanityPathHandler vph = mapEntries.vph;
+        vph.initializeVanityPaths();
+        assertFalse(vph.isReady());
+
+        // bg init will wait until we give green light
+        mapEntries.onChange(List.of(new 
ResourceChange(ResourceChange.ChangeType.REMOVED, leaf.getPath(), false)));
+
+        greenLight.countDown();
+        waitForBgInit();
+
+        assertTrue(vph.isReady());
+
+        Map<String, List<String>> vanityPathMappings = 
mapEntries.getVanityPathMappings();
+        List<String> mappings = vanityPathMappings.get("/foo/leaf");
+
+        assertNull("expected no (null) mapping for /foo/leaf", mappings);
+    }
+
     // checks for the expected list of queries and the cache statistics
     private void checkCounters(
             String testName,

Reply via email to