-
Notifications
You must be signed in to change notification settings - Fork 80
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
feat: add storage.upload(path) #269
Conversation
Codecov Report
@@ Coverage Diff @@
## master #269 +/- ##
============================================
+ Coverage 63.13% 63.19% +0.06%
- Complexity 601 609 +8
============================================
Files 32 32
Lines 5078 5111 +33
Branches 481 485 +4
============================================
+ Hits 3206 3230 +24
- Misses 1708 1717 +9
Partials 164 164
Continue to review full report at Codecov.
|
|
||
@Test | ||
public void testUploadDirectory() throws IOException { | ||
EasyMock.replay(storageRpcMock); |
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.
Please use Mockito for all new tests. It really is better.
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.
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.
@elharo, new tests for upload() converted to mockito.
It's not a final version yet. upload() method will be updated to return Blob (now they return void), that will require test update as well.
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.
1 nit so far, added @JesseLovelace for surface review as well.
* @throws StorageException on failure | ||
* @see #upload(BlobInfo, Path, int, BlobWriteOption...) | ||
*/ | ||
void upload(BlobInfo blobInfo, Path path, BlobWriteOption... options) throws IOException; |
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.
Blob should be returned from upload() methods similar to create() methods.
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.
returning Blob requires an extra RPC request to be issued, that is not always needed.
I can add uploadFrom() method to the Blob class (symmetric to downloadTo) to return an updated Blob.
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.
A month ago I compared upload/download implemented in various ways for several types of file. This is the summary
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.
Thanks @dmitry-fa,
I was thinking about the issue you filed: #149
When the upload is complete GCS responds with object metadata so we don't need to perform an additional get request. flushBuffer doesn't return a value so we'd diverge from the spec a bit to get the metadata.
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.
Do you mean we can update the StorageRpc interface to make void write(uploadId, ...)
to return a StorageObject?
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.
1 nit so far, added @JesseLovelace for surface review as well.
Blob should be returned from upload() methods similar to create() methods.
It's not a nit at all :) It's a significant change. I agree with you, upload() should return Blob.
I see the following ways how to implement:
-
Update the StorageRpc interface and make write() to return a StorageObject instance or null in write is not final request for the given upload. Now StorageRpc .write() returns null.
-
Update HttpStorageRpc.write() to remember StorageObject and return this object in a separate method.
In this case BlobWriterChannel.fluchBuffer() will look like:
public void run() {
StorageRpc rpc = getOptions().getStorageRpcV1();
rpc.write(getUploadId(), getBuffer(), 0, getPosition(), length, last);
if (last && rpc instnceof HttpStorageRpc) {
this.uploadedBlob = ((HttpStorageRpc)rpc.getUplodedBlob())
} else {
this.uploadedBlob = null; // let storage.upload() to resolve it
}
}
- Issue an extra rpc per upload to return a Blob
I believe 2. is not a Google way, so we should go 1. As a temporary solution 3. is also considered, because it could be improved to 1.
WDYT?
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.
Hi @frankyn,
When the upload is complete GCS responds with object metadata so we don't need to perform an additional get request.
I managed to implement upload based on your hint. I modified StorageRpc.write()
to return StorageObject
instead of void
.
Two issues were found:
-
GCS does not respond with object metadata if writer was created by
storage.writer(signedUrl)
Not sure if it's a bug or a feature, looks like a bug: spec says nothing about it. I worked it around. -
Change StrorageRpc affects storage-nio, Kokoro - Test: Linkage Monitor fails:
(com.google.cloud:google-cloud-nio:0.120.0-alpha) com.google.cloud.storage.contrib.nio.testing.FakeStorageRpc's method write(String arg1, byte[] arg2, int arg3, long arg4, int arg6, boolean arg7) is not implemented in the class referenced from com.google.cloud.storage.spi.v1.StorageRpc (com.google.cloud:google-cloud-storage:1.107.1-SNAPSHOT)
cc: @JesseLovelace
google-cloud-storage/src/main/java/com/google/cloud/storage/StorageImpl.java
Outdated
Show resolved
Hide resolved
* @throws StorageException on failure | ||
* @see #upload(BlobInfo, Path, int, BlobWriteOption...) | ||
*/ | ||
void upload(BlobInfo blobInfo, Path path, BlobWriteOption... options) throws IOException; |
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.
Thanks @dmitry-fa,
I was thinking about the issue you filed: #149
When the upload is complete GCS responds with object metadata so we don't need to perform an additional get request. flushBuffer doesn't return a value so we'd diverge from the spec a bit to get the metadata.
We found a Contributor License Agreement for you (the sender of this pull request), but were unable to find agreements for all the commit author(s) or Co-authors. If you authored these, maybe you used a different email address in the git commits than was used to sign the CLA (login here to double check)? If these were authored by someone else, then they will need to sign a CLA as well, and confirm that they're okay with these being contributed to Google. ℹ️ Googlers: Go here for more info. |
67c6544
to
6af9ce2
Compare
CLAs look good, thanks! ℹ️ Googlers: Go here for more info. |
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.
Thanks @dmitry-fa for your patience.
The more I think about this you may want to use StorageRpc.open() and StorageRpc.write() directly instead of through the writer.
That is an alternative solution there, but it does introduce duplication of code. I'm not convinced that there a clean solution other than what you've done by introducing a new value of objectProto.
As for the linkagefailure, it's known and I'm working on addressing it in #242. Need to address the split in resources here and I'm still working on it.
google-cloud-storage/pom.xml
Outdated
<groupId>org.mockito</groupId> | ||
<artifactId>mockito-core</artifactId> | ||
<scope>test</scope> | ||
</dependency> |
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.
Can you split out mockito tests into a separate PR because it got a bit confusing in review? Apologies for churn on this.
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.
Agree. Done #284
google-cloud-storage/src/main/java/com/google/cloud/storage/BlobWriteChannel.java
Outdated
Show resolved
Hide resolved
google-cloud-storage/src/main/java/com/google/cloud/storage/BlobWriteChannel.java
Outdated
Show resolved
Hide resolved
google-cloud-storage/src/main/java/com/google/cloud/storage/Storage.java
Outdated
Show resolved
Hide resolved
Hi @frankyn, Thanks for you comments.
I agree, |
Thanks @dmitry-fa, let's move forward for now. It's not introducing new surface methods in the BlobWriteChannel class. Please resolve merge conflicts. This will be blocked until Linkage Monitor is resolved because the StorageRpc update. |
Hi @frankyn, thanks for the prompt response. I have one more question regarding this feature.
The differences between them:
Would it make sense to use |
# Conflicts: # google-cloud-storage/src/test/java/com/google/cloud/storage/StorageImplMockitoTest.java # pom.xml
# Conflicts: # google-cloud-storage/clirr-ignored-differences.xml # google-cloud-storage/src/main/java/com/google/cloud/storage/StorageImpl.java # google-cloud-storage/src/test/java/com/google/cloud/storage/StorageImplMockitoTest.java # google-cloud-storage/src/test/java/com/google/cloud/storage/it/ITStorageTest.java
# Please enter a commit message to explain why this merge is necessary, # especially if it merges an updated upstream into a topic branch. # # Lines starting with '#' will be ignored, and an empty message aborts # the commit.
@dmitry-fa could you address the conflict added after merging #138 PR? |
@frankyn I think it's not needed to be merged. |
Fixes #179