Hello Matt,

I don’t think we should rely on the bundle activation / deactivation, but 
rather on the service registration / reregistration. OSGi allows to use 
MANDATORY_MULTIPLE cardinality for a @Reference - in this case, the service 
consumer will be informed every time there is a new service implementing given 
interface.

Then, if the CompositeDataStoreService thinks that all the required partial 
data stores are there, it can register itself as a BlobStore, using 
BundleContext#registerService.

Also, we probably need some kind of differentiation between “partial” and the 
“final” datastore (so the node store won’t pick the first one). For the node 
stores, we introduced a new property “role”. If the node store service is 
configured with this property in place, it registers a NodeStoreProvider rather 
than NodeStore (so we are sure the partial node store is not used directly).

So, my idea is as follows:

1. Create new BlobStoreProvider interface, with just one method: getBlobStore().
2. Modify all the existing blob store services adding them an optional “role” 
property (any string).
3. If the data store service is configured with this role, it should register 
the BlobStoreProvider service rather than a normal BlobStore.
4. The CompositeDataStoreService should be configured with a list of blob store 
roles it should wait for.
5. The CompositeDataStoreService has a MANDATORY_MULTIPLE @Reference of type 
BlobStoreProvider.
6. Once (a) the CompositeDataStoreService is activated and (b) all the blob 
store providers are there, it’ll register a BlobStore service, which will be 
picked up by the node store.

It’s similar to what we have in the Composite Node Store [1].

Regards,
Tomek

[1] 
https://github.com/apache/jackrabbit-oak/blob/trunk/oak-store-composite/src/main/java/org/apache/jackrabbit/oak/composite/CompositeNodeStoreService.java

-- 
Tomek Rękawek | Adobe Research | www.adobe.com
[email protected]

> On 3 Oct 2017, at 01:00, Matt Ryan <[email protected]> wrote:
> 
> Hi,
> 
> A CompositeDataStore in practice will generally have at least two other
> data stores “inside” it (if there are less than two, there’s little point
> in using CompositeDataStore).  I refer to these as “delegate” data stores
> or just “delegates”.
> 
> In my prototype, the addition and removal of delegates was OSGi-lifecycle
> aware:
> - When the CompositeDataStoreService was being activated, any delegate data
> stores implemented in already-active bundles would be created then.
> - As additional bundles were activated, if a bundle contained the
> implementation for a delegate it would be created then.
> - As bundles were deactivated, if a bundle contained the implementation for
> a delegate it would be deleted then.
> 
> My question then has to do with how to create the delegate data store.
> 
> I assumed that creating an instance of the Service class wouldn’t work
> because I can envision scenarios where I would want multiple delegate data
> stores of the same type - for example, two FileDataStores - and I am of the
> understanding that I wouldn’t be able to create more than one of any type
> of service.
> 
> So instead I simply constructed the delegate data stores using reflection.
> Something like this:
> 
> private DataStore createDelegateDataStore(String className, Properties
> properties, Bundle bundle) {
> if (Bundle.ACTIVE == bundle.getState()) {
> Class dataStoreClass = bundle.loadClass(className);
> DataStore dataStore = (DataStore) dataStoreClass.newInstance();
> Method setPropertiesMethod = dataStoreClass.getMethod(“setProperties”,
> Properties.class);
> setPropertiesMethod.invoke(dataStore, properties);
> }
> }
> 
> (Of course handling of exceptions like NoSuchMethodException,
> ClassNotFoundException, etc are not included here for brevity.)
> 
> Is a reasonable way to do this or should some other approach be used?  What
> would be the best way to go about doing this?
> 
> -MR

Reply via email to