Skip to content

CF-1007: Download documents from sumsub#1134

Merged
filipocelka merged 3 commits intoGENERALBYTESCOM:feature/1.17-snapshotfrom
thoagb:feature/CF-1007-fetch-document-from-sumsub
Feb 6, 2026
Merged

CF-1007: Download documents from sumsub#1134
filipocelka merged 3 commits intoGENERALBYTESCOM:feature/1.17-snapshotfrom
thoagb:feature/CF-1007-fetch-document-from-sumsub

Conversation

@thoagb
Copy link
Copy Markdown
Contributor

@thoagb thoagb commented Feb 4, 2026

No description provided.

return httpConnection;
}

private static String getContentType(HttpURLConnection httpConnection) {
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.

Static is unnecessary.

return contentType;
}

private static void validateResponseCode(HttpURLConnection httpConnection, String imageId) throws IOException {
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.

Static is unnecessary.

private final int retryDelaySeconds; // with increasing backoff (attemptNumber * retryDelaySeconds)

public SumsubDocumentDownloader(SumsubDocumentClient client, SumsubIdentityPieceCreator creator,
int maxDownloadRetries, int retryDelaySeconds) {
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.

I would make maxDownloadRetries and retryDelaySeconds as constants in the class. It seems unnecessary to set them in the constructor.

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.

I refactored it to use constants in the calling class, but kept the constructor injection for easier testability.


List<InspectionImage> mappableImages = images.stream()
.filter(img -> {
if (img.getImageId() == null || img.getIdDocDef() == null) {
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.

I would divide it into two conditions and write a specific message - for possible easier debugging.

*
* @param docType the Sumsub document type
* @param contentType the MIME type of the content
* @param content the raw content bytes
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.

Formatting.

}

List<InspectionImage> mappableImages = images.stream()
.filter(img -> {
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.

You could put this filtering logic into a method and give it a nice name to make ti more readable.


if (!failedImages.isEmpty()) {
List<String> failedImageDetails = failedImages.stream()
.map(img -> img.getImageId() + " (" + (img.getIdDocDef() != null ? img.getIdDocDef().getIdDocType() : "unknown") + ")")
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.

Maybe extract this into a method. It's hard to tell what it's supposed to do.

@MethodSource("provideSelfieDocumentTypes")
void createIdentityPieceReturnsSelfieForSelfieVideoSelfie(SumSubDocumentType documentType) {
byte[] content = "selfie-data".getBytes();
String contentType = "image/png";
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.

Just something to consider here. I'm sure the contentType will be different for videos in reality. It's not a problem in this test, but perhaps it would be a good idea to validate the content types somewhere? You are basically storing raw data without even checking what it is, or if it's valid for the given doc type.

public SumsubDocumentClient(String token, String secret, String baseUrl) {
this.token = token;
this.baseUrl = baseUrl.endsWith("/") ? baseUrl.substring(0, baseUrl.length() - 1) : baseUrl;
try {
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.

I'd put this try-catch into a private method

return Hex.bytesToHexString(mac.doFinal());
}

public record DownloadedDocument(byte[] content, String contentType) {
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.

This is just an idea, but if you extracted this record, you could make it package-private. It's not needed anywhere outside this package anyway, if I'm not wrong.

return failedImages;
}

private void addRetryDelay(int attempt) {
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.

add could be confusing. Consider a better name like waitBeforeRetry or applyRetryDelay.

@filipocelka filipocelka merged commit 842a36c into GENERALBYTESCOM:feature/1.17-snapshot Feb 6, 2026
1 check passed
thoagb added a commit to thoagb/batm_public that referenced this pull request Feb 12, 2026
* CF-1007: Download documents from sumsub

* CF-1007: Refactor constants, filters, formatting

* CF-1007: Content type validation
filipocelka pushed a commit that referenced this pull request Feb 12, 2026
* CF-1007: Download documents from sumsub

* CF-1007: Refactor constants, filters, formatting

* CF-1007: Content type validation
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.

4 participants