Skip to content

Commit 9347903

Browse files
andrey-qlogicsduskis
authored andcommitted
---
yaml --- r: 20691 b: refs/heads/autosynth-iamcredentials c: cef877c h: refs/heads/master i: 20689: 0b6f92b 20687: 707b796
1 parent 9a6a533 commit 9347903

6 files changed

Lines changed: 104 additions & 1 deletion

File tree

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ refs/heads/pubsub-ordering-keys: 858d4e986a0ba48e08f00d42f51cbdecb175f5d6
162162
refs/tags/v0.75.0: c3673089ae09a897c1b4cf7dfe167fe4f8ab32fb
163163
refs/tags/v0.76.0: 395b016826d3ddf9cb8b34919636df15a4dbd032
164164
refs/tags/v0.77.0: 28a85a77883ccf5d48f297fd0ef3b3dca6ce01f0
165-
refs/heads/autosynth-iamcredentials: 2e239f7148c852b7b7e2de4af66e8e5707d9d049
165+
refs/heads/autosynth-iamcredentials: cef877c477f35e253254aff5ae6381dfc82f0e4d
166166
refs/heads/release-google-cloud-java-v0.78.0: fae5e980779cf0173a152636b278015b9f60ee55
167167
refs/heads/release-google-cloud-java-v0.81.0: 0352cd0dd11f4fd1fbd1ff16e7a96beaccc7b475
168168
refs/heads/release-google-cloud-java-v0.81.1-SNAPSHOT: 5a74ccb1f12506a3b67b65521881298fde20bd6f

branches/autosynth-iamcredentials/google-cloud-clients/google-cloud-storage/src/main/java/com/google/cloud/storage/Storage.java

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1442,6 +1442,30 @@ public static Builder newBuilder() {
14421442
*/
14431443
Blob create(BlobInfo blobInfo, byte[] content, BlobTargetOption... options);
14441444

1445+
/**
1446+
* Creates a new blob with the sub array of the given byte array. Direct upload is used to upload
1447+
* {@code content}. For large content, {@link #writer} is recommended as it uses resumable upload.
1448+
* MD5 and CRC32C hashes of {@code content} are computed and used for validating transferred data.
1449+
* Accepts a userProject {@link BlobGetOption} option, which defines the project id to assign
1450+
* operational costs.
1451+
*
1452+
* <p>Example of creating a blob from a byte array.
1453+
*
1454+
* <pre>{@code
1455+
* String bucketName = "my_unique_bucket";
1456+
* String blobName = "my_blob_name";
1457+
* BlobId blobId = BlobId.of(bucketName, blobName);
1458+
* BlobInfo blobInfo = BlobInfo.newBuilder(blobId).setContentType("text/plain").build();
1459+
* Blob blob = storage.create(blobInfo, "Hello, World!".getBytes(UTF_8), 7, 5);
1460+
* }</pre>
1461+
*
1462+
* @return a [@code Blob} with complete information
1463+
* @throws StorageException upon failure
1464+
* @see <a href="https://cloud.google.com/storage/docs/hashes-etags">Hashes and ETags</a>
1465+
*/
1466+
Blob create(
1467+
BlobInfo blobInfo, byte[] content, int offset, int length, BlobTargetOption... options);
1468+
14451469
/**
14461470
* Creates a new blob. Direct upload is used to upload {@code content}. For large content, {@link
14471471
* #writer} is recommended as it uses resumable upload. By default any md5 and crc32c values in

branches/autosynth-iamcredentials/google-cloud-clients/google-cloud-storage/src/main/java/com/google/cloud/storage/StorageImpl.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,22 @@ public Blob create(BlobInfo blobInfo, byte[] content, BlobTargetOption... option
149149
return internalCreate(updatedInfo, content, options);
150150
}
151151

152+
@Override
153+
public Blob create(
154+
BlobInfo blobInfo, byte[] content, int offset, int length, BlobTargetOption... options) {
155+
content = firstNonNull(content, EMPTY_BYTE_ARRAY);
156+
byte[] subContent = Arrays.copyOfRange(content, offset, offset + length);
157+
BlobInfo updatedInfo =
158+
blobInfo
159+
.toBuilder()
160+
.setMd5(BaseEncoding.base64().encode(Hashing.md5().hashBytes(subContent).asBytes()))
161+
.setCrc32c(
162+
BaseEncoding.base64()
163+
.encode(Ints.toByteArray(Hashing.crc32c().hashBytes(subContent).asInt())))
164+
.build();
165+
return internalCreate(updatedInfo, subContent, options);
166+
}
167+
152168
@Override
153169
@Deprecated
154170
public Blob create(BlobInfo blobInfo, InputStream content, BlobWriteOption... options) {

branches/autosynth-iamcredentials/google-cloud-clients/google-cloud-storage/src/test/java/com/google/cloud/storage/StorageImplTest.java

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,11 @@ public class StorageImplTest {
9797
private static final String BLOB_NAME2 = "n2";
9898
private static final String BLOB_NAME3 = "n3";
9999
private static final byte[] BLOB_CONTENT = {0xD, 0xE, 0xA, 0xD};
100+
private static final byte[] BLOB_SUB_CONTENT = {0xE, 0xA};
100101
private static final String CONTENT_MD5 = "O1R4G1HJSDUISJjoIYmVhQ==";
101102
private static final String CONTENT_CRC32C = "9N3EPQ==";
103+
private static final String SUB_CONTENT_MD5 = "5e7c7CdasUiOn3BO560jPg==";
104+
private static final String SUB_CONTENT_CRC32C = "bljNYA==";
102105
private static final int DEFAULT_CHUNK_SIZE = 2 * 1024 * 1024;
103106
private static final String BASE64_KEY = "JVzfVl8NLD9FjedFuStegjRfES5ll5zc59CIXw572OA=";
104107
private static final Key KEY =
@@ -445,6 +448,34 @@ public void testCreateBlob() throws IOException {
445448
assertEquals(-1, byteStream.read(streamBytes));
446449
}
447450

451+
@Test
452+
public void testCreateBlobWithSubArrayFromByteArray() throws IOException {
453+
Capture<ByteArrayInputStream> capturedStream = Capture.newInstance();
454+
EasyMock.expect(
455+
storageRpcMock.create(
456+
EasyMock.eq(
457+
BLOB_INFO1
458+
.toBuilder()
459+
.setMd5(SUB_CONTENT_MD5)
460+
.setCrc32c(SUB_CONTENT_CRC32C)
461+
.build()
462+
.toPb()),
463+
EasyMock.capture(capturedStream),
464+
EasyMock.eq(EMPTY_RPC_OPTIONS)))
465+
.andReturn(BLOB_INFO1.toPb());
466+
EasyMock.replay(storageRpcMock);
467+
initializeService();
468+
469+
Blob blob = storage.create(BLOB_INFO1, BLOB_CONTENT, 1, 2);
470+
471+
assertEquals(expectedBlob1, blob);
472+
ByteArrayInputStream byteStream = capturedStream.getValue();
473+
byte[] streamBytes = new byte[BLOB_SUB_CONTENT.length];
474+
assertEquals(BLOB_SUB_CONTENT.length, byteStream.read(streamBytes));
475+
assertArrayEquals(BLOB_SUB_CONTENT, streamBytes);
476+
assertEquals(-1, byteStream.read(streamBytes));
477+
}
478+
448479
@Test
449480
public void testCreateBlobRetry() throws IOException {
450481
Capture<ByteArrayInputStream> capturedStream1 = Capture.newInstance();

branches/autosynth-iamcredentials/google-cloud-examples/src/main/java/com/google/cloud/examples/storage/snippets/StorageSnippets.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,20 @@ public Blob createBlobFromByteArray(String bucketName, String blobName) {
132132
return blob;
133133
}
134134

135+
/** Example of creating a blob with sub array from a byte array. */
136+
// [TARGET create(BlobInfo, byte[], offset, length, BlobTargetOption...)]
137+
// [VARIABLE "my_unique_bucket"]
138+
// [VARIABLE "my_blob_name"]
139+
public Blob createBlobWithSubArrayFromByteArray(
140+
String bucketName, String blobName, int offset, int length) {
141+
// [START createBlobWithSubArrayFromByteArray]
142+
BlobId blobId = BlobId.of(bucketName, blobName);
143+
BlobInfo blobInfo = BlobInfo.newBuilder(blobId).setContentType("text/plain").build();
144+
Blob blob = storage.create(blobInfo, "Hello, World!".getBytes(UTF_8), offset, length);
145+
// [END createBlobWithSubArrayFromByteArray]
146+
return blob;
147+
}
148+
135149
/** Example of creating a blob from an input stream. */
136150
// [TARGET create(BlobInfo, InputStream, BlobWriteOption...)]
137151
// [VARIABLE "my_unique_bucket"]

branches/autosynth-iamcredentials/google-cloud-examples/src/test/java/com/google/cloud/examples/storage/snippets/ITStorageSnippets.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,24 @@ public void testCreateCopyAndGetBlob() {
206206
copiedBlob.delete();
207207
}
208208

209+
@Test
210+
public void testCreateCopyAndGetBlobFromSubArray() {
211+
String blobName = "test-create-copy-get-blob-from-sub-array";
212+
Blob blob = storageSnippets.createBlobWithSubArrayFromByteArray(BUCKET, blobName, 7, 1);
213+
assertNotNull(blob);
214+
Blob copiedBlob = storageSnippets.copyBlobInChunks(BUCKET, blobName, "copy-blob");
215+
assertNotNull(copiedBlob);
216+
try {
217+
storageSnippets.getBlobFromIdWithMetageneration(BUCKET, blobName, -1);
218+
fail("Expected StorageException to be thrown");
219+
} catch (StorageException ex) {
220+
// expected
221+
}
222+
assertTrue(
223+
storageSnippets.deleteBlobFromIdWithGeneration(BUCKET, blobName, blob.getGeneration()));
224+
copiedBlob.delete();
225+
}
226+
209227
@Test
210228
public void testCreateBlobFromInputStream() {
211229
Blob blob =

0 commit comments

Comments
 (0)