From c41a3711c71e3b2814f78cf7c9a63cc40b2a9e54 Mon Sep 17 00:00:00 2001
From: Robert Munteanu <rombert@apache.org>
Date: Tue, 29 Nov 2016 14:03:38 +0200
Subject: [PATCH] OAK-5179 - MultiplexingNodeStoreService does not register an
 OSGi service for oak.api.Descriptors

Register the relevant Descriptors from the SegmentNodeStoreFactory.

Also make sure to tolerate NodeStore instances being bound before the
component is activated ( which is the norm ).
---
 .../multiplex/MultiplexingNodeStoreService.java    | 10 +++++
 .../oak/segment/SegmentNodeStoreFactory.java       | 50 ++++++++++++++++++++++
 2 files changed, 60 insertions(+)

diff --git a/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/multiplex/MultiplexingNodeStoreService.java b/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/multiplex/MultiplexingNodeStoreService.java
index 4d63797..478ccff 100644
--- a/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/multiplex/MultiplexingNodeStoreService.java
+++ b/oak-core/src/main/java/org/apache/jackrabbit/oak/plugins/multiplex/MultiplexingNodeStoreService.java
@@ -163,6 +163,11 @@ public class MultiplexingNodeStoreService {
         NodeStoreWithProps newNs = new NodeStoreWithProps(ns, config);
         nodeStores.add(newNs);
 
+        if (context == null) {
+            LOG.info("bindNodeStore: context is null, delaying reconfiguration");
+            return;
+        }
+
         unregisterMultiplexingNodeStore();
         registerMultiplexingNodeStore();
     }
@@ -175,6 +180,11 @@ public class MultiplexingNodeStoreService {
             }
         }
 
+        if (context == null) {
+            LOG.info("unbindNodeStore: context is null, delaying reconfiguration");
+            return;
+        }
+
         unregisterMultiplexingNodeStore();
         registerMultiplexingNodeStore();
     }
diff --git a/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentNodeStoreFactory.java b/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentNodeStoreFactory.java
index d71e047..f016ca1 100644
--- a/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentNodeStoreFactory.java
+++ b/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/SegmentNodeStoreFactory.java
@@ -35,8 +35,11 @@ import org.apache.felix.scr.annotations.Property;
 import org.apache.felix.scr.annotations.Reference;
 import org.apache.felix.scr.annotations.ReferenceCardinality;
 import org.apache.felix.scr.annotations.ReferencePolicy;
+import org.apache.jackrabbit.commons.SimpleValueFactory;
+import org.apache.jackrabbit.oak.api.Descriptors;
 import org.apache.jackrabbit.oak.commons.PropertiesUtil;
 import org.apache.jackrabbit.oak.osgi.OsgiWhiteboard;
+import org.apache.jackrabbit.oak.plugins.identifier.ClusterRepositoryInfo;
 import org.apache.jackrabbit.oak.segment.file.FileStore;
 import org.apache.jackrabbit.oak.segment.file.FileStoreBuilder;
 import org.apache.jackrabbit.oak.segment.file.FileStoreStatsMBean;
@@ -48,6 +51,7 @@ import org.apache.jackrabbit.oak.spi.state.ProxyNodeStore;
 import org.apache.jackrabbit.oak.spi.whiteboard.Registration;
 import org.apache.jackrabbit.oak.spi.whiteboard.WhiteboardExecutor;
 import org.apache.jackrabbit.oak.stats.StatisticsProvider;
+import org.apache.jackrabbit.oak.util.GenericDescriptors;
 import org.osgi.framework.ServiceRegistration;
 import org.osgi.service.component.ComponentContext;
 import org.slf4j.Logger;
@@ -111,6 +115,11 @@ public class SegmentNodeStoreFactory extends ProxyNodeStore {
     )
     public static final String CUSTOM_BLOB_STORE = "customBlobStore";
 
+    @Property(boolValue = false,
+            label = "Register JCR descriptors as OSGi services",
+            description="Should only be done for one factory instance")
+    public static final String REGISTER_DESCRIPTORS = "registerDescriptors";
+
     private final Logger log = LoggerFactory.getLogger(getClass());
 
     private String name;
@@ -136,6 +145,12 @@ public class SegmentNodeStoreFactory extends ProxyNodeStore {
 
     private String role;
 
+    private boolean registerRepositoryDescriptors;
+
+    private ServiceRegistration clusterIdDescriptorRegistration;
+
+    private ServiceRegistration discoveryLiteDescriptorRegistration;
+
     @Override
     protected SegmentNodeStore getNodeStore() {
         checkState(segmentNodeStore != null, "service must be activated when used");
@@ -149,6 +164,7 @@ public class SegmentNodeStoreFactory extends ProxyNodeStore {
         this.role = property(ROLE);
         //In secondaryNodeStore mode customBlobStore is always enabled
         this.customBlobStore = Boolean.parseBoolean(property(CUSTOM_BLOB_STORE)) || isSecondaryStoreMode();
+        this.registerRepositoryDescriptors = Boolean.parseBoolean(property(REGISTER_DESCRIPTORS));
         log.info("activate: SegmentNodeStore '"+role+"' starting.");
 
         if (blobStore == null && customBlobStore) {
@@ -205,6 +221,32 @@ public class SegmentNodeStoreFactory extends ProxyNodeStore {
                 },
                 props);
         log.info("Registered NodeStoreProvider backed by SegmentNodeStore of type '{}'", role);
+
+        if (registerRepositoryDescriptors) {
+
+            log.info("Registering JCR descriptors");
+
+            // TODO - copied from SegmentNodeStoreService
+            // ensure a clusterId is initialized
+            // and expose it as 'oak.clusterid' repository descriptor
+            GenericDescriptors clusterIdDesc = new GenericDescriptors();
+            clusterIdDesc.put(ClusterRepositoryInfo.OAK_CLUSTERID_REPOSITORY_DESCRIPTOR_KEY,
+                    new SimpleValueFactory().createValue(
+                            ClusterRepositoryInfo.getOrCreateId(segmentNodeStore)), true, false);
+            clusterIdDescriptorRegistration = context.getBundleContext().registerService(
+                    Descriptors.class.getName(),
+                    clusterIdDesc,
+                    new Hashtable<>()
+            );
+
+            // Register "discovery lite" descriptors
+            discoveryLiteDescriptorRegistration = context.getBundleContext().registerService(
+                    Descriptors.class.getName(),
+                    new SegmentDiscoveryLiteDescriptors(segmentNodeStore),
+                    new Hashtable<>()
+            );
+        }
+
     }
 
     private boolean registerSegmentStore() throws IOException {
@@ -266,6 +308,14 @@ public class SegmentNodeStoreFactory extends ProxyNodeStore {
             executor.stop();
             executor = null;
         }
+        if (clusterIdDescriptorRegistration != null) {
+            clusterIdDescriptorRegistration.unregister();
+            clusterIdDescriptorRegistration = null;
+        }
+        if (discoveryLiteDescriptorRegistration != null) {
+            discoveryLiteDescriptorRegistration.unregister();
+            discoveryLiteDescriptorRegistration = null;
+        }
     }
 
     private File getBaseDirectory() {
-- 
2.10.2

