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 95a4164a..80556f07 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 @@ -1166,8 +1166,10 @@ protected void initializeVanityPaths() throws IOException { this.initializing.lock(); try { if (this.factory.isVanityPathEnabled()) { + vanityPathsProcessed.set(false); this.vanityBloomFilter = createVanityBloomFilter(); VanityPathInitializer vpi = new VanityPathInitializer(this.factory); + if (this.factory.isVanityPathCacheInitInBackground()) { this.log.debug("bg init starting"); Thread vpinit = new Thread(vpi, "VanityPathInitializer"); 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 218db150..d0da9dfc 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 @@ -90,23 +90,26 @@ public class VanityPathMapEntriesTest extends AbstractMappingMapEntriesTest { @Mock private EventAdmin eventAdmin; - private int pageSize; - private boolean isMaxCachedVanityPathEntriesStartup; + private final int pageSize; + private final boolean isMaxCachedVanityPathEntriesStartup; + private final boolean isVanityPathCacheInitInBackground; private int prevPageSize = 1000; - @Parameters(name="{0} {1}") + @Parameters(name="{0} {1} {2}") public static Collection data() { return List.of(new Object[][] { - {1000, false}, - {1, true}, - {1000, true}} + {1000, false, true}, + {1, true, false}, + {1000, true, false}} ); } - public VanityPathMapEntriesTest(int pageSize, boolean isMaxCachedVanityPathEntriesStartup) { + public VanityPathMapEntriesTest(int pageSize, boolean isMaxCachedVanityPathEntriesStartup, + boolean isVanityPathCacheInitInBackground) { this.pageSize = pageSize; this.isMaxCachedVanityPathEntriesStartup = isMaxCachedVanityPathEntriesStartup; + this.isVanityPathCacheInitInBackground = isVanityPathCacheInitInBackground; } @Override @@ -133,6 +136,7 @@ public void setup() throws Exception { Collections.sort(configs); when(bundle.getSymbolicName()).thenReturn("TESTBUNDLE"); when(bundleContext.getBundle()).thenReturn(bundle); + when(resourceResolverFactory.getServiceUserAuthenticationInfo(anyString())).thenReturn(Map.of()); when(resourceResolverFactory.getServiceResourceResolver(any(Map.class))).thenReturn(resourceResolver); when(resourceResolverFactory.isVanityPathEnabled()).thenReturn(true); when(resourceResolverFactory.getVanityPathConfig()).thenReturn(configs); @@ -140,6 +144,7 @@ public void setup() throws Exception { when(resourceResolverFactory.getMapRoot()).thenReturn(MapEntries.DEFAULT_MAP_ROOT); when(resourceResolverFactory.getMaxCachedVanityPathEntries()).thenReturn(-1L); when(resourceResolverFactory.isMaxCachedVanityPathEntriesStartup()).thenReturn(isMaxCachedVanityPathEntriesStartup); + when(resourceResolverFactory.isVanityPathCacheInitInBackground()).thenReturn(isVanityPathCacheInitInBackground); when(resourceResolver.findResources(anyString(), eq("sql"))).thenReturn( Collections.emptyIterator()); when(resourceResolver.findResources(anyString(), eq("JCR-SQL2"))).thenReturn( @@ -149,6 +154,35 @@ public void setup() throws Exception { Optional metrics = Optional.empty(); mapEntries = new MapEntries(resourceResolverFactory, bundleContext, eventAdmin, stringInterpolationProvider, metrics); + waitForBgInit(); + } + + // get internal flag that signals completion of background task + private AtomicBoolean getVanityPathsProcessed() { + try { + Field field = MapEntries.class.getDeclaredField("vanityPathsProcessed"); + field.setAccessible(true); + return (AtomicBoolean) field.get(mapEntries); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + // wait for background thread to complete + private void waitForBgInit() { + while (!getVanityPathsProcessed().get()) { + try { + Thread.sleep(10); + } catch (InterruptedException e) { + // ignored + } + } + } + + // get vanity paths (after waiting for bg init to complete) + private void initializeVanityPaths() throws IOException { + mapEntries.initializeVanityPaths(); + waitForBgInit(); } @Override @@ -166,8 +200,9 @@ public void test_simple_vanity_path() throws IOException { String oneMore = "one-more"; prepareMapEntriesForVanityPath(false, false, containerName, childName, oneMore, vanityPath); - mapEntries.doInit(); - mapEntries.initializeVanityPaths(); + + initializeVanityPaths(); + Map> vanityMap = mapEntries.getVanityPathMappings(); assertNotNull(vanityMap); assertEquals(vanityPath, vanityMap.get("/" + containerName + "/" + childName).get(0)); @@ -184,8 +219,9 @@ public void test_simple_vanity_path_support_with_null_parent() throws IOExceptio String oneMore = "one-more"; prepareMapEntriesForVanityPath(true, true, containerName, childName, oneMore, vanityPath); - mapEntries.doInit(); - mapEntries.initializeVanityPaths(); + + initializeVanityPaths(); + Map> vanityMap = mapEntries.getVanityPathMappings(); assertNotNull(vanityMap); // not present @@ -299,8 +335,7 @@ public void test_vanity_path_registration() throws Exception { } }); - mapEntries.doInit(); - mapEntries.initializeVanityPaths(); + initializeVanityPaths(); List entries = mapEntries.getResolveMaps(); @@ -346,8 +381,7 @@ public void test_vanity_path_updates() throws Exception { when(resourceResolver.findResources(anyString(), eq("JCR-SQL2"))).thenAnswer((Answer>) invocation -> Collections.emptyIterator()); - mapEntries.doInit(); - mapEntries.initializeVanityPaths(); + initializeVanityPaths(); // map entries should have no alias atm assertTrue( mapEntries.getResolveMaps().isEmpty()); @@ -460,7 +494,6 @@ public void test_vanity_path_registration_include_exclude() throws IOException { resources.add(getVanityPathResource(val)); } - when(resourceResolver.findResources(anyString(), eq("JCR-SQL2"))).thenAnswer((Answer>) invocation -> { String query = invocation.getArguments()[0].toString(); if (matchesPagedQuery(query)) { @@ -475,8 +508,7 @@ public void test_vanity_path_registration_include_exclude() throws IOException { } }); - mapEntries.doInit(); - mapEntries.initializeVanityPaths(); + initializeVanityPaths(); List entries = mapEntries.getResolveMaps(); // each valid resource results in 2 entries @@ -1254,7 +1286,7 @@ private String getFirstVanityPath(Resource r) { return vp.length == 0 ? "": vp[0]; } - private Comparator vanityResourceComparator = (o1, o2) -> { + private final Comparator vanityResourceComparator = (o1, o2) -> { String s1 = getFirstVanityPath(o1); String s2 = getFirstVanityPath(o2); return s1.compareTo(s2);