Basically only an interface for the ConfigurationContextBuilder. Nothing more...
- Anatole Tresch Glärnischweg 10 8620 Wetzikon Tel +41 (43) 317 05 30 - Send from Mobile > Am 26.02.2015 um 11:07 schrieb Mark Struberg <[email protected]>: > > I smell some kind of overcomplicating things? > > How many classes would that add to our API? > And what is the benefit? > > LieGrue, > strub > > >> Am 24.02.2015 um 14:19 schrieb Anatole Tresch <[email protected]>: >> >> Yes, makes sense, so I would refine my proposal to: >> >> - Create a ConfigurationContextBuilder. >> - We could hereby access a new ConfigurationContextBuilder from the >> ConfigurationProvider. >> - Extend the ConfigurationProvider with the switch(ConfigurationContext) >> method. >> >> >> >> 2015-02-24 14:11 GMT+01:00 Romain Manni-Bucau <[email protected]>: >> >>> Hmm >>> >>> Personally I'd prefer a builder (+ a clear lifecycle of the app build >>> phase) and a switch(ConfigContext) method to mutate it at runtime >>> build behing handled by the builder. switch would just be responsible >>> to 1) check the new config if needed, 2) fire the event(s) of the >>> update 3) do the real mutation >>> >>> said otherwise builder extracts the config of the config in its own >>> part and decorelate it from runtime >>> >>> wdyt? >>> >>> >>> >>> >>> >>> Romain Manni-Bucau >>> @rmannibucau >>> http://www.tomitribe.com >>> http://rmannibucau.wordpress.com >>> https://github.com/rmannibucau >>> >>> >>> 2015-02-24 14:01 GMT+01:00 Anatole Tresch <[email protected]>: >>>> See inline... >>>> >>>> 2015-02-24 13:39 GMT+01:00 Romain Manni-Bucau <[email protected]>: >>>> >>>>> Ok so ConfigurationContextUpdates is "part of the SPI" thanks to >>>>> ConfigurationContext itself, am I right? >>>> Yep. Also adding property sources already was there... >>>> >>>> >>>> >>>> >>>>> That said seeing it I really think we should just use a builder where >>>>> custom extensions (ServiceLoader in SE, events in CDI, getBeanOfType >>>>> in Spring) can add/remove components during "build" phase. >>>> >>>> The problem is that configuration changes during runtime exactly change >>>> these things. E.g. >>>> >>>> - 1) >>>> a file could be removed -> the according propertysource >>>> ( >>>> s >>>> ) >>>> must be removed. >>>> - 2) a file could be added -> additional property source(s) must be >>>> registered. >>>> >>>> - 3) a file was updated -> coud simply be an update of the >>>> propertysource, but it could also mean that the ordinal has been >>> changed, >>>> so the whole chain must be reordered. In case a file produces entries >>> with >>>> different ordinals, multiple propertysources may be affected, mappping >>>> logically to 1 and 2 again. >>>> >>>> So if we agree (and many people want that) that configuration can change >>>> during runtime, we must allow this. >>>> If we want to prevent that we can simply never return a >>>> ConfigurationContextUpdate instance, everything will stay read-only. >>>> Breaking things basically is still a question of adding good default >>>> entries. Of course, if someone also removes the defaults, things may get >>>> out of order, but I assume this is not a common case... >>>> >>>> Doing everything with a bulder is possible. We would then add according >>>> methods >>>> >>>> ConfigurationContextBuilder getBuilder(); >>>> void apply(ConfigurationContext context); >>>> >>>> to the ConfigurationContext. WDYT? >>>> >>>> >>>> >>>>> Why I worry about it is this kind of thing: >>>>> >>>>> 1) start a context >>>>> 2) start to use the config >>>>> 3) wow this is awesome >>>>> 4) a part of the app modify it >>>>> 5) oops 2 and 3 are broken >>>>> >>>>> builder creating immutable objects sounds far better to me (by itself, >>>>> then you can still mutate sources/converters if that's what you want >>>>> but that's not what we provide) >>>>> >>>>> >>>>> >>>>> >>>>> >>>>> Romain Manni-Bucau >>>>> @rmannibucau >>>>> http://www.tomitribe.com >>>>> http://rmannibucau.wordpress.com >>>>> https://github.com/rmannibucau >>>>> >>>>> >>>>> 2015-02-24 13:24 GMT+01:00 Anatole Tresch <[email protected]>: >>>>>> Hi Roamin >>>>>> >>>>>> not sure, if I get your concerns: >>>>>> >>>>>> - the ConfigurationContext already is part of the current SPI. >>>>>> >>>>>> - the only change is that I extracted the methods for changing the >>>>> context >>>>>> into a separate process step/artifact with a fluent API style to have >>>>> more >>>>>> control on changes applied. And I added additional functions, so I >>> also >>>>> can >>>>>> remove PropertySources, and have similar mechanisms for filters and >>> the >>>>>> other aspects. From what I wanted to achieve, currently only >>>>> PropertySource >>>>>> management per se, would be enough. But for me it would look somehow >>>>>> weired, if I can change PropertySources, but not the rest... >>>>>> >>>>>> Anatole >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> 2015-02-24 11:57 GMT+01:00 Romain Manni-Bucau <[email protected] >>>> : >>>>>> >>>>>>> Hmm >>>>>>> >>>>>>> I have to admit I'm a bit lost, is the SPI useful then? Do we need >>>>>>> another spi? Maybe to start we shouldnt use any spi then move to spi >>>>>>> once API is finished >>>>>>> >>>>>>> That said this update new class looks like a builder to get context >>>>>>> immutable which sounds more common and easier to understand to me >>>>>>> >>>>>>> >>>>>>> >>>>>>> Romain Manni-Bucau >>>>>>> @rmannibucau >>>>>>> http://www.tomitribe.com >>>>>>> http://rmannibucau.wordpress.com >>>>>>> https://github.com/rmannibucau >>>>>>> >>>>>>> >>>>>>> 2015-02-24 10:30 GMT+01:00 Anatole Tresch <[email protected]>: >>>>>>>> Hi all >>>>>>>> >>>>>>>> I would like to propose a small but effective change in the >>>>>>>> ConfigurationContext SPI (the explanation why comes later in this >>>>> email). >>>>>>>> Currently >>>>>>>> it is defined as: >>>>>>>> >>>>>>>> *public interface *ConfigurationContext { >>>>>>>> >>>>>>>> *void *addPropertySources(PropertySource... propertySourcesToAdd); >>>>>>>> List<PropertySource> getPropertySources(); >>>>>>>> <T> *void *addPropertyConverter(TypeLiteral<T> typeToConvert, >>>>>>>> PropertyConverter<T> propertyConverter); >>>>>>>> <T> List<PropertyConverter<T>> getPropertyConverters(TypeLiteral<T> >>>>>>> type); >>>>>>>> List<PropertyFilter> getPropertyFilters(); >>>>>>>> PropertyValueCombinationPolicy getPropertyValueCombinationPolicy(); >>>>>>>> >>>>>>>> } >>>>>>>> >>>>>>>> My proposal is add an additional ConfigurationContextUpdates >>>>> interface, >>>>>>>> that allows to apply multiple changes to a ConfigurationContext and >>>>>>> finally >>>>>>>> apply the changes, once they are done. So the interface would be >>>>> changed >>>>>>> as >>>>>>>> follows: >>>>>>>> >>>>>>>> *public interface *ConfigurationContext { >>>>>>>> >>>>>>>> List<PropertySource> getPropertySources(); >>>>>>>> <T> List<PropertyConverter<T>> getPropertyConverters(TypeLiteral<T> >>>>>>> type); >>>>>>>> List<PropertyFilter> getPropertyFilters(); >>>>>>>> PropertyValueCombinationPolicy getPropertyValueCombinationPolicy(); >>>>>>>> >>>>>>>> // moved methods: >>>>>>>> *// void *addPropertySources(PropertySource... >>> propertySourcesToAdd); >>>>>>>> // <T> *void *addPropertyConverter(TypeLiteral<T> typeToConvert, >>>>>>>> // PropertyConverter<T> >>>>> propertyConverter); >>>>>>>> *ConfigurationContextUpdates startUpdate(); // new* >>>>>>>> >>>>>>>> } >>>>>>>> >>>>>>>> ConfigurationContextUpdates would be defined as follows: >>>>>>>> >>>>>>>> *public interface *ConfigurationContextUpdates { >>>>>>>> >>>>>>>> ConfigurationContext getContext(); >>>>>>>> >>>>>>>> *default *ConfigurationContextUpdates >>>>>>>> addPropertySources(PropertySource... propertySourcesToAdd); >>>>>>>> ConfigurationContextUpdates >>>>>>>> addPropertySources(Collection<PropertySource> >>> propertySourcesToAdd); >>>>>>>> *default *ConfigurationContextUpdates >>>>>>>> removePropertySources(PropertySource... propertySourcesToRemove); >>>>>>>> ConfigurationContextUpdates >>>>>>>> removePropertySources(Collection<PropertySource> >>>>>>> propertySourcesToRemove); >>>>>>>> * default *ConfigurationContextUpdates >>>>>>>> removePropertySources(Predicate<PropertySource> selector); >>>>>>>> >>>>>>>> *default *ConfigurationContextUpdates >>>>>>>> addPropertyFilters(PropertyFilter... filters); >>>>>>>> ConfigurationContextUpdates >>>>>>>> addPropertyFilters(Collection<PropertyFilter> filters); >>>>>>>> *default *ConfigurationContextUpdates >>>>>>>> removePropertyFilters(PropertyFilter... filters); >>>>>>>> *default *ConfigurationContextUpdates >>>>>>>> removePropertyFilters(Predicate<PropertyFilter> selector); >>>>>>>> ConfigurationContextUpdates >>>>>>>> removePropertyFilters(Collection<PropertyFilter> filters); >>>>>>>> >>>>>>>> >>>>>>>> <T> ConfigurationContextUpdates >>>>> addPropertyConverter(TypeLiteral<T> >>>>>>>> typeToConvert, >>>>>>>> >>>>>>>> PropertyConverter<T> propertyConverter); >>>>>>>> *default *ConfigurationContextUpdates >>>>>>>> removePropertyConverters(PropertyConverter<?>... converters); >>>>>>>> ConfigurationContextUpdates >>>>>>>> removePropertyConverters(Collection<PropertyConverter<?>> >>> converters); >>>>>>>> >>>>>>>> ConfigurationContextUpdates >>>>>>>> setPropertyValueCombinationPolicy(PropertyValueCombinationPolicy >>>>> policy); >>>>>>>> >>>>>>>> /** >>>>>>>> * Apply all the changes to the underlying context. >>>>>>>> * @throws java.lang.IllegalStateException if the operation is >>>>> called >>>>>>>> multiple times, or another update was already >>>>>>>> * applied before. >>>>>>>> */ >>>>>>>> *void *apply(); >>>>>>>> } >>>>>>>> >>>>>>>> Now here are the reasons, why I think this makes sense: >>>>>>>> >>>>>>>> - it is much more easy to lock/synchronize the current state of >>> a >>>>>>>> ConfigurationContext, since only for the time where the apply() >>> is >>>>>>>> running special synchronization logi >>>>>>>> - a configuration context can not support being mutable at all >>> by >>>>>>> simply >>>>>>>> throwing a UnsupportedMethodException, when startUpdate() is >>>>> called. >>>>>>>> - Changing a ConfigurationContext, e.g. for testing can now be >>> as >>>>>>>> flexible as using CDIUnit for CDI. The regarding test support >>>>>>> flexibility >>>>>>>> is easy to achieve. >>>>>>>> - *But most of all (and that was the reason, why I started to >>>>> think on >>>>>>>> this enhancements), we can implement automatic configuration >>>>> updates, >>>>>>> e.g. >>>>>>>> based on new files added to a configuration directory or added >>> to a >>>>>>>> database table, by implementing the mechanism as part of an >>> "event" >>>>>>> module. >>>>>>>> The event listener can determine from the change event the >>> affected >>>>>>>> PropertySource, compare with the PropertySource already >>> registered >>>>> in >>>>>>> the >>>>>>>> context(s) and remove/add/update new PropertySources as needed >>> for >>>>> the >>>>>>>> affected contexts. *This module currently is in development, >>> and as >>>>>>> soon >>>>>>>> as we would agree on this proposal I can add (and test it >>> before), >>>>> so >>>>>>> we >>>>>>>> have an initial version for supporting configuration updates. >>>>>>>> >>>>>>>> WDYT? >>>>>>>> >>>>>>>> Anatole >>>>>> >>>>>> >>>>>> >>>>>> -- >>>>>> *Anatole Tresch* >>>>>> Java Engineer & Architect, JSR Spec Lead >>>>>> Glärnischweg 10 >>>>>> CH - 8620 Wetzikon >>>>>> >>>>>> *Switzerland, Europe Zurich, GMT+1* >>>>>> *Twitter: @atsticks* >>>>>> *Blogs: **http://javaremarkables.blogspot.ch/ >>>>>> <http://javaremarkables.blogspot.ch/>* >>>>>> >>>>>> *Google: atsticksMobile +41-76 344 62 79* >>>> >>>> >>>> >>>> -- >>>> *Anatole Tresch* >>>> Java Engineer & Architect, JSR Spec Lead >>>> Glärnischweg 10 >>>> CH - 8620 Wetzikon >>>> >>>> *Switzerland, Europe Zurich, GMT+1* >>>> *Twitter: @atsticks* >>>> *Blogs: **http://javaremarkables.blogspot.ch/ >>>> <http://javaremarkables.blogspot.ch/>* >>>> >>>> *Google: atsticksMobile +41-76 344 62 79* >> >> >> >> -- >> *Anatole Tresch* >> Java Engineer & Architect, JSR Spec Lead >> Glärnischweg 10 >> CH - 8620 Wetzikon >> >> *Switzerland, Europe Zurich, GMT+1* >> *Twitter: @atsticks* >> *Blogs: **http://javaremarkables.blogspot.ch/ >> <http://javaremarkables.blogspot.ch/>* >> >> *Google: atsticksMobile +41-76 344 62 79* >
