Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow users to supply a custom HttpClientBuilder and HttpClientConnectionManager #352

Conversation

tjcelaya
Copy link
Contributor

@tjcelaya tjcelaya commented Oct 4, 2017

Resolves #310.

Purpose

Accept an HttpClientBuilder and associated HttpClientConnectionManager (since the connection manager handles SSL configuration) and allow MantaConnectionFactory to work with both provided and internally-constructed versions of both.

Why create a new class?

These two objects are closely coupled and one has a lifecycle that needs to be managed. I'm open to switching to passing the builder and manager directly but this way allows us to avoid null checks. Keeping the class for use in #357

@tjcelaya tjcelaya self-assigned this Oct 4, 2017
*/
ConfigContext getConfig() {
return config;
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removing unused method that was mistakenly included by #344

…g HttpClientBuilder and HttpClientConnectionManager using MantaConnectionFactoryConfigurator

Tests for MantaConnectionFactory and MantaConnectionFactoryConfigurator

Include a comment about why we don't use Mockito.verify()

Split retry handler test case
@tjcelaya tjcelaya closed this Oct 5, 2017
@tjcelaya tjcelaya force-pushed the enhancement/310-supply-custom-HttpClientBuilder branch from 798eeb1 to ed31c89 Compare October 5, 2017 18:23
@tjcelaya tjcelaya reopened this Oct 5, 2017
@tjcelaya tjcelaya force-pushed the enhancement/310-supply-custom-HttpClientBuilder branch from ffd9bd3 to 7938bef Compare October 5, 2017 20:06
Copy link
Contributor

@dekobon dekobon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Copy link
Contributor

@cburroughs cburroughs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I glanced through this and asked a few clarifying questions but will be out Monday and unable to respond in a timely manner.

I think the largest missing piece is guidance (in the form of CHANGELOG and/or javadoc) for why a user should (or should not!) use these new methods. I think we probably want some language affirming that the defaults are expected to work well for a wide variety of workloards. And as I understand the original request in #310 this is less able tuning for performance, and more about integration of threadpool, lifecycles, etc.

* This method is typically used by unit tests to inject connection factory
* customizations so we can simulate different network events.
* Creates a new instance of the Manta client based on user-provided connection objects. This allows for a larger
* degree of customization at the cost of
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Trailing off?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Must've been interrupted, thanks for catching that.

new BasicHeader(HttpHeaders.ACCEPT, "application/json, */*")
);
public static final Collection<? extends Header> HEADERS =
Collections.unmodifiableList(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this needed for this change? It looks like a fine improvement but was unsure if it was demonstrating one of the "spooky" issues with all this being user configurable.

Copy link
Contributor Author

@tjcelaya tjcelaya Oct 6, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll change these back to private since the decision was never made and is better addressed in #357 but the background is I punted on the decision between:

  • document default headers and tell MantaConnectionFactoryConfigurator users to include these headers in their HttpClientBuilder configuration
  • add these headers to whatever default headers are provided by the user. This might require inspecting the HttpClientBuilder's internal state to determine if we've already added them in Lazily read ConfigContext in MantaClient #311?
  • add a setDefaultHeaders method to MantaConnectionFactoryConfigurator so users can tell us what headers they want to mix into the HttpClientBuilder (this is only really relevant to Lazy-loading configuration for MantaClient #357)
  • something else?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One thought is to change the HEADERS constant into an array of org.apache.http.Header[] objects and store it as a constant in MantaHttpRequestFactory or in StandardHttpHelper and add the headers to every HttpHead, HttpGet, etc. This would be a solution that would always make sure the right headers were there regardless of the HttpClientBuilder that was used.

Copy link
Contributor Author

@tjcelaya tjcelaya Oct 6, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That suggestion led me to discover default headers are implemented as just another HttpRequestInterceptor, definitely going to use MantaHttpRequestFactory for that and remove our call to HttpClientBuilder#setDefaultHeaders (in #357). Thanks!

DefaultsConfigContext.DEFAULT_DISABLE_NATIVE_SIGNATURES)) {
builder.providerCode("stdlib");
}
final ThreadLocalSigner signer = new ThreadLocalSigner(builder);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This block looks the same as in the other constructor. Should it be DRYed out?

I probably wrote this block,but I admit I am having trouble recalling why DefaultsConfigContext needs to explicitly be referenced? We allow config contexts that don't start with the defaults?

Copy link
Contributor Author

@tjcelaya tjcelaya Oct 6, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll simplify the constructors.

Regarding config defaults: people could pass a StandardConfigContext which would throw NPEs if accessed directly. I've been fighting with the tradeoff between documenting defaults by directly referencing the DefaultsConfigContext and expressing the default behavior through for example structuring if clauses and using BooleanUtils.isTrue() for handling nulls. This small check would probably benefit from the latter since it's a simple boolean check though.

MantaClient(final ConfigContext config,
final KeyPair keyPair,
final MantaConnectionFactory connectionFactory,
final ThreadLocalSigner signer) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dropping the ability to pass in a signer is intentional, correct?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This constructor was only used in a single test which was has been disabled for a while (by being commented out in the testng.xml file) and needs to be revisted. That test case is documented in #354 and could be achieved with the MantaConnectionFactoryConfigurator and some simple mocks.

*
* @throws IOException
*/
@Test(enabled = false)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the intention here to fix this resolve this before merging?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, this test has been disabled since December 2016 and has been documented in #354 to be addressed soon (but not here).

@@ -0,0 +1,33 @@
package com.joyent.manta.http;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

^^ License headers

@@ -0,0 +1,197 @@
package com.joyent.manta.http;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

^^ License headers.

Copy link

@dkocher dkocher left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I pulled this and have green integration tests in cyberduckapp.

/**
* An existing {@link HttpClientConnectionManager} to use with the {@link #httpClientBuilder}.
*/
private final HttpClientConnectionManager connectionManager;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This parameter could be omitted and set to null in MantaConnectionFactory.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just to be clear, you'd expect to call HttpClientBuilder#setConnnectionManager with your own HttpClientConnectionManager before passing it into MantaConnectionFactoryConfigurator? In retrospect it does seem unnecessary to hold onto the connection manager since we won't be terminating it. Thanks for the input!

true);
this.httpClientBuilder.addInterceptorLast(authInterceptor);
if (connectionFactoryConfigurator != null) {
this.connectionManager = connectionFactoryConfigurator.getConnectionManager();
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Set to null instead.

@@ -116,38 +117,49 @@
private final HttpClientConnectionManager connectionManager;

/**
* Flag indicating if we created the {@link #connectionManager} ourselves and are responsible for shutting it down.
*/
private final boolean connectionManagerShared;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove unused variable as null check will suffice.

@tjcelaya tjcelaya force-pushed the enhancement/310-supply-custom-HttpClientBuilder branch from f84a9a7 to fc2e08b Compare October 9, 2017 17:54
…rator. Keep the configurator since it will be in charge of lazily-reloading objects in the next PR
@tjcelaya tjcelaya force-pushed the enhancement/310-supply-custom-HttpClientBuilder branch from fc2e08b to 990a3b5 Compare October 9, 2017 18:16
@tjcelaya tjcelaya merged commit ae71cf3 into TritonDataCenter:master Oct 9, 2017
@tjcelaya tjcelaya deleted the enhancement/310-supply-custom-HttpClientBuilder branch October 9, 2017 19:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Allow configuration of client with custom MantaApacheHttpClientContext
4 participants