Search in sources :

Example 1 with FindTokenType

use of com.github.ambry.replication.FindTokenType in project ambry by linkedin.

the class StoreFindTokenTest method getSerializedStream.

/**
 * Gets a serialized format of {@code token} in the version {@code version}.
 * @param token the {@link StoreFindToken} to serialize.
 * @param version the version to serialize it in.
 * @return a serialized format of {@code token} in the version {@code version}.
 */
static DataInputStream getSerializedStream(StoreFindToken token, short version) {
    byte[] bytes;
    FindTokenType type = token.getType();
    byte[] sessionIdBytes = token.getSessionIdInBytes();
    byte[] storeKeyInBytes = token.getStoreKeyInBytes();
    switch(version) {
        case StoreFindToken.VERSION_0:
            // version size + sessionId length size + session id size + log offset size + index segment start offset size
            // + store key size
            int size = 2 + 4 + sessionIdBytes.length + 8 + 8 + storeKeyInBytes.length;
            bytes = new byte[size];
            ByteBuffer bufWrap = ByteBuffer.wrap(bytes);
            // add version
            bufWrap.putShort(StoreFindToken.VERSION_0);
            // add sessionId
            bufWrap.putInt(sessionIdBytes.length);
            bufWrap.put(sessionIdBytes);
            long logOffset = -1;
            long indexStartOffset = -1;
            if (type.equals(FindTokenType.JournalBased)) {
                logOffset = token.getOffset().getOffset();
            } else if (type.equals(FindTokenType.IndexBased)) {
                indexStartOffset = token.getOffset().getOffset();
            }
            // add offset
            bufWrap.putLong(logOffset);
            // add index start offset
            bufWrap.putLong(indexStartOffset);
            // add storeKey
            if (storeKeyInBytes.length > 0) {
                bufWrap.put(storeKeyInBytes);
            }
            break;
        case StoreFindToken.VERSION_1:
            byte[] offsetBytes = token.getOffsetInBytes();
            // version size + sessionId length size + session id size + type + log offset / index segment start offset size
            // + store key size
            size = 2 + 4 + sessionIdBytes.length + 2 + offsetBytes.length + storeKeyInBytes.length;
            bytes = new byte[size];
            bufWrap = ByteBuffer.wrap(bytes);
            // add version
            bufWrap.putShort(StoreFindToken.VERSION_1);
            // add sessionId
            bufWrap.putInt(sessionIdBytes.length);
            bufWrap.put(sessionIdBytes);
            // add type
            bufWrap.putShort((byte) type.ordinal());
            bufWrap.put(offsetBytes);
            if (storeKeyInBytes.length > 0) {
                bufWrap.put(storeKeyInBytes);
            }
            break;
        case VERSION_2:
            offsetBytes = token.getOffsetInBytes();
            byte[] incarnationIdBytes = token.getIncarnationIdInBytes();
            size = VERSION_SIZE + TYPE_SIZE;
            if (type != FindTokenType.Uninitialized) {
                size += INCARNATION_ID_LENGTH_SIZE + incarnationIdBytes.length + SESSION_ID_LENGTH_SIZE + sessionIdBytes.length + offsetBytes.length;
                if (type == FindTokenType.JournalBased) {
                    size += INCLUSIVE_BYTE_SIZE;
                } else if (type == FindTokenType.IndexBased) {
                    size += storeKeyInBytes.length;
                }
            }
            bytes = new byte[size];
            bufWrap = ByteBuffer.wrap(bytes);
            // add version
            bufWrap.putShort(VERSION_2);
            // add type
            bufWrap.putShort((short) type.ordinal());
            if (type != FindTokenType.Uninitialized) {
                // add incarnationId
                bufWrap.putInt(incarnationIdBytes.length);
                bufWrap.put(incarnationIdBytes);
                // add sessionId
                bufWrap.putInt(sessionIdBytes.length);
                bufWrap.put(sessionIdBytes);
                // add offset
                bufWrap.put(offsetBytes);
                if (type == FindTokenType.JournalBased) {
                    bufWrap.put(token.getInclusive() ? (byte) 1 : (byte) 0);
                } else if (type == FindTokenType.IndexBased) {
                    bufWrap.put(storeKeyInBytes);
                }
            }
            break;
        case StoreFindToken.CURRENT_VERSION:
            bytes = token.toBytes();
            break;
        default:
            throw new IllegalArgumentException("Version " + version + " of StoreFindToken does not exist");
    }
    return new DataInputStream(new ByteBufferInputStream(ByteBuffer.wrap(bytes)));
}
Also used : ByteBufferInputStream(com.github.ambry.utils.ByteBufferInputStream) FindTokenType(com.github.ambry.replication.FindTokenType) DataInputStream(java.io.DataInputStream) ByteBuffer(java.nio.ByteBuffer)

Example 2 with FindTokenType

use of com.github.ambry.replication.FindTokenType in project ambry by linkedin.

the class StoreFindTokenTest method constructionErrorCasesTest.

/**
 * Tests {@link StoreFindToken} for construction error cases.
 */
@Test
public void constructionErrorCasesTest() {
    UUID sessionId = UUID.randomUUID();
    UUID incarnationId = UUID.randomUUID();
    LogSegmentName logSegmentName = LogSegmentName.generateFirstSegmentName(isLogSegmented);
    Offset offset = new Offset(logSegmentName, 0);
    MockId key = new MockId(TestUtils.getRandomString(10));
    MockId resetKey = new MockId(TestUtils.getRandomString(10));
    PersistentIndex.IndexEntryType resetKeyType = PersistentIndex.IndexEntryType.values()[(new Random()).nextInt(PersistentIndex.IndexEntryType.values().length)];
    short resetKeyVersion = (short) random.nextInt(5);
    // no offset
    testConstructionFailure(key, sessionId, incarnationId, null);
    // no session id
    testConstructionFailure(key, null, incarnationId, offset);
    // no incarnation Id
    testConstructionFailure(key, sessionId, null, offset);
    // no key in IndexBased
    try {
        new StoreFindToken(null, offset, sessionId, null, null, null, UNINITIALIZED_RESET_KEY_VERSION);
        fail("Construction of StoreFindToken should have failed");
    } catch (IllegalArgumentException e) {
    // expected. Nothing to do.
    }
    // version 3 token without reset key or reset key type
    for (FindTokenType type : EnumSet.of(FindTokenType.JournalBased, FindTokenType.IndexBased)) {
        for (Pair<MockId, PersistentIndex.IndexEntryType> pair : Arrays.asList(new Pair<MockId, PersistentIndex.IndexEntryType>(resetKey, null), new Pair<MockId, PersistentIndex.IndexEntryType>(null, resetKeyType))) {
            try {
                new StoreFindToken(type, offset, key, sessionId, incarnationId, type == FindTokenType.JournalBased, VERSION_3, pair.getFirst(), pair.getSecond(), resetKeyVersion);
                fail("Construction of StoreFindToken should have failed because rest key or its type is null.");
            } catch (IllegalArgumentException e) {
            // expected
            }
        }
    }
}
Also used : StoreFindToken(com.github.ambry.store.StoreFindToken) Random(java.util.Random) UUID(java.util.UUID) FindTokenType(com.github.ambry.replication.FindTokenType) Test(org.junit.Test)

Example 3 with FindTokenType

use of com.github.ambry.replication.FindTokenType in project ambry by linkedin.

the class CosmosUpdateTimeFindToken method fromBytes.

/**
 * Utility to construct a previously serialized {@code CloudFindToken} from input stream.
 * @param inputStream {@code DataInputStream} from which to read the token.
 * @return deserialized {@code CloudFindToken} object.
 * @throws IOException
 */
static CosmosUpdateTimeFindToken fromBytes(DataInputStream inputStream) throws IOException {
    CosmosUpdateTimeFindToken cloudFindToken;
    DataInputStream stream = new DataInputStream(inputStream);
    short version = stream.readShort();
    switch(version) {
        case VERSION_0:
            FindTokenType type = FindTokenType.values()[stream.readShort()];
            long lastUpdateTime = stream.readLong();
            long bytesRead = stream.readLong();
            int numBlobs = stream.readShort();
            Set<String> blobIds = new HashSet<>();
            while (numBlobs > 0) {
                int blobIdLength = stream.readShort();
                byte[] blobIdBytes = new byte[blobIdLength];
                stream.read(blobIdBytes, 0, blobIdLength);
                blobIds.add(new String(blobIdBytes));
                numBlobs--;
            }
            cloudFindToken = new CosmosUpdateTimeFindToken(version, lastUpdateTime, bytesRead, blobIds);
            break;
        default:
            throw new IllegalStateException("Unknown version: " + version);
    }
    return cloudFindToken;
}
Also used : DataInputStream(java.io.DataInputStream) FindTokenType(com.github.ambry.replication.FindTokenType) HashSet(java.util.HashSet)

Example 4 with FindTokenType

use of com.github.ambry.replication.FindTokenType in project ambry by linkedin.

the class StoreFindToken method fromBytes.

static StoreFindToken fromBytes(DataInputStream stream, StoreKeyFactory factory) throws IOException {
    StoreFindToken storeFindToken;
    // read version
    short version = stream.readShort();
    switch(version) {
        case VERSION_0:
            // backwards compatibility
            LogSegmentName logSegmentName = LogSegmentName.generateFirstSegmentName(false);
            // read sessionId
            String sessionId = Utils.readIntString(stream);
            UUID sessionIdUUID = null;
            if (!sessionId.isEmpty()) {
                sessionIdUUID = UUID.fromString(sessionId);
            }
            // read offset
            long offset = stream.readLong();
            // read index start offset
            long indexStartOffset = stream.readLong();
            if (indexStartOffset != UNINITIALIZED_OFFSET) {
                // read store key if needed
                storeFindToken = new StoreFindToken(FindTokenType.IndexBased, new Offset(logSegmentName, indexStartOffset), factory.getStoreKey(stream), sessionIdUUID, null, false, VERSION_0, null, null, UNINITIALIZED_RESET_KEY_VERSION);
            } else if (offset != UNINITIALIZED_OFFSET) {
                storeFindToken = new StoreFindToken(FindTokenType.JournalBased, new Offset(logSegmentName, offset), null, sessionIdUUID, null, false, VERSION_0, null, null, UNINITIALIZED_RESET_KEY_VERSION);
            } else {
                storeFindToken = new StoreFindToken(FindTokenType.Uninitialized, null, null, null, null, true, VERSION_0, null, null, UNINITIALIZED_RESET_KEY_VERSION);
            }
            break;
        case VERSION_1:
            // read sessionId
            sessionId = Utils.readIntString(stream);
            sessionIdUUID = null;
            if (!sessionId.isEmpty()) {
                sessionIdUUID = UUID.fromString(sessionId);
            }
            // read type
            FindTokenType type = FindTokenType.values()[stream.readShort()];
            switch(type) {
                case Uninitialized:
                    storeFindToken = new StoreFindToken(FindTokenType.Uninitialized, null, null, null, null, true, VERSION_1, null, null, UNINITIALIZED_RESET_KEY_VERSION);
                    break;
                case JournalBased:
                    Offset logOffset = Offset.fromBytes(stream);
                    storeFindToken = new StoreFindToken(FindTokenType.JournalBased, logOffset, null, sessionIdUUID, null, false, VERSION_1, null, null, UNINITIALIZED_RESET_KEY_VERSION);
                    break;
                case IndexBased:
                    Offset indexSegmentStartOffset = Offset.fromBytes(stream);
                    storeFindToken = new StoreFindToken(FindTokenType.IndexBased, indexSegmentStartOffset, factory.getStoreKey(stream), sessionIdUUID, null, false, VERSION_1, null, null, UNINITIALIZED_RESET_KEY_VERSION);
                    break;
                default:
                    throw new IllegalStateException("Unknown store find token type: " + type);
            }
            break;
        case VERSION_2:
            // read type
            type = FindTokenType.values()[stream.readShort()];
            switch(type) {
                case Uninitialized:
                    storeFindToken = new StoreFindToken(FindTokenType.Uninitialized, null, null, null, null, true, VERSION_2, null, null, UNINITIALIZED_RESET_KEY_VERSION);
                    break;
                case JournalBased:
                    // read incarnationId
                    String incarnationId = Utils.readIntString(stream);
                    UUID incarnationIdUUID = UUID.fromString(incarnationId);
                    // read sessionId
                    sessionId = Utils.readIntString(stream);
                    sessionIdUUID = UUID.fromString(sessionId);
                    Offset logOffset = Offset.fromBytes(stream);
                    byte inclusive = stream.readByte();
                    storeFindToken = new StoreFindToken(FindTokenType.JournalBased, logOffset, null, sessionIdUUID, incarnationIdUUID, inclusive == (byte) 1, VERSION_2, null, null, UNINITIALIZED_RESET_KEY_VERSION);
                    break;
                case IndexBased:
                    // read incarnationId
                    incarnationId = Utils.readIntString(stream);
                    incarnationIdUUID = UUID.fromString(incarnationId);
                    // read sessionId
                    sessionId = Utils.readIntString(stream);
                    sessionIdUUID = UUID.fromString(sessionId);
                    Offset indexSegmentStartOffset = Offset.fromBytes(stream);
                    StoreKey storeKey = factory.getStoreKey(stream);
                    storeFindToken = new StoreFindToken(FindTokenType.IndexBased, indexSegmentStartOffset, storeKey, sessionIdUUID, incarnationIdUUID, false, VERSION_2, null, null, UNINITIALIZED_RESET_KEY_VERSION);
                    break;
                default:
                    throw new IllegalStateException("Unknown store find token type: " + type);
            }
            break;
        case VERSION_3:
            // read type
            type = FindTokenType.values()[stream.readShort()];
            switch(type) {
                case Uninitialized:
                    storeFindToken = new StoreFindToken();
                    break;
                case JournalBased:
                    // read incarnationId
                    String incarnationId = Utils.readIntString(stream);
                    UUID incarnationIdUUID = UUID.fromString(incarnationId);
                    // read sessionId
                    sessionId = Utils.readIntString(stream);
                    sessionIdUUID = UUID.fromString(sessionId);
                    Offset logOffset = Offset.fromBytes(stream);
                    byte inclusive = stream.readByte();
                    byte hasRestKeyInfo = stream.readByte();
                    // read reset key (if present)
                    StoreKey journalTokenResetKey = hasRestKeyInfo == (byte) 1 ? factory.getStoreKey(stream) : null;
                    // read reset key type (if present)
                    PersistentIndex.IndexEntryType journalResetKeyType = hasRestKeyInfo == (byte) 1 ? PersistentIndex.IndexEntryType.values()[stream.readShort()] : null;
                    // read reset key life version (if present)
                    short journalResetKeyVersion = hasRestKeyInfo == (byte) 1 ? stream.readShort() : UNINITIALIZED_RESET_KEY_VERSION;
                    storeFindToken = new StoreFindToken(logOffset, sessionIdUUID, incarnationIdUUID, inclusive == (byte) 1, journalTokenResetKey, journalResetKeyType, journalResetKeyVersion);
                    break;
                case IndexBased:
                    // read incarnationId
                    incarnationId = Utils.readIntString(stream);
                    incarnationIdUUID = UUID.fromString(incarnationId);
                    // read sessionId
                    sessionId = Utils.readIntString(stream);
                    sessionIdUUID = UUID.fromString(sessionId);
                    Offset indexSegmentStartOffset = Offset.fromBytes(stream);
                    StoreKey storeKey = factory.getStoreKey(stream);
                    hasRestKeyInfo = stream.readByte();
                    // read reset key (if present)
                    StoreKey indexTokenResetKey = hasRestKeyInfo == (short) 1 ? factory.getStoreKey(stream) : null;
                    // read reset key type (if present)
                    PersistentIndex.IndexEntryType indexResetKeyType = hasRestKeyInfo == (short) 1 ? PersistentIndex.IndexEntryType.values()[stream.readShort()] : null;
                    // read reset key life version (if present)
                    short indexResetKeyVersion = hasRestKeyInfo == (short) 1 ? stream.readShort() : UNINITIALIZED_RESET_KEY_VERSION;
                    storeFindToken = new StoreFindToken(storeKey, indexSegmentStartOffset, sessionIdUUID, incarnationIdUUID, indexTokenResetKey, indexResetKeyType, indexResetKeyVersion);
                    break;
                default:
                    throw new IllegalStateException("Unknown store find token type: " + type);
            }
            break;
        default:
            throw new IllegalArgumentException("Unrecognized version in StoreFindToken: " + version);
    }
    return storeFindToken;
}
Also used : UUID(java.util.UUID) FindTokenType(com.github.ambry.replication.FindTokenType)

Example 5 with FindTokenType

use of com.github.ambry.replication.FindTokenType in project ambry by linkedin.

the class CosmosChangeFeedFindToken method fromBytes.

/**
 * Deserialize {@link CosmosChangeFeedFindToken} object from input stream.
 * @param inputStream {@link DataOutputStream} to deserialize from.
 * @return {@link CosmosChangeFeedFindToken} object.
 * @throws IOException
 */
public static CosmosChangeFeedFindToken fromBytes(DataInputStream inputStream) throws IOException {
    DataInputStream stream = new DataInputStream(inputStream);
    short version = stream.readShort();
    switch(version) {
        case VERSION_0:
            FindTokenType type = FindTokenType.values()[stream.readShort()];
            if (type != FindTokenType.CloudBased) {
                throw new IllegalArgumentException(String.format("Invalid token type %s found while deserialization. Expected %s.", type, FindTokenType.CloudBased));
            }
            long bytesRead = stream.readLong();
            String startContinuationToken = readIntString(inputStream);
            String endContinuationToken = readIntString(inputStream);
            int index = inputStream.readInt();
            int totalItems = inputStream.readInt();
            String cacheSessionId = readIntString(inputStream);
            return new CosmosChangeFeedFindToken(bytesRead, startContinuationToken, endContinuationToken, index, totalItems, cacheSessionId, version);
        default:
            throw new IllegalStateException("Unknown version of cloud token: " + version);
    }
}
Also used : DataInputStream(java.io.DataInputStream) FindTokenType(com.github.ambry.replication.FindTokenType)

Aggregations

FindTokenType (com.github.ambry.replication.FindTokenType)5 DataInputStream (java.io.DataInputStream)3 UUID (java.util.UUID)2 StoreFindToken (com.github.ambry.store.StoreFindToken)1 ByteBufferInputStream (com.github.ambry.utils.ByteBufferInputStream)1 ByteBuffer (java.nio.ByteBuffer)1 HashSet (java.util.HashSet)1 Random (java.util.Random)1 Test (org.junit.Test)1