Search in sources :

Example 6 with Message

use of com.github.ambry.store.Message in project ambry by linkedin.

the class ValidatingTransformer method transform.

@Override
public TransformationOutput transform(Message message) {
    ByteBuffer encryptionKey;
    BlobProperties props;
    ByteBuffer metadata;
    BlobData blobData;
    MessageInfo msgInfo = message.getMessageInfo();
    InputStream msgStream = message.getStream();
    TransformationOutput transformationOutput = null;
    try {
        // Read header
        ByteBuffer headerVersion = ByteBuffer.allocate(Version_Field_Size_In_Bytes);
        msgStream.read(headerVersion.array());
        short version = headerVersion.getShort();
        if (!isValidHeaderVersion(version)) {
            throw new MessageFormatException("Header version not supported " + version, MessageFormatErrorCodes.Data_Corrupt);
        }
        int headerSize = getHeaderSizeForVersion(version);
        ByteBuffer headerBuffer = ByteBuffer.allocate(headerSize);
        headerBuffer.put(headerVersion.array());
        msgStream.read(headerBuffer.array(), Version_Field_Size_In_Bytes, headerSize - Version_Field_Size_In_Bytes);
        headerBuffer.rewind();
        MessageHeader_Format header = getMessageHeader(version, headerBuffer);
        header.verifyHeader();
        StoreKey keyInStream = storeKeyFactory.getStoreKey(new DataInputStream(msgStream));
        if (header.isPutRecord()) {
            if (header.hasLifeVersion() && header.getLifeVersion() != msgInfo.getLifeVersion()) {
                logger.trace("LifeVersion in stream: {} failed to match lifeVersion from Index: {} for key {}", header.getLifeVersion(), msgInfo.getLifeVersion(), keyInStream);
            }
            encryptionKey = header.hasEncryptionKeyRecord() ? deserializeBlobEncryptionKey(msgStream) : null;
            props = deserializeBlobProperties(msgStream);
            metadata = deserializeUserMetadata(msgStream);
            blobData = deserializeBlob(msgStream);
        } else {
            throw new IllegalStateException("Message cannot be anything rather than put record ");
        }
        if (msgInfo.getStoreKey().equals(keyInStream)) {
            // BlobIDTransformer only exists on ambry-server and replication between servers is relying on blocking channel
            // which is still using java ByteBuffer. So, no need to consider releasing stuff.
            // @todo, when netty Bytebuf is adopted for blocking channel on ambry-server, remember to release this ByteBuf.
            PutMessageFormatInputStream transformedStream = new PutMessageFormatInputStream(keyInStream, encryptionKey, props, metadata, new ByteBufInputStream(blobData.content(), true), blobData.getSize(), blobData.getBlobType(), msgInfo.getLifeVersion());
            MessageInfo transformedMsgInfo = new MessageInfo.Builder(msgInfo).size(transformedStream.getSize()).isDeleted(false).isUndeleted(false).build();
            transformationOutput = new TransformationOutput(new Message(transformedMsgInfo, transformedStream));
        } else {
            throw new IllegalStateException("StoreKey in stream: " + keyInStream + " failed to match store key from Index: " + msgInfo.getStoreKey());
        }
    } catch (Exception e) {
        transformationOutput = new TransformationOutput(e);
    }
    return transformationOutput;
}
Also used : Message(com.github.ambry.store.Message) DataInputStream(java.io.DataInputStream) ByteBufInputStream(io.netty.buffer.ByteBufInputStream) InputStream(java.io.InputStream) ByteBufInputStream(io.netty.buffer.ByteBufInputStream) DataInputStream(java.io.DataInputStream) ByteBuffer(java.nio.ByteBuffer) StoreKey(com.github.ambry.store.StoreKey) MessageInfo(com.github.ambry.store.MessageInfo) TransformationOutput(com.github.ambry.store.TransformationOutput)

Example 7 with Message

use of com.github.ambry.store.Message in project ambry by linkedin.

the class ReplicationTestHelper method replicateAndVerify.

/**
 * Replicate between local and remote hosts and verify the results on local host are expected.
 * 1.remote host has different versions of blobIds and local host is empty;
 * 2.remote and local hosts have different conversion maps (StoreKeyConverter).
 * @param testSetup the {@link ReplicationTestSetup} used to provide test environment info.
 * @param expectedStr the string presenting expected sequence of PUT, DELETE messages on local host.
 * @throws Exception
 */
protected void replicateAndVerify(ReplicationTestSetup testSetup, String expectedStr) throws Exception {
    PartitionId partitionId = testSetup.partitionIds.get(0);
    List<RemoteReplicaInfo> singleReplicaList = testSetup.replicasToReplicate.get(testSetup.remoteHost.dataNodeId).stream().filter(e -> e.getReplicaId().getPartitionId() == partitionId).collect(Collectors.toList());
    // Do the replica metadata exchange.
    List<ReplicaThread.ExchangeMetadataResponse> responses = testSetup.replicaThread.exchangeMetadata(new MockConnectionPool.MockConnection(testSetup.remoteHost, 10, testSetup.remoteConversionMap), singleReplicaList);
    // Do Get request to fix missing keys
    testSetup.replicaThread.fixMissingStoreKeys(new MockConnectionPool.MockConnection(testSetup.remoteHost, 10, testSetup.remoteConversionMap), singleReplicaList, responses, false);
    // Verify
    String[] expectedResults = expectedStr.equals("") ? new String[0] : expectedStr.split("\\s");
    int size = testSetup.localHost.infosByPartition.get(partitionId).size();
    assertEquals("Mismatch in number of messages on local host after replication", expectedResults.length, size);
    for (int i = 0; i < size; ++i) {
        String blobIdStr = testSetup.localHost.infosByPartition.get(partitionId).get(i).getStoreKey().toString();
        boolean isDeleteMessage = testSetup.localHost.infosByPartition.get(partitionId).get(i).isDeleted();
        switch(expectedResults[i]) {
            case "OP":
                assertEquals("Mismatch in blodId on local host after replication", testSetup.oldKey.toString(), blobIdStr);
                assertFalse("Mismatch in message type on local host after replication", isDeleteMessage);
                break;
            case "OD":
                assertEquals("Mismatch in blodId on local host after replication", testSetup.oldKey.toString(), blobIdStr);
                assertTrue("Mismatch in message type on local host after replication", isDeleteMessage);
                break;
            case "NP":
                assertEquals("Mismatch in blodId on local host after replication", testSetup.newKey.toString(), blobIdStr);
                assertFalse("Mismatch in message type on local host after replication", isDeleteMessage);
                break;
            case "ND":
                assertEquals("Mismatch in blodId on local host after replication", testSetup.newKey.toString(), blobIdStr);
                assertTrue("Mismatch in message type on local host after replication", isDeleteMessage);
                break;
        }
    }
}
Also used : Arrays(java.util.Arrays) StorageManager(com.github.ambry.store.StorageManager) BlobProperties(com.github.ambry.messageformat.BlobProperties) StoreKeyConverter(com.github.ambry.store.StoreKeyConverter) DataNodeId(com.github.ambry.clustermap.DataNodeId) Random(java.util.Random) ByteBuffer(java.nio.ByteBuffer) MockReplicaId(com.github.ambry.clustermap.MockReplicaId) JSONObject(org.json.JSONObject) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) TestUtils(com.github.ambry.utils.TestUtils) Map(java.util.Map) DeleteMessageFormatInputStream(com.github.ambry.messageformat.DeleteMessageFormatInputStream) ReplicaMetadataRequest(com.github.ambry.protocol.ReplicaMetadataRequest) Parameterized(org.junit.runners.Parameterized) ReplicationConfig(com.github.ambry.config.ReplicationConfig) ReplicaSyncUpManager(com.github.ambry.clustermap.ReplicaSyncUpManager) DiskManagerConfig(com.github.ambry.config.DiskManagerConfig) StoreKeyFactory(com.github.ambry.store.StoreKeyFactory) Set(java.util.Set) Utils(com.github.ambry.utils.Utils) MockPartitionId(com.github.ambry.clustermap.MockPartitionId) Collectors(java.util.stream.Collectors) MessageFormatInputStream(com.github.ambry.messageformat.MessageFormatInputStream) StoreKey(com.github.ambry.store.StoreKey) List(java.util.List) ReplicaMetadataResponse(com.github.ambry.protocol.ReplicaMetadataResponse) MockTime(com.github.ambry.utils.MockTime) Optional(java.util.Optional) BlobType(com.github.ambry.messageformat.BlobType) InMemAccountService(com.github.ambry.account.InMemAccountService) PartitionId(com.github.ambry.clustermap.PartitionId) BlobId(com.github.ambry.commons.BlobId) ResponseHandler(com.github.ambry.commons.ResponseHandler) AccountService(com.github.ambry.account.AccountService) Message(com.github.ambry.store.Message) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) TransformationOutput(com.github.ambry.store.TransformationOutput) TestUtils(com.github.ambry.clustermap.TestUtils) Transformer(com.github.ambry.store.Transformer) MockHelixParticipant(com.github.ambry.clustermap.MockHelixParticipant) CommonTestUtils(com.github.ambry.commons.CommonTestUtils) SystemTime(com.github.ambry.utils.SystemTime) MockStoreKeyConverterFactory(com.github.ambry.store.MockStoreKeyConverterFactory) ReplicaState(com.github.ambry.clustermap.ReplicaState) StoreConfig(com.github.ambry.config.StoreConfig) MetricRegistry(com.codahale.metrics.MetricRegistry) Properties(java.util.Properties) Pair(com.github.ambry.utils.Pair) Iterator(java.util.Iterator) PutMessageFormatInputStream(com.github.ambry.messageformat.PutMessageFormatInputStream) VerifiableProperties(com.github.ambry.config.VerifiableProperties) ConnectionPool(com.github.ambry.network.ConnectionPool) UndeleteMessageFormatInputStream(com.github.ambry.messageformat.UndeleteMessageFormatInputStream) ClusterMap(com.github.ambry.clustermap.ClusterMap) IOException(java.io.IOException) BlobIdFactory(com.github.ambry.commons.BlobIdFactory) MessageFormatException(com.github.ambry.messageformat.MessageFormatException) TimeUnit(java.util.concurrent.TimeUnit) Mockito(org.mockito.Mockito) MessageInfo(com.github.ambry.store.MessageInfo) ReplicaId(com.github.ambry.clustermap.ReplicaId) ByteBufferInputStream(com.github.ambry.utils.ByteBufferInputStream) ClusterMapConfig(com.github.ambry.config.ClusterMapConfig) Assert(org.junit.Assert) Collections(java.util.Collections) MockClusterMap(com.github.ambry.clustermap.MockClusterMap) TtlUpdateMessageFormatInputStream(com.github.ambry.messageformat.TtlUpdateMessageFormatInputStream) MockPartitionId(com.github.ambry.clustermap.MockPartitionId) PartitionId(com.github.ambry.clustermap.PartitionId)

Example 8 with Message

use of com.github.ambry.store.Message in project ambry by linkedin.

the class ReplicationTestHelper method addPutMessagesToReplicasOfPartition.

public static void addPutMessagesToReplicasOfPartition(List<StoreKey> ids, List<Transformer> transformPerId, List<MockHost> hosts) throws MessageFormatException, IOException {
    Iterator<Transformer> transformerIterator = transformPerId.iterator();
    for (StoreKey storeKey : ids) {
        Transformer transformer = transformerIterator.next();
        BlobId id = (BlobId) storeKey;
        PutMsgInfoAndBuffer msgInfoAndBuffer = createPutMessage(id, id.getAccountId(), id.getContainerId(), BlobId.isEncrypted(id.toString()));
        MessageInfo msgInfo = msgInfoAndBuffer.messageInfo;
        ByteBuffer byteBuffer = msgInfoAndBuffer.byteBuffer;
        if (transformer != null) {
            Message message = new Message(msgInfo, new ByteBufferInputStream(byteBuffer));
            TransformationOutput output = transformer.transform(message);
            assertNull(output.getException());
            message = output.getMsg();
            byteBuffer = ByteBuffer.wrap(Utils.readBytesFromStream(message.getStream(), (int) message.getMessageInfo().getSize()));
            msgInfo = message.getMessageInfo();
        }
        for (MockHost host : hosts) {
            host.addMessage(id.getPartition(), msgInfo, byteBuffer.duplicate());
        }
    }
}
Also used : Transformer(com.github.ambry.store.Transformer) Message(com.github.ambry.store.Message) TransformationOutput(com.github.ambry.store.TransformationOutput) ByteBufferInputStream(com.github.ambry.utils.ByteBufferInputStream) StoreKey(com.github.ambry.store.StoreKey) BlobId(com.github.ambry.commons.BlobId) ByteBuffer(java.nio.ByteBuffer) MessageInfo(com.github.ambry.store.MessageInfo)

Aggregations

Message (com.github.ambry.store.Message)8 MessageInfo (com.github.ambry.store.MessageInfo)7 StoreKey (com.github.ambry.store.StoreKey)6 TransformationOutput (com.github.ambry.store.TransformationOutput)6 ByteBuffer (java.nio.ByteBuffer)5 IOException (java.io.IOException)4 BlobId (com.github.ambry.commons.BlobId)3 Transformer (com.github.ambry.store.Transformer)3 ByteBufferInputStream (com.github.ambry.utils.ByteBufferInputStream)3 ByteBufInputStream (io.netty.buffer.ByteBufInputStream)3 DataInputStream (java.io.DataInputStream)3 BlobProperties (com.github.ambry.messageformat.BlobProperties)2 MessageFormatException (com.github.ambry.messageformat.MessageFormatException)2 PutMessageFormatInputStream (com.github.ambry.messageformat.PutMessageFormatInputStream)2 InputStream (java.io.InputStream)2 MetricRegistry (com.codahale.metrics.MetricRegistry)1 AccountService (com.github.ambry.account.AccountService)1 InMemAccountService (com.github.ambry.account.InMemAccountService)1 ClusterMap (com.github.ambry.clustermap.ClusterMap)1 DataNodeId (com.github.ambry.clustermap.DataNodeId)1