1) ok 2) we spoke about it earlier but I think here a builder would be the easiest and cleaner solution. Extensions can work on the builder IMO but shouldn't be able to modify at runtime the configuration itself.
Romain Manni-Bucau @rmannibucau http://www.tomitribe.com http://rmannibucau.wordpress.com https://github.com/rmannibucau 2015-01-22 19:44 GMT+01:00 Anatole Tresch <[email protected]>: > Hi Romain¨ > > so lets focus on the first aspect: > > 1) I would agree to provide ConfigurationProvider as an accessor singleton > class in Java 7 and 8 similarly. As a consequence I would agree to > remove Configuration.current() > in Java 8 and use ConfigurationProvider as the entry point into Tamaya > config. > 2) I would then define a ConfigurationProviderSpi, which implements exactly > how Configuration instances are managed, depending on the context or > whatever is appropriate. This class is loaded from the ServiceContext once > and then hold as a static variable within ConfigurationProvider. What is > happening inside ConfigurationProvider/ConfigurationProviderSpi is > basically completely transparent. In SE it will be true singleton, in > EE/OSGI environments something different perhaps. > > -> This should give you a direct OOTB API to decide how Configuration > instances are managed. > > 2a) If we would remove ConfigurationContext, we might add the method > > /** > * This method can be used for programmatically adding {@link > PropertySource}s. > * It is not needed for normal 'usage' by end users, but only for > Extension Developers! > * > * @param propertySourcesToAdd the PropertySources to add > */ > void addPropertySources(PropertySource... propertySourcesToAdd); > > to the Configuration interface. > > 2b) The other methods look nevertheless somehow detailed, and when writing > extensions they may be still very helpful. So basically if we want to > remove ConfigurationContext completely some of them would end up on > Configuration. > Best we can do is probably to add a method ConfigurationContext > getContext() on Configuration, or on ConfigurationProvider. Disadvantage is > that PropertyFilter and PropertySource also get API artefacts (basically > PropertyConverter already is one, since it can be passed as parameter for > adhoc conversion), so let's see what Mark thinks on that... > > WDYT? Would that match at least first couple of aspects you mentioned? > > -Anatole > > > 2015-01-22 17:47 GMT+01:00 Romain Manni-Bucau <[email protected]>: > >> few more comments inline >> >> >> >> 2015-01-22 17:41 GMT+01:00 Tresch, Anatole < >> [email protected]>: >> > inline as usual >> > >> > 2015-01-22 16:56 GMT+01:00 Tresch, Anatole < >> [email protected]>: >> >> Feedback inline: >> >> >> >> -----Original Message----- >> >> From: Romain Manni-Bucau [mailto:[email protected]] >> >> Sent: Donnerstag, 22. Januar 2015 16:18 >> >> To: [email protected] >> >> Subject: Re: PropertyQuery >> >> >> >> shouldnt prevent us to go futher but also means we make a lot of noise >> >> and no progress... >> >> -> That depends on the quality of discussion, not on the fact that we >> discuss ;). And if you say my posts are noise, well... I take that into >> account. Thanks. >> >> >> > >> > we all tend to do it but that's hard to follow where we are and >> > finally 1-2 people are doing the product which is bad IMO >> > -> I agree. And I also trying to motivate my colluegues to participate >> the discussions... >> > >> >> That said here the feedbacks I try to make precise: >> >> -> Nice, thanks! >> >> >> >> - java 7 module: >> >> -- ConfigurationProvider should be called ConfigurationFactory IMO (see >> next) >> >> -> NO! NO! NO! We already discussed multiple times that this is not >> necessarily a factory. >> >> >> >> - org.apache.tamaya.spi.ServiceContext#getServices should disappear -> >> >> no usage at least >> >> -> Of course it is used. How do you think the services in core are >> loaded from? Read the code before you state things that are not true or >> join our hangouts. >> >> >> > >> > not justified if you prefer. Said otherwise we shouldn't get a single >> > ServiceLoader abstraction since both needs are really different. >> > -> I do not agree here, but I am not sure I got your point. >> ServiceLoader is not powerful enough and users may want to use a different >> approach. Also for testing you might want to have a more flexible solution >> as well. >> > >> >> Point is we are exactly in between 2 states. We should either fuilly >> control programmatically the config config (the context more or less) >> with just good default fully overridable or not at all. ATM we can't >> fully control it but we can modify it a bit which is just a workaround >> IMO for several sub config cases. >> >> > >> >> -- Configuration.current() miss the "config" stage where you can >> >> select your impl: Configuration.byDefaultProvider() or >> >> Configuration.byProvider(MySuperProvider.class) and then we just call >> >> build() (or we can add in between addPropertySource/Converter). Doing >> >> it we don't need to cache >> >> >> org.apache.tamaya.spi.ServiceContextManager#serviceContextProviderDelegate >> >> which makes it more reliable >> >> -> Obviously you still in case of a factory, which it is not. It is a >> service!!! >> > >> > this is broken in most of environment...just test, check you leaked, >> > check you don't have the config you should etc...mainly works in SE >> > only where this abstraction is useless >> > -> Just a claim. Credit Suisse runs plusminus 800 plus instances also >> with low latency requirements successfully. Some are running in Weblogic, >> some in Tomcat, some standalone... >> > Also here: your expertise is welcome, but your argument is simply >> not true. >> > >> >> Cause your property sources are not everywhere in the app parts I >> guess. You can say I can just switch the "locator" to solve it, it is >> true but not the default :(. >> >> >> -> For me it seems you are still stuck in the commons config design >> somehow. Oliver BTW is currently trying to build an extension module, where >> you can "build" your configuration in such/similar way. >> >> So you can still do your own coding of everything there. We can >> then still discuss if we want to have that moved into the core/API part at >> a later stage. >> >> >> >> - org.apache.tamaya.spi.ConfigurationContext#context has no real >> >> meaning IMO and shouldn't be public if it is needed (it is not IMO) >> >> -> tbd. This could be an implementation detail, indeed (or I missed >> something). >> >> >> >> - org.apache.tamaya.spi.PropertySource#isScannable is not used ATM >> >> AFAIK so we should remove it IMO >> >> -> That is not true as well. Non scannable property source are not >> called for Configuration.getProperties(). >> >> >> > >> > ok - I should have a cache issue in Idea, sorry >> > -> fair enough. >> > >> > >> >> - I'd remove org.apache.tamaya.ConfigOperator and just allow to export >> >> a Config as a Map -> then use Map API to actually "map" >> >> - ConfigQuery -> same as previous comment >> >> -> adapt Configuration with 2 previous comments >> >> -> Well, JSR 310 as well as JSR 354 use this concept very successfully. >> I would definitively deny removing it. If you don’t get it talk with >> Stephen Colebourne. >> >> -> In many cases exporting to the full Map is not necessary. >> >> -> Creating of views will get implementation dependent. >> >> -> Summarizing: no way! IMO useless and inefficient proposal compared >> to what we have. >> >> >> >> - finally check it does worth to keep this j8 module (think only >> >> drawback removing it would be to loose Configuration.current() - or >> >> new equivalent - which is not a big deal IMO. >> >> >> >> -> Again this is not true again. There are as well the additional >> accessor using Optional, which are legit additions if someone uses Java 8. >> > >> > yep which is a very poor gain IMO for a lot of complexity: >> > -> on our side >> > -> on user side (in real life you often have multiple java version so >> > multiple apis?) >> > -> fair enough. your opinion, I have another one! >> > >> >> -> And to say it again once more: if you don’t want to support Java 8 >> as a first citizen, many people here on the list would probably leave the >> project. >> >> >> > please shout guys if that statement is true >> > >> > -> yes please! >> > >> >> >> >> >> >> Romain Manni-Bucau >> >> @rmannibucau >> >> http://www.tomitribe.com >> >> http://rmannibucau.wordpress.com >> >> https://github.com/rmannibucau >> >> >> >> >> >> 2015-01-22 16:01 GMT+01:00 Tresch, Anatole < >> [email protected]>: >> >>> Hi Romain >> >>> >> >>>>well why I want to step back is just cause we slowly leave config >> >>>>field and we are implementing a storage solution. >> >>> >> >>> Do we? I am only focused on config related use cases and know about >> what I am talking: >> >>> - Exposing a part of the internals as API does not make a storage >> solution. >> >>> - Using TypeLiteral for property conversion does not have anything in >> common with a storage solution. >> >>> >> >>> -> So please stay on the topic and keep off things that are not >> relevant, please. >> >>> >> >>>>There are already >> >>>>numerous projects doing it at apache - even if they can sometimes >> >>>>mandate some infra - so we should stick to the first goal of tamaya. >> >>> >> >>> -> Which is providing a configuration solution. I have well defined >> and well important use cases. If you don’t have them, well... >> >>> -> I do not care (too much) what other projects do. Often others >> provide good features, but also some less good ones. To argue not to >> repeat, what others did >> >>> IMO is useless. We should take the good things and combine it >> here, so we get a good solution. And again: if you have something that >> disturbs you, be >> >>> explicit. Just claiming or writing down your feelings does not >> help anybody here. Either you write down your concerns clearly, at the end >> by code, or your input >> >>> is not much of use. It is that simple IMO. I am exposing me by >> writing down and trying to do things as Java API, simply because that is >> the only way it works to get >> >>> a common understanding. Sorry for the hard words here. >> >>> >> >>>> I also not fully agree with the basis - in particular the SPI to be >> >>>> clear - we have ATM. >> >>>> >> >>>>To sumamrize a first release with: >> >>>>1) SPI ("provider" + property source) >> >>>>2) basic merge/conflict policy >> >>>>3) String read API >> >>>>4) basic convertion support >> >>>> >> >>>>Is far enough IMO. >> >>>> >> >>>>Once all of it is clear I'd like we do a release to gather feedback >> >>>>then continue building on top of it - we are ATM in the tunnel ;). >> >>> >> >>> -> So we have a scope discussion for the new release now. IMO the >> current artifacts within the API are clearly in focus for release 1 (from >> an API perspective). If you want to remove anything, you should >> >>> exactly write down, WHAT should be removed and also WHY. >> >>> -> About Collection support, we may have a vote on it. Or other people >> here on the mailing list should add their cents ;) >> >>> -> Gathering feedback is OK. Nevertheless we can mark the release as >> alpha, so everybody is clear that things may still change. >> >>> -> And again discussing what should be part of release 1 IMO must not >> constrain us to discuss on further concepts as long as the threads are >> clearly separated and not too many. So help us constructively with the >> >>> discussion instead of throwing woods into our legs all the times. >> That would be great! >> >>> >> >>> >> >>> Romain Manni-Bucau >> >>> @rmannibucau >> >>> http://www.tomitribe.com >> >>> http://rmannibucau.wordpress.com >> >>> https://github.com/rmannibucau >> >>> >> >>> >> >>> 2015-01-22 13:47 GMT+01:00 Tresch, Anatole < >> [email protected]>: >> >>>> Hi Romain/all >> >>>> >> >>>> I think we have quite a common agreement on the basic functions >> designed so far and I do not want to >> >>>> reinvent or change any of the basic mechanism. I simply come up with >> a simple request to use the algorithm pattern >> >>>> for a small subset of a functionality (how the final property value >> is evaluated). The usage of TypeLiteral was even your >> >>>> own proposal AFAIK, when we discussed PropertyConverters ;) ). >> >>>> >> >>>> Our current configuration model in general IMO is a very good start. >> It is already so flexible that I can implement 60-70% of use cases >> >>>> I have currently in use within Credit Suisse (this is somehow my >> "benchmark", which from my discussions I had during the last years covers a >> >>>> majority of use cases when dealing with distributed and modular >> systems). >> >>>> >> >>>> I am sure you remember, we had a discussion on another mail thread >> yesterday about Collection support. My proposal >> >>>> basically is the outcome of having played around to extend our API to >> support collections based only on Map<String,String> >> >>>> only as internal PropertySource representation thus avoiding the >> String[] getListProperty(String) methods. >> >>>> >> >>>> So for getting type information and define the content type of >> collections we need TypeLiterals, which similarly is useful perhaps for >> other non collection >> >>>> cases. Since collection entries can be defined in different property >> sources, a final list may want to contain all the properties found, instead >> of overriding, >> >>>> so values of different property sources are to be combined. AFAIK >> you already agreed on that UC. Hardcoding yet another strategy IMO makes >> >>>> no sense, so I would recommend use the default for all common aspects >> (that is what we already have in place) and add support for adapting the >> default >> >>>> where it is not appropriate. Thinking on this IMO both aspects >> (TypeLiterals and the collector) are the same for evaluating single >> property values as well, >> >>>> so regarding that it makes no sense to model collections differently, >> but extend/flexibilize the way how we can access properties in general. >> >>>> >> >>>> I tried to combine both aspects in one class, which I called >> PropertyQuery. Perhaps also the name PropertyQuery is confusing. Alternates >> would be >> >>>> PropertyRequest, PropertyAccess,... or whatever you like, I am >> completely open here ;) >> >>>> >> >>>> We can postpone that discussion, but just stopping this discussion >> now will not solve anything. Also we already invested a lot of discussing >> collection support, why stop here. >> >>>> We have enough time I think. We have important use cases to solve >> that may affect the Configuration interface as a whole. Adding them later >> may be a bad idea, so we >> >>>> should sort out these things now IMO. >> >>>> >> >>>> So I am curious to see your concrete (improvement) proposals ;), so >> we can continue to see, if we end up in a common view. If so, others on the >> mailing list also have a >> >>>> chance to join us again, I think. >> >>>> >> >>>> Anatole >> >>>> >> >>>> >> >>>> -----Original Message----- >> >>>> From: Romain Manni-Bucau [mailto:[email protected]] >> >>>> Sent: Donnerstag, 22. Januar 2015 09:45 >> >>>> To: [email protected] >> >>>> Subject: Re: PropertyQuery >> >>>> >> >>>> not exactly, it is different to expose MapReduce in API and to >> >>>> implement it behind another concept, ATM it is an implementation >> >>>> detail. >> >>>> >> >>>> Why I worry a bit about Query stuff is we start to leave configuration >> >>>> layer to enter backend one, not sure it does worth it *to start* - I >> >>>> understand your feature even if I never needed it but I'd really like >> >>>> we ensure our basis are solid enough before adding features on top of >> >>>> them. >> >>>> >> >>>> Said otherwise I think we should now focus on trying to make a 0.1 - >> >>>> we can add alpha to make obvious we are not done - and stop adding >> >>>> anything before being fully agree on all we have. >> >>>> >> >>>> Does it make sense? >> >>>> >> >>>> >> >>>> >> >>>> Romain Manni-Bucau >> >>>> @rmannibucau >> >>>> http://www.tomitribe.com >> >>>> http://rmannibucau.wordpress.com >> >>>> https://github.com/rmannibucau >> >>>> >> >>>> >> >>>> 2015-01-22 9:39 GMT+01:00 Anatole Tresch <[email protected]>: >> >>>>> Hi Romain >> >>>>> >> >>>>> About lamba friendly I can still have a Builder that creates a >> query. Works perfectly. >> >>>>> The default use cases would remain as is. Queries would just add >> about 3 methods to Configuration. We get as well all the flexibility we >> would need for collection support as well ;) >> >>>>> >> >>>>> Mapreduce? Well what else is evaluating a chain of propsources by >> overridding? Its already there, but hardcoded the same, which is obviously >> not flexible enough! >> >>>>> >> >>>>> - >> >>>>> Anatole Tresch >> >>>>> Glärnischweg 10 >> >>>>> 8620 Wetzikon >> >>>>> Tel +41 (43) 317 05 30 >> >>>>> - >> >>>>> Send from Mobile >> >>>>> >> >>>>>> Am 22.01.2015 um 09:11 schrieb Romain Manni-Bucau < >> [email protected]>: >> >>>>>> >> >>>>>> isnt it too complicated for most common use cases (+ not that lambda >> >>>>>> friendly cause of the 4 parameters which dont help writing readable >> >>>>>> code IMO). >> >>>>>> >> >>>>>> Functionally it works but it makes default cases "hard" and actually >> >>>>>> you just want to implement the MapReduce pattern so maybe we should >> >>>>>> call it this way if we go this way. >> >>>>>> >> >>>>>> >> >>>>>> Romain Manni-Bucau >> >>>>>> @rmannibucau >> >>>>>> http://www.tomitribe.com >> >>>>>> http://rmannibucau.wordpress.com >> >>>>>> https://github.com/rmannibucau >> >>>>>> >> >>>>>> >> >>>>>> 2015-01-22 8:44 GMT+01:00 Anatole Tresch <[email protected]>: >> >>>>>>> Dear all >> >>>>>>> >> >>>>>>> *let's think about additional use cases:* >> >>>>>>> 1) as mentioned in my last mail about collection types,* >> overriding may not >> >>>>>>> always be the right resolution policy *for accessing a configured >> value >> >>>>>>> (e.g. for collecting all configured values in a final set/list). >> >>>>>>> 2) sometimes I want to define my own PropertyConverters (already >> >>>>>>> implemented) >> >>>>>>> 3) sometimes I even would like to evaluate multiple keys taking >> the result >> >>>>>>> of the first property key that returns a config property (nice >> convenience) >> >>>>>>> >> >>>>>>> When we will add all this kind of aspect into Configuration, we >> will end up >> >>>>>>> in a messy interface, e.g. for >> >>>>>>> String get(String); >> >>>>>>> <T> T get(String, Class<T>); >> >>>>>>> <T> T get(String, Class<T>, PropertyConverter); >> >>>>>>> >> >>>>>>> String get(String, ValueCollector); >> >>>>>>> <T> T get(String, Class<T>, ValueCollector); >> >>>>>>> <T> T get(String, Class<T>, PropertyConverter, ValueCollector); >> >>>>>>> ... >> >>>>>>> >> >>>>>>> Obviously that does not make sense. >> >>>>>>> >> >>>>>>> Instead of I would propose, we would define a PropertyQuery, which >> >>>>>>> basically is >> >>>>>>> >> >>>>>>> - is the same as a TypeLiteral<T> solving the type aspects >> >>>>>>> - has a list of *keys* to be evaluated, at least one >> >>>>>>> - optionally has a ValueCollector >> >>>>>>> - optionally has a list of PropertyConverter >> >>>>>>> >> >>>>>>> With that our interface gets much leaner, but still flexible >> enough to >> >>>>>>> accommodate the use cases above: >> >>>>>>> >> >>>>>>> String get(String); >> >>>>>>> <T> T get(String, Class<T>); >> >>>>>>> <T> T get(String, Class<T>, PropertyConverter); // may be ommitted >> as well ? >> >>>>>>> <T> get(PropertyQuery<T> query); >> >>>>>>> ... >> >>>>>>> >> >>>>>>> This solves all use cases above and gives us an easy way to add >> additional >> >>>>>>> feature, if needed (I dont see any, but who knows). Hereby >> ValueCollector >> >>>>>>> would be defined as follows: >> >>>>>>> >> >>>>>>> @FunctionalInterface >> >>>>>>> public interface ValueCollector { >> >>>>>>> >> >>>>>>> /** >> >>>>>>> * Method that is called for each value returned by a >> PropertySource >> >>>>>>> for the given key. >> >>>>>>> * @param currentValue the current value, including null. >> >>>>>>> * The collector should either combine the >> existing >> >>>>>>> value with value from {@code currentValue} >> >>>>>>> * or replace the value in {@code >> currentValue} >> >>>>>>> with {@code valueRead}, hereby returning the >> >>>>>>> * result to be used as new {@code >> currentValue}. >> >>>>>>> * @param key The current key to be evaluated. >> >>>>>>> * @param newValue the new value read from the current {@code >> >>>>>>> propertySource}, not null. >> >>>>>>> * @param propertySource The PropertySource that returned the >> current >> >>>>>>> value (either as the result of a direct >> >>>>>>> * access of as a property Map containing >> the >> >>>>>>> given key. The PropertySource given >> >>>>>>> * may be evaluated for additional >> meta-data, how >> >>>>>>> the given values are to be combined. >> >>>>>>> * @return the value to be used for future evaluation. >> >>>>>>> */ >> >>>>>>> String collect(String key, String newValue, PropertySource >> >>>>>>> propertySource, >> >>>>>>> String currentValue); >> >>>>>>> >> >>>>>>> /** >> >>>>>>> * Default overriding collector. >> >>>>>>> */ >> >>>>>>> public final ValueCollector DEFAULT_OVERRIDING_COLLECTOR = (k, >> nv, ps, >> >>>>>>> cv) -> nv; >> >>>>>>> } >> >>>>>>> >> >>>>>>> Feedback? >> >>>>>>> >> >>>>>>> Cheers, >> >>>>>>> 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*
