You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by kw...@apache.org on 2022/07/18 11:18:50 UTC

[jackrabbit-oak] branch trunk updated: OAK-9840: Wait for all required MountInfoConfigs (#623)

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

kwin pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/jackrabbit-oak.git


The following commit(s) were added to refs/heads/trunk by this push:
     new 455080db72 OAK-9840: Wait for all required MountInfoConfigs (#623)
455080db72 is described below

commit 455080db72224b6b563dcfbe86f9991d15cb6433
Author: Konrad Windszus <kw...@apache.org>
AuthorDate: Mon Jul 18 13:18:46 2022 +0200

    OAK-9840: Wait for all required MountInfoConfigs (#623)
    
    MountInfoConfig services should be bound dynamically to consider configs being activated later
---
 .../oak/composite/MountInfoProviderService.java    | 23 ++++++++++++----------
 .../composite/MountInfoProviderServiceTest.java    | 13 ++++++++++++
 2 files changed, 26 insertions(+), 10 deletions(-)

diff --git a/oak-store-composite/src/main/java/org/apache/jackrabbit/oak/composite/MountInfoProviderService.java b/oak-store-composite/src/main/java/org/apache/jackrabbit/oak/composite/MountInfoProviderService.java
index e163694a42..4dd1c08093 100644
--- a/oak-store-composite/src/main/java/org/apache/jackrabbit/oak/composite/MountInfoProviderService.java
+++ b/oak-store-composite/src/main/java/org/apache/jackrabbit/oak/composite/MountInfoProviderService.java
@@ -19,9 +19,10 @@
 
 package org.apache.jackrabbit.oak.composite;
 
-import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 import java.util.concurrent.CopyOnWriteArrayList;
 import java.util.stream.Stream;
 import org.apache.jackrabbit.oak.spi.mount.MountInfoProvider;
@@ -33,14 +34,15 @@ import org.osgi.service.component.annotations.Component;
 import org.osgi.service.component.annotations.Deactivate;
 import org.osgi.service.component.annotations.Reference;
 import org.osgi.service.component.annotations.ReferenceCardinality;
+import org.osgi.service.component.annotations.ReferencePolicy;
+import org.osgi.service.component.annotations.ReferencePolicyOption;
 import org.osgi.service.metatype.annotations.AttributeDefinition;
 import org.osgi.service.metatype.annotations.Designate;
 import org.osgi.service.metatype.annotations.ObjectClassDefinition;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import static java.util.stream.Collectors.joining;
-import static java.util.stream.Collectors.toList;
+import static java.util.stream.Collectors.toSet;
 
 @Component
 @Designate(ocd = MountInfoProviderService.Props.class)
@@ -54,7 +56,7 @@ public class MountInfoProviderService {
 
         @AttributeDefinition(
             name = "Expected mounts",
-            description = "List of all expected read-only mount names"
+            description = "List of all required mount names"
         )
         String[] expectedMounts() default {};
 
@@ -90,7 +92,7 @@ public class MountInfoProviderService {
 
     private final List<MountInfoConfig> mountInfoConfigs = new CopyOnWriteArrayList<>();
 
-    private List<String> expectedMounts;
+    private Set<String> expectedMounts;
     private ServiceRegistration reg;
     private BundleContext context;
 
@@ -101,9 +103,9 @@ public class MountInfoProviderService {
             this.expectedMounts = Stream.of(expectedMounts)
                 .map(String::trim)
                 .filter(s -> !s.isEmpty())
-                .collect(toList());
+                .collect(toSet());
         } else {
-            this.expectedMounts = new ArrayList<>();
+            this.expectedMounts = new HashSet<>();
         }
         context = bundleContext;
         addMountInfoConfigFromProperties(props);
@@ -125,7 +127,7 @@ public class MountInfoProviderService {
         }
     }
 
-    @Reference(cardinality = ReferenceCardinality.MULTIPLE)
+    @Reference(cardinality = ReferenceCardinality.MULTIPLE, policy = ReferencePolicy.DYNAMIC)
     protected void bindMountInfoConfig(MountInfoConfig config) {
         if (!config.getPaths().isEmpty()) { // Ignore empty configs
             mountInfoConfigs.add(config);
@@ -137,9 +139,10 @@ public class MountInfoProviderService {
         if (context == null || reg != null) {
             return;
         }
-        if (!mountInfoConfigs.stream().allMatch(mountInfo -> expectedMounts.contains(mountInfo.getMountName()))) {
+        Set<String> providedMounts = mountInfoConfigs.stream().map(MountInfoConfig::getMountName).collect(toSet());
+        if (!providedMounts.containsAll(expectedMounts)) {
             LOG.info("Not all expected mounts are present yet (expected: {}, current: {}). Postponing configuration...",
-                expectedMounts, mountInfoConfigs.stream().map(MountInfoConfig::getMountName).collect(joining(",", "[", "]")));
+                expectedMounts, providedMounts);
             return;
         }
 
diff --git a/oak-store-composite/src/test/java/org/apache/jackrabbit/oak/composite/MountInfoProviderServiceTest.java b/oak-store-composite/src/test/java/org/apache/jackrabbit/oak/composite/MountInfoProviderServiceTest.java
index eff96869a6..08862e78b9 100644
--- a/oak-store-composite/src/test/java/org/apache/jackrabbit/oak/composite/MountInfoProviderServiceTest.java
+++ b/oak-store-composite/src/test/java/org/apache/jackrabbit/oak/composite/MountInfoProviderServiceTest.java
@@ -121,6 +121,19 @@ public class MountInfoProviderServiceTest {
         assertEquals(m, provider.getMountByPath("/c"));
     }
 
+    @Test
+    public void mountWithConfig_Multiple_NotAllExpected() {
+        registerActivateMountInfoConfig(propsBuilder().withMountName("foo").withMountPaths("/a").buildMountInfoProps());
+        registerActivateMountInfoConfig(propsBuilder().withMountName("bar").withMountPaths("/b").buildMountInfoProps());
+
+        MockOsgi.injectServices(service, context.bundleContext());
+        service.activate(context.bundleContext(), withExpectedMounts("foo", "bar", "baz"));
+        MockOsgi.activate(service, context.bundleContext(), ImmutableMap.of("expectedMounts", new String[]{"foo", "bar", "baz"}));
+
+        MountInfoProvider provider = context.getService(MountInfoProvider.class);
+        assertNull("Not all expected mounts have been provided", provider);
+    }
+
     @Test
     public void mountWithConfig_Name() {
         registerActivateMountInfoConfig(propsBuilder().withMountName("foo").withMountPaths("/a", "/b").buildMountInfoProps());