@Override public Blob create(BlobInfo blobInfo, byte[] content, BlobTargetOption... options) { content = firstNonNull(content, EMPTY_BYTE_ARRAY); BlobInfo updatedInfo = blobInfo .toBuilder() .setMd5(BaseEncoding.base64().encode(Hashing.md5().hashBytes(content).asBytes())) .setCrc32c( BaseEncoding.base64() .encode(Ints.toByteArray(Hashing.crc32c().hashBytes(content).asInt()))) .build(); return internalCreate(updatedInfo, content, options); }
@Override public Blob create(BlobInfo blobInfo, BlobTargetOption... options) { BlobInfo updatedInfo = blobInfo .toBuilder() .setMd5(EMPTY_BYTE_ARRAY_MD5) .setCrc32c(EMPTY_BYTE_ARRAY_CRC32C) .build(); return internalCreate(updatedInfo, EMPTY_BYTE_ARRAY, options); }
static Tuple<BlobInfo, BlobTargetOption[]> convert(BlobInfo info, BlobWriteOption... options) { BlobInfo.Builder infoBuilder = info.toBuilder().setCrc32c(null).setMd5(null); List<BlobTargetOption> targetOptions = Lists.newArrayListWithCapacity(options.length); for (BlobWriteOption option : options) { switch (option.option) { case IF_CRC32C_MATCH: infoBuilder.setCrc32c(info.getCrc32c()); break; case IF_MD5_MATCH: infoBuilder.setMd5(info.getMd5()); break; default: targetOptions.add(option.toTargetOption()); break; } } return Tuple.of( infoBuilder.build(), targetOptions.toArray(new BlobTargetOption[targetOptions.size()])); } }
@Test public void testToBuilder() { compareBlobs(BLOB_INFO, BLOB_INFO.toBuilder().build()); BlobInfo blobInfo = BLOB_INFO.toBuilder().setBlobId(BlobId.of("b2", "n2")).setSize(200L).build(); assertEquals("n2", blobInfo.getName()); assertEquals("b2", blobInfo.getBucket()); assertEquals(Long.valueOf(200), blobInfo.getSize()); blobInfo = blobInfo.toBuilder().setBlobId(BlobId.of("b", "n", GENERATION)).setSize(SIZE).build(); compareBlobs(BLOB_INFO, blobInfo); }
@Test public void testUpdateBlob() { BlobInfo updatedBlobInfo = BLOB_INFO1.toBuilder().setContentType("some-content-type").build(); EasyMock.expect(storageRpcMock.patch(updatedBlobInfo.toPb(), EMPTY_RPC_OPTIONS)) .andReturn(updatedBlobInfo.toPb()); EasyMock.replay(storageRpcMock); initializeService(); Blob blob = storage.update(updatedBlobInfo); assertEquals(new Blob(storage, new BlobInfo.BuilderImpl(updatedBlobInfo)), blob); }
@Test public void testUpdateBlobWithOptions() { BlobInfo updatedBlobInfo = BLOB_INFO1.toBuilder().setContentType("some-content-type").build(); EasyMock.expect(storageRpcMock.patch(updatedBlobInfo.toPb(), BLOB_TARGET_OPTIONS_UPDATE)) .andReturn(updatedBlobInfo.toPb()); EasyMock.replay(storageRpcMock); initializeService(); Blob blob = storage.update(updatedBlobInfo, BLOB_TARGET_METAGENERATION, BLOB_TARGET_PREDEFINED_ACL); assertEquals(new Blob(storage, new BlobInfo.BuilderImpl(updatedBlobInfo)), blob); }
@Test public void testToBuilderIncomplete() { BlobInfo incompleteBlobInfo = BlobInfo.newBuilder(BlobId.of("b2", "n2")).build(); compareBlobs(incompleteBlobInfo, incompleteBlobInfo.toBuilder().build()); }
@Test public void testWriterWithOptions() { BlobInfo info = BLOB_INFO1.toBuilder().setMd5(CONTENT_MD5).setCrc32c(CONTENT_CRC32C).build(); EasyMock.expect(storageRpcMock.open(info.toPb(), BLOB_TARGET_OPTIONS_CREATE)) .andReturn("upload-id"); EasyMock.replay(storageRpcMock); initializeService(); WriteChannel channel = storage.writer( info, BLOB_WRITE_METAGENERATION, BLOB_WRITE_NOT_EXIST, BLOB_WRITE_PREDEFINED_ACL, BLOB_WRITE_CRC2C, BLOB_WRITE_MD5_HASH); assertNotNull(channel); assertTrue(channel.isOpen()); }
@Test public void testWriter() { BlobInfo.Builder infoBuilder = BLOB_INFO1.toBuilder(); BlobInfo infoWithHashes = infoBuilder.setMd5(CONTENT_MD5).setCrc32c(CONTENT_CRC32C).build(); BlobInfo infoWithoutHashes = infoBuilder.setMd5(null).setCrc32c(null).build(); EasyMock.expect(storageRpcMock.open(infoWithoutHashes.toPb(), EMPTY_RPC_OPTIONS)) .andReturn("upload-id"); EasyMock.replay(storageRpcMock); initializeService(); WriteChannel channel = storage.writer(infoWithHashes); assertNotNull(channel); assertTrue(channel.isOpen()); }
@Test public void testUpdateBlobsFail() { String sourceBlobName1 = "test-update-blobs-fail-1"; String sourceBlobName2 = "test-update-blobs-fail-2"; BlobInfo sourceBlob1 = BlobInfo.newBuilder(BUCKET, sourceBlobName1).build(); BlobInfo sourceBlob2 = BlobInfo.newBuilder(BUCKET, sourceBlobName2).build(); BlobInfo remoteBlob1 = storage.create(sourceBlob1); assertNotNull(remoteBlob1); List<Blob> updatedBlobs = storage.update( remoteBlob1.toBuilder().setContentType(CONTENT_TYPE).build(), sourceBlob2.toBuilder().setContentType(CONTENT_TYPE).build()); assertEquals(sourceBlob1.getBucket(), updatedBlobs.get(0).getBucket()); assertEquals(sourceBlob1.getName(), updatedBlobs.get(0).getName()); assertEquals(CONTENT_TYPE, updatedBlobs.get(0).getContentType()); assertNull(updatedBlobs.get(1)); }
@Test public void testCreateEmptyBlob() throws IOException { Capture<ByteArrayInputStream> capturedStream = Capture.newInstance(); EasyMock.expect( storageRpcMock.create( EasyMock.eq( BLOB_INFO1 .toBuilder() .setMd5("1B2M2Y8AsgTpgAmY7PhCfg==") .setCrc32c("AAAAAA==") .build() .toPb()), EasyMock.capture(capturedStream), EasyMock.eq(EMPTY_RPC_OPTIONS))) .andReturn(BLOB_INFO1.toPb()); EasyMock.replay(storageRpcMock); initializeService(); Blob blob = storage.create(BLOB_INFO1); assertEquals(expectedBlob1, blob); ByteArrayInputStream byteStream = capturedStream.getValue(); byte[] streamBytes = new byte[BLOB_CONTENT.length]; assertEquals(-1, byteStream.read(streamBytes)); }
@Test public void testCreateBlobWithDisabledGzipContent() throws IOException { Capture<ByteArrayInputStream> capturedStream = Capture.newInstance(); EasyMock.expect( storageRpcMock.create( EasyMock.eq( BLOB_INFO1 .toBuilder() .setMd5(CONTENT_MD5) .setCrc32c(CONTENT_CRC32C) .build() .toPb()), EasyMock.capture(capturedStream), EasyMock.eq(BLOB_TARGET_OPTIONS_CREATE_DISABLE_GZIP_CONTENT))) .andReturn(BLOB_INFO1.toPb()); EasyMock.replay(storageRpcMock); initializeService(); Blob blob = storage.create(BLOB_INFO1, BLOB_CONTENT, BLOB_TARGET_DISABLE_GZIP_CONTENT); assertEquals(expectedBlob1, blob); ByteArrayInputStream byteStream = capturedStream.getValue(); byte[] streamBytes = new byte[BLOB_CONTENT.length]; assertEquals(BLOB_CONTENT.length, byteStream.read(streamBytes)); assertArrayEquals(BLOB_CONTENT, streamBytes); assertEquals(-1, byteStream.read(streamBytes)); }
@Test public void testCreateBlobFromStreamWithEncryptionKey() throws IOException { ByteArrayInputStream fileStream = new ByteArrayInputStream(BLOB_CONTENT); BlobInfo.Builder infoBuilder = BLOB_INFO1.toBuilder(); BlobInfo infoWithHashes = infoBuilder.setMd5(CONTENT_MD5).setCrc32c(CONTENT_CRC32C).build(); BlobInfo infoWithoutHashes = infoBuilder.setMd5(null).setCrc32c(null).build(); EasyMock.expect( storageRpcMock.create(infoWithoutHashes.toPb(), fileStream, ENCRYPTION_KEY_OPTIONS)) .andReturn(BLOB_INFO1.toPb()) .times(2); EasyMock.replay(storageRpcMock); initializeService(); Blob blob = storage.create(infoWithHashes, fileStream, BlobWriteOption.encryptionKey(BASE64_KEY)); assertEquals(expectedBlob1, blob); blob = storage.create(infoWithHashes, fileStream, BlobWriteOption.encryptionKey(BASE64_KEY)); assertEquals(expectedBlob1, blob); }
@Test public void testCreateBlobFromStream() throws IOException { Capture<ByteArrayInputStream> capturedStream = Capture.newInstance(); ByteArrayInputStream fileStream = new ByteArrayInputStream(BLOB_CONTENT); BlobInfo.Builder infoBuilder = BLOB_INFO1.toBuilder(); BlobInfo infoWithHashes = infoBuilder.setMd5(CONTENT_MD5).setCrc32c(CONTENT_CRC32C).build(); BlobInfo infoWithoutHashes = infoBuilder.setMd5(null).setCrc32c(null).build(); EasyMock.expect( storageRpcMock.create( EasyMock.eq(infoWithoutHashes.toPb()), EasyMock.capture(capturedStream), EasyMock.eq(EMPTY_RPC_OPTIONS))) .andReturn(BLOB_INFO1.toPb()); EasyMock.replay(storageRpcMock); initializeService(); Blob blob = storage.create(infoWithHashes, fileStream); assertEquals(expectedBlob1, blob); ByteArrayInputStream byteStream = capturedStream.getValue(); byte[] streamBytes = new byte[BLOB_CONTENT.length]; assertEquals(BLOB_CONTENT.length, byteStream.read(streamBytes)); assertArrayEquals(BLOB_CONTENT, streamBytes); assertEquals(-1, byteStream.read(streamBytes)); }
@Test public void testCreateBlob() throws IOException { Capture<ByteArrayInputStream> capturedStream = Capture.newInstance(); EasyMock.expect( storageRpcMock.create( EasyMock.eq( BLOB_INFO1 .toBuilder() .setMd5(CONTENT_MD5) .setCrc32c(CONTENT_CRC32C) .build() .toPb()), EasyMock.capture(capturedStream), EasyMock.eq(EMPTY_RPC_OPTIONS))) .andReturn(BLOB_INFO1.toPb()); EasyMock.replay(storageRpcMock); initializeService(); Blob blob = storage.create(BLOB_INFO1, BLOB_CONTENT); assertEquals(expectedBlob1, blob); ByteArrayInputStream byteStream = capturedStream.getValue(); byte[] streamBytes = new byte[BLOB_CONTENT.length]; assertEquals(BLOB_CONTENT.length, byteStream.read(streamBytes)); assertArrayEquals(BLOB_CONTENT, streamBytes); assertEquals(-1, byteStream.read(streamBytes)); }
@Test public void testWriterWithKmsKeyName() { BlobInfo info = BLOB_INFO1.toBuilder().setMd5(null).setCrc32c(null).build(); EasyMock.expect(storageRpcMock.open(info.toPb(), KMS_KEY_NAME_OPTIONS)) .andReturn("upload-id") .times(2); EasyMock.replay(storageRpcMock); initializeService(); WriteChannel channel = storage.writer(info, BlobWriteOption.kmsKeyName(KMS_KEY_NAME)); assertNotNull(channel); assertTrue(channel.isOpen()); channel = storage.writer(info, BlobWriteOption.kmsKeyName(KMS_KEY_NAME)); assertNotNull(channel); assertTrue(channel.isOpen()); }
@Test public void testWriterWithEncryptionKey() { BlobInfo info = BLOB_INFO1.toBuilder().setMd5(null).setCrc32c(null).build(); EasyMock.expect(storageRpcMock.open(info.toPb(), ENCRYPTION_KEY_OPTIONS)) .andReturn("upload-id") .times(2); EasyMock.replay(storageRpcMock); initializeService(); WriteChannel channel = storage.writer(info, BlobWriteOption.encryptionKey(KEY)); assertNotNull(channel); assertTrue(channel.isOpen()); channel = storage.writer(info, BlobWriteOption.encryptionKey(BASE64_KEY)); assertNotNull(channel); assertTrue(channel.isOpen()); }
EasyMock.eq( BLOB_INFO1 .toBuilder() .setMd5(CONTENT_MD5) .setCrc32c(CONTENT_CRC32C)
EasyMock.eq( BLOB_INFO1 .toBuilder() .setMd5(CONTENT_MD5) .setCrc32c(CONTENT_CRC32C)
@Test public void testCreateBlobFromStreamRetryableException() throws IOException { Capture<ByteArrayInputStream> capturedStream = Capture.newInstance(); ByteArrayInputStream fileStream = new ByteArrayInputStream(BLOB_CONTENT); BlobInfo.Builder infoBuilder = BLOB_INFO1.toBuilder(); BlobInfo infoWithHashes = infoBuilder.setMd5(CONTENT_MD5).setCrc32c(CONTENT_CRC32C).build(); BlobInfo infoWithoutHashes = infoBuilder.setMd5(null).setCrc32c(null).build(); EasyMock.expect( storageRpcMock.create( EasyMock.eq(infoWithoutHashes.toPb()), EasyMock.capture(capturedStream), EasyMock.eq(EMPTY_RPC_OPTIONS))) .andThrow(new StorageException(500, "internalError")) .once(); EasyMock.replay(storageRpcMock); storage = options .toBuilder() .setRetrySettings(ServiceOptions.getDefaultRetrySettings()) .build() .getService(); // Even though this exception is retryable, storage.create(BlobInfo, InputStream) // shouldn't retry. thrown.expect(StorageException.class); thrown.expectMessage("internalError"); storage.create(infoWithHashes, fileStream); }