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