-
Notifications
You must be signed in to change notification settings - Fork 2.9k
NIFI-15386 - Upgrade Box SDK to Version 10 #10716
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
base: main
Are you sure you want to change the base?
Conversation
7e2cda4 to
dbbe953
Compare
awelless
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
First round of review.
The changes marked as "nitpicking" are mostly stylistic and subjective. Feel free to ignore them.
The rest of the comments are worth of attention, as they may affect the processor behavior.
I reviewed the controller services classes. Also I reviewed Events, Metadata Instance, and Extract Metadata processors and their tests.
I'll review the rest during the next review round.
| ProxyServiceMigration.renameProxyConfigurationServiceProperty(config); | ||
| // Remove timeout properties that are no longer supported in Box SDK 10.x | ||
| config.removeProperty("Connect Timeout"); | ||
| config.removeProperty("Read Timeout"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It should be possible to still configure these fields.
final OkHttpClient okHttpClient = BoxNetworkClient.getDefaultOkHttpClientBuilder()
.connectTimeout(context.getProperty(CONNECT_TIMEOUT).asDuration())
.readTimeout(context.getProperty(READ_TIMEOUT).asDuration())
.build();
final NetworkClient networkClient = new BoxNetworkClient(okHttpClient);
final NetworkSession networkSession = new NetworkSession.Builder()
.networkClient(networkClient)
.build();
return new BoxClient.Builder(new BoxJWTAuth(...))
.networkSession(networkSession)
.build();There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another option to consider, although a more radical, is to use NiFi web-client instead of okhttp.
NetworkClient provides a concise interface which we can use as an adapter to a web-client.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Regarding the use of the NiFi web client, I'd consider this as a follow up improvement. I think this does make sense but I don't think this should be part of this initial effort.
...-box-processors/src/main/java/org/apache/nifi/processors/box/ConsumeBoxEnterpriseEvents.java
Outdated
Show resolved
Hide resolved
...-box-processors/src/main/java/org/apache/nifi/processors/box/ConsumeBoxEnterpriseEvents.java
Outdated
Show resolved
Hide resolved
...-processors/src/test/java/org/apache/nifi/processors/box/ConsumeBoxEnterpriseEventsTest.java
Outdated
Show resolved
Hide resolved
...undle/nifi-box-processors/src/main/java/org/apache/nifi/processors/box/ConsumeBoxEvents.java
Outdated
Show resolved
Hide resolved
...x-processors/src/main/java/org/apache/nifi/processors/box/DeleteBoxFileMetadataInstance.java
Outdated
Show resolved
Hide resolved
...x-processors/src/main/java/org/apache/nifi/processors/box/UpdateBoxFileMetadataInstance.java
Outdated
Show resolved
Hide resolved
...x-processors/src/main/java/org/apache/nifi/processors/box/UpdateBoxFileMetadataInstance.java
Outdated
Show resolved
Hide resolved
...x-processors/src/main/java/org/apache/nifi/processors/box/UpdateBoxFileMetadataInstance.java
Outdated
Show resolved
Hide resolved
...x-processors/src/main/java/org/apache/nifi/processors/box/UpdateBoxFileMetadataInstance.java
Show resolved
Hide resolved
awelless
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Round 2 of review.
I reviewed all source files, but not the tests.
| } catch (Exception e) { | ||
| throw new ProcessException("Failed to download file from Box", e); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Previously, the SDK errors thrown by fetchFile would've been propagated to the caller and handled in onTrigger.
Since everything is wrapped into a ProcessException, so the handling of BoxAPIError in onTrigger won't take place. Let's catch only IOException here, passing the rest up the call chain
| } | ||
|
|
||
| final GetFileByIdQueryParams queryParams = new GetFileByIdQueryParams.Builder() | ||
| .fields(List.of("id", "name", "size", "modified_at", "path_collection")) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nitpicking. These fields can be moved to a constant.
| "owned_by", "parent", "etag", "sha1", "item_status", "sequence_id", "path_collection", | ||
| "content_created_at", "content_modified_at", "trashed_at", "purged_at", "shared_link"); | ||
| final GetFileByIdQueryParams queryParams = new GetFileByIdQueryParams.Builder() | ||
| .fields(List.of("name", "description", "size", "created_at", "modified_at", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nitpicking. A constant for the parameter list.
| HttpClient client = HttpClient.newHttpClient(); | ||
| HttpRequest request = HttpRequest.newBuilder() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I didn't find a method in the SDK to download the representation, either.
I have some concerns about using java's HttpClient here. Any configuration of BoxClientService is ignored.
I recommend considering the usage of NetworkSession and NetworkClient from boxClient and see how it's done in boxClient.getDownloads().downloadFile() method. This is going to be more verbose, but will use an already configured Box connection.
If we decide to proceed with another client, will a dedicated WebClient be a better option?
If we decide to keep using java HttpClient, shall we create it only once in @OnScheduled?
| final Set<String> allowedRoles, | ||
| final Set<String> allowedStatuses, | ||
| final Map<String, List<String>> attributeValues) { | ||
| int count = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nitpicking. No need to keep count, as collaborations.getEntries() returns a list, so size() can be used.
| final Items items = boxClient.getFolders().getFolderItems(parentFolderId, queryParams); | ||
|
|
||
| if (items.getEntries() != null) { | ||
| for (Object itemObj : items.getEntries()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
items.getEntries() returns a list of Item. Item is OneOfThree<FileFull, FolderFull, WebLink>.
So:
- We should use
OneOfThreeapi instead of instanceof checks. - We can operate on
FolderFullinstead of folder ids. This will allow us to getFolderFullinonTrigger(line 232), so fetching a folder info on line 233 would be redundant.
| final String parentFolderId = getOrCreateDirectParentFolder(context, flowFile); | ||
| final FolderFull parentFolderInfo = getFolderInfo(parentFolderId); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fetching a full folder representation seems redundant. See my comment in the getFolderIdByName method.
| if (existingFileId.isPresent()) { | ||
| final String fileId = existingFileId.get(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nitpicking. Optional.isPresent() - get() can be replaced with a more type-safe and idiomatic handling. Otherwise it doesn't differ from a plain null check.
return getFileIdByName(filename, parentFolderId)
.flatMap(fileId -> {
final UploadFileVersionRequestBodyAttributesField attributes = new UploadFileVersionRequestBodyAttributesField(filename);
final UploadFileVersionRequestBody requestBody = new UploadFileVersionRequestBody(attributes, inputStream);
final Files files = boxClient.getUploads().uploadFileVersion(fileId, requestBody);
return files.getEntries() != null && !files.getEntries().isEmpty()
? Optional.of(files.getEntries().getFirst())
: Optional.empty();
});There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Plain null check is also fine, but then there is little value in wrapping the result of getFileIdByName in Optional.
| if (files.getEntries() != null && !files.getEntries().isEmpty()) { | ||
| return files.getEntries().get(0); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shall we throw an exception if file upload succeeds, but no file metadata is returned?
How shall the caller handle absent FileFull?
| if (files.getEntries() != null && !files.getEntries().isEmpty()) { | ||
| return files.getEntries().get(0); | ||
| } | ||
| return null; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shall we throw an exception if file upload succeeds, but no file metadata is returned?
How shall the caller handle absent FileFull?
e655e70 to
bdd7ff8
Compare
|
Thanks @awelless - I pushed another commit to address your comments |
Summary
NIFI-15386 - Upgrade Box SDK to Version 10
Tracking
Please complete the following tracking steps prior to pull request creation.
Issue Tracking
Pull Request Tracking
NIFI-00000NIFI-00000VerifiedstatusPull Request Formatting
mainbranchVerification
Please indicate the verification steps performed prior to pull request creation.
Build
./mvnw clean install -P contrib-checkLicensing
LICENSEandNOTICEfilesDocumentation