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

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

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

Scott

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:[hidden email]]
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 <[hidden email]> 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
[hidden email]
https://mail.osgi.org/mailman/listinfo/osgi-dev

Reply | Threaded
Open this post in threaded view
|

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

Scott

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:[hidden email]]
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 <[hidden email]>:

 

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 [[hidden email]] 
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 <[hidden email]>:

 

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 [[hidden email]] 
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 <[hidden email]> 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
[hidden email]
https://mail.osgi.org/mailman/listinfo/osgi-dev

_______________________________________________
OSGi Developer Mail List
[hidden email]
https://mail.osgi.org/mailman/listinfo/osgi-dev

 

Reply | Threaded
Open this post in threaded view
|

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

Tim Ward-2
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 <[hidden email]> 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 [[hidden email]] 
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 <[hidden email]>:
 
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 [[hidden email]] 
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 <[hidden email]>:
 
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 [[hidden email]] 
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 <[hidden email]> 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
[hidden email]
https://mail.osgi.org/mailman/listinfo/osgi-dev
_______________________________________________
OSGi Developer Mail List
[hidden email]
https://mail.osgi.org/mailman/listinfo/osgi-dev

Reply | Threaded
Open this post in threaded view
|

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

Scott

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:[hidden email]]
Sent: Monday, December 18, 2017 5:04 AM
To: [hidden email]
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 <[hidden email]> 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 [[hidden email]] 
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 <[hidden email]>:

 

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 [[hidden email]] 
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 <[hidden email]>:

 

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 [[hidden email]] 
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 <[hidden email]> 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
[hidden email]
https://mail.osgi.org/mailman/listinfo/osgi-dev

_______________________________________________
OSGi Developer Mail List
[hidden email]
https://mail.osgi.org/mailman/listinfo/osgi-dev