Re: On another topic: Creating services programatically again
Inline... Sent from my iPhone > On Feb 23, 2018, at 4:05 PM, Leschke, Scott wrote: > > Well, the ConfigurationAdmin.createFactoryConfiguration method call works in > the version of ConfigurationAdmin that gets installed into Karaf 4.2M2, ie. a > service gets created and is activated. If that's not what you're referring > to, then I guess I'm misunderstanding. That has always worked:-) however it generates a new pid for the configuration and you have no control over it. In R7 you can specify the pid. I think what is happening to you is that the ca call is generating a configuration with one pid, then you write it to a .cfg file and file install reads it and generates a new configuration with a different pid. A future R7 fileinstall ought to be able to determine that you only intend one configuration and update it instead. I’m not very familiar with fileinstall so there might be a proprietary non-spec way to do that already; if there is I don’t know about it. > > I currently only have 1 instance and it's unlikely I'll ever go to a > multi-instance setup. If I ever do go to a such an architecture, the service > being created would only apply to a single instance and the service would be > specific to a team who is associated with the instance. In that case, yes I > imagine that there would be one instance that acted as a manager for the > others. More likely, each team would get a separate instance to use in their > own VM thereby keeping things pretty much like they are now. > > I'd have to check to be sure, but I think configuration changes are already > written out to .cfg files now. Seems to me that you can make updates to a > configuration via the Karaf console and they end up in the associated .cfg. > My recollection is that it was even careful to not mess up the formatting of > the .cfg. I thought I remembered something like that, but I’ve never known exactly what it does or where the change detection happens. David Jencks > > Thanks for the help. I appreciate the input. > > Regards, > > Scott > > -Original Message- > From: David Jencks [mailto:david.a.jen...@gmail.com] > Sent: Friday, February 23, 2018 5:14 PM > To: user@karaf.apache.org > Subject: Re: On another topic: Creating services programatically again > > 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 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
RE: On another topic: Creating services programatically again
Well, the ConfigurationAdmin.createFactoryConfiguration method call works in the version of ConfigurationAdmin that gets installed into Karaf 4.2M2, ie. a service gets created and is activated. If that's not what you're referring to, then I guess I'm misunderstanding. I currently only have 1 instance and it's unlikely I'll ever go to a multi-instance setup. If I ever do go to a such an architecture, the service being created would only apply to a single instance and the service would be specific to a team who is associated with the instance. In that case, yes I imagine that there would be one instance that acted as a manager for the others. More likely, each team would get a separate instance to use in their own VM thereby keeping things pretty much like they are now. I'd have to check to be sure, but I think configuration changes are already written out to .cfg files now. Seems to me that you can make updates to a configuration via the Karaf console and they end up in the associated .cfg. My recollection is that it was even careful to not mess up the formatting of the .cfg. Thanks for the help. I appreciate the input. Regards, Scott -Original Message- From: David Jencks [mailto:david.a.jen...@gmail.com] Sent: Friday, February 23, 2018 5:14 PM To: user@karaf.apache.org Subject: Re: On another topic: Creating services programatically again 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 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 s
Re: On another topic: Creating services programatically again
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 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 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 >>
RE: On another topic: Creating services programatically again
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 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 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 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 co
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 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 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 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 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 programati
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 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 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 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 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 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-
RE: On another topic: Creating services programatically again
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 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 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 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 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.s
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 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 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
RE: On another topic: Creating services programatically again
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 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 props) >>> >>>*throws* Exception >>> >>> { >>> >>>
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 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 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 confProps = toDictionary(props); >>> >>>confProps.put("felix.fileinst
RE: On another topic: Creating services programatically again
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 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 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
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 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 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
RE: On another topic: Creating services programatically again
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 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 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
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 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 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