You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@karaf.apache.org by "Leschke, Scott" <SL...@medline.com> on 2017/12/13 21:24:47 UTC

RE: [osgi-dev] Create instance of factory configuration at runtime

Hey Tim,

Thanks for this. Yes that worked. I recall seeing something about this a number of months ago but didn’t pay much attention since it didn’t apply to me at the time. Not sure why I didn’t think to give that a try though.

Two additional questions for anybody who cares to answer.


1)      If “?” isn’t used, what would the location argument look like?  Is it like a bundle symbolic id, with wildcards perhaps? It’s unclear to me how this would be used even if you wanted to.

2)      Now for a Karaf question to any/all takers. When a service instance is created this way, is there a way to associate a .cfg file with it so that the service configuration will persist across Karaf upgrades?  I know that if a Configuration record is updated, the service’s corresponding .cfg file is updated, but if you create a new service, you don’t get a .cfg file.

Scott

From: Tim Ward [mailto:tim.ward@paremus.com]
Sent: Saturday, December 09, 2017 3:04 AM
To: Leschke, Scott; OSGi Developer Mail List
Subject: Re: [osgi-dev] Create instance of factory configuration at runtime

Hi Scott,

That does work, but Configuration Admin has an old feature called location binding. This feature prevents a configuration being delivered to bundles other than the bundle with the specified bundle location.

The one-arg version of createFactoryConfiguration that you’re using defaults the bundle location to the location of the bundle which got the ConfigurationAdmin service instance that you’re using. This is almost never the correct location as it usually means only the management bundle can see your configuration.

The location binding behaviour is so annoying that the general recommendation is to disable it by using the two arg versions of Config Admin methods with a wildcard location binding (a “?”).

My guess is that the two arg version will give you what you’re looking for.

Tim
Sent from my iPhone

On 9 Dec 2017, at 00:36, Leschke, Scott via osgi-dev <os...@mail.osgi.org>> wrote:
How does one create a new instance of a factory configuration programmatically?

I thought it was like

ConfigurationAdmin ca;
ca.createFactoryConfiguration(“my.configuration.pid”).update(newServiceProps);

but that doesn’t seem to work for me.

Thanks in advance,

Scott
_______________________________________________
OSGi Developer Mail List
osgi-dev@mail.osgi.org<ma...@mail.osgi.org>
https://mail.osgi.org/mailman/listinfo/osgi-dev

RE: [osgi-dev] Create instance of factory configuration at runtime

Posted by "Leschke, Scott" <SL...@medline.com>.
Hi Tim,

Thanks for the response. Regarding

  *   It’s important to remember that every time you call “createFactoryConfiguration” you’re getting a *new* configuration, not updating an existing one. The code snipped below will create an increasing number of configurations over time
Yes, I’m aware of that.  That’s what I want.  I just want / need to be able to create a service instance in response to a form being filled out. Writing a .cfg file isn’t optimal do to the polling delay but I need to be able to place the .cfg at a particular location so I create the Configuration object after which I create the associated .cfg file in the correct location.  Seems to work well enough, at least to the level I’ve tested it thus far.

  *   You don’t set the PID or FACTORYPID in the configuration dictionary. Config Admin does that for you.
I didn’t expect this to be the case but the example that I received seemed to indicate that it was necessary.  I think it was just intended for context but wasn’t sure.

My question regarding location was mostly just a curiosity type thing. Just thought I’d ask.

Scott

From: Tim Ward [mailto:tim.ward@paremus.com]
Sent: Monday, December 18, 2017 5:04 AM
To: user@karaf.apache.org
Subject: Re: [osgi-dev] Create instance of factory configuration at runtime

Hi Scott,

A few things:


  *   It’s important to remember that every time you call “createFactoryConfiguration” you’re getting a *new* configuration, not updating an existing one. The code snipped below will create an increasing number of configurations over time
  *   You don’t set the PID or FACTORYPID in the configuration dictionary. Config Admin does that for you.
  *   You will need to be sure that you don’t end up infinitely looping if your component ever attempts to update its own configuration.

In answer to your earlier question about the bundle location parameter - it is supposed to match against the URL from which the bundle was installed (literally the bundle location that you can get from the bundle). You can do targeting of pids against symbolicname/version, but that’s done in a different way. If you’re interested I can recommend reading the Config Admin spec.

Tim




On 15 Dec 2017, at 22:11, Leschke, Scott <SL...@medline.com>> wrote:

Hi again Michael,

Just to be clear, you’re saying that something like the following will achieve the desired affect:

@Reference
volatile ConfigurationAdmin ca;

Dictionary<String,Object> serviceProps = toDictionary(previouslyInitializedServiceProperties);

serviceProps.put(ConfigurationAdmin.SERVICE_FACTORYPID, “my.factory.pid”);
serviceProps.put(“org.apache.felix.fileinstall.filename”, “my.service.config.path”);

ca.createFactoryConfiguration(“my.factory.pid”, “?”)
    .update(serviceProps);

// Manually write the .cfg at the previously specified location.
writeCfgHere(“my.service.config.path”);

Is this a correct understanding?  If so, my only comment would be that it would seem that respecifying the factory PID seems as it’s given in the call to createFactoryConfiguration.

Scott

From: Michael Wirth [mailto:mwirth@apollon.de]
Sent: Friday, December 15, 2017 2:09 PM
To: Leschke, Scott
Cc: OSGi Developer Mail List
Subject: Re: [osgi-dev] Create instance of factory configuration at runtime

Hi Scott,

I did a short successful test. See the following steps:

1. create a new configuration: Configuration config = ca.createFactoryConfiguration(factoryPid, „?“);
2. create and set the following properties: prop.put(„service.factoryPid“, factoryPid); prop.put(„felix.fileinstall.filename“, path), prop.put(„service.factoryPid“, factoryPid); config.update(prop);
3. create the configurationfile using variable path (same as for „felix.fileinstall.filename“). Managed by Fileinstall.

After a click on a button on a webpage the configuration was created and displayed without delay.
If the file is changed, the webpage UI gets updated and the Web Console shows the new value(s).
If I change a value in the Web Console the value in the webpage UI and in the file is changed, and so on ...

It was only a short test based on an idea, so no guarantee.

Michael

Am 15.12.2017 um 17:56 schrieb Leschke, Scott <SL...@medline.com>>:

Hi Michael,

Thanks for the response. Yes I’m aware of that mechanism. That’s part of Karaf’s hot deploy scheme which I’ve used extensively to date. What I need to do is create new service instances from a UI and have the created services available immediately, i.e. without the delay, so that the UI can update without a refresh.

I know that if you modify a service programmatically, the corresponding .cfg, if the service has one, is updated.  I can’t see anyway to tell the CA service to persist the new service configuration to a particular location. For my app, I’ve overridden the org.apache.felix.fileinstall.dir-deploy.cfg file with my own that causes Karaf to scan a directory hierarchy outside of the Karaf install hierarchy. That way I don’t have to physically move the directory structure whenever I update Karaf.

Anyway, what I’m curious about is whether a .cfg file can/will be associated with a service after it’s already been created using createFactoryConfiguration.update(props);  ?  If I just create one after the fact, where I want it to reside, I’m curious if it will get associated with the existing service. Of course I can test this and intend to, I just haven’t got to that point yet.

Of course if someone can tell me definitively whether that will work or not, I won’t have to bother.

Scott

From: Michael Wirth [mailto:mwirth@apollon.de]
Sent: Friday, December 15, 2017 9:00 AM
To: Leschke, Scott; OSGi Developer Mail List
Subject: Re: [osgi-dev] Create instance of factory configuration at runtime

Hi Scott,

to point 2)
about 2-3 years ago I had a similar problem. The 'solution' was to create a configuration file (with the properties) in the 'felix.fileinstall.dir'-Directory. If it is a Factory the filename should be <componentname>-<uniqueId>.cfg
After some time (depending on configuration) FileInstall will scan the file, create the configuration and the service will be instantiated.

ps. I have just checked, the 'hack' still exists and is live

Michael

Am 13.12.2017 um 22:24 schrieb Leschke, Scott via osgi-dev <os...@mail.osgi.org>>:

Hey Tim,

Thanks for this. Yes that worked. I recall seeing something about this a number of months ago but didn’t pay much attention since it didn’t apply to me at the time. Not sure why I didn’t think to give that a try though.

Two additional questions for anybody who cares to answer.

1)      If “?” isn’t used, what would the location argument look like?  Is it like a bundle symbolic id, with wildcards perhaps? It’s unclear to me how this would be used even if you wanted to.
2)      Now for a Karaf question to any/all takers. When a service instance is created this way, is there a way to associate a .cfg file with it so that the service configuration will persist across Karaf upgrades?  I know that if a Configuration record is updated, the service’s corresponding .cfg file is updated, but if you create a new service, you don’t get a .cfg file.

Scott

From: Tim Ward [mailto:tim.ward@paremus.com]
Sent: Saturday, December 09, 2017 3:04 AM
To: Leschke, Scott; OSGi Developer Mail List
Subject: Re: [osgi-dev] Create instance of factory configuration at runtime

Hi Scott,

That does work, but Configuration Admin has an old feature called location binding. This feature prevents a configuration being delivered to bundles other than the bundle with the specified bundle location.

The one-arg version of createFactoryConfiguration that you’re using defaults the bundle location to the location of the bundle which got the ConfigurationAdmin service instance that you’re using. This is almost never the correct location as it usually means only the management bundle can see your configuration.

The location binding behaviour is so annoying that the general recommendation is to disable it by using the two arg versions of Config Admin methods with a wildcard location binding (a “?”).

My guess is that the two arg version will give you what you’re looking for.

Tim
Sent from my iPhone

On 9 Dec 2017, at 00:36, Leschke, Scott via osgi-dev <os...@mail.osgi.org>> wrote:
How does one create a new instance of a factory configuration programmatically?

I thought it was like

ConfigurationAdmin ca;
ca.createFactoryConfiguration(“my.configuration.pid”).update(newServiceProps);

but that doesn’t seem to work for me.

Thanks in advance,

Scott
_______________________________________________
OSGi Developer Mail List
osgi-dev@mail.osgi.org<ma...@mail.osgi.org>
https://mail.osgi.org/mailman/listinfo/osgi-dev
_______________________________________________
OSGi Developer Mail List
osgi-dev@mail.osgi.org<ma...@mail.osgi.org>
https://mail.osgi.org/mailman/listinfo/osgi-dev


Re: [osgi-dev] Create instance of factory configuration at runtime

Posted by Tim Ward <ti...@paremus.com>.
Hi Scott,

A few things:

It’s important to remember that every time you call “createFactoryConfiguration” you’re getting a *new* configuration, not updating an existing one. The code snipped below will create an increasing number of configurations over time
You don’t set the PID or FACTORYPID in the configuration dictionary. Config Admin does that for you.
You will need to be sure that you don’t end up infinitely looping if your component ever attempts to update its own configuration.

In answer to your earlier question about the bundle location parameter - it is supposed to match against the URL from which the bundle was installed (literally the bundle location that you can get from the bundle). You can do targeting of pids against symbolicname/version, but that’s done in a different way. If you’re interested I can recommend reading the Config Admin spec.

Tim



> On 15 Dec 2017, at 22:11, Leschke, Scott <SL...@medline.com> wrote:
> 
> Hi again Michael,
>  
> Just to be clear, you’re saying that something like the following will achieve the desired affect:
>  
> @Reference
> volatile ConfigurationAdmin ca;
>  
> Dictionary<String,Object> serviceProps = toDictionary(previouslyInitializedServiceProperties);
>  
> serviceProps.put(ConfigurationAdmin.SERVICE_FACTORYPID, “my.factory.pid”);
> serviceProps.put(“org.apache.felix.fileinstall.filename”, “my.service.config.path”);
>  
> ca.createFactoryConfiguration(“my.factory.pid”, “?”)
>     .update(serviceProps);
>  
> // Manually write the .cfg at the previously specified location.
> writeCfgHere(“my.service.config.path”);
>  
> Is this a correct understanding?  If so, my only comment would be that it would seem that respecifying the factory PID seems as it’s given in the call to createFactoryConfiguration.
>  
> Scott
>  
> From: Michael Wirth [mailto:mwirth@apollon.de] 
> Sent: Friday, December 15, 2017 2:09 PM
> To: Leschke, Scott
> Cc: OSGi Developer Mail List
> Subject: Re: [osgi-dev] Create instance of factory configuration at runtime
>  
> Hi Scott, 
>  
> I did a short successful test. See the following steps:
>  
> 1. create a new configuration: Configuration config = ca.createFactoryConfiguration(factoryPid, „?“);
> 2. create and set the following properties: prop.put(„service.factoryPid“, factoryPid); prop.put(„felix.fileinstall.filename“, path), prop.put(„service.factoryPid“, factoryPid); config.update(prop);
> 3. create the configurationfile using variable path (same as for „felix.fileinstall.filename“). Managed by Fileinstall.
>  
> After a click on a button on a webpage the configuration was created and displayed without delay.
> If the file is changed, the webpage UI gets updated and the Web Console shows the new value(s).
> If I change a value in the Web Console the value in the webpage UI and in the file is changed, and so on ...
>  
> It was only a short test based on an idea, so no guarantee.
>  
> Michael
>  
> Am 15.12.2017 um 17:56 schrieb Leschke, Scott <SLeschke@medline.com <ma...@medline.com>>:
>  
> Hi Michael,
>  
> Thanks for the response. Yes I’m aware of that mechanism. That’s part of Karaf’s hot deploy scheme which I’ve used extensively to date. What I need to do is create new service instances from a UI and have the created services available immediately, i.e. without the delay, so that the UI can update without a refresh.
>  
> I know that if you modify a service programmatically, the corresponding .cfg, if the service has one, is updated.  I can’t see anyway to tell the CA service to persist the new service configuration to a particular location. For my app, I’ve overridden the org.apache.felix.fileinstall.dir-deploy.cfg file with my own that causes Karaf to scan a directory hierarchy outside of the Karaf install hierarchy. That way I don’t have to physically move the directory structure whenever I update Karaf.
>  
> Anyway, what I’m curious about is whether a .cfg file can/will be associated with a service after it’s already been created using createFactoryConfiguration.update(props);  ?  If I just create one after the fact, where I want it to reside, I’m curious if it will get associated with the existing service. Of course I can test this and intend to, I just haven’t got to that point yet.
>  
> Of course if someone can tell me definitively whether that will work or not, I won’t have to bother.
>  
> Scott
>  
> From: Michael Wirth [mailto:mwirth@apollon.de <ma...@apollon.de>] 
> Sent: Friday, December 15, 2017 9:00 AM
> To: Leschke, Scott; OSGi Developer Mail List
> Subject: Re: [osgi-dev] Create instance of factory configuration at runtime
>  
> Hi Scott, 
>  
> to point 2)
> about 2-3 years ago I had a similar problem. The 'solution' was to create a configuration file (with the properties) in the 'felix.fileinstall.dir'-Directory. If it is a Factory the filename should be <componentname>-<uniqueId>.cfg
> After some time (depending on configuration) FileInstall will scan the file, create the configuration and the service will be instantiated.
>  
> ps. I have just checked, the 'hack' still exists and is live
>  
> Michael
>  
> Am 13.12.2017 um 22:24 schrieb Leschke, Scott via osgi-dev <osgi-dev@mail.osgi.org <ma...@mail.osgi.org>>:
>  
> Hey Tim,
>  
> Thanks for this. Yes that worked. I recall seeing something about this a number of months ago but didn’t pay much attention since it didn’t apply to me at the time. Not sure why I didn’t think to give that a try though.
>  
> Two additional questions for anybody who cares to answer.
>  
> 1)      If “?” isn’t used, what would the location argument look like?  Is it like a bundle symbolic id, with wildcards perhaps? It’s unclear to me how this would be used even if you wanted to.
> 2)      Now for a Karaf question to any/all takers. When a service instance is created this way, is there a way to associate a .cfg file with it so that the service configuration will persist across Karaf upgrades?  I know that if a Configuration record is updated, the service’s corresponding .cfg file is updated, but if you create a new service, you don’t get a .cfg file.
>  
> Scott
>  
> From: Tim Ward [mailto:tim.ward@paremus.com <ma...@paremus.com>] 
> Sent: Saturday, December 09, 2017 3:04 AM
> To: Leschke, Scott; OSGi Developer Mail List
> Subject: Re: [osgi-dev] Create instance of factory configuration at runtime
>  
> Hi Scott,
>  
> That does work, but Configuration Admin has an old feature called location binding. This feature prevents a configuration being delivered to bundles other than the bundle with the specified bundle location. 
>  
> The one-arg version of createFactoryConfiguration that you’re using defaults the bundle location to the location of the bundle which got the ConfigurationAdmin service instance that you’re using. This is almost never the correct location as it usually means only the management bundle can see your configuration.
>  
> The location binding behaviour is so annoying that the general recommendation is to disable it by using the two arg versions of Config Admin methods with a wildcard location binding (a “?”).
>  
> My guess is that the two arg version will give you what you’re looking for. 
>  
> Tim
> 
> Sent from my iPhone
> 
> On 9 Dec 2017, at 00:36, Leschke, Scott via osgi-dev <osgi-dev@mail.osgi.org <ma...@mail.osgi.org>> wrote:
> 
> How does one create a new instance of a factory configuration programmatically?
>  
> I thought it was like
>  
> ConfigurationAdmin ca;
> ca.createFactoryConfiguration(“my.configuration.pid”).update(newServiceProps);
>  
> but that doesn’t seem to work for me.
>  
> Thanks in advance,
>  
> Scott
> _______________________________________________
> OSGi Developer Mail List
> osgi-dev@mail.osgi.org <ma...@mail.osgi.org>
> https://mail.osgi.org/mailman/listinfo/osgi-dev <https://mail.osgi.org/mailman/listinfo/osgi-dev>
> _______________________________________________
> OSGi Developer Mail List
> osgi-dev@mail.osgi.org <ma...@mail.osgi.org>
> https://mail.osgi.org/mailman/listinfo/osgi-dev <https://mail.osgi.org/mailman/listinfo/osgi-dev>

RE: [osgi-dev] Create instance of factory configuration at runtime

Posted by "Leschke, Scott" <SL...@medline.com>.
Hi again Michael,

Just to be clear, you’re saying that something like the following will achieve the desired affect:

@Reference
volatile ConfigurationAdmin ca;

Dictionary<String,Object> serviceProps = toDictionary(previouslyInitializedServiceProperties);

serviceProps.put(ConfigurationAdmin.SERVICE_FACTORYPID, “my.factory.pid”);
serviceProps.put(“org.apache.felix.fileinstall.filename”, “my.service.config.path”);

ca.createFactoryConfiguration(“my.factory.pid”, “?”)
    .update(serviceProps);

// Manually write the .cfg at the previously specified location.
writeCfgHere(“my.service.config.path”);

Is this a correct understanding?  If so, my only comment would be that it would seem that respecifying the factory PID seems as it’s given in the call to createFactoryConfiguration.

Scott

From: Michael Wirth [mailto:mwirth@apollon.de]
Sent: Friday, December 15, 2017 2:09 PM
To: Leschke, Scott
Cc: OSGi Developer Mail List
Subject: Re: [osgi-dev] Create instance of factory configuration at runtime

Hi Scott,

I did a short successful test. See the following steps:

1. create a new configuration: Configuration config = ca.createFactoryConfiguration(factoryPid, „?“);
2. create and set the following properties: prop.put(„service.factoryPid“, factoryPid); prop.put(„felix.fileinstall.filename“, path), prop.put(„service.factoryPid“, factoryPid); config.update(prop);
3. create the configurationfile using variable path (same as for „felix.fileinstall.filename“). Managed by Fileinstall.

After a click on a button on a webpage the configuration was created and displayed without delay.
If the file is changed, the webpage UI gets updated and the Web Console shows the new value(s).
If I change a value in the Web Console the value in the webpage UI and in the file is changed, and so on ...

It was only a short test based on an idea, so no guarantee.

Michael

Am 15.12.2017 um 17:56 schrieb Leschke, Scott <SL...@medline.com>>:

Hi Michael,

Thanks for the response. Yes I’m aware of that mechanism. That’s part of Karaf’s hot deploy scheme which I’ve used extensively to date. What I need to do is create new service instances from a UI and have the created services available immediately, i.e. without the delay, so that the UI can update without a refresh.

I know that if you modify a service programmatically, the corresponding .cfg, if the service has one, is updated.  I can’t see anyway to tell the CA service to persist the new service configuration to a particular location. For my app, I’ve overridden the org.apache.felix.fileinstall.dir-deploy.cfg file with my own that causes Karaf to scan a directory hierarchy outside of the Karaf install hierarchy. That way I don’t have to physically move the directory structure whenever I update Karaf.

Anyway, what I’m curious about is whether a .cfg file can/will be associated with a service after it’s already been created using createFactoryConfiguration.update(props);  ?  If I just create one after the fact, where I want it to reside, I’m curious if it will get associated with the existing service. Of course I can test this and intend to, I just haven’t got to that point yet.

Of course if someone can tell me definitively whether that will work or not, I won’t have to bother.

Scott

From: Michael Wirth [mailto:mwirth@apollon.de]
Sent: Friday, December 15, 2017 9:00 AM
To: Leschke, Scott; OSGi Developer Mail List
Subject: Re: [osgi-dev] Create instance of factory configuration at runtime

Hi Scott,

to point 2)
about 2-3 years ago I had a similar problem. The 'solution' was to create a configuration file (with the properties) in the 'felix.fileinstall.dir'-Directory. If it is a Factory the filename should be <componentname>-<uniqueId>.cfg
After some time (depending on configuration) FileInstall will scan the file, create the configuration and the service will be instantiated.

ps. I have just checked, the 'hack' still exists and is live

Michael

Am 13.12.2017 um 22:24 schrieb Leschke, Scott via osgi-dev <os...@mail.osgi.org>>:

Hey Tim,

Thanks for this. Yes that worked. I recall seeing something about this a number of months ago but didn’t pay much attention since it didn’t apply to me at the time. Not sure why I didn’t think to give that a try though.

Two additional questions for anybody who cares to answer.

1)      If “?” isn’t used, what would the location argument look like?  Is it like a bundle symbolic id, with wildcards perhaps? It’s unclear to me how this would be used even if you wanted to.
2)      Now for a Karaf question to any/all takers. When a service instance is created this way, is there a way to associate a .cfg file with it so that the service configuration will persist across Karaf upgrades?  I know that if a Configuration record is updated, the service’s corresponding .cfg file is updated, but if you create a new service, you don’t get a .cfg file.

Scott

From: Tim Ward [mailto:tim.ward@paremus.com]
Sent: Saturday, December 09, 2017 3:04 AM
To: Leschke, Scott; OSGi Developer Mail List
Subject: Re: [osgi-dev] Create instance of factory configuration at runtime

Hi Scott,

That does work, but Configuration Admin has an old feature called location binding. This feature prevents a configuration being delivered to bundles other than the bundle with the specified bundle location.

The one-arg version of createFactoryConfiguration that you’re using defaults the bundle location to the location of the bundle which got the ConfigurationAdmin service instance that you’re using. This is almost never the correct location as it usually means only the management bundle can see your configuration.

The location binding behaviour is so annoying that the general recommendation is to disable it by using the two arg versions of Config Admin methods with a wildcard location binding (a “?”).

My guess is that the two arg version will give you what you’re looking for.

Tim
Sent from my iPhone

On 9 Dec 2017, at 00:36, Leschke, Scott via osgi-dev <os...@mail.osgi.org>> wrote:
How does one create a new instance of a factory configuration programmatically?

I thought it was like

ConfigurationAdmin ca;
ca.createFactoryConfiguration(“my.configuration.pid”).update(newServiceProps);

but that doesn’t seem to work for me.

Thanks in advance,

Scott
_______________________________________________
OSGi Developer Mail List
osgi-dev@mail.osgi.org<ma...@mail.osgi.org>
https://mail.osgi.org/mailman/listinfo/osgi-dev
_______________________________________________
OSGi Developer Mail List
osgi-dev@mail.osgi.org<ma...@mail.osgi.org>
https://mail.osgi.org/mailman/listinfo/osgi-dev