use of com.github.ambry.utils.ByteBufferInputStream in project ambry by linkedin.
the class HaltingInputStream method readIntoAWCFailureTest.
/**
* Tests that the right exceptions are thrown when reading into {@link AsyncWritableChannel} fails.
* @throws Exception
*/
@Test
public void readIntoAWCFailureTest() throws Exception {
String errMsg = "@@ExpectedExceptionMessage@@";
InputStream stream = new ByteBufferInputStream(ByteBuffer.allocate(1));
// Bad AWC.
InputStreamReadableStreamChannel channel = new InputStreamReadableStreamChannel(stream, EXECUTOR_SERVICE);
ReadIntoCallback callback = new ReadIntoCallback();
try {
channel.readInto(new BadAsyncWritableChannel(new IOException(errMsg)), callback).get();
fail("Should have failed because BadAsyncWritableChannel would have thrown exception");
} catch (ExecutionException e) {
Exception exception = (Exception) Utils.getRootCause(e);
assertEquals("Exception message does not match expected (future)", errMsg, exception.getMessage());
callback.awaitCallback();
assertEquals("Exception message does not match expected (callback)", errMsg, callback.exception.getMessage());
}
// Read after close.
channel = new InputStreamReadableStreamChannel(stream, EXECUTOR_SERVICE);
channel.close();
RetainingAsyncWritableChannel writeChannel = new RetainingAsyncWritableChannel();
callback = new ReadIntoCallback();
try {
channel.readInto(writeChannel, callback).get();
fail("InputStreamReadableStreamChannel has been closed, so read should have thrown ClosedChannelException");
} catch (ExecutionException e) {
Exception exception = (Exception) Utils.getRootCause(e);
assertTrue("Exception is not ClosedChannelException", exception instanceof ClosedChannelException);
callback.awaitCallback();
assertEquals("Exceptions of callback and future differ", exception.getMessage(), callback.exception.getMessage());
}
// Reading more than once.
channel = new InputStreamReadableStreamChannel(stream, EXECUTOR_SERVICE);
writeChannel = new RetainingAsyncWritableChannel();
channel.readInto(writeChannel, null);
try {
channel.readInto(writeChannel, null);
fail("Should have failed because readInto cannot be called more than once");
} catch (IllegalStateException e) {
// expected. Nothing to do.
}
}
use of com.github.ambry.utils.ByteBufferInputStream in project ambry by linkedin.
the class ValidatingKeyConvertingTransformer method testValidBlobs.
private void testValidBlobs(short blobVersion, BlobType blobType, short headerVersionToUse) throws Exception {
// MessageSievingInputStream contains put records for 3 valid blobs
// id1(put record for valid blob), id2(put record for valid blob) and id3(put record for valid blob)
MessageFormatRecord.headerVersionToUse = headerVersionToUse;
byte[] encryptionKey = new byte[100];
RANDOM.nextBytes(encryptionKey);
// create message stream for blob 1
StoreKey key1 = new MockId("id1");
short accountId1 = Utils.getRandomShort(RANDOM);
short containerId1 = Utils.getRandomShort(RANDOM);
BlobProperties prop1 = new BlobProperties(10, "servid1", accountId1, containerId1, false);
byte[] usermetadata1 = new byte[1000];
RANDOM.nextBytes(usermetadata1);
int blobContentSize = 2000;
byte[] data1 = new byte[blobContentSize];
RANDOM.nextBytes(data1);
long blobSize;
if (blobType == BlobType.DataBlob) {
blobSize = (int) Blob_Format_V2.getBlobRecordSize(blobContentSize);
} else {
ByteBuffer byteBufferBlob = MessageFormatTestUtils.getBlobContentForMetadataBlob(blobContentSize);
data1 = byteBufferBlob.array();
blobContentSize = data1.length;
blobSize = (int) Blob_Format_V2.getBlobRecordSize(blobContentSize);
}
ByteBufferInputStream stream1 = new ByteBufferInputStream(ByteBuffer.wrap(data1));
// For Blob_Version_V2, encryption key is null.
MessageFormatInputStream messageFormatStream1 = (blobVersion == Blob_Version_V2) ? new PutMessageFormatInputStream(key1, null, prop1, ByteBuffer.wrap(usermetadata1), stream1, blobContentSize, blobType) : new PutMessageFormatBlobV1InputStream(key1, prop1, ByteBuffer.wrap(usermetadata1), stream1, blobContentSize, blobType);
MessageInfo msgInfo1 = new MessageInfo(key1, messageFormatStream1.getSize(), accountId1, containerId1, prop1.getCreationTimeInMs());
// create message stream for blob 2
StoreKey key2 = new MockId("id2");
short accountId2 = Utils.getRandomShort(RANDOM);
short containerId2 = Utils.getRandomShort(RANDOM);
BlobProperties prop2 = new BlobProperties(10, "servid2", accountId2, containerId2, false);
byte[] usermetadata2 = new byte[1000];
RANDOM.nextBytes(usermetadata2);
blobContentSize = 2000;
byte[] data2 = new byte[blobContentSize];
RANDOM.nextBytes(data2);
if (blobType == BlobType.MetadataBlob) {
ByteBuffer byteBufferBlob = MessageFormatTestUtils.getBlobContentForMetadataBlob(blobContentSize);
data2 = byteBufferBlob.array();
blobContentSize = data2.length;
}
ByteBufferInputStream stream2 = new ByteBufferInputStream(ByteBuffer.wrap(data2));
// For Blob_Version_V2, encryption key is non-null.
MessageFormatInputStream messageFormatStream2 = (blobVersion == Blob_Version_V2) ? new PutMessageFormatInputStream(key2, ByteBuffer.wrap(encryptionKey), prop2, ByteBuffer.wrap(usermetadata2), stream2, blobContentSize, blobType) : new PutMessageFormatBlobV1InputStream(key2, prop2, ByteBuffer.wrap(usermetadata2), stream2, blobContentSize, blobType);
MessageInfo msgInfo2 = new MessageInfo(key2, messageFormatStream2.getSize(), accountId2, containerId2, prop2.getCreationTimeInMs());
// create message stream for blob 3
StoreKey key3 = new MockId("id3");
short accountId3 = Utils.getRandomShort(RANDOM);
short containerId3 = Utils.getRandomShort(RANDOM);
BlobProperties prop3 = new BlobProperties(10, "servid3", accountId3, containerId3, false);
byte[] usermetadata3 = new byte[1000];
RANDOM.nextBytes(usermetadata3);
blobContentSize = 2000;
byte[] data3 = new byte[blobContentSize];
RANDOM.nextBytes(data3);
if (blobType == BlobType.MetadataBlob) {
ByteBuffer byteBufferBlob = MessageFormatTestUtils.getBlobContentForMetadataBlob(blobContentSize);
data3 = byteBufferBlob.array();
blobContentSize = data3.length;
}
ByteBufferInputStream stream3 = new ByteBufferInputStream(ByteBuffer.wrap(data3));
// For Blob_Version_V2, encryption key is null.
MessageFormatInputStream messageFormatStream3 = (blobVersion == Blob_Version_V2) ? new PutMessageFormatInputStream(key3, null, prop3, ByteBuffer.wrap(usermetadata3), stream3, blobContentSize, blobType) : new PutMessageFormatBlobV1InputStream(key3, prop3, ByteBuffer.wrap(usermetadata3), stream3, blobContentSize, blobType);
MessageInfo msgInfo3 = new MessageInfo(key3, messageFormatStream3.getSize(), accountId3, containerId3, prop3.getCreationTimeInMs());
MessageInfo msgInfo4 = null;
MessageFormatInputStream messageFormatStream4 = null;
MessageInfo msgInfo5 = null;
MessageFormatInputStream messageFormatStream5 = null;
// create message stream for blob 4. Header version 2, with encryption key.
StoreKey key4 = new MockId("id4");
short accountId4 = Utils.getRandomShort(RANDOM);
short containerId4 = Utils.getRandomShort(RANDOM);
BlobProperties prop4 = new BlobProperties(10, "servid4", accountId4, containerId4, false);
byte[] usermetadata4 = new byte[1000];
RANDOM.nextBytes(usermetadata4);
blobContentSize = 2000;
byte[] data4 = new byte[blobContentSize];
RANDOM.nextBytes(data4);
if (blobType == BlobType.MetadataBlob) {
ByteBuffer byteBufferBlob = MessageFormatTestUtils.getBlobContentForMetadataBlob(blobContentSize);
data4 = byteBufferBlob.array();
blobContentSize = data4.length;
}
if (blobVersion == Blob_Version_V2) {
ByteBufferInputStream stream4 = new ByteBufferInputStream(ByteBuffer.wrap(data4));
MessageFormatRecord.headerVersionToUse = Message_Header_Version_V2;
// encryption key is non-null.
messageFormatStream4 = new PutMessageFormatInputStream(key4, ByteBuffer.wrap(encryptionKey), prop4, ByteBuffer.wrap(usermetadata4), stream4, blobContentSize, blobType);
msgInfo4 = new MessageInfo(key4, messageFormatStream4.getSize(), accountId4, containerId4, prop4.getCreationTimeInMs());
}
// create message stream for blob 5. Header version 2, without encryption key.
StoreKey key5 = new MockId("id5");
short accountId5 = Utils.getRandomShort(RANDOM);
short containerId5 = Utils.getRandomShort(RANDOM);
BlobProperties prop5 = new BlobProperties(10, "servid5", accountId5, containerId5, false);
byte[] usermetadata5 = new byte[1000];
RANDOM.nextBytes(usermetadata5);
blobContentSize = 2000;
byte[] data5 = new byte[blobContentSize];
RANDOM.nextBytes(data5);
if (blobType == BlobType.MetadataBlob) {
ByteBuffer byteBufferBlob = MessageFormatTestUtils.getBlobContentForMetadataBlob(blobContentSize);
data5 = byteBufferBlob.array();
blobContentSize = data5.length;
}
if (blobVersion == Blob_Version_V2) {
ByteBufferInputStream stream5 = new ByteBufferInputStream(ByteBuffer.wrap(data5));
MessageFormatRecord.headerVersionToUse = Message_Header_Version_V2;
// encryption key is null.
messageFormatStream5 = new PutMessageFormatInputStream(key5, null, prop5, ByteBuffer.wrap(usermetadata5), stream5, blobContentSize, blobType);
msgInfo5 = new MessageInfo(key5, messageFormatStream5.getSize(), accountId5, containerId5, prop5.getCreationTimeInMs());
}
// create input stream for all blob messages together
byte[] totalMessageStreamContent = new byte[(int) (messageFormatStream1.getSize() + messageFormatStream2.getSize() + messageFormatStream3.getSize() + (blobVersion == Blob_Version_V2 ? messageFormatStream4.getSize() + messageFormatStream5.getSize() : 0))];
messageFormatStream1.read(totalMessageStreamContent, 0, (int) messageFormatStream1.getSize());
messageFormatStream2.read(totalMessageStreamContent, (int) messageFormatStream1.getSize(), (int) messageFormatStream2.getSize());
messageFormatStream3.read(totalMessageStreamContent, (int) messageFormatStream1.getSize() + (int) messageFormatStream2.getSize(), (int) messageFormatStream3.getSize());
if (blobVersion == Blob_Version_V2) {
messageFormatStream4.read(totalMessageStreamContent, (int) messageFormatStream1.getSize() + (int) messageFormatStream2.getSize() + (int) messageFormatStream3.getSize(), (int) messageFormatStream4.getSize());
messageFormatStream5.read(totalMessageStreamContent, (int) messageFormatStream1.getSize() + (int) messageFormatStream2.getSize() + (int) messageFormatStream3.getSize() + (int) messageFormatStream4.getSize(), (int) messageFormatStream5.getSize());
}
InputStream inputStream = new ByteBufferInputStream(ByteBuffer.wrap(totalMessageStreamContent));
List<MessageInfo> msgInfoList = new ArrayList<MessageInfo>();
msgInfoList.add(msgInfo1);
msgInfoList.add(msgInfo2);
msgInfoList.add(msgInfo3);
if (blobVersion == Blob_Version_V2) {
msgInfoList.add(msgInfo4);
msgInfoList.add(msgInfo5);
}
MessageSievingInputStream sievedStream = new MessageSievingInputStream(inputStream, msgInfoList, transformers, new MetricRegistry());
Map<StoreKey, StoreKey> convertedMap = randomKeyConverter.convert(Arrays.asList(key1, key2, key3));
Map<StoreKey, StoreKey> convertedMapExtra = randomKeyConverter.convert(Arrays.asList(key4, key5));
int headerSizeV1 = MessageHeader_Format_V1.getHeaderSize();
int headerSizeV2 = MessageHeader_Format_V2.getHeaderSize();
int blobPropertiesRecordSize = BlobProperties_Format_V1.getBlobPropertiesRecordSize(prop1);
int userMetadataSize = UserMetadata_Format_V1.getUserMetadataSize(ByteBuffer.wrap(usermetadata1));
int totalHeadSize = 3 * (headerVersionToUse == MessageFormatRecord.Message_Header_Version_V1 ? headerSizeV1 : headerSizeV2);
int totalEncryptionRecordSize = 0;
int totalBlobPropertiesSize = 3 * blobPropertiesRecordSize;
int totalUserMetadataSize = 3 * userMetadataSize;
int totalBlobSize = 3 * (int) blobSize;
int totalKeySize = (options.contains(TransformerOptions.KeyConvert) ? convertedMap.values() : convertedMap.keySet()).stream().mapToInt(StoreKey::sizeInBytes).sum();
int encryptionRecordSize = BlobEncryptionKey_Format_V1.getBlobEncryptionKeyRecordSize(ByteBuffer.wrap(encryptionKey));
if (blobVersion == Blob_Version_V2) {
totalHeadSize += 2 * headerSizeV2;
// stream 2 and stream 4 have encryption keys.
totalEncryptionRecordSize += 2 * encryptionRecordSize;
totalBlobPropertiesSize += 2 * blobPropertiesRecordSize;
totalUserMetadataSize += 2 * userMetadataSize;
totalBlobSize += 2 * (int) blobSize;
totalKeySize += (options.contains(TransformerOptions.KeyConvert) ? convertedMapExtra.values() : convertedMapExtra.keySet()).stream().mapToInt(StoreKey::sizeInBytes).sum();
}
Assert.assertFalse(sievedStream.hasInvalidMessages());
if (!options.isEmpty()) {
Assert.assertEquals(options.isEmpty() ? totalMessageStreamContent.length : totalHeadSize + totalEncryptionRecordSize + totalBlobPropertiesSize + totalUserMetadataSize + totalBlobSize + totalKeySize, sievedStream.getSize());
Assert.assertEquals((int) sievedStream.getValidMessageInfoList().stream().mapToLong(MessageInfo::getSize).sum(), sievedStream.getSize());
verifySievedTransformedMessage(sievedStream, options.contains(TransformerOptions.KeyConvert) ? convertedMap.get(key1) : key1, "servid1", accountId1, containerId1, null, usermetadata1, data1, blobVersion, blobType);
verifySievedTransformedMessage(sievedStream, options.contains(TransformerOptions.KeyConvert) ? convertedMap.get(key2) : key2, "servid2", accountId2, containerId2, blobVersion == Blob_Version_V2 ? encryptionKey : null, usermetadata2, data2, blobVersion, blobType);
verifySievedTransformedMessage(sievedStream, options.contains(TransformerOptions.KeyConvert) ? convertedMap.get(key3) : key3, "servid3", accountId3, containerId3, null, usermetadata3, data3, blobVersion, blobType);
if (blobVersion == Blob_Version_V2) {
verifySievedTransformedMessage(sievedStream, options.contains(TransformerOptions.KeyConvert) ? convertedMapExtra.get(key4) : key4, "servid4", accountId4, containerId4, encryptionKey, usermetadata4, data4, blobVersion, blobType);
verifySievedTransformedMessage(sievedStream, options.contains(TransformerOptions.KeyConvert) ? convertedMapExtra.get(key5) : key5, "servid5", accountId5, containerId5, null, usermetadata5, data5, blobVersion, blobType);
}
} else {
Assert.assertEquals(totalMessageStreamContent.length, sievedStream.getSize());
byte[] sievedBytes = Utils.readBytesFromStream(sievedStream, sievedStream.getSize());
Assert.assertArrayEquals(totalMessageStreamContent, sievedBytes);
}
Assert.assertEquals(-1, sievedStream.read());
}
use of com.github.ambry.utils.ByteBufferInputStream in project ambry by linkedin.
the class MessageFormatInputStreamTest method messageFormatPutRecordsTest.
private void messageFormatPutRecordsTest(short blobVersion, BlobType blobType, short headerVersion) throws IOException, MessageFormatException {
StoreKey key = new MockId("id1");
StoreKeyFactory keyFactory = new MockIdFactory();
short accountId = Utils.getRandomShort(TestUtils.RANDOM);
short containerId = Utils.getRandomShort(TestUtils.RANDOM);
BlobProperties prop = new BlobProperties(10, "servid", accountId, containerId, false);
byte[] encryptionKey = new byte[100];
new Random().nextBytes(encryptionKey);
byte[] usermetadata = new byte[1000];
new Random().nextBytes(usermetadata);
int blobContentSize = 2000;
byte[] data = new byte[blobContentSize];
new Random().nextBytes(data);
short lifeVersion = 1;
long blobSize = -1;
MessageFormatRecord.headerVersionToUse = headerVersion;
if (blobVersion == MessageFormatRecord.Blob_Version_V1) {
blobSize = MessageFormatRecord.Blob_Format_V1.getBlobRecordSize(blobContentSize);
} else if (blobVersion == MessageFormatRecord.Blob_Version_V2 && blobType == BlobType.DataBlob) {
blobSize = (int) MessageFormatRecord.Blob_Format_V2.getBlobRecordSize(blobContentSize);
} else if (blobVersion == MessageFormatRecord.Blob_Version_V2 && blobType == BlobType.MetadataBlob) {
ByteBuffer byteBufferBlob = MessageFormatTestUtils.getBlobContentForMetadataBlob(blobContentSize);
data = byteBufferBlob.array();
blobContentSize = data.length;
blobSize = (int) MessageFormatRecord.Blob_Format_V2.getBlobRecordSize(blobContentSize);
}
ByteBufferInputStream stream = new ByteBufferInputStream(ByteBuffer.wrap(data));
MessageFormatInputStream messageFormatStream = (blobVersion == MessageFormatRecord.Blob_Version_V2) ? new PutMessageFormatInputStream(key, ByteBuffer.wrap(encryptionKey), prop, ByteBuffer.wrap(usermetadata), stream, blobContentSize, blobType, lifeVersion) : new PutMessageFormatBlobV1InputStream(key, prop, ByteBuffer.wrap(usermetadata), stream, blobContentSize, blobType);
int headerSize = MessageFormatRecord.getHeaderSizeForVersion(headerVersion);
int blobEncryptionKeySize = headerVersion != MessageFormatRecord.Message_Header_Version_V1 ? MessageFormatRecord.BlobEncryptionKey_Format_V1.getBlobEncryptionKeyRecordSize(ByteBuffer.wrap(encryptionKey)) : 0;
int blobPropertiesRecordSize = MessageFormatRecord.BlobProperties_Format_V1.getBlobPropertiesRecordSize(prop);
int userMetadataSize = MessageFormatRecord.UserMetadata_Format_V1.getUserMetadataSize(ByteBuffer.wrap(usermetadata));
Assert.assertEquals(messageFormatStream.getSize(), headerSize + blobEncryptionKeySize + blobPropertiesRecordSize + userMetadataSize + blobSize + key.sizeInBytes());
// verify header
byte[] headerOutput = new byte[headerSize];
messageFormatStream.read(headerOutput);
ByteBuffer headerBuf = ByteBuffer.wrap(headerOutput);
Assert.assertEquals(headerVersion, headerBuf.getShort());
if (headerVersion == MessageFormatRecord.Message_Header_Version_V3) {
Assert.assertEquals(lifeVersion, headerBuf.getShort());
}
Assert.assertEquals(blobEncryptionKeySize + blobPropertiesRecordSize + userMetadataSize + blobSize, headerBuf.getLong());
switch(headerVersion) {
case MessageFormatRecord.Message_Header_Version_V1:
Assert.assertEquals(headerSize + key.sizeInBytes(), headerBuf.getInt());
Assert.assertEquals(MessageFormatRecord.Message_Header_Invalid_Relative_Offset, headerBuf.getInt());
Assert.assertEquals(headerSize + key.sizeInBytes() + blobPropertiesRecordSize, headerBuf.getInt());
Assert.assertEquals(headerSize + key.sizeInBytes() + blobPropertiesRecordSize + userMetadataSize, headerBuf.getInt());
break;
default:
// case MessageFormatRecord.Message_Header_Version_V2 or V3:
Assert.assertEquals(headerSize + key.sizeInBytes(), headerBuf.getInt());
Assert.assertEquals(headerSize + key.sizeInBytes() + blobEncryptionKeySize, headerBuf.getInt());
Assert.assertEquals(MessageFormatRecord.Message_Header_Invalid_Relative_Offset, headerBuf.getInt());
Assert.assertEquals(headerSize + key.sizeInBytes() + blobEncryptionKeySize + blobPropertiesRecordSize, headerBuf.getInt());
Assert.assertEquals(headerSize + key.sizeInBytes() + blobEncryptionKeySize + blobPropertiesRecordSize + userMetadataSize, headerBuf.getInt());
}
Crc32 crc = new Crc32();
crc.update(headerOutput, 0, headerSize - MessageFormatRecord.Crc_Size);
Assert.assertEquals(crc.getValue(), headerBuf.getLong());
// verify handle
byte[] handleOutput = new byte[key.sizeInBytes()];
ByteBuffer handleOutputBuf = ByteBuffer.wrap(handleOutput);
messageFormatStream.read(handleOutput);
byte[] dest = new byte[key.sizeInBytes()];
handleOutputBuf.get(dest);
Assert.assertArrayEquals(dest, key.toBytes());
// verify encryption key
if (headerVersion != MessageFormatRecord.Message_Header_Version_V1) {
byte[] blobEncryptionKeyOutput = new byte[blobEncryptionKeySize];
ByteBuffer blobEncryptionKeyBuf = ByteBuffer.wrap(blobEncryptionKeyOutput);
messageFormatStream.read(blobEncryptionKeyOutput);
Assert.assertEquals(blobEncryptionKeyBuf.getShort(), MessageFormatRecord.Blob_Encryption_Key_V1);
Assert.assertEquals(blobEncryptionKeyBuf.getInt(), 100);
dest = new byte[100];
blobEncryptionKeyBuf.get(dest);
Assert.assertArrayEquals(dest, encryptionKey);
crc = new Crc32();
crc.update(blobEncryptionKeyOutput, 0, blobEncryptionKeySize - MessageFormatRecord.Crc_Size);
Assert.assertEquals(crc.getValue(), blobEncryptionKeyBuf.getLong());
}
// verify blob properties
byte[] blobPropertiesOutput = new byte[blobPropertiesRecordSize];
ByteBuffer blobPropertiesBuf = ByteBuffer.wrap(blobPropertiesOutput);
messageFormatStream.read(blobPropertiesOutput);
Assert.assertEquals(blobPropertiesBuf.getShort(), 1);
BlobProperties propOutput = BlobPropertiesSerDe.getBlobPropertiesFromStream(new DataInputStream(new ByteBufferInputStream(blobPropertiesBuf)));
Assert.assertEquals(10, propOutput.getBlobSize());
Assert.assertEquals("servid", propOutput.getServiceId());
Assert.assertEquals("AccountId mismatch", accountId, propOutput.getAccountId());
Assert.assertEquals("ContainerId mismatch", containerId, propOutput.getContainerId());
crc = new Crc32();
crc.update(blobPropertiesOutput, 0, blobPropertiesRecordSize - MessageFormatRecord.Crc_Size);
Assert.assertEquals(crc.getValue(), blobPropertiesBuf.getLong());
// verify user metadata
byte[] userMetadataOutput = new byte[userMetadataSize];
ByteBuffer userMetadataBuf = ByteBuffer.wrap(userMetadataOutput);
messageFormatStream.read(userMetadataOutput);
Assert.assertEquals(userMetadataBuf.getShort(), 1);
Assert.assertEquals(userMetadataBuf.getInt(), 1000);
dest = new byte[1000];
userMetadataBuf.get(dest);
Assert.assertArrayEquals(dest, usermetadata);
crc = new Crc32();
crc.update(userMetadataOutput, 0, userMetadataSize - MessageFormatRecord.Crc_Size);
Assert.assertEquals(crc.getValue(), userMetadataBuf.getLong());
// verify blob
CrcInputStream crcstream = new CrcInputStream(messageFormatStream);
DataInputStream streamData = new DataInputStream(crcstream);
Assert.assertEquals(streamData.readShort(), blobVersion);
if (blobVersion == MessageFormatRecord.Blob_Version_V2) {
Assert.assertEquals(streamData.readShort(), blobType.ordinal());
}
Assert.assertEquals(streamData.readLong(), blobContentSize);
for (int i = 0; i < blobContentSize; i++) {
Assert.assertEquals((byte) streamData.read(), data[i]);
}
long crcVal = crcstream.getValue();
Assert.assertEquals(crcVal, streamData.readLong());
// Verify Blob All
stream = new ByteBufferInputStream(ByteBuffer.wrap(data));
messageFormatStream = (blobVersion == MessageFormatRecord.Blob_Version_V2) ? new PutMessageFormatInputStream(key, ByteBuffer.wrap(encryptionKey), prop, ByteBuffer.wrap(usermetadata), stream, blobContentSize, blobType) : new PutMessageFormatBlobV1InputStream(key, prop, ByteBuffer.wrap(usermetadata), stream, blobContentSize, blobType);
int totalSize;
switch(headerVersion) {
case MessageFormatRecord.Message_Header_Version_V1:
totalSize = headerSize + key.sizeInBytes() + blobPropertiesRecordSize + userMetadataSize + (int) blobSize;
break;
default:
// case MessageFormatRecord.Message_Header_Version_V2:
totalSize = headerSize + key.sizeInBytes() + blobEncryptionKeySize + blobPropertiesRecordSize + userMetadataSize + (int) blobSize;
}
ByteBuffer allBuf = ByteBuffer.allocate(totalSize);
messageFormatStream.read(allBuf.array());
BlobAll blobAll = MessageFormatRecord.deserializeBlobAll(new ByteBufferInputStream(allBuf), keyFactory);
Assert.assertEquals(key, blobAll.getStoreKey());
Assert.assertArrayEquals(usermetadata, blobAll.getBlobInfo().getUserMetadata());
Assert.assertEquals(blobContentSize, blobAll.getBlobData().getSize());
Assert.assertEquals(blobType, blobAll.getBlobData().getBlobType());
if (headerVersion != MessageFormatRecord.Message_Header_Version_V1) {
Assert.assertEquals(ByteBuffer.wrap(encryptionKey), blobAll.getBlobEncryptionKey());
} else {
Assert.assertEquals(null, blobAll.getBlobEncryptionKey());
}
ByteBuf byteBuf = blobAll.getBlobData().content();
try {
Assert.assertEquals(Unpooled.wrappedBuffer(data), byteBuf);
} finally {
byteBuf.release();
}
}
use of com.github.ambry.utils.ByteBufferInputStream in project ambry by linkedin.
the class MessageFormatSendTest method doSendWriteSingleMessageTest.
/**
* Helper method for testing single message sends.
* @param encryptionKey the encryption key to include in the message while writing it.
* @param expectedEncryptionKey the key expected when reading the sent message.
*/
private void doSendWriteSingleMessageTest(ByteBuffer encryptionKey, ByteBuffer expectedEncryptionKey) throws Exception {
String serviceId = "serviceId";
String ownerId = "owner";
String contentType = "bin";
short accountId = 10;
short containerId = 2;
byte[] blob = TestUtils.getRandomBytes(10000);
byte[] userMetadata = TestUtils.getRandomBytes(2000);
StoreKey storeKey = new MockId("012345678910123456789012");
BlobProperties properties = new BlobProperties(blob.length, serviceId, ownerId, contentType, false, 100, accountId, containerId, encryptionKey != null, null, null, null);
MessageFormatInputStream putStream;
MessageFormatRecord.MessageHeader_Format header;
if (putFormat.equals(PutMessageFormatInputStream.class.getSimpleName())) {
header = getHeader(new PutMessageFormatInputStream(storeKey, encryptionKey == null ? null : encryptionKey.duplicate(), properties, ByteBuffer.wrap(userMetadata), new ByteBufferInputStream(ByteBuffer.wrap(blob)), blob.length, BlobType.DataBlob));
putStream = new PutMessageFormatInputStream(storeKey, encryptionKey, properties, ByteBuffer.wrap(userMetadata), new ByteBufferInputStream(ByteBuffer.wrap(blob)), blob.length, BlobType.DataBlob);
} else {
header = getHeader(new PutMessageFormatBlobV1InputStream(storeKey, properties, ByteBuffer.wrap(userMetadata), new ByteBufferInputStream(ByteBuffer.wrap(blob)), blob.length, BlobType.DataBlob));
putStream = new PutMessageFormatBlobV1InputStream(storeKey, properties, ByteBuffer.wrap(userMetadata), new ByteBufferInputStream(ByteBuffer.wrap(blob)), blob.length, BlobType.DataBlob);
}
ByteBuffer buf1 = ByteBuffer.allocate((int) putStream.getSize());
putStream.read(buf1.array());
ArrayList<ByteBuffer> listbuf = new ArrayList<ByteBuffer>();
listbuf.add(buf1);
ArrayList<StoreKey> storeKeys = new ArrayList<StoreKey>();
storeKeys.add(storeKey);
MockMessageReadSet readSet = new MockMessageReadSet(listbuf, storeKeys);
MetricRegistry registry = new MetricRegistry();
MessageFormatMetrics metrics = new MessageFormatMetrics(registry);
// get all
MessageFormatSend send = new MessageFormatSend(readSet, MessageFormatFlags.All, metrics, new MockIdFactory());
Assert.assertEquals(send.sizeInBytes(), putStream.getSize());
Assert.assertEquals(1, send.getMessageMetadataList().size());
Assert.assertEquals(null, send.getMessageMetadataList().get(0));
ByteBuffer bufresult = ByteBuffer.allocate((int) putStream.getSize());
WritableByteChannel channel = Channels.newChannel(new ByteBufferOutputStream(bufresult));
while (!send.isSendComplete()) {
send.writeTo(channel);
}
Assert.assertArrayEquals(buf1.array(), bufresult.array());
Assert.assertTrue(readSet.isPrefetchInfoCorrect(0, readSet.sizeInBytes(0)));
// get blob
send = new MessageFormatSend(readSet, MessageFormatFlags.Blob, metrics, new MockIdFactory());
long blobRecordSize = putFormat.equals(PutMessageFormatInputStream.class.getSimpleName()) ? MessageFormatRecord.Blob_Format_V2.getBlobRecordSize(blob.length) : MessageFormatRecord.Blob_Format_V1.getBlobRecordSize(blob.length);
Assert.assertEquals(send.sizeInBytes(), blobRecordSize);
bufresult.clear();
channel = Channels.newChannel(new ByteBufferOutputStream(bufresult));
while (!send.isSendComplete()) {
send.writeTo(channel);
}
for (int i = 0; i < blob.length; i++) {
Assert.assertEquals(blob[i], bufresult.array()[i + (int) blobRecordSize - MessageFormatRecord.Crc_Size - blob.length]);
}
if (expectedEncryptionKey == null) {
Assert.assertEquals(null, send.getMessageMetadataList().get(0));
} else {
Assert.assertEquals(expectedEncryptionKey, send.getMessageMetadataList().get(0).getEncryptionKey());
}
Assert.assertTrue(readSet.isPrefetchInfoCorrect(0, readSet.sizeInBytes(0)));
// get user metadata
send = new MessageFormatSend(readSet, MessageFormatFlags.BlobUserMetadata, metrics, new MockIdFactory());
long userMetadataRecordSize = MessageFormatRecord.UserMetadata_Format_V1.getUserMetadataSize(ByteBuffer.wrap(userMetadata));
Assert.assertEquals(send.sizeInBytes(), userMetadataRecordSize);
bufresult.clear();
channel = Channels.newChannel(new ByteBufferOutputStream(bufresult));
while (!send.isSendComplete()) {
send.writeTo(channel);
}
bufresult.flip();
// read off the header.
for (int i = 0; i < userMetadataRecordSize - MessageFormatRecord.Crc_Size - userMetadata.length; i++) {
bufresult.get();
}
verifyBlobUserMetadata(userMetadata, bufresult);
if (expectedEncryptionKey == null) {
Assert.assertEquals(null, send.getMessageMetadataList().get(0));
} else {
Assert.assertEquals(expectedEncryptionKey, send.getMessageMetadataList().get(0).getEncryptionKey());
}
Assert.assertTrue(readSet.isPrefetchInfoCorrect(header.getUserMetadataRecordRelativeOffset(), header.getUserMetadataRecordSize()));
// get blob properties
send = new MessageFormatSend(readSet, MessageFormatFlags.BlobProperties, metrics, new MockIdFactory());
long blobPropertiesRecordSize = MessageFormatRecord.BlobProperties_Format_V1.getBlobPropertiesRecordSize(properties);
Assert.assertEquals(send.sizeInBytes(), blobPropertiesRecordSize);
bufresult.clear();
channel = Channels.newChannel(new ByteBufferOutputStream(bufresult));
while (!send.isSendComplete()) {
send.writeTo(channel);
}
bufresult.flip();
// read off the header.
for (int i = 0; i < blobPropertiesRecordSize - MessageFormatRecord.Crc_Size - BlobPropertiesSerDe.getBlobPropertiesSerDeSize(properties); i++) {
bufresult.get();
}
verifyBlobProperties(properties, BlobPropertiesSerDe.getBlobPropertiesFromStream(new DataInputStream(new ByteBufferInputStream(bufresult))));
Assert.assertEquals(null, send.getMessageMetadataList().get(0));
Assert.assertTrue(readSet.isPrefetchInfoCorrect(header.getBlobPropertiesRecordRelativeOffset(), header.getBlobPropertiesRecordSize()));
// get blob info
send = new MessageFormatSend(readSet, MessageFormatFlags.BlobInfo, metrics, new MockIdFactory());
Assert.assertEquals(send.sizeInBytes(), blobPropertiesRecordSize + userMetadataRecordSize);
bufresult.clear();
channel = Channels.newChannel(new ByteBufferOutputStream(bufresult));
while (!send.isSendComplete()) {
send.writeTo(channel);
}
bufresult.flip();
for (int i = 0; i < blobPropertiesRecordSize - MessageFormatRecord.Crc_Size - BlobPropertiesSerDe.getBlobPropertiesSerDeSize(properties); i++) {
bufresult.get();
}
verifyBlobProperties(properties, BlobPropertiesSerDe.getBlobPropertiesFromStream(new DataInputStream(new ByteBufferInputStream(bufresult))));
for (int i = 0; i < userMetadataRecordSize - userMetadata.length; i++) {
bufresult.get();
}
verifyBlobUserMetadata(userMetadata, bufresult);
if (expectedEncryptionKey == null) {
Assert.assertEquals(null, send.getMessageMetadataList().get(0));
} else {
Assert.assertEquals(expectedEncryptionKey, send.getMessageMetadataList().get(0).getEncryptionKey());
}
Assert.assertTrue(readSet.isPrefetchInfoCorrect(header.getBlobPropertiesRecordRelativeOffset(), header.getBlobPropertiesRecordSize() + header.getUserMetadataRecordSize()));
}
use of com.github.ambry.utils.ByteBufferInputStream in project ambry by linkedin.
the class MessageFormatSendTest method doSendWriteCompositeMessagesTest.
/**
* Helper method to test multiple messages in a single Send involving different combinations of header format
* versions, put formats and encryption keys.
* @param blob the array of blob records for the messages.
* @param userMetadata the array of userMetadata for the messages.
* @param storeKeys the array of store keys for the messages.
* @param encryptionKeys the array of encryption keys for the messages.
* @param putFormats the array of Put Format class names to use to create the message streams.
* @param headerVersions the array of Message Header versions to use for the messages.
*/
private void doSendWriteCompositeMessagesTest(byte[][] blob, byte[][] userMetadata, StoreKey[] storeKeys, ByteBuffer[] encryptionKeys, String[] putFormats, short[] headerVersions) throws MessageFormatException, IOException {
String serviceIdPrefix = "serviceId";
String ownerIdPrefix = "owner";
String contentTypePrefix = "bin";
short accountIdBase = 10;
short containerIdBase = 2;
BlobProperties[] properties = new BlobProperties[5];
for (int i = 0; i < 5; i++) {
properties[i] = new BlobProperties(blob[i].length, serviceIdPrefix + i, ownerIdPrefix + i, contentTypePrefix + i, false, 100, (short) (accountIdBase + i), (short) (containerIdBase + i), encryptionKeys[i] != null, null, null, null);
}
MessageFormatInputStream[] putStreams = new MessageFormatInputStream[5];
for (int i = 0; i < 5; i++) {
MessageFormatRecord.headerVersionToUse = headerVersions[i];
if (putFormats[i].equals(PutMessageFormatInputStream.class.getSimpleName())) {
putStreams[i] = new PutMessageFormatInputStream(storeKeys[i], (ByteBuffer) encryptionKeys[i].rewind(), properties[i], ByteBuffer.wrap(userMetadata[i]), new ByteBufferInputStream(ByteBuffer.wrap(blob[i])), blob[i].length, BlobType.DataBlob);
} else {
putStreams[i] = new PutMessageFormatBlobV1InputStream(storeKeys[i], properties[i], ByteBuffer.wrap(userMetadata[i]), new ByteBufferInputStream(ByteBuffer.wrap(blob[i])), blob[i].length, BlobType.DataBlob);
}
}
int totalStreamSize = (int) Arrays.stream(putStreams).mapToLong(MessageFormatInputStream::getSize).sum();
ByteBuffer compositeBuf = ByteBuffer.allocate(totalStreamSize);
ArrayList<ByteBuffer> listbuf = new ArrayList<>();
for (int i = 0; i < 5; i++) {
ByteBuffer buf = ByteBuffer.allocate((int) putStreams[i].getSize());
putStreams[i].read(buf.array());
compositeBuf.put(buf.array());
listbuf.add(buf);
}
MessageReadSet readSet = new MockMessageReadSet(listbuf, new ArrayList<>(Arrays.asList(storeKeys)));
MetricRegistry registry = new MetricRegistry();
MessageFormatMetrics metrics = new MessageFormatMetrics(registry);
// get all
MessageFormatSend send = new MessageFormatSend(readSet, MessageFormatFlags.All, metrics, new MockIdFactory());
Assert.assertEquals(send.sizeInBytes(), totalStreamSize);
Assert.assertEquals(5, send.getMessageMetadataList().size());
for (int i = 0; i < 5; i++) {
Assert.assertEquals(null, send.getMessageMetadataList().get(i));
}
ByteBuffer bufresult = ByteBuffer.allocate(totalStreamSize);
WritableByteChannel channel = Channels.newChannel(new ByteBufferOutputStream(bufresult));
while (!send.isSendComplete()) {
send.writeTo(channel);
}
Assert.assertArrayEquals(compositeBuf.array(), bufresult.array());
// get blob
send = new MessageFormatSend(readSet, MessageFormatFlags.Blob, metrics, new MockIdFactory());
int[] blobRecordSizes = new int[5];
for (int i = 0; i < 5; i++) {
blobRecordSizes[i] = (int) (putFormats[i].equals(PutMessageFormatInputStream.class.getSimpleName()) ? MessageFormatRecord.Blob_Format_V2.getBlobRecordSize(blob[i].length) : MessageFormatRecord.Blob_Format_V1.getBlobRecordSize(blob[i].length));
}
Assert.assertEquals(send.sizeInBytes(), (long) Arrays.stream(blobRecordSizes).sum());
bufresult.clear();
channel = Channels.newChannel(new ByteBufferOutputStream(bufresult));
while (!send.isSendComplete()) {
send.writeTo(channel);
}
int startOffset = 0;
for (int i = 0; i < 5; i++) {
DeserializedBlob deserializedBlob = MessageFormatRecord.deserializeAndGetBlobWithVersion(new ByteArrayInputStream(bufresult.array(), startOffset, blobRecordSizes[i]));
Assert.assertEquals(putFormats[i].equals(PutMessageFormatInputStream.class.getSimpleName()) ? MessageFormatRecord.Blob_Version_V2 : MessageFormatRecord.Blob_Version_V1, deserializedBlob.getVersion());
Assert.assertEquals(BlobType.DataBlob, deserializedBlob.getBlobData().getBlobType());
Assert.assertEquals(blob[i].length, deserializedBlob.getBlobData().getSize());
byte[] readBlob = new byte[blob[i].length];
deserializedBlob.getBlobData().content().readBytes(readBlob);
Assert.assertArrayEquals(blob[i], readBlob);
deserializedBlob.getBlobData().release();
if (headerVersions[i] == MessageFormatRecord.Message_Header_Version_V1) {
Assert.assertEquals(null, send.getMessageMetadataList().get(i));
} else {
Assert.assertEquals(encryptionKeys[i].rewind(), send.getMessageMetadataList().get(i).getEncryptionKey());
}
startOffset += blobRecordSizes[i];
}
// get user metadata
send = new MessageFormatSend(readSet, MessageFormatFlags.BlobUserMetadata, metrics, new MockIdFactory());
int[] userMetadataSizes = new int[5];
for (int i = 0; i < 5; i++) {
userMetadataSizes[i] = MessageFormatRecord.UserMetadata_Format_V1.getUserMetadataSize(ByteBuffer.wrap(userMetadata[i]));
}
Assert.assertEquals(send.sizeInBytes(), (long) Arrays.stream(userMetadataSizes).sum());
bufresult.clear();
channel = Channels.newChannel(new ByteBufferOutputStream(bufresult));
while (!send.isSendComplete()) {
send.writeTo(channel);
}
startOffset = 0;
for (int i = 0; i < 5; i++) {
DeserializedUserMetadata deserializedUserMetadata = MessageFormatRecord.deserializeAndGetUserMetadataWithVersion(new ByteArrayInputStream(bufresult.array(), startOffset, userMetadataSizes[i]));
Assert.assertEquals(MessageFormatRecord.UserMetadata_Version_V1, deserializedUserMetadata.getVersion());
verifyBlobUserMetadata(userMetadata[i], deserializedUserMetadata.getUserMetadata());
if (headerVersions[i] == MessageFormatRecord.Message_Header_Version_V1) {
Assert.assertEquals(null, send.getMessageMetadataList().get(i));
} else {
Assert.assertEquals(encryptionKeys[i].rewind(), send.getMessageMetadataList().get(i).getEncryptionKey());
}
startOffset += userMetadataSizes[i];
}
// get blob properties
send = new MessageFormatSend(readSet, MessageFormatFlags.BlobProperties, metrics, new MockIdFactory());
int[] blobPropertiesSizes = new int[5];
for (int i = 0; i < 5; i++) {
blobPropertiesSizes[i] = MessageFormatRecord.BlobProperties_Format_V1.getBlobPropertiesRecordSize(properties[i]);
}
Assert.assertEquals(send.sizeInBytes(), (long) Arrays.stream(blobPropertiesSizes).sum());
bufresult.clear();
channel = Channels.newChannel(new ByteBufferOutputStream(bufresult));
while (!send.isSendComplete()) {
send.writeTo(channel);
}
startOffset = 0;
for (int i = 0; i < 5; i++) {
DeserializedBlobProperties deserializedBlobProperties = MessageFormatRecord.deserializeAndGetBlobPropertiesWithVersion(new ByteArrayInputStream(bufresult.array(), startOffset, blobPropertiesSizes[i]));
Assert.assertEquals(MessageFormatRecord.BlobProperties_Version_V1, deserializedBlobProperties.getVersion());
verifyBlobProperties(properties[i], deserializedBlobProperties.getBlobProperties());
Assert.assertEquals(null, send.getMessageMetadataList().get(i));
startOffset += blobPropertiesSizes[i];
}
// get blob info
send = new MessageFormatSend(readSet, MessageFormatFlags.BlobInfo, metrics, new MockIdFactory());
int[] blobInfoSizes = new int[5];
for (int i = 0; i < 5; i++) {
blobInfoSizes[i] = MessageFormatRecord.BlobProperties_Format_V1.getBlobPropertiesRecordSize(properties[i]) + MessageFormatRecord.UserMetadata_Format_V1.getUserMetadataSize(ByteBuffer.wrap(userMetadata[i]));
}
Assert.assertEquals(send.sizeInBytes(), (long) Arrays.stream(blobInfoSizes).sum());
bufresult.clear();
channel = Channels.newChannel(new ByteBufferOutputStream(bufresult));
while (!send.isSendComplete()) {
send.writeTo(channel);
}
startOffset = 0;
for (int i = 0; i < 5; i++) {
ByteArrayInputStream inputStream = new ByteArrayInputStream(bufresult.array(), startOffset, blobInfoSizes[i]);
DeserializedBlobProperties deserializedBlobProperties = MessageFormatRecord.deserializeAndGetBlobPropertiesWithVersion(inputStream);
DeserializedUserMetadata deserializedUserMetadata = MessageFormatRecord.deserializeAndGetUserMetadataWithVersion(inputStream);
Assert.assertEquals(MessageFormatRecord.BlobProperties_Version_V1, deserializedBlobProperties.getVersion());
verifyBlobProperties(properties[i], deserializedBlobProperties.getBlobProperties());
Assert.assertEquals(MessageFormatRecord.UserMetadata_Version_V1, deserializedUserMetadata.getVersion());
verifyBlobUserMetadata(userMetadata[i], deserializedUserMetadata.getUserMetadata());
if (headerVersions[i] == MessageFormatRecord.Message_Header_Version_V1) {
Assert.assertEquals(null, send.getMessageMetadataList().get(i));
} else {
Assert.assertEquals(encryptionKeys[i].rewind(), send.getMessageMetadataList().get(i).getEncryptionKey());
}
startOffset += blobInfoSizes[i];
}
}
Aggregations