@Test public void testUpdateRecordV3() throws IOException, MessageFormatException { short accountId = Utils.getRandomShort(TestUtils.RANDOM); short containerId = Utils.getRandomShort(TestUtils.RANDOM); long updateTimeMs = SystemTime.getInstance().milliseconds() + TestUtils.RANDOM.nextInt(); long updatedExpiryTimesMs = SystemTime.getInstance().milliseconds() + TestUtils.RANDOM.nextInt(); for (SubRecord.Type type : SubRecord.Type.values()) { ByteBuffer updateRecordBuf = ByteBuffer.allocate(Update_Format_V3.getRecordSize(type)); UpdateRecord updateRecord = null; switch (type) { case DELETE: DeleteSubRecord deleteSubRecord = new DeleteSubRecord(); updateRecord = new UpdateRecord(accountId, containerId, updateTimeMs, deleteSubRecord); break; case TTL_UPDATE: TtlUpdateSubRecord ttlUpdateSubRecord = new TtlUpdateSubRecord(updatedExpiryTimesMs); updateRecord = new UpdateRecord(accountId, containerId, updateTimeMs, ttlUpdateSubRecord); break; case UNDELETE: UndeleteSubRecord undeleteSubRecord = new UndeleteSubRecord(); updateRecord = new UpdateRecord(accountId, containerId, updateTimeMs, undeleteSubRecord); break; default: fail("Unknown update record type: " + type); } Update_Format_V3.serialize(updateRecordBuf, updateRecord); updateRecordBuf.flip(); UpdateRecord deserializeUpdateRecord = MessageFormatRecord.deserializeUpdateRecord(new ByteBufferInputStream(updateRecordBuf)); Assert.assertEquals("AccountId mismatch ", accountId, deserializeUpdateRecord.getAccountId()); Assert.assertEquals("ContainerId mismatch ", containerId, deserializeUpdateRecord.getContainerId()); Assert.assertEquals("UpdateTime mismatch ", updateTimeMs, deserializeUpdateRecord.getUpdateTimeInMs()); Assert.assertEquals("Type of update record incorrect", type, deserializeUpdateRecord.getType()); switch (type) { case DELETE: Assert.assertNotNull("DeleteSubRecord is null", deserializeUpdateRecord.getDeleteSubRecord()); break; case TTL_UPDATE: TtlUpdateSubRecord ttlUpdateSubRecord = deserializeUpdateRecord.getTtlUpdateSubRecord(); Assert.assertNotNull("TtlUpdateSubRecord is null", ttlUpdateSubRecord); Assert.assertEquals("Updated expiry time is incorrect", updatedExpiryTimesMs, ttlUpdateSubRecord.getUpdatedExpiryTimeMs()); break; case UNDELETE: Assert.assertNotNull("UndeleteSubRecord is null", deserializeUpdateRecord.getUndeleteSubRecord()); break; default: fail("Unknown update record type: " + type); } updateRecordBuf.flip(); byte toCorrupt = updateRecordBuf.get(10); updateRecordBuf.put(10, (byte) (toCorrupt + 1)); try { MessageFormatRecord.deserializeUpdateRecord(new ByteBufferInputStream(updateRecordBuf)); fail("Deserialization of a corrupt update record V3 should have failed "); } catch (MessageFormatException e) { Assert.assertEquals(e.getErrorCode(), MessageFormatErrorCodes.Data_Corrupt); } } }
public static UpdateRecord deserializeUpdateRecord(InputStream stream) throws IOException, MessageFormatException { CrcInputStream crcStream = new CrcInputStream(stream); DataInputStream inputStream = new DataInputStream(crcStream); short version = inputStream.readShort(); switch (version) { case Update_Version_V1: return Update_Format_V1.deserialize(crcStream); case Update_Version_V2: return Update_Format_V2.deserialize(crcStream); case Update_Version_V3: return Update_Format_V3.deserialize(crcStream); default: throw new MessageFormatException("update record version not supported: " + version, MessageFormatErrorCodes.Unknown_Format_Version); } }
MessageFormatRecord { public static UpdateRecord deserializeUpdateRecord(InputStream stream) throws IOException, MessageFormatException { CrcInputStream crcStream = new CrcInputStream(stream); DataInputStream inputStream = new DataInputStream(crcStream); short version = inputStream.readShort(); switch (version) { case Update_Version_V1: return Update_Format_V1.deserialize(crcStream); case Update_Version_V2: return Update_Format_V2.deserialize(crcStream); case Update_Version_V3: return Update_Format_V3.deserialize(crcStream); default: throw new MessageFormatException("update record version not supported: " + version, MessageFormatErrorCodes.Unknown_Format_Version); } } }
MessageFormatRecord { public static UpdateRecord deserializeUpdateRecord(InputStream stream) throws IOException, MessageFormatException { CrcInputStream crcStream = new CrcInputStream(stream); DataInputStream inputStream = new DataInputStream(crcStream); short version = inputStream.readShort(); switch (version) { case Update_Version_V1: return Update_Format_V1.deserialize(crcStream); case Update_Version_V2: return Update_Format_V2.deserialize(crcStream); case Update_Version_V3: return Update_Format_V3.deserialize(crcStream); default: throw new MessageFormatException("update record version not supported: " + version, MessageFormatErrorCodes.Unknown_Format_Version); } }  }
MessageFormatRecord { public static UpdateRecord deserializeUpdateRecord(InputStream stream) throws IOException, MessageFormatException { CrcInputStream crcStream = new CrcInputStream(stream); DataInputStream inputStream = new DataInputStream(crcStream); short version = inputStream.readShort(); switch (version) { case Update_Version_V1: return Update_Format_V1.deserialize(crcStream); case Update_Version_V2: return Update_Format_V2.deserialize(crcStream); case Update_Version_V3: return Update_Format_V3.deserialize(crcStream); default: throw new MessageFormatException("update record version not supported: " + version, MessageFormatErrorCodes.Unknown_Format_Version); } }  static boolean isValidHeaderVersion(short headerVersion); static short getCurrentMessageHeaderVersion(); static int getHeaderSizeForVersion(short headerVersion); static MessageHeader_Format getMessageHeader(short headerVersion, ByteBuffer input); static BlobProperties deserializeBlobProperties(InputStream stream); static UpdateRecord deserializeUpdateRecord(InputStream stream); static ByteBuffer deserializeBlobEncryptionKey(InputStream stream); static ByteBuffer deserializeUserMetadata(InputStream stream); static BlobData deserializeBlob(InputStream stream); static BlobAll deserializeBlobAll(InputStream stream, StoreKeyFactory storeKeyFactory); }
MessageFormatRecord { public static UpdateRecord deserializeUpdateRecord(InputStream stream) throws IOException, MessageFormatException { CrcInputStream crcStream = new CrcInputStream(stream); DataInputStream inputStream = new DataInputStream(crcStream); short version = inputStream.readShort(); switch (version) { case Update_Version_V1: return Update_Format_V1.deserialize(crcStream); case Update_Version_V2: return Update_Format_V2.deserialize(crcStream); case Update_Version_V3: return Update_Format_V3.deserialize(crcStream); default: throw new MessageFormatException("update record version not supported: " + version, MessageFormatErrorCodes.Unknown_Format_Version); } }  static boolean isValidHeaderVersion(short headerVersion); static short getCurrentMessageHeaderVersion(); static int getHeaderSizeForVersion(short headerVersion); static MessageHeader_Format getMessageHeader(short headerVersion, ByteBuffer input); static BlobProperties deserializeBlobProperties(InputStream stream); static UpdateRecord deserializeUpdateRecord(InputStream stream); static ByteBuffer deserializeBlobEncryptionKey(InputStream stream); static ByteBuffer deserializeUserMetadata(InputStream stream); static BlobData deserializeBlob(InputStream stream); static BlobAll deserializeBlobAll(InputStream stream, StoreKeyFactory storeKeyFactory); static final int Version_Field_Size_In_Bytes; static final int Crc_Size; static final short Message_Header_Version_V1; static final short Message_Header_Version_V2; static final short Message_Header_Version_V3; static final short BlobProperties_Version_V1; static final short Update_Version_V1; static final short Update_Version_V2; static final short Update_Version_V3; static final short Blob_Encryption_Key_V1; static final short UserMetadata_Version_V1; static final short Blob_Version_V1; static final short Blob_Version_V2; static final short Metadata_Content_Version_V2; static final short Metadata_Content_Version_V3; static final int Message_Header_Invalid_Relative_Offset; }