You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@karaf.apache.org by Steinar Bang <sb...@dod.no> on 2025/02/04 20:07:33 UTC

Shared config between SCR components possible?

Is it possible to have two SCR components share a karaf config value and
have the other component pick up the changed config when one of the
components changes the config value?

I have a use case where I would like two different components, that
otherwise have no knowledge of each others, share an integer value,


Re: Shared config between SCR components possible?

Posted by Jean-Baptiste Onofré <jb...@nanthrax.net>.
Hi

It won’t work with reload policy: only one component can listen for config
change afair.

You can create another component on the config and use this component in
the other ones, that should work.

Regards
JB

Le jeu. 6 févr. 2025 à 21:02, Steinar Bang <sb...@dod.no> a écrit :

> >>>>> Jean-Baptiste Onofré <jb...@nanthrax.net>:
>
> > Hi Steinar
> > By default, SCR use the componentName as configuration PID.
> > However, you can pass the configurationPid to the component and so
> > several components can share the same configurationPid.
>
> Thanks!
>
> So far I've tried this:
> @Component(service=UserManagementService.class, immediate=true,
> configurationPid="no.priv.bang.authservice.config", property= {
> "excessiveFailedLoginLimit:Integer=3" } )
> public class UserManagementServiceProvider implements
> UserManagementService {
>
>     @Activate
>     public void activate(Map<String, Object> config) {
>         excessiveFailedLoginLimit = (int)
> config.get("excessiveFailedLoginLimit");
>     }
>
> and this:
> @Component( service=Realm.class, immediate=true,
> configurationPid="no.priv.bang.authservice.config" )
> public class AuthserviceDbRealm extends JdbcRealm {
>
>     @Activate
>     public void activate(Map<String, Object> config) {
>
> And UserManagementService.activate() receives excessiveFailedLoginLimit
> in its map, while AuthserviceDbRealm.activate() does not receive
> excessiveFailedLoginLimit in its map.
>
> I guess I could get a value in AuthserviceDbRealm.activate by setting a
> property argumenet to @Component there as well...?
>
> But setting the default two places does sort of defeat the purpose (I
> would like to set the default in a single place and use config to
> override config for both components).
>
>

Re: Shared config between SCR components possible?

Posted by "apache-karaf-user.pyr3x.com via user" <us...@karaf.apache.org>.
On Sun, Feb 09, 2025 at 05:50:03PM +0000, Paul McCulloch wrote:
> Got you. It's frequently frustrated me that the config admin metatype
> default value can't be used to provide values in the absence of a
> configuration. I've just used constants to provide default property values
> that can be shared between components.
> 
> On Sun, 9 Feb 2025 at 16:37, Steinar Bang <sb...@dod.no> wrote:
> 
> > >>>>> Paul McCulloch <pk...@gmail.com>:
> >
> > > To create a configuration use the web or ssh console, or create the file
> > > no.priv.bang.authservice.config.cfg in /etc.
> >
> > Yes, I know.
> >
> > But what I tried to achieve (if possible) was to have one component
> > create and populate the file with defaults set in code if not present,
> > and use the configured values in the file if present, and then have a
> > different component use that same configuration.
> >
> > If possible... and it looks like it wasn't possible (or at least: not
> > possible without a lot of code).
> >
> > Anyway, both components are connected to the same database using
> > DataSource injections and I do the shared value setting in the database
> > (it was simpler for component #2, I could just add the config value to
> > the existing select to retrieve the config value from the database).
> >
> > (I'll post links to the code in question to this thread after it is
> > pushed. Can't be pushed yet because I have a dependency I have to
> > release to maven central first... or... it can be pushed but the CI will
> > break)
> >
> >

You can use the OSGi Configurator to create the configurations.

https://docs.osgi.org/specification/osgi.cmpn/7.0.0/service.configurator.html

-- 
Chaz

Re: Shared config between SCR components possible?

Posted by Paul McCulloch <pk...@gmail.com>.
Got you. It's frequently frustrated me that the config admin metatype
default value can't be used to provide values in the absence of a
configuration. I've just used constants to provide default property values
that can be shared between components.

On Sun, 9 Feb 2025 at 16:37, Steinar Bang <sb...@dod.no> wrote:

> >>>>> Paul McCulloch <pk...@gmail.com>:
>
> > To create a configuration use the web or ssh console, or create the file
> > no.priv.bang.authservice.config.cfg in /etc.
>
> Yes, I know.
>
> But what I tried to achieve (if possible) was to have one component
> create and populate the file with defaults set in code if not present,
> and use the configured values in the file if present, and then have a
> different component use that same configuration.
>
> If possible... and it looks like it wasn't possible (or at least: not
> possible without a lot of code).
>
> Anyway, both components are connected to the same database using
> DataSource injections and I do the shared value setting in the database
> (it was simpler for component #2, I could just add the config value to
> the existing select to retrieve the config value from the database).
>
> (I'll post links to the code in question to this thread after it is
> pushed. Can't be pushed yet because I have a dependency I have to
> release to maven central first... or... it can be pushed but the CI will
> break)
>
>

Re: Shared config between SCR components possible?

Posted by Steinar Bang <sb...@dod.no>.
>>>>> Paul McCulloch <pk...@gmail.com>:

> To create a configuration use the web or ssh console, or create the file
> no.priv.bang.authservice.config.cfg in /etc.

Yes, I know.

But what I tried to achieve (if possible) was to have one component
create and populate the file with defaults set in code if not present,
and use the configured values in the file if present, and then have a
different component use that same configuration.

If possible... and it looks like it wasn't possible (or at least: not
possible without a lot of code).

Anyway, both components are connected to the same database using
DataSource injections and I do the shared value setting in the database
(it was simpler for component #2, I could just add the config value to
the existing select to retrieve the config value from the database).

(I'll post links to the code in question to this thread after it is
pushed. Can't be pushed yet because I have a dependency I have to
release to maven central first... or... it can be pushed but the CI will
break) 


Re: Shared config between SCR components possible?

Posted by Paul McCulloch <pk...@gmail.com>.
I'm a bit late to the party, but I don't see an explicit mention of
actually creating the configuration. Adding a property to the @Component
doesn't create a configuration - it just supplies a default value in the
Map provided to the activate method if one isn't defined in a configuration.

To create a configuration use the web or ssh console, or create the file
no.priv.bang.authservice.config.cfg in /etc.

On Thu, 6 Feb 2025 at 20:02, Steinar Bang <sb...@dod.no> wrote:

> >>>>> Jean-Baptiste Onofré <jb...@nanthrax.net>:
>
> > Hi Steinar
> > By default, SCR use the componentName as configuration PID.
> > However, you can pass the configurationPid to the component and so
> > several components can share the same configurationPid.
>
> Thanks!
>
> So far I've tried this:
> @Component(service=UserManagementService.class, immediate=true,
> configurationPid="no.priv.bang.authservice.config", property= {
> "excessiveFailedLoginLimit:Integer=3" } )
> public class UserManagementServiceProvider implements
> UserManagementService {
>
>     @Activate
>     public void activate(Map<String, Object> config) {
>         excessiveFailedLoginLimit = (int)
> config.get("excessiveFailedLoginLimit");
>     }
>
> and this:
> @Component( service=Realm.class, immediate=true,
> configurationPid="no.priv.bang.authservice.config" )
> public class AuthserviceDbRealm extends JdbcRealm {
>
>     @Activate
>     public void activate(Map<String, Object> config) {
>
> And UserManagementService.activate() receives excessiveFailedLoginLimit
> in its map, while AuthserviceDbRealm.activate() does not receive
> excessiveFailedLoginLimit in its map.
>
> I guess I could get a value in AuthserviceDbRealm.activate by setting a
> property argumenet to @Component there as well...?
>
> But setting the default two places does sort of defeat the purpose (I
> would like to set the default in a single place and use config to
> override config for both components).
>
>

Re: Shared config between SCR components possible?

Posted by Steinar Bang <sb...@dod.no>.
>>>>> Jean-Baptiste Onofré <jb...@nanthrax.net>:

> Hi Steinar
> By default, SCR use the componentName as configuration PID.
> However, you can pass the configurationPid to the component and so
> several components can share the same configurationPid.

Thanks!

So far I've tried this:
@Component(service=UserManagementService.class, immediate=true, configurationPid="no.priv.bang.authservice.config", property= { "excessiveFailedLoginLimit:Integer=3" } )
public class UserManagementServiceProvider implements UserManagementService {

    @Activate
    public void activate(Map<String, Object> config) {
        excessiveFailedLoginLimit = (int) config.get("excessiveFailedLoginLimit");
    }

and this:
@Component( service=Realm.class, immediate=true, configurationPid="no.priv.bang.authservice.config" )
public class AuthserviceDbRealm extends JdbcRealm {

    @Activate
    public void activate(Map<String, Object> config) {

And UserManagementService.activate() receives excessiveFailedLoginLimit
in its map, while AuthserviceDbRealm.activate() does not receive
excessiveFailedLoginLimit in its map.

I guess I could get a value in AuthserviceDbRealm.activate by setting a
property argumenet to @Component there as well...?

But setting the default two places does sort of defeat the purpose (I
would like to set the default in a single place and use config to
override config for both components).


Re: Shared config between SCR components possible?

Posted by Jean-Baptiste Onofré <jb...@nanthrax.net>.
Hi Steinar

By default, SCR use the componentName as configuration PID.
However, you can pass the configurationPid to the component and so
several components can share the same configurationPid.

Regards
JB

On Tue, Feb 4, 2025 at 9:07 PM Steinar Bang <sb...@dod.no> wrote:
>
> Is it possible to have two SCR components share a karaf config value and
> have the other component pick up the changed config when one of the
> components changes the config value?
>
> I have a use case where I would like two different components, that
> otherwise have no knowledge of each others, share an integer value,
>

Re: Shared config between SCR components possible?

Posted by Steinar Bang <sb...@dod.no>.
>>>>> Paul Spencer <pa...@me.com>:

> Many components can share a configurationPid and changes to properties in the configurationPid will notify all of the components.
> @Component(name = "my-component", immediate = true, configurationPid = "org.apache.karaf.example.config”)
> public class MyComponent {
> …
> }

> @Component(name = “my-anothercomponentt", immediate = true, configurationPid = "org.apache.karaf.example.config”)
> public class MyAnotherComponent {
> …
> }

> @Component(name = “my-thirdcomponent", immediate = true, configurationPid = "org.apache.karaf.example.config”)
> public class MyThirdComponent {
> …
> }

Thanks for the example! I will try!


Re: Shared config between SCR components possible?

Posted by Paul Spencer <pa...@me.com>.
Many components can share a configurationPid and changes to properties in the configurationPid will notify all of the components.

@Component(name = "my-component", immediate = true, configurationPid = "org.apache.karaf.example.config”)
public class MyComponent {
…
}

@Component(name = “my-anothercomponentt", immediate = true, configurationPid = "org.apache.karaf.example.config”)
public class MyAnotherComponent {
…
}

@Component(name = “my-thirdcomponent", immediate = true, configurationPid = "org.apache.karaf.example.config”)
public class MyThirdComponent {
…
}


Paul Spencer

> On Feb 4, 2025, at 3:07 PM, Steinar Bang <sb...@dod.no> wrote:
> 
> Is it possible to have two SCR components share a karaf config value and
> have the other component pick up the changed config when one of the
> components changes the config value?
> 
> I have a use case where I would like two different components, that
> otherwise have no knowledge of each others, share an integer value,
> 


Re: Shared config between SCR components possible?

Posted by Christian Lutz <Ch...@kreeloo.de>.
Good morning,

as far as I know it isnt possible. I tried it several times in the past and failed. 

Instead of the db I have created an additional service that uses that config and provides it to other services. 

kind regards
Christian 

> Am 07.02.2025 um 07:50 schrieb Steinar Bang <sb...@dod.no>:
> 
> 
>> 
>>>>>> Steinar Bang <sb...@dod.no>:
> 
>> Is it possible to have two SCR components share a karaf config value and
>> have the other component pick up the changed config when one of the
>> components changes the config value?
> 
>> I have a use case where I would like two different components, that
>> otherwise have no knowledge of each others, share an integer value,
> 
> To provide a little more context.
> 
> The SCR components that should share a config value are a component that
> exposes a shiro "realm" OSGi service[1] and a component that exposes an
> OSGi service that provides the backend for a react.js admin UI for
> creating and modifying users, roles and permissions[2].
> 
> They are both part of a karaf application that I made to work as a forms
> auth service for nginx[3]
> 
> I am extending the shiro realm[4] in [1] to handle repeatedly failed
> logins and lock the account when a limit is reached.
> 
> And it's that limit I would like to share between the admin backend[2]
> and the realm[1].
> 
> Since both components talkt to the database the simplest way would be to
> add that value to the database schema, but a table with a single value
> felt... wrong... so I decided to explore the configuration approach.
> 
> Short story: if I can do it with config with a minimum of code (just
> annotations) I'll do it with config. But if not I'll bite the bullet and
> create a table with a single value in the database.
> 
> (and after sleeping on it I think I will try the database approach, in
> that way I can just join the config value for limit for number of failed
> logins in the select that checks for number of logins done so far... I
> think I will do that...)
> 
> 
> References:
> [1] <https://github.com/steinarb/authservice/blob/b3b03de37b618cd5a78dba6fc6719131754d4a98/authservice/authservice.web.security.dbrealm/src/main/java/no/priv/bang/authservice/web/security/dbrealm/AuthserviceDbRealm.java#L11>
> [2] <https://github.com/steinarb/authservice/blob/b3b03de37b618cd5a78dba6fc6719131754d4a98/authservice/authservice.users/src/main/java/no/priv/bang/authservice/users/UserManagementServiceProvider.java#L56>
> [3] <https://github.com/steinarb/authservice?tab=readme-ov-file#forms-based-nginx-login-and-pluggable-shiro-auth-in-karaf>
> [4] <https://shiro.apache.org/realm.html>
> 


Re: Shared config between SCR components possible?

Posted by Steinar Bang <sb...@dod.no>.
>>>>> Steinar Bang <sb...@dod.no>:

> Is it possible to have two SCR components share a karaf config value and
> have the other component pick up the changed config when one of the
> components changes the config value?

> I have a use case where I would like two different components, that
> otherwise have no knowledge of each others, share an integer value,

To provide a little more context.

The SCR components that should share a config value are a component that
exposes a shiro "realm" OSGi service[1] and a component that exposes an
OSGi service that provides the backend for a react.js admin UI for
creating and modifying users, roles and permissions[2].

They are both part of a karaf application that I made to work as a forms
auth service for nginx[3]

I am extending the shiro realm[4] in [1] to handle repeatedly failed
logins and lock the account when a limit is reached.

And it's that limit I would like to share between the admin backend[2]
and the realm[1].

Since both components talkt to the database the simplest way would be to
add that value to the database schema, but a table with a single value
felt... wrong... so I decided to explore the configuration approach.

Short story: if I can do it with config with a minimum of code (just
annotations) I'll do it with config. But if not I'll bite the bullet and
create a table with a single value in the database.

(and after sleeping on it I think I will try the database approach, in
that way I can just join the config value for limit for number of failed
logins in the select that checks for number of logins done so far... I
think I will do that...)


References:
 [1] <https://github.com/steinarb/authservice/blob/b3b03de37b618cd5a78dba6fc6719131754d4a98/authservice/authservice.web.security.dbrealm/src/main/java/no/priv/bang/authservice/web/security/dbrealm/AuthserviceDbRealm.java#L11>
 [2] <https://github.com/steinarb/authservice/blob/b3b03de37b618cd5a78dba6fc6719131754d4a98/authservice/authservice.users/src/main/java/no/priv/bang/authservice/users/UserManagementServiceProvider.java#L56>
 [3] <https://github.com/steinarb/authservice?tab=readme-ov-file#forms-based-nginx-login-and-pluggable-shiro-auth-in-karaf>
 [4] <https://shiro.apache.org/realm.html>


Re: Shared config between SCR components possible?

Posted by Steinar Bang <sb...@dod.no>.
>>>>> Steinar Bang <sb...@dod.no>:
>>>>> Eric Lilja <mi...@gmail.com>:

>> Does it not work to annotate both service implementations
>> with @Designate(ocd = Config.class) (replace Config.class with your config
>> class)?

> Thanks for the tip! I will try!

Hm... this is different to the way Paul and JB suggested...?

I picked the way I interpreted Paul's and JB's suggestion first because
that was most similar to the way I've created config for @Components
before (and I've never created a Config class, I've always used a Map).

But @Designate is different. Then you do need to create a Config class.

I have to think about this!



Re: Shared config between SCR components possible?

Posted by Steinar Bang <sb...@dod.no>.
>>>>> Eric Lilja <mi...@gmail.com>:

> Does it not work to annotate both service implementations
> with @Designate(ocd = Config.class) (replace Config.class with your config
> class)?

Thanks for the tip! I will try!


Re: Shared config between SCR components possible?

Posted by Eric Lilja <mi...@gmail.com>.
Does it not work to annotate both service implementations
with @Designate(ocd = Config.class) (replace Config.class with your config
class)?

- Eric L

On Tue, Feb 4, 2025 at 9:09 PM Steinar Bang <sb...@dod.no> wrote:

> Is it possible to have two SCR components share a karaf config value and
> have the other component pick up the changed config when one of the
> components changes the config value?
>
> I have a use case where I would like two different components, that
> otherwise have no knowledge of each others, share an integer value,
>
>