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)));
}
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
}
}
}
}
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;
}
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;
}
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);
}
}
Aggregations