Skip to content

[FLINK-39115][s3] Support URI Handling Utility - #29127

Open
Samrat002 wants to merge 1 commit into
apache:masterfrom
Samrat002:FLINK-39115
Open

Samrat002 wants to merge 1 commit into
apache:masterfrom
Samrat002:FLINK-39115

Conversation

@Samrat002

Copy link
Copy Markdown
Contributor

What is the purpose of the change

Add S3URIUtils and remove duplicated helpers.

Brief change log

Introduce S3URIUtils.

Verifying this change

  1. Exisiting UT and IT on Seaweedfs
  2. Running WordCount job with s3 as statebacked for snapshot ,
  3. Write output to s3 using flink job

Does this pull request potentially affect one of the following parts:

  • Dependencies (does it add or upgrade a dependency): (yes / no) no
  • The public API, i.e., is any changed class annotated with @Public(Evolving): (yes / no) no
  • The serializers: (yes / no / don't know) no
  • The runtime per-record code paths (performance sensitive): (yes / no / don't know) no
  • Anything that affects deployment or recovery: JobManager (and its components), Checkpointing, Kubernetes/Yarn, ZooKeeper: (yes / no / don't know) no
  • The S3 file system connector: (yes / no / don't know) yes

Documentation

  • Does this pull request introduce a new feature? (yes / no) no
  • If yes, how is the feature documented? (not applicable / docs / JavaDocs / not documented)

Was generative AI tooling used to co-author this PR?
  • Yes (please specify the tool below)

Generated-by: [Tool Name and Version]

@flinkbot

flinkbot commented Sep 8, 2026

Copy link
Copy Markdown
Collaborator

CI report:

Bot commands The @flinkbot bot supports the following commands:
  • @flinkbot run azure re-run the last Azure build

@Samrat002

Copy link
Copy Markdown
Contributor Author

@flinkbot run azure

@spuru9 spuru9 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM. One optional nit.

}

public static String extractKey(String s3Uri) {
String uri = s3Uri.replaceFirst(S3A, S3);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nit: now that extractKey(Path) and extractKey(String) live side by side in the same class, they still use two completely different parsing strategies (one via Path/URI, the other via manual indexOf/substring). Was consolidating them into one implementation considered, or is keeping them separate intentional?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

thanks , made changes

Comment on lines -92 to -96
*
* <p><b>S3 URI Handling:</b> The {@link #extractKey(Path)} and {@link #extractBucketName(Path)}
* methods expect URIs in the standard {@code s3://bucket/key} format. Other formats like path-style
* ({@code https://s3.amazonaws.com/bucket/key}) or virtual-hosted-style ({@code
* https://bucket.s3.amazonaws.com/key}) are not currently supported.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Now we're dropping the format expectation and we don't have any enforcement in code too. Maybe we should add and blow up early.

@davidradl davidradl Sep 15, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Though I guess requireSupportedScheme will catch these.

}

@ParameterizedTest
@CsvSource({"file:///tmp/foo", "hdfs://bucket/key", "gs://bucket/key"})

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Should we also have no schema option test?

@ParameterizedTest
@CsvSource({
"s3://bucket",
"s3://bucket/",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

what would happen for s3://bucket//?

@Izeren Izeren left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thank you @Samrat002, LGTM assuming that CI is green and feedback about indexof checks is addressed

@github-actions github-actions Bot added the community-reviewed-LGTM Applied if there are 2 non-committer approves on a PR. (The submitter cannot approve their own PR.) label Sep 8, 2026
@github-actions github-actions Bot added community-reviewed PR has been reviewed by the community. and removed community-reviewed PR has been reviewed by the community. community-reviewed-LGTM Applied if there are 2 non-committer approves on a PR. (The submitter cannot approve their own PR.) labels Sep 10, 2026
@Samrat002

Copy link
Copy Markdown
Contributor Author

@flinkbot run azure

@Samrat002

Copy link
Copy Markdown
Contributor Author

CI is failing due to https://issues.apache.org/jira/browse/FLINK-40635.
this failure is unrelated to the code changes in current PR.

@gaborgsomogyi

Copy link
Copy Markdown
Contributor

Is this flaky? We're not in a rush

@Samrat002

Copy link
Copy Markdown
Contributor Author

@flinkbot run azure

1 similar comment
@Samrat002

Copy link
Copy Markdown
Contributor Author

@flinkbot run azure

@davidradl davidradl left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

My AI says (with slight amendments from me) :

  1. Behaviour change on extractKey(Path) — now throws instead of silently accepting
    I suggest this is a change in behaviour - I suggest calling this out in the release notes on back ports.

  2. extractBucket(String) vs extractBucketName(Path) — naming inconsistency
    The two string-based methods are extractBucket(String) and extractKey(String). The two Path-based methods are extractBucketName(Path) and extractKey(Path). The inconsistency (extractBucket vs extractBucketName) is a small but unnecessary cognitive bump. extractBucketName is arguably more explicit, but consistency across overloads would be cleaner. This was noted by a reviewer as a nit.

  3. extractKey(String) with s3://bucket/ returns "" but test case says it should
    Looking at testExtractKeyReturnsEmptyForBucketOnly:

"s3://bucket/", // expects empty

In requireSupportedScheme, s3://bucket/ doesn't start with s3a://, so stays as-is. S3.length() = 5, uri.indexOf('/', 5) finds the / at index 11 (s3://bucket/), so keyStart = 11, returns uri.substring(12) = "".

  1. CI is failing — unrelated flaky test (FLINK-40635)
    The author confirmed this. Reviewer gaborgsomogyi questioned whether it's flaky; the author re-triggered CI but the failure persists on the latest push. This should be resolved before merge to confirm it's truly unrelated and not masking a real regression.

  2. Minor: extractKey(String) javadoc is missing
    extractBucket(String) has a Javadoc with @throws. extractKey(String) has no Javadoc at all, even though it can also throw IllegalArgumentException for unsupported schemes. Inconsistent documentation.

@Samrat002

Copy link
Copy Markdown
Contributor Author

Thank you @davidradl.

Please find the inline reply

  1. Behaviour change on extractKey(Path) — now throws instead of silently accepting
    I suggest this is a change in behaviour - I suggest calling this out in the release notes on backports.

native-s3-fs has been released as experimental in flink-2.3. Since then, there have been huge changes it has gone through. The entry-point classes NativeS3FileSystemFactory, NativeS3AFileSystemFactory, and NativeS3RecoverableWriter are @Experimental and S3UriUtils is @Internal, so there's no released behaviour to change and nothing to back-port. Happy to add a note if the module is ever back-ported.

  1. extractBucket(String) vs extractBucketName(Path) — naming inconsistency
    The two string-based methods are extractBucket(String) and extractKey(String). The two Path-based methods are extractBucketName(Path) and extractKey(Path). The inconsistency (extractBucket vs extractBucketName) is a small but unnecessary cognitive bump. extractBucketName is arguably more explicit, but consistency across overloads would be cleaner. This was noted by a reviewer as a nit.

I have made changes to address the concern and renamed the method to extractBucketName(String)

  1. extractKey(String) with s3://bucket/ returns "" but test case says it should
    Looking at testExtractKeyReturnsEmptyForBucketOnly:
    "s3://bucket/", // expects empty
    In requireSupportedScheme, s3://bucket/ doesn't start with s3a://, so stays as-is. S3.length() = 5, uri.indexOf('/', 5) finds the / at index 11 (s3://bucket/), so keyStart = 11, returns uri.substring(12) = "".

Test behaviour is as expected. I think AI was confused by the lack of docs. Fixed it now

Minor: extractKey(String) javadoc is missing
extractBucket(String) has a Javadoc with @throws. extractKey(String) has no Javadoc at all, even though it can also throw IllegalArgumentException for unsupported schemes. Inconsistent documentation.

Thanks for pointing it out. Added minimal Javadoc

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

community-reviewed PR has been reviewed by the community.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants