Hi Alain,

>> Since you are annotating classes that are generated, does the generator has 
>> some configurability?
> Yes, it is our own.

Ok, great! That will make things easier.


>> Is it possible for you to instead generate configurations? The config could 
>> be a properties file, a JSON, or even a class if necessary.
> IMHO I am generating the configuration as part of the "main" component that I 
> showed. What would be the advantage to put those in a file (we do have those 
> for standard config).  

I am making a few assumptions here about how your system works, but I recommend 
that you read up on the “Extender Pattern”. Essentially, it allows you to 
automate the creation of a service. The services need to have a known structure 
(which it seems yours do), and have to be configurable (which again, it seems 
yours are).

What you would do using this pattern is output the necessary configuration to a 
file, probably one file per configuration. You could put them all in a “known” 
folder, and include the folder in a bundle. You would use a BundleTracker to 
test for the presence of these configuration files. If a folder is detected 
that contains these files, you would load the configuration, one config for 
each file.

Your component would require a configuration and have a known configurationPid. 
I think the scope should be PROTOTYPE, but you’ll have to try it out to be 
sure, I can’t remember off hand.

Using the ConfigurationAdmin, you would create a factory configuration, which 
would create a new component instance.

I think this approach would be much nicer than handcrafting a new component for 
each generated class, even if you are only doing it once.


>> If this is possible, you could for instance use the extender pattern to 
>> instantiate the services for you, rather than trying to manually build a 
>> single component for each generated file. Generate the configurations, 
>> export them to a known folder in a bundle, and when the bundle is deployed, 
>> read the configs and instantiate the services.
>> 
>> Right now, it sounds like you are making yourself an extension to the 
>> generator. If you can reduce the manual work by capturing only what varies 
>> and automating the repetition, perhaps that would be a more elegant solution.
> At which level. The generator generates the "main" mapData class, the table, 
> record and readers/writers. Some of those might have methods marked as 
> @notGenerated when manual changes are required. The classes leveraging this 
> (like the exporter that I showed), are not generated.

To make this approach work, the configured components should contain only the 
parts that change. I guess you’d have to carefully pull apart what changes from 
what doesn’t.


>> One service per generated “class” sounds right to me, but IMO there seems to 
>> be a bit of a smell to the manual additions to each generated file. Think of 
>> it from the perspective of your builds. Every time you build a new system, 
>> you’ll have to do manual work to construct your components. Would be better 
>> to have an end-to-end build that does not require manual intervention. Don’t 
>> you think?
> I don't, there is a fair amount of manual boilerplate involved in the 
> non-generated classes, but no further manual intervention.

Well, if it’s one of these things where you invest 2 hours of work, and it 
almost never changes, then maybe you’re doing the right thing. If, however, you 
need to consistently intervene manually, that can be boring and error prone. 
Also, it puts the knowledge into a person, who can forgot or leave the company. 
If the knowledge is instead embedded in the build system, then you can 
concentrate your energies on other things. But like anything, it’s always a 
trade off. YMMV.


>> In case you did not now (it was not obvious to me before I first discovered 
>> it) you can also configure the @References with a “xxx.target” configuration 
>> property. DS should give you all you need to configure your services.
> Is that different than what I showed with:
> @Reference(target=BaModelAssetMapData.TARGET_TABLE_NAME)
>     private ExportTable<BaModelAssetMapTable> exportTable;

That is the effect, but it is done via configuration, not annotation.

Example:

        ConfigurationAdmin cm = ...;
        Configuration config = cm.createFactoryConfiguration( "some.pid", "?" );

        Dictionary<String, Object> properties = new Hashtable<>();
        properties.put( "XXX.target", "(some.prop=foo)" );

        config.update( properties );


The call to config.update(properties) will create a new component with PID 
“some.pid” using the provided configuration.

Cheers,
=David


_______________________________________________
OSGi Developer Mail List
[email protected]
https://mail.osgi.org/mailman/listinfo/osgi-dev

Reply via email to