What the authentication support provides is a way for the app to setup
the environment have HttpOp act on it. Often, the app is not itself
dealing with HttpOp, only indirectly via varous ARQ remote operations.
Yes - this may break existing code but I suspect rarely if at all.
The choice seems to be stick with the deprecated HttpClient classes or
make some kind of break.
For the majority of auth uses though I am assuming it is "setup the auth
in the environment" and use ARQ. This should not need to change.
yes - at he moment, authentication is late in the game - too late for
the new httpClient API.
I think we need to make Jena API change and break the idea we can modify
an HttpClient.
This splits HttpOp into two separate parts: all the calls that take a
HttpClient, but not HttpAuthenticator (these are all the calls that are
performing the operation on the HttpClient unchanged, and some code to
create HttpClients with, optionally, authentication. Indeed, they could
be two classes, HttpOp and HttpClientMaker.
HttpClientMaker has operations that takes a HttpClientBuilder and the
HttpAuthenticator. If there is one that is make(HttpAuthenticator)
using the default builder, the app needs to chnage by write two lines:
make HttpClient, call HttpOp, where it was one.
HttpClient hc = HttpClientMaker.make(HttpAuthenticator) ;
HttpOp.....(hc, ...)
The internal "exec" becomes simpler.
private static void exec(String url, HttpUriRequest request,
String acceptHeader,
HttpResponseHandler handler,
HttpClient httpClient,
HttpContext httpContext) {
a first step is to move the auth stuff first and:
private static void exec(String url, HttpUriRequest request,
String acceptHeader,
HttpResponseHandler handler,
HttpClient httpClient,
HttpContext httpContext,
HttpAuthenticator authenticator) {
httpClient = ensureClient(httpClient, authenticator);
httpContext = ensureContext(httpContext);
applyAuthentication(asAbstractClient(httpClient), url,
httpContext, authenticator);
exec(url, request, acceptHeader, handler,
httpClient, httpContext);
}
[As I happen to have done that change locally to check it, I'll commit
it anyway.]
Andy
On 16/05/16 17:29, A. Soroka wrote:
Okay, coming back with a quick design question. The current type for
authentication (o.a.j.atlas.web.auth.HttpAuthenticator), works via
the following signature:
public void apply(AbstractHttpClient client, HttpContext httpContext,
URI target);
The idea here (IIUC) is to apply authentication to an _extant_ HTTP
client, context and URI. The problem for option 2 is that this is
pretty late in the game, obviously later than client construction.
Is the idea to bake in the HttpAuthenticator as part of the
(immutable) state of a subclass of o.a.h.c.HttpClient that
automatically applies the behavior at request execution? That tangles
Jena and o.a.http.client types in a way that seems to me to be a bit
odd, but my sense of Jena's idiom is pretty undeveloped. Just want to
make sure I am on the right road. It would mean altering
FormsAuthenticator to factor cookies out of the client into the
context, and that means an HttpClientContext, so we'd end up with
something like:
public void apply(HttpClient client, HttpClientContext httpContext,
URI target);
which would break HttpAuthenticator impls out there in the world, but
not horrifically. It would also mean that the client in that
signature would have immutable state going forward, and that has more
potential, I think, to break impls, but anyone doing a custom
authenticator should also be able to factor that state out of the
client into the context like I describe above.
--- A. Soroka The University of Virginia Library
On May 15, 2016, at 8:33 AM, Andy Seaborne <[email protected]>
wrote:
On 11/05/16 16:38, A. Soroka wrote:
I recently did some work on a project for those exact
deprecation warnings (introducing HttpClientBuilder). I would be
happy to take a crack at those if you want to make me a ticket. I
don't remember it being too hairy.
https://issues.apache.org/jira/browse/JENA-576
The uprade looks easy but there is one area
In the old API http-client, authentication is done by modifying the
HttpClient object. In the new API, HttpClient (CloseableHttpClient)
is immutable and chnages need to be made at the HttpClientBuilder
stage.
That impacts the HttpOp interface - some functions are of the form
HttpClient+HttpAuthenticator. And the public alls all go to one
operation that takes HttpClient+HttpAuthenticator.
So I think (I have not tried) the forms:
1/ operation(HttpClient, ....) // No auth unless already in
HttpClient operation(HttpClientBuilder, HttpAuthenticator, ....)
i.e. HttpClientBuilder if HttpAuthenticator
2/ Or move the creation/setup of authentication out of the
operations call flow and provide creator operations.
Remove all operation(HttpClient, HttpAuthenticator, ....)
and have
HttpClient hc
hc = createHttpClient(HttpAuthenticator, ....) // default
builder. hc = createHttpClient(HttpClientBuilder,
HttpAuthenticator, ....)
i.e. separate creation and auth setup.
This, to me, looks more in tune with the new API
3/ Stick to the deprecated AbstractHttpClient style.
ATM I favour (2). We don't preserve exact current HttpOp API in
(1) or (2) so let's do the better design. 3.2.0 if necessary (but
I don't believe that rigid semantic versions makes sense in large
system with semi-independent sub-systems; version number changes
when many users aren't affected can be more confusion than help;
"semantic version" is a guidance not a rule).
Andy