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:[email protected]]
Sent: Friday, February 23, 2018 12:23 PM
To: [email protected]
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 <[email protected]> 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:[email protected]]
> Sent: Friday, February 23, 2018 11:03 AM
> To: [email protected]
> 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 <[email protected]> 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:[email protected]]
>> Sent: Thursday, February 22, 2018 9:53 PM
>> To: [email protected]
>> 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:[email protected]]
>>> Sent: Thursday, February 22, 2018 9:38 PM
>>> To: [email protected]
>>> 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é
>>> [email protected]
>>> http://blog.nanthrax.net
>>> Talend - http://www.talend.com
>>>
>>
>> --
>> Jean-Baptiste Onofré
>> [email protected]
>> http://blog.nanthrax.net
>> Talend - http://www.talend.com