Pawel,

  the best DS alternative would be using two components:

 one EntityManager whiteboard listening for EntityManager services
and one PersonRepository registry managing the PersonRepository services.

A untested but compiling code example replacing EntityManager with DataSourceFactory and PersonRepository with DataSource yields:

 For the registry:

@Component(service=DataSourceRegistry.class)
public class DataSourceRegistry {

    private volatile BundleContext context;
private final Map<DataSourceFactory, ServiceRegistration<DataSource>> register = new ConcurrentHashMap<>();

    @Activate
    public void activate(BundleContext context) {
        this.context = context;
    }

public void register(DataSourceFactory dataSourceFactory) throws SQLException { DataSource dataSource = dataSourceFactory.createDataSource(getProps()); ServiceRegistration<DataSource> reference = context.registerService(DataSource.class, dataSource, null);
        register.put(dataSourceFactory, reference);
    }

    public void unregister(DataSourceFactory dataSourceFactory) {
ServiceRegistration<DataSource> registration = register.remove(dataSourceFactory);
        if (registration != null) {
            registration.unregister();
        }
    }

    private Properties getProps() {
        // TO DO
        return new Properties();
    }

}

For the whiteboard

@Component
public class DataSourceFactoryWhiteboard {

    private volatile DataSourceRegistry registry;

    @Reference
    public void setRegistry(DataSourceRegistry registry) {
        this.registry = registry;
    }

@Reference(name = "zDataSourceFactory", cardinality = ReferenceCardinality.MULTIPLE , policy = ReferencePolicy.DYNAMIC) public void addDataSourceFactory(DataSourceFactory factory) throws SQLException {
        registry.register(factory);
    }

    public void removeDataSourceFactory(DataSourceFactory factory) {
        registry.unregister(factory);
    }

}

Probably a matter of taste if you prefer this over the ServicTracker code.
Some remarks:
- For the whiteboard using zDataSourceFactory for the name of the dynamic reference ensures that no addDataSourceFactory methods are invoked before the static reference method setRegistry has been called - The main reason you need two components is that you cannot control the sequencing between a dynamic reference and the activate method. Using one component you would need the BundleContext from the activate method in the addDataSourceFactory method. This would lead to ugly code accumulating all DataSources in a thread safe list untill the activate method has been called. In short if you use ReferencePolicy.DYNAMIC you do not want an activate method on your component.

regards,
 Karel


On 24/04/2015 22:01, Pawel Pogorzelski wrote:
Neil, David, thank you. I'll go for a ServiceTracker hosted in a DS
component.

Pawel

On Fri, Apr 24, 2015 at 7:33 PM, Neil Bartlett <[email protected]> wrote:

Hi David, yes I agree. Additionally, using a DS component as the entry
point would allow for ease of configuration through Config Admin.

The blog post also needs to be updated for Java Generics…

Regards,
Neil

On 24 Apr 2015, at 17:21, David Jencks <[email protected]>
wrote:
It looks to me like your article leaves out an important detail, namely
what is supposed to cause the service tracker extensions to get set up in
the first place.  I'd suggest that the ideal answer is…. a DS component.
If your per-service objects need other "constant" service references (i.e.
they get the same ref for each per-service instance) then these can be
provided as DS references in this DS component.
I agree that using ServiceTracker in this way is reasonable and simpler
than only using DS.
thanks
david jencks

On Apr 24, 2015, at 12:05 PM, Neil Bartlett <[email protected]>
wrote:
Service tracker really is better for this. See my (very old) blog post:

http://njbartlett.name/2010/08/05/when-servicetrackers-trump-ds.html

In your case I recommend returning the ServiceRegistration object from
addingService().
Neil

--
Neil Bartlett


On Friday, 24 April 2015 at 16:53, Pawel Pogorzelski wrote:

Guys,
what's the standard approach for registering a DS component/OSGi
service in
response to a service appearing in the container? Is ServiceTracker
the way
to go? I'm using Declarative Services and would like stick to DS if
possible. Explanation of what I'm trying to accomplish below.

I'm using Felix with Gemini JPA which registers EntityManagerFactory as
OSGi service per each persistence unit configuration. Since I need to
open
connections to multiple DBs with the same schema I end up having
multiple
EntityManagerFactories in the container. I'd like to map them to DAL
classes one-by-one. So, assuming I have PersonReposity in DAL I'd like
to
have as many instances of it as EntityManagerFactories for the given
schema. Is SCR able to do it?

Cheers,
Pawel




---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]




---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to