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

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

commit 3b01927fd8b8771c1b3c6ba4d4e6d98f02cf5a22
Author: Julian Reschke <[email protected]>
AuthorDate: Thu Aug 21 13:04:08 2025 +0100

    SLING-12900: improve test coverage for VP bg init vs events, minor 
refactoring
---
 .../resourceresolver/impl/mapping/MapEntries.java  | 27 ++++++++-------
 .../impl/mapping/VanityPathMapEntriesTest.java     | 40 ++++++++++++++++++++++
 2 files changed, 55 insertions(+), 12 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..e0fd3a38 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,27 @@ 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;
             }
 
-            // during startup: just enqueue the events
-            if (inStartup) {
-                if (type == ResourceChange.ChangeType.REMOVED
-                        || type == ResourceChange.ChangeType.ADDED
-                        || type == ResourceChange.ChangeType.CHANGED) {
+            boolean queued = false;
+
+            if (RELEVANT_CHANGE_TYPES.contains(type)) {
+                // during startup: just enqueue the events
+                if (inStartup) {
                     Map.Entry<String, ResourceChange.ChangeType> entry = new 
SimpleEntry<>(path, type);
                     log.trace("enqueue: {}", entry);
                     resourceChangeQueue.add(entry);
+                    queued = true;
                 }
-            } else {
-                boolean changed = handleResourceChange(type, path, 
resolverRefreshed, hasReloadedConfig);
+            }
 
-                if (changed) {
-                    sendEvent = 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