The fundamental question is:

What is the best way to create service instances (from a factory component) 
programmatically and store the associated configurations such that they persist 
across installations/upgrades of the platform, preferably using the facilities 
of the platform itself (ie. no DB).
Preferably, default configuration values are defined in a single location, code 
or file, if possible.

It would seem that at the moment at least, you probably need to lead by writing 
the .cfg file and just deal with the FIleInstall delay even though it seems to 
me that using ConfigurationAdmin.createFactoryConfiguration would be the 
preferred approach.

Scott

-----Original Message-----
From: Leschke, Scott [mailto:slesc...@medline.com] 
Sent: Friday, February 23, 2018 3:14 PM
To: user@karaf.apache.org
Subject: RE: On another topic: Creating services programatically again

I should have clarified that this is running on Karaf 4.2 M2 so I suppose 
that's R7.  The only issue with writing the .cfg myself and relying on Felix 
FileInstall to do its thing is that I really didn't want to have to wait for 
FIleInstall to hit its poll interval since the UI needs to update the display 
with the new service.

I have to wait for the service to get created either way but if I create the 
configuration first I can look up the associated service by its configuration 
PID.  It would be if you could have the ConfigurationAdmin service write a .cfg 
file at the location of your choosing but that doesn't seem to be the case.

Scott

-----Original Message-----
From: David Jencks [mailto:david.a.jen...@gmail.com]
Sent: Friday, February 23, 2018 2:57 PM
To: user@karaf.apache.org
Subject: Re: On another topic: Creating services programatically again

I’m not sure what all of your code is doing. However, pre R7 you can’t specify 
the pid of a factory configuration. You might get the desired result by, on 
only one karaf instance, writing the .cfg file without creating a factory 
configuration yourself.

David Jencks 

Sent from my iPhone

> On Feb 23, 2018, at 11:59 AM, Leschke, Scott <slesc...@medline.com> wrote:
> 
> That should have read "a service from a factory".  To clarify, I have a 
> component that is a factory (component), I create a new instance of the 
> configuration and service using cfgAdmin.createFactoryConfiguration as shown 
> below.  I have a single Karaf instance but if I had multiple, since my 
> hierarchy is outside of the Karaf installation, I think they would all just 
> look at the same folder structure.
> 
> My experience that Karaf DOES NOT write a .cfg file when a configuration is 
> created.  If it wrote a file to the location given by 
> "felix.fileinstall.filename", this would solve my problem.
> 
>    private void createConfig(String cpid, String dir, String name, 
> Map<String,Object> props)
>        throws Exception
>    {
>        Configuration conf =
> parent.cfgAdmin.createFactoryConfiguration(cpid, "?");
> 
>        dir  = (dir.endsWith("/") ? dir : dir + '/');
>        name = name.replaceAll(" ", "_").toLowerCase();
>        File cfg = new File(dir + cpid + '-' + name + ".cfg");
> 
>        Dictionary<String,Object> confProps = toDictionary(props);
>        confProps.put("felix.fileinstall.filename",
> cfg.toURI().toString());
> 
>        try
>        {
>            conf.update(confProps);
> 
>            // Get the properties for the new service object
>            props = getProps(conf.getPid());
> 
>            // Create .cfg file with initial property set
>            ITemplate tmp = parent.templateMgr.getTemplate( 
> configTemplates.get(cpid) );
>            tmp.bind("cfg", props);
> 
>            try (FileLineWriter w = new FileLineWriter(cfg))
>            {
>                w.putLine(tmp.render());
>            }
>        }
>        catch (Exception e)
>        {
>            cfg.delete();
>            conf.delete();
>            throw e;
>        }
>    }
> 
> -----Original Message-----
> From: David Jencks [mailto:david.a.jen...@gmail.com]
> Sent: Friday, February 23, 2018 12:23 PM
> To: user@karaf.apache.org
> Subject: Re: On another topic: Creating services programatically again
> 
> What do you mean by “create instances of service from a factory” and how 
> would doing this result in a configuration at all?
> How are you proposing to replicate the configuration or .cfg file across 
> multiple karaf instances?
> 
> I’m not sure if or when karaf writes out a .cfg for a ca configuration 
> created through the ca api, but doing both of creating a configuration and 
> writing out a .cfg file is pretty sure to result in 2 instances, at least 
> until the r7 ca changes let you specify the pid of a factory configuration.
> 
> David Jencks
> 
> Sent from my iPhone
> 
>> On Feb 23, 2018, at 9:20 AM, Leschke, Scott <slesc...@medline.com> wrote:
>> 
>> That's exactly what I'm currently doing but I want to create instances of 
>> service from a factory and write the resulting configuration to .cfg.  I 
>> need to do this so that I can save the configurations across Karaf installs. 
>>  My app hierarchy resides outside of the Karaf installation so this works 
>> well.  Unfortunately, the code I show below gives me two separate service 
>> instances.
>> 
>> Scott
>> 
>> -----Original Message-----
>> From: David Jencks [mailto:david.a.jen...@gmail.com]
>> Sent: Friday, February 23, 2018 11:03 AM
>> To: user@karaf.apache.org
>> Subject: Re: On another topic: Creating services programatically 
>> again
>> 
>> Rather than using a relatively low level api such as ManagedServiceFactory 
>> I’d suggest considering a ds component with configuration required and 
>> supplying it with factory configurations to get multiple instances. By using 
>> a configuration annotation you can have the configuration injected in a 
>> typed form and you can supply default values for any keys not present in the 
>> factory configuration.
>> 
>> David Jencks
>> 
>> Sent from my iPhone
>> 
>>> On Feb 23, 2018, at 6:32 AM, Leschke, Scott <slesc...@medline.com> wrote:
>>> 
>>> OK, that sounds like it may be a good approach.  Could you point me to the 
>>> Decanter code as a reference?
>>> 
>>> Thanks,
>>> 
>>> Scott
>>> 
>>> -----Original Message-----
>>> From: Jean-Baptiste Onofré [mailto:j...@nanthrax.net]
>>> Sent: Thursday, February 22, 2018 9:53 PM
>>> To: user@karaf.apache.org
>>> Subject: Re: On another topic: Creating services programatically 
>>> again
>>> 
>>> Hi Scott,
>>> 
>>> Service Managed Factory is the other way around: you start from the cfg 
>>> file, then the service is created. The content of the file can be default 
>>> or whatever, it doesn't matter.
>>> 
>>> Basically, you would have:
>>> 
>>> etc/org.scott.foo-one.cfg
>>> etc/org.scott.foo-two.cfg
>>> etc/org.scott.foo-three.cfg
>>> 
>>> with the corresponding service for each cfg file. If you create 
>>> etc/org.scott.foo-four.cfg, then, automatically,  you will have a new 
>>> corresponding service created.
>>> 
>>> For instance, it's what we are using in Decanter for the JMX collector: you 
>>> can create a new JMX collector "on the fly", just adding a new 
>>> etc/org.apache.karaf.decanter.collector.jmx-foobar.cfg file.
>>> 
>>> Regards
>>> JB
>>> 
>>>> On 02/23/2018 04:47 AM, Leschke, Scott wrote:
>>>> Thanks JB,
>>>> 
>>>> Initially, the .cfg would be populated almost entirely with the defaults  
>>>> the service receives using a configuration type so the idea is that the 
>>>> service creation needs to come first so that the service can be used to 
>>>> get the values to write the .cfg.
>>>> 
>>>> Is there a way to get those value without actually having a service 
>>>> instance or hard-coding them? 
>>>> 
>>>> Scott
>>>> 
>>>> -----Original Message-----
>>>> From: Jean-Baptiste Onofré [mailto:j...@nanthrax.net]
>>>> Sent: Thursday, February 22, 2018 9:38 PM
>>>> To: user@karaf.apache.org
>>>> Subject: Re: On another topic: Creating services programatically 
>>>> again
>>>> 
>>>> Hi Scott,
>>>> 
>>>> why don't use a managed service factory ?
>>>> 
>>>> It would automatically create a service based on a cfg. So for your user, 
>>>> he creates the cfg file, and then, automatically, the corresponding 
>>>> service is created.
>>>> 
>>>> Thoughts ?
>>>> 
>>>> Regards
>>>> JB
>>>> 
>>>>> On 02/22/2018 09:18 PM, Leschke, Scott wrote:
>>>>> As I mentioned a few weeks ago, I'm trying to create a service 
>>>>> instance programmatically and write the associated .cfg file for it.
>>>>> Based on feedback I got, I create the following method.
>>>>> 
>>>>> 
>>>>> 
>>>>> The goal is to create the service instance and then get its 
>>>>> configuration which at this point will mostly be the defaults that 
>>>>> it receives in its configuration type (hence my previous post). It 
>>>>> /appears/ to work, except what is really happening is that I get 
>>>>> two services. One is created by createFactoryConfguration call and 
>>>>> the other by Felix FileInstall after the .cfg file is written.
>>>>> 
>>>>> 
>>>>> 
>>>>> Actually I'm a bit surprised that placeholder .cfg file isn't 
>>>>> created if property /felix.fileinstall.filename/is defined, as I 
>>>>> think that would solve this problem, but perhaps there's another way?
>>>>> 
>>>>> 
>>>>> 
>>>>> Thoughts?
>>>>> 
>>>>> * *
>>>>> 
>>>>> * *
>>>>> 
>>>>> *private**void* createConfig(String cpid, String dir, String name, 
>>>>> Map<String,Object> props)
>>>>> 
>>>>>      *throws* Exception
>>>>> 
>>>>> {
>>>>> 
>>>>>      Configuration conf =
>>>>> parent.cfgAdmin.createFactoryConfiguration(cpid, "?");
>>>>> 
>>>>> 
>>>>> 
>>>>>      dir  = (dir.endsWith("/") ? dir : dir + '/');
>>>>> 
>>>>>      name = name.replaceAll(" ", "_").toLowerCase();
>>>>> 
>>>>>      File cfg = *new* File(dir + cpid + '-' + name + ".cfg");
>>>>> 
>>>>> 
>>>>> 
>>>>>      Dictionary<String,Object> confProps = toDictionary(props);
>>>>> 
>>>>>      confProps.put("felix.fileinstall.filename",
>>>>> cfg.toURI().toString());
>>>>> 
>>>>> 
>>>>> 
>>>>>      *try*
>>>>> 
>>>>>      {
>>>>> 
>>>>>             conf.update(confProps);
>>>>> 
>>>>> 
>>>>> 
>>>>>             // Get the properties for the new service object
>>>>> 
>>>>>             props = getProps(conf.getPid());
>>>>> 
>>>>> 
>>>>> 
>>>>>             // Create .cfg file with initial property set
>>>>> 
>>>>>             ITemplate tmp = parent.templateMgr.getTemplate(
>>>>> configTemplates.get(cpid) );
>>>>> 
>>>>>             tmp.bind("cfg", props);
>>>>> 
>>>>> 
>>>>> 
>>>>>             *try* (FileLineWriter w = *new* FileLineWriter(cfg))
>>>>> 
>>>>>             {
>>>>> 
>>>>>                    w.putLine(tmp.render());
>>>>> 
>>>>>             }
>>>>> 
>>>>>      }
>>>>> 
>>>>>      *catch* (Exception e)
>>>>> 
>>>>>      {
>>>>> 
>>>>>             cfg.delete();
>>>>> 
>>>>>             conf.delete();
>>>>> 
>>>>>             *throw* e;
>>>>> 
>>>>>      }
>>>>> 
>>>>> }
>>>>> 
>>>>> 
>>>>> 
>>>> 
>>>> --
>>>> Jean-Baptiste Onofré
>>>> jbono...@apache.org
>>>> http://blog.nanthrax.net
>>>> Talend - http://www.talend.com
>>>> 
>>> 
>>> --
>>> Jean-Baptiste Onofré
>>> jbono...@apache.org
>>> http://blog.nanthrax.net
>>> Talend - http://www.talend.com

Reply via email to