Issue 7459: Hadoop can't create S3 client with latest AWS SDK#7520
Issue 7459: Hadoop can't create S3 client with latest AWS SDK#7520rtjd6554 wants to merge 60 commits into
Conversation
There was a problem hiding this comment.
There's a lot of code added here, I know the ticket says the existing test covers everything for this ticket but are there any unit tests that could be added for this class?
There was a problem hiding this comment.
There is a lot of coverage of this already. It's used in all the integration tests for code that uses Hadoop, although that's just against LocalStack.
I think if we run the full performance test suite against this branch before merging that's probably enough?
There was a problem hiding this comment.
I think the PR description needs updating to clarify which tests have been run or need to be run.
There was a problem hiding this comment.
I think we do need to run the performance test suite against this branch before we can merge it, because we don't know how this affects performance, or if it's working for Spark in a deployed instance.
There was a problem hiding this comment.
Thinking about it, the behaviour of applying the Hadoop configuration properties would be good to have unit tests for. Can we do that?
If I could see a direct one-to-one correspondence with the Hadoop equivalent of this class I'd be less worried. As it is, the diff between this and the Hadoop version isn't easily comparable.
Would you prefer to unit test the behaviour or make it a more direct copy of the Hadoop code?
Here's a link to the original thread if you're reading this in the review: #7520 (comment)
|
Overall looks good, one comment about if we can add more tests |
There was a problem hiding this comment.
Thinking about it, the behaviour of applying the Hadoop configuration properties would be good to have unit tests for. Can we do that?
If I could see a direct one-to-one correspondence with the Hadoop equivalent of this class I'd be less worried. As it is, the diff between this and the Hadoop version isn't easily comparable.
Would you prefer to unit test the behaviour or make it a more direct copy of the Hadoop code?
Here's a link to the original thread if you're reading this in the review: #7520 (comment)
| import static org.apache.hadoop.fs.s3a.Constants.REQUEST_TIMEOUT; | ||
| import static org.assertj.core.api.Assertions.assertThat; | ||
|
|
||
| class HadoopS3ClientFactoryTest { |
There was a problem hiding this comment.
It looks like most of the behaviour isn't covered by these tests yet?
There's quite a bit of logic in HadoopS3ClientFactory, and right now this is testing it can:
- Set
fs.s3a.s3.client.factory.implon a Hadoop configuration - Apply an explicit endpoint override from S3ClientCreationParameters
- Apply configuration that's set via
AWSClientConfig.createClientConfigBuilder(just the request timeout is tested, which might be okay)
These look good, but it just touches the fringes of the actual behaviour implemented in HadoopS3ClientFactory.
I think we could do with some combination of more tests, and/or a clearer equivalence between ours and the Hadoop implementation. Some of the other comments on this review address the equivalence between our code and the Hadoop implementation. I'd focus on testing the parts where our code is different.
There was a problem hiding this comment.
More equivalance gone for
| } | ||
|
|
||
| @Test | ||
| void shouldApplyRequestTimeoutFromConfiguration() throws Exception { |
There was a problem hiding this comment.
It looks like this behaviour is delegated to the Hadoop implementation in AWSClientConfig. I think we probably don't need to cover everything that's done via AWSClientConfig.createClientConfigBuilder, having one test like this looks good.
We could clarify the intention of this test to demonstrate that HadoopS3ClientFactory applies configuration to ClientOverrideConfiguration through AWSClientConfig. Maybe just add a comment explaining this?
| clientOverrideConfigBuilder.addMetricPublisher( | ||
| new AwsStatisticsCollector(parameters.getMetrics())); | ||
| } | ||
|
|
There was a problem hiding this comment.
In the Hadoop implementation there's code here to set the retry policy. Should that still be here?
There was a problem hiding this comment.
Addressed, added Standard Retry strategy
|
|
||
| @Override | ||
| public S3Client createS3Client(URI uri, S3ClientCreationParameters params) throws IOException { | ||
| return configureClientBuilder(S3Client.builder(), params, getConf(), uri.getHost()) |
There was a problem hiding this comment.
There's a lot of connection settings that were set on the HTTP client at this point in the Hadoop code, via AWSClientConfig.createHttpClientBuilder in AWSClientConfig.createConnectionSettings.
Those look like they probably matter. Can we replicate that configuration against the new AWS client? It doesn't look like this is resolved in the latest Hadoop, since they haven't updated the AWS SDK yet.
I think the proxy settings don't look like they matter to us, though I could be wrong about that.
This also applies to createS3AsyncClient.
| } | ||
|
|
||
| @Override | ||
| public S3AsyncClient createS3AsyncClient(final URI uri, final S3ClientCreationParameters parameters) throws IOException { |
There was a problem hiding this comment.
Please can these public methods be moved above the private methods, as described in our coding conventions: https://github.com/gchq/sleeper/blob/develop/docs/development/conventions.md#ordering-within-a-java-class
This would also match the ordering in the original Hadoop code. In general it would be nice if we can match the ordering of methods from the Hadoop version.
| if (configuredRegion != null && !configuredRegion.isEmpty()) { | ||
| region = Region.of(configuredRegion); | ||
| } | ||
|
|
There was a problem hiding this comment.
The Hadoop implementation sets fipsEnabled on the builder here. Should that still be here?
| } | ||
|
|
||
| if (endpoint != null) { | ||
| boolean endpointEndsWithCentral = endpointStr.endsWith(CENTRAL_ENDPOINT); |
There was a problem hiding this comment.
The Hadoop implementation has some validation code here with checkArgument. Should that still be here?
| } | ||
|
|
||
| private static Region getS3RegionFromEndpoint(final String endpoint, | ||
| final boolean endpointEndsWithCentral) { |
There was a problem hiding this comment.
It looks like the logging has been stripped out of this method. Should that still be here?
There was a problem hiding this comment.
Logging was removed as part of simplification as little value would be gained.
| } | ||
| return AwsHostNameUtils.parseSigningRegion(endpoint, "s3").orElse(null); | ||
| } | ||
| return Region.EU_WEST_2; |
There was a problem hiding this comment.
The use of this as the default region is duplicated between here and configureEndpointAndRegion. Please can we set this in one place?
In general, using eu-west-2 as the default region could cause problems for us because things could continue to work if the region is defaulted, just because it happens to match what we're using. This could hide real failures. It might be worth keeping Hadoop's default region instead, or failing completely if it would default?
There was a problem hiding this comment.
Addressed, defaulting back to us-east-2
| final ClientOverrideConfiguration.Builder clientOverrideConfigBuilder = AWSClientConfig.createClientConfigBuilder(conf, AWS_SERVICE_IDENTIFIER_S3); | ||
|
|
||
| parameters.getHeaders().forEach((h, v) -> clientOverrideConfigBuilder.putHeader(h, v)); | ||
|
|
There was a problem hiding this comment.
In the Hadoop implementation there's code here to set the requester pays header. Should that still be here?
Make sure you have checked all steps below.
Issue
Feature". Note that before an issue is finished, you can still make a pull request by raising a separate issue
for your progress.
Tests
E.g. DockerInstanceIT, TpchSchemaPartitionedInsertPartitioningEnabledIT or DataFusionCompactionRunnerLocalStackIT
Documentation
separate issue for that below.