Nothing R7 is released yet, the specs aren’t final, so I doubt very much that 
karaf implements any of it.

I don’t think you’ve considered very many ramifications of what you’re 
proposing. In my experience an osgi web server has its port and interface 
configured via config admin, so you aren’t going to be able to have two 
instances with the same set of configurations.  Therefore IMO having a CA 
implementation that somehow uses a shared persistence location isn’t going to 
be useful, ignoring whether it’s spec compliant or not (I think not).

If all of your instances have the same services running on them, then you’d 
need all of them to get the stimulus to create the factory configuration, or 
they will respond differently;  with a shared fileinstall directory you get the 
behavior you have now, where one instance gets 2 copies of the service and the 
others presumably get one, or without the shared fileinstall you get one or two 
services on one instance and none on the others.

If one of your instances (or a separate process) is acting as a management 
agent for config admin, then that has to give all the instances the same 
stimulus.  I’m suggesting that since the stimulus for all the other instances 
is fileinstall noticing the new .cfg file, you can use that for the instance 
that is acting as the management agent as well.  Note that config admin is 
asynchronous, so at best the delay is shorter if you create the config in code 
rather than letting fileinstall find it.

There might possibly be a way to configure fileinstall to detect configuration 
changes and write them back out, but when I’ve thought that class of approaches 
to configuration management I’ve decided the behavior is too hard to reason 
about for it to be a plausible solution to anything except making an unusable 
system.  Other people might have different points of view.

david jencks

> On Feb 23, 2018, at 1:49 PM, Leschke, Scott <slesc...@medline.com> wrote:
> 
> 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