HttpClient parameterization
Rod Widdowson
rdw at steadingsoftware.com
Wed Feb 8 10:01:45 EST 2017
I took an AI last Friday to write up some thoughts about defaulting http client parameters.
It turns out that the code structure is more complex than I remembered which may make this suggestion just too Byzantine (I was
already worried that it might be), but I'll write this up anyway.
The current hierarchy of building goes roughly:
- The Spring Parser (if there is one) or the native base class in system/conf is written in terms of
- A FactoryBean in java-identity-provider
- Which is derived from a FactoryBean in spring-support (by adding a sensible userAgent)
- This in turn is has an encapsulated ClientBuilder from java-support
- Which has an encapsulated Apache ClientBuilder.
The complication comes in that there are similar class hierarchies for InMemoryCaching clients and for FileSystemCaching Trees (they
fork in java-support).
So, what's my problems?
Currently the "default defaults" (except for the userAgent which I propose ignoring) are all in java-support. Mostly they are in
HttpClientBuilder, but the caching ClientBuilders (obviously) have their own defaults for specific parameterizations.
If a specific use has different requirements then we have to add this knowledge at the top - which is to say in the parser (or in
the global conf file which I don't think to be relevant to this argument but which I mention for completeness)
So now we have defaults in two (possible more) places, the builder and the parser. Having information about one thing in two places
is a bit of an issue for me, but less so that the fact that some of these defaults are in the parsers. I have it deeply engrained
on my consciousness that "In V3 the defaults are never in the parsers", so that worried me. Again, this isn't a big deal really, I
just present it as motivation for what happens next.
A proposed solution to this was to centralize all the defaults somewhere. Apart from the structural issue that all these defaults
(for all use cases) would need to be in Java-Support I don't think that making a third (or fourth) place where there is knowledge of
defaults solves any problems. We would now have
- The defaults file.
- The builder which needs to know about the defaults file.
- The parser which needs to know that this value has a default.
- (and maybe another derived builder for a Caching provider)
This will all work, there will be one place to go for defaults; but my concern is maintainability going forward since the
information is now scattered - and we need to remember to update everything.
My proposal.
I'll start by saying that the fact that I have to propose changes in java-support makes this less appealing, but "I've started so
I'll finish".
Let us put all our defaults into a separate DefaultParameterClass, with getters for each value.
(Let us derive from DefaultParameterClass for the caching builders)
Let us add a field (defaulting to be null) of type DefaultParameterClass to the builder and add an appropriate setter.
Let us replace the ints and booleans which hold the values with Integers and Booleans
Then when we get told to build the client
- if the new field is null, get the value from the base default class.
- when we populate the encapsulated apache builder we look to see if the parameter field is still null and if it is consult the
DefaultParameterClass.
The parsers now "just" have to
- set the default parameter before it started processing
- only call the setter if the attribute in the XML segment is non null.
Critically the parser does not know about default values, only about the default parameter.
If a particular usage pattern (for instance the DynamicMetadataProvider) needs a different parameterization then we derive a new
class from the base DefaultParameterClass and change just those values that we care about.
In terms of maintainability:
- The parser only cares about what it is parsing, not about defaults a value is there or not.
- A single change to the base DefaultParameterClass will affect everything
- But changing a specific case will only change that (and derived values)
- This is by design backwards compatible so all existing code will continue to work.
- Of course the defaults are still smeared around - the "default default" is in java-support and the per-use defaults are where we
want them to be.
Rod
More information about the dev
mailing list