You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@sling.apache.org by Nicola Cisternino <nc...@cointa.it> on 2020/12/11 15:16:11 UTC
Datasource selection
Hi all
I'm using Sling Datasource Bundle (org.apache.sling.datasource) and I
configured two entries named (datasource.name property): *source1* and
*source2*.
I can select single datasource using DS annotations:
@Reference(target =
"(&(objectclass=javax.sql.DataSource)(datasource.name=*source1*))")
private DataSource dataSource;
But ... how can I select single datasource programmatically ?
Thanks a lot.
Regards.
Re: Datasource selection
Posted by Bertrand Delacretaz <bd...@apache.org>.
Hi,
On Fri, Dec 11, 2020 at 4:16 PM Nicola Cisternino <nc...@cointa.it> wrote:
> ...I can select single datasource using DS annotations:
> @Reference(target =
> "(&(objectclass=javax.sql.DataSource)(datasource.name=*source1*))")
> private DataSource dataSource;
>
> But ... how can I select single datasource programmatically ?
The BundleContext.getServiceReferences(java.lang.Class<S> clazz,
java.lang.String filter) method [1] takes an OSGi LDAP-style filter
with the same syntax quoted above, that's probably what you need.
There are a number of examples using it in the Sling codebase.
-Bertrand
[1] https://docs.osgi.org/javadoc/osgi.core/7.0.0/org/osgi/framework/BundleContext.html#getServiceReferences-java.lang.Class-java.lang.String-
Re: Datasource selection
Posted by Nicola Cisternino <nc...@cointa.it>.
Il 12/15/20 6:34 PM, Eric Norman ha scritto:
> For simplicity, you could probably let the framework do a bit more work for
> you and remove the need for the BundleContext field by using the reference
> bind method technique that sends you the service instance + the properties.
>
> For example, something like this:
>
> private Map<String, DataSource> dataSources = new ConcurrentHashMap<>();
>
> @Reference(service=DataSource.class, policy = DYNAMIC, cardinality=MULTIPLE)
> void bindDataSource(DataSource ds, Map<String, Object> properties) {
> dataSources.put((String) properties.getProperty("datasource.name"), ds);
> }
>
> void unbindDataSource(DataSource ds, Map<String, Object> properties) {
> dataSources.remove((String) properties.getProperty("datasource.name"),
> ds);
> }
>
>
> On Tue, Dec 15, 2020 at 8:13 AM Bertrand Delacretaz <bd...@apache.org>
> wrote:
>
>> On Tue, Dec 15, 2020 at 4:58 PM Robert Munteanu <ro...@apache.org>
>> wrote:
>>> ...This way you get the datasources injected and via SCR and you get to
>>> use the datasource.name as a key...
>> sounds good and it's certainly more efficient than what I suggested.
>>
>> -Bertrand
>>
Thank you Bertrand and Eric !
Your solution works fine !
--
Nicola Cisternino
CTO - Ergon Project Manager - IT Architect
Cointa s.r.l.
Tel. +39 080 9371015
ncister@cointa.it
http://www.cointa.it
Re: Datasource selection
Posted by Eric Norman <en...@apache.org>.
For simplicity, you could probably let the framework do a bit more work for
you and remove the need for the BundleContext field by using the reference
bind method technique that sends you the service instance + the properties.
For example, something like this:
private Map<String, DataSource> dataSources = new ConcurrentHashMap<>();
@Reference(service=DataSource.class, policy = DYNAMIC, cardinality=MULTIPLE)
void bindDataSource(DataSource ds, Map<String, Object> properties) {
dataSources.put((String) properties.getProperty("datasource.name"), ds);
}
void unbindDataSource(DataSource ds, Map<String, Object> properties) {
dataSources.remove((String) properties.getProperty("datasource.name"),
ds);
}
On Tue, Dec 15, 2020 at 8:13 AM Bertrand Delacretaz <bd...@apache.org>
wrote:
> On Tue, Dec 15, 2020 at 4:58 PM Robert Munteanu <ro...@apache.org>
> wrote:
> > ...This way you get the datasources injected and via SCR and you get to
> > use the datasource.name as a key...
>
> sounds good and it's certainly more efficient than what I suggested.
>
> -Bertrand
>
Re: Datasource selection
Posted by Bertrand Delacretaz <bd...@apache.org>.
On Tue, Dec 15, 2020 at 4:58 PM Robert Munteanu <ro...@apache.org> wrote:
> ...This way you get the datasources injected and via SCR and you get to
> use the datasource.name as a key...
sounds good and it's certainly more efficient than what I suggested.
-Bertrand
Re: Datasource selection
Posted by Robert Munteanu <ro...@apache.org>.
On Tue, 2020-12-15 at 14:35 +0100, Nicola Cisternino wrote:
> Hi Robert.
> Declarative services are best way ... but i need to use different
> datasources starting from a (request) payload attribute received from
> a
> servlet ...
> So I decided to migrate (in a bundle service) the custom pool engine
> that we used in the old webapp.
I would suggest trying the following (may need adjustment, typing out
of memory):
private Map<String, DataSource> dataSources = new
ConcurrentHashMap<>();
private BundleContext ctx;
@Activate
void activate(BundleContext ctx) {
this.ctx = ctx;
}
@Reference(service=DataSource.class, policy = DYNAMIC,
cardinality=MULTIPLE)
void bindDataSource(ServiceReference<DataSource> ref) {
dataSources.put((String) ref.getProperty("datasource.name"),
ctx.getServiceReference(ref));
}
void unbindDataSource(ServiceReference<DataSource> ref) {
dataSources.remove((String) ref.getProperty("datasource.name"));
}
This way you get the datasources injected and via SCR and you get to
use the datasource.name as a key. There is probably more defensive
coding needed, but this is what I would use as a starting point.
Thanks,
Robert
>
> Thanks.
> Nicola.
>
> Il 12/14/20 12:55 PM, Robert Munteanu ha scritto:
> > Hi Nicola,
> >
> > On Fri, 2020-12-11 at 16:16 +0100, Nicola Cisternino wrote:
> > > Hi all
> > >
> > > I'm using Sling Datasource Bundle (org.apache.sling.datasource)
> > > and I
> > > configured two entries named (datasource.name property):
> > > *source1*
> > > and
> > > *source2*.
> > > I can select single datasource using DS annotations:
> > >
> > > @Reference(target =
> > > "(&(objectclass=javax.sql.DataSource)(datasource.name=*source1*))
> > > ")
> > > private DataSource dataSource;
> > >
> > > But ... how can I select single datasource programmatically ?
> > How do you select the datasources programatically now?
> >
> > As a side note, I'd try to stick to declarative services as much as
> > possible as it makes things simpler to write and understand.
> >
> > Thanks,
> > Robert
> >
>
Re: Datasource selection
Posted by Nicola Cisternino <nc...@cointa.it>.
Hi Robert.
Declarative services are best way ... but i need to use different
datasources starting from a (request) payload attribute received from a
servlet ...
So I decided to migrate (in a bundle service) the custom pool engine
that we used in the old webapp.
Thanks.
Nicola.
Il 12/14/20 12:55 PM, Robert Munteanu ha scritto:
> Hi Nicola,
>
> On Fri, 2020-12-11 at 16:16 +0100, Nicola Cisternino wrote:
>> Hi all
>>
>> I'm using Sling Datasource Bundle (org.apache.sling.datasource) and I
>> configured two entries named (datasource.name property): *source1*
>> and
>> *source2*.
>> I can select single datasource using DS annotations:
>>
>> @Reference(target =
>> "(&(objectclass=javax.sql.DataSource)(datasource.name=*source1*))")
>> private DataSource dataSource;
>>
>> But ... how can I select single datasource programmatically ?
> How do you select the datasources programatically now?
>
> As a side note, I'd try to stick to declarative services as much as
> possible as it makes things simpler to write and understand.
>
> Thanks,
> Robert
>
Re: Datasource selection
Posted by Robert Munteanu <ro...@apache.org>.
Hi Nicola,
On Fri, 2020-12-11 at 16:16 +0100, Nicola Cisternino wrote:
> Hi all
>
> I'm using Sling Datasource Bundle (org.apache.sling.datasource) and I
> configured two entries named (datasource.name property): *source1*
> and
> *source2*.
> I can select single datasource using DS annotations:
>
> @Reference(target =
> "(&(objectclass=javax.sql.DataSource)(datasource.name=*source1*))")
> private DataSource dataSource;
>
> But ... how can I select single datasource programmatically ?
How do you select the datasources programatically now?
As a side note, I'd try to stick to declarative services as much as
possible as it makes things simpler to write and understand.
Thanks,
Robert