Search in sources :

Example 11 with Crc32

use of com.github.ambry.utils.Crc32 in project ambry by linkedin.

the class MessageFormatInputStreamTest method messageFormatRecordsTest.

private void messageFormatRecordsTest(short blobVersion, BlobType blobType, boolean useV2Header) 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);
    long blobSize = -1;
    MessageFormatRecord.headerVersionToUse = useV2Header ? MessageFormatRecord.Message_Header_Version_V2 : MessageFormatRecord.Message_Header_Version_V1;
    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) : new PutMessageFormatBlobV1InputStream(key, prop, ByteBuffer.wrap(usermetadata), stream, blobContentSize, blobType);
    int headerSize = MessageFormatRecord.getHeaderSizeForVersion(useV2Header ? MessageFormatRecord.Message_Header_Version_V2 : MessageFormatRecord.Message_Header_Version_V1);
    int blobEncryptionKeySize = useV2Header ? 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(useV2Header ? MessageFormatRecord.Message_Header_Version_V2 : MessageFormatRecord.Message_Header_Version_V1, headerBuf.getShort());
    Assert.assertEquals(blobEncryptionKeySize + blobPropertiesRecordSize + userMetadataSize + blobSize, headerBuf.getLong());
    if (useV2Header) {
        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());
    } else {
        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());
    }
    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 (useV2Header) {
        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;
    if (useV2Header) {
        totalSize = headerSize + key.sizeInBytes() + blobEncryptionKeySize + blobPropertiesRecordSize + userMetadataSize + (int) blobSize;
    } else {
        totalSize = headerSize + key.sizeInBytes() + 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 (useV2Header) {
        Assert.assertEquals(ByteBuffer.wrap(encryptionKey), blobAll.getBlobEncryptionKey());
    } else {
        Assert.assertEquals(null, blobAll.getBlobEncryptionKey());
    }
    Assert.assertEquals(ByteBuffer.wrap(data), blobAll.getBlobData().getStream().getByteBuffer());
}
Also used : ByteBufferInputStream(com.github.ambry.utils.ByteBufferInputStream) DataInputStream(java.io.DataInputStream) StoreKey(com.github.ambry.store.StoreKey) ByteBuffer(java.nio.ByteBuffer) StoreKeyFactory(com.github.ambry.store.StoreKeyFactory) CrcInputStream(com.github.ambry.utils.CrcInputStream) Random(java.util.Random) Crc32(com.github.ambry.utils.Crc32)

Example 12 with Crc32

use of com.github.ambry.utils.Crc32 in project ambry by linkedin.

the class MessageSievingInputStreamTest method verifyBlob.

private boolean verifyBlob(MessageSievingInputStream validMessageDetectionInputStream, short headerVersion, int headerSize, int blobEncryptionRecordSize, int blobPropertiesRecordSize, int userMetadataSize, int blobSize, StoreKey key, int blobPropertiesSize, String serviceId, short accountId, short containerId, byte[] encryptionKey, byte[] usermetadata, byte[] data, short blobVersion, BlobType blobType) throws IOException {
    // verify header
    byte[] headerOutput = new byte[headerSize];
    validMessageDetectionInputStream.read(headerOutput);
    ByteBuffer headerBuf = ByteBuffer.wrap(headerOutput);
    Assert.assertEquals(headerVersion, headerBuf.getShort());
    Assert.assertEquals(blobEncryptionRecordSize + blobPropertiesRecordSize + userMetadataSize + blobSize, headerBuf.getLong());
    if (headerVersion == Message_Header_Version_V2) {
        if (blobEncryptionRecordSize == 0) {
            Assert.assertEquals(Message_Header_Invalid_Relative_Offset, headerBuf.getInt());
        } else {
            Assert.assertEquals(headerSize + key.sizeInBytes(), headerBuf.getInt());
        }
    }
    Assert.assertEquals(headerSize + key.sizeInBytes() + blobEncryptionRecordSize, headerBuf.getInt());
    Assert.assertEquals(Message_Header_Invalid_Relative_Offset, headerBuf.getInt());
    Assert.assertEquals(headerSize + key.sizeInBytes() + blobEncryptionRecordSize + blobPropertiesRecordSize, headerBuf.getInt());
    Assert.assertEquals(headerSize + key.sizeInBytes() + blobEncryptionRecordSize + blobPropertiesRecordSize + userMetadataSize, headerBuf.getInt());
    Crc32 crc = new Crc32();
    crc.update(headerOutput, 0, headerSize - Crc_Size);
    Assert.assertEquals(crc.getValue(), headerBuf.getLong());
    // verify handle
    byte[] handleOutput = new byte[key.sizeInBytes()];
    ByteBuffer handleOutputBuf = ByteBuffer.wrap(handleOutput);
    validMessageDetectionInputStream.read(handleOutput);
    byte[] dest = new byte[key.sizeInBytes()];
    handleOutputBuf.get(dest);
    Assert.assertArrayEquals(dest, key.toBytes());
    if (headerVersion == Message_Header_Version_V2 && blobEncryptionRecordSize != 0) {
        // verify blob encryption record
        byte[] blobEncryptionOutput = new byte[blobEncryptionRecordSize];
        ByteBuffer blobEncryptionBuf = ByteBuffer.wrap(blobEncryptionOutput);
        validMessageDetectionInputStream.read(blobEncryptionOutput);
        Assert.assertEquals(blobEncryptionBuf.getShort(), Blob_Encryption_Key_V1);
        Assert.assertEquals(blobEncryptionBuf.getInt(), encryptionKey.length);
        dest = new byte[encryptionKey.length];
        blobEncryptionBuf.get(dest);
        Assert.assertArrayEquals(dest, encryptionKey);
        crc = new Crc32();
        crc.update(blobEncryptionOutput, 0, blobEncryptionRecordSize - Crc_Size);
        Assert.assertEquals(crc.getValue(), blobEncryptionBuf.getLong());
    }
    // verify blob properties
    byte[] blobPropertiesOutput = new byte[blobPropertiesRecordSize];
    ByteBuffer blobPropertiesBuf = ByteBuffer.wrap(blobPropertiesOutput);
    validMessageDetectionInputStream.read(blobPropertiesOutput);
    Assert.assertEquals(blobPropertiesBuf.getShort(), 1);
    BlobProperties propOutput = BlobPropertiesSerDe.getBlobPropertiesFromStream(new DataInputStream(new ByteBufferInputStream(blobPropertiesBuf)));
    Assert.assertEquals(blobPropertiesSize, propOutput.getBlobSize());
    Assert.assertEquals(serviceId, propOutput.getServiceId());
    Assert.assertEquals("AccountId mismatch", accountId, propOutput.getAccountId());
    Assert.assertEquals("ContainerId mismatch", containerId, propOutput.getContainerId());
    crc = new Crc32();
    crc.update(blobPropertiesOutput, 0, blobPropertiesRecordSize - Crc_Size);
    Assert.assertEquals(crc.getValue(), blobPropertiesBuf.getLong());
    // verify user metadata
    byte[] userMetadataOutput = new byte[userMetadataSize];
    ByteBuffer userMetadataBuf = ByteBuffer.wrap(userMetadataOutput);
    validMessageDetectionInputStream.read(userMetadataOutput);
    Assert.assertEquals(userMetadataBuf.getShort(), 1);
    Assert.assertEquals(userMetadataBuf.getInt(), usermetadata.length);
    dest = new byte[usermetadata.length];
    userMetadataBuf.get(dest);
    Assert.assertArrayEquals(dest, usermetadata);
    crc = new Crc32();
    crc.update(userMetadataOutput, 0, userMetadataSize - Crc_Size);
    Assert.assertEquals(crc.getValue(), userMetadataBuf.getLong());
    // verify blob
    CrcInputStream crcstream = new CrcInputStream(validMessageDetectionInputStream);
    DataInputStream streamData = new DataInputStream(crcstream);
    Assert.assertEquals(streamData.readShort(), blobVersion);
    if (blobVersion == Blob_Version_V2) {
        Assert.assertEquals(blobType.ordinal(), streamData.readShort());
    }
    Assert.assertEquals(streamData.readLong(), data.length);
    for (int i = 0; i < data.length; i++) {
        Assert.assertEquals((byte) streamData.read(), data[i]);
    }
    long crcVal = crcstream.getValue();
    Assert.assertEquals(crcVal, streamData.readLong());
    return true;
}
Also used : CrcInputStream(com.github.ambry.utils.CrcInputStream) Crc32(com.github.ambry.utils.Crc32) ByteBufferInputStream(com.github.ambry.utils.ByteBufferInputStream) DataInputStream(java.io.DataInputStream) ByteBuffer(java.nio.ByteBuffer)

Example 13 with Crc32

use of com.github.ambry.utils.Crc32 in project ambry by linkedin.

the class RestUtils method buildUsermetadata.

/**
 *  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * |         |   size    |  total   |           |          |             |            |            |            |            |
 * | version | excluding |  no of   | key1 size |   key1   | value1 size |  value 1   |  key2 size |     ...    |     Crc    |
 * |(2 bytes)| ver & crc | entries  | (4 bytes) |(key1 size| (4 bytes)   |(value1 size|  (4 bytes) |     ...    |  (8 bytes) |
 * |         | (4 bytes) | (4 bytes)|           |   bytes) |             |   bytes)   |            |            |            |
 *  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 *  version        - The version of the user metadata record
 *
 *  size exluding
 *  ver & CRC      - The size of the user metadata content excluding the version and the CRC
 *
 *  total no of
 *  entries        - Total number of entries in user metadata
 *
 *  key1 size      - Size of 1st key
 *
 *  key1           - Content of key1
 *
 *  value1 size    - Size of 1st value
 *
 *  value1         - Content of value1
 *
 *  key2 size      - Size of 2nd key
 *
 *  crc        - The crc of the user metadata record
 */
/**
 * Builds user metadata given the arguments associated with a request.
 * @param args the arguments associated with the request.
 * @return the user metadata extracted from arguments.
 * @throws RestServiceException if usermetadata arguments have null values.
 */
public static byte[] buildUsermetadata(Map<String, Object> args) throws RestServiceException {
    ByteBuffer userMetadata;
    if (args.containsKey(MultipartPost.USER_METADATA_PART)) {
        userMetadata = (ByteBuffer) args.get(MultipartPost.USER_METADATA_PART);
    } else {
        Map<String, String> userMetadataMap = new HashMap<String, String>();
        int sizeToAllocate = 0;
        for (Map.Entry<String, Object> entry : args.entrySet()) {
            String key = entry.getKey();
            if (key.toLowerCase().startsWith(Headers.USER_META_DATA_HEADER_PREFIX)) {
                // key size
                sizeToAllocate += 4;
                String keyToStore = key.substring(Headers.USER_META_DATA_HEADER_PREFIX.length());
                sizeToAllocate += keyToStore.getBytes(StandardCharsets.US_ASCII).length;
                String value = getHeader(args, key, true);
                userMetadataMap.put(keyToStore, value);
                // value size
                sizeToAllocate += 4;
                sizeToAllocate += value.getBytes(StandardCharsets.US_ASCII).length;
            }
        }
        if (sizeToAllocate == 0) {
            userMetadata = ByteBuffer.allocate(0);
        } else {
            // version
            sizeToAllocate += 2;
            // size excluding version and crc
            sizeToAllocate += 4;
            // total number of entries
            sizeToAllocate += 4;
            // crc size
            sizeToAllocate += CRC_SIZE;
            userMetadata = ByteBuffer.allocate(sizeToAllocate);
            userMetadata.putShort(USER_METADATA_VERSION_V1);
            // total size = sizeToAllocate - version size - sizeToAllocate size - crc size
            userMetadata.putInt(sizeToAllocate - 6 - CRC_SIZE);
            userMetadata.putInt(userMetadataMap.size());
            for (Map.Entry<String, String> entry : userMetadataMap.entrySet()) {
                String key = entry.getKey();
                Utils.serializeString(userMetadata, key, StandardCharsets.US_ASCII);
                Utils.serializeString(userMetadata, entry.getValue(), StandardCharsets.US_ASCII);
            }
            Crc32 crc = new Crc32();
            crc.update(userMetadata.array(), 0, sizeToAllocate - CRC_SIZE);
            userMetadata.putLong(crc.getValue());
        }
    }
    return userMetadata.array();
}
Also used : HashMap(java.util.HashMap) Crc32(com.github.ambry.utils.Crc32) ByteBuffer(java.nio.ByteBuffer) HashMap(java.util.HashMap) Map(java.util.Map)

Example 14 with Crc32

use of com.github.ambry.utils.Crc32 in project ambry by linkedin.

the class RestUtils method buildUserMetadata.

/**
 * Builds user metadata given the arguments associated with a request.
 * <p>
 * The following binary format will be used:
 * <pre>
 *  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 * |         |   size    |  total   |           |          |             |            |            |            |            |
 * | version | excluding |  no of   | key1 size |   key1   | value1 size |  value 1   |  key2 size |     ...    |     Crc    |
 * |(2 bytes)| ver & crc | entries  | (4 bytes) |(key1 size| (4 bytes)   |(value1 size|  (4 bytes) |     ...    |  (8 bytes) |
 * |         | (4 bytes) | (4 bytes)|           |   bytes) |             |   bytes)   |            |            |            |
 *  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 *  version        - The version of the user metadata record
 *
 *  size exluding
 *  ver & CRC      - The size of the user metadata content excluding the version and the CRC
 *
 *  total no of
 *  entries        - Total number of entries in user metadata
 *
 *  key1 size      - Size of 1st key
 *
 *  key1           - Content of key1
 *
 *  value1 size    - Size of 1st value
 *
 *  value1         - Content of value1
 *
 *  key2 size      - Size of 2nd key
 *
 *  crc        - The crc of the user metadata record
 * </pre>
 *
 * @param args the arguments associated with the request.
 * @return the user metadata extracted from arguments.
 * @throws RestServiceException if usermetadata arguments have null values.
 */
public static byte[] buildUserMetadata(Map<String, Object> args) throws RestServiceException {
    ByteBuffer userMetadata;
    if (args.containsKey(MultipartPost.USER_METADATA_PART)) {
        userMetadata = (ByteBuffer) args.get(MultipartPost.USER_METADATA_PART);
    } else {
        Map<String, String> userMetadataMap = new HashMap<String, String>();
        int sizeToAllocate = 0;
        for (Map.Entry<String, Object> entry : args.entrySet()) {
            String key = entry.getKey();
            if (key.toLowerCase().startsWith(Headers.USER_META_DATA_HEADER_PREFIX)) {
                // key size
                sizeToAllocate += 4;
                String keyToStore = key.substring(Headers.USER_META_DATA_HEADER_PREFIX.length());
                sizeToAllocate += keyToStore.getBytes(CHARSET).length;
                String value = getHeader(args, key, true);
                userMetadataMap.put(keyToStore, value);
                // value size
                sizeToAllocate += 4;
                sizeToAllocate += value.getBytes(CHARSET).length;
            }
        }
        if (sizeToAllocate == 0) {
            userMetadata = ByteBuffer.allocate(0);
        } else {
            // version
            sizeToAllocate += 2;
            // size excluding version and crc
            sizeToAllocate += 4;
            // total number of entries
            sizeToAllocate += 4;
            // crc size
            sizeToAllocate += CRC_SIZE;
            userMetadata = ByteBuffer.allocate(sizeToAllocate);
            userMetadata.putShort(USER_METADATA_VERSION_V1);
            // total size = sizeToAllocate - version size - sizeToAllocate size - crc size
            userMetadata.putInt(sizeToAllocate - 6 - CRC_SIZE);
            userMetadata.putInt(userMetadataMap.size());
            for (Map.Entry<String, String> entry : userMetadataMap.entrySet()) {
                String key = entry.getKey();
                Utils.serializeString(userMetadata, key, CHARSET);
                Utils.serializeString(userMetadata, entry.getValue(), CHARSET);
            }
            Crc32 crc = new Crc32();
            crc.update(userMetadata.array(), 0, sizeToAllocate - CRC_SIZE);
            userMetadata.putLong(crc.getValue());
        }
    }
    return userMetadata.array();
}
Also used : HashMap(java.util.HashMap) Crc32(com.github.ambry.utils.Crc32) ByteBuffer(java.nio.ByteBuffer) HashMap(java.util.HashMap) Map(java.util.Map)

Example 15 with Crc32

use of com.github.ambry.utils.Crc32 in project ambry by linkedin.

the class RestUtils method buildUserMetadata.

/**
 * Gets deserialized metadata from the byte array if possible
 * @param userMetadata the byte array which has the user metadata
 * @return the user metadata that is read from the byte array, or {@code null} if the {@code userMetadata} cannot be
 * parsed in expected format
 */
public static Map<String, String> buildUserMetadata(byte[] userMetadata) {
    if (userMetadata.length == 0) {
        return Collections.emptyMap();
    }
    Map<String, String> toReturn = null;
    try {
        ByteBuffer userMetadataBuffer = ByteBuffer.wrap(userMetadata);
        short version = userMetadataBuffer.getShort();
        switch(version) {
            case USER_METADATA_VERSION_V1:
                int sizeToRead = userMetadataBuffer.getInt();
                if (sizeToRead != (userMetadataBuffer.remaining() - 8)) {
                    logger.trace("Size didn't match. Returning null");
                } else {
                    int entryCount = userMetadataBuffer.getInt();
                    int counter = 0;
                    if (entryCount > 0) {
                        toReturn = new HashMap<>();
                    }
                    while (counter++ < entryCount) {
                        String key = Utils.deserializeString(userMetadataBuffer, CHARSET);
                        String value = Utils.deserializeString(userMetadataBuffer, CHARSET);
                        toReturn.put(Headers.USER_META_DATA_HEADER_PREFIX + key, value);
                    }
                    long actualCRC = userMetadataBuffer.getLong();
                    Crc32 crc32 = new Crc32();
                    crc32.update(userMetadata, 0, userMetadata.length - CRC_SIZE);
                    long expectedCRC = crc32.getValue();
                    if (actualCRC != expectedCRC) {
                        logger.error("corrupt data while parsing user metadata Expected CRC {} Actual CRC {}", expectedCRC, actualCRC);
                        toReturn = null;
                    }
                }
                break;
            default:
                toReturn = null;
                logger.trace("Failed to parse version in new format. Returning null");
        }
    } catch (RuntimeException e) {
        logger.trace("Runtime Exception on parsing user metadata. Returning null");
        toReturn = null;
    }
    return toReturn;
}
Also used : Crc32(com.github.ambry.utils.Crc32) ByteBuffer(java.nio.ByteBuffer)

Aggregations

Crc32 (com.github.ambry.utils.Crc32)22 ByteBuffer (java.nio.ByteBuffer)14 ByteBufferInputStream (com.github.ambry.utils.ByteBufferInputStream)6 CrcInputStream (com.github.ambry.utils.CrcInputStream)6 Random (java.util.Random)6 StoreKey (com.github.ambry.store.StoreKey)5 DataInputStream (java.io.DataInputStream)4 Test (org.junit.Test)4 MockId (com.github.ambry.store.MockId)3 HashMap (java.util.HashMap)3 MockIdFactory (com.github.ambry.store.MockIdFactory)2 StoreKeyFactory (com.github.ambry.store.StoreKeyFactory)2 ArrayList (java.util.ArrayList)2 Map (java.util.Map)2 MetricRegistry (com.codahale.metrics.MetricRegistry)1 BlobProperties (com.github.ambry.messageformat.BlobProperties)1 MessageFormatException (com.github.ambry.messageformat.MessageFormatException)1 MessageFormatRecord (com.github.ambry.messageformat.MessageFormatRecord)1 MessageMetadata (com.github.ambry.messageformat.MessageMetadata)1 ByteBufferSend (com.github.ambry.network.ByteBufferSend)1