Search in sources :

Example 1 with FindToken

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

the class HardDeleteVerifier method getOffsetFromCleanupToken.

private long getOffsetFromCleanupToken(File cleanupTokenFile) throws Exception {
    long parsedTokenValue = -1;
    if (cleanupTokenFile.exists()) {
        CrcInputStream crcStream = new CrcInputStream(new FileInputStream(cleanupTokenFile));
        DataInputStream stream = new DataInputStream(crcStream);
        try {
            // The format of the cleanup token is documented in PersistentIndex.persistCleanupToken()
            short version = stream.readShort();
            if (version != HARD_DELETE_TOKEN_V0) {
                throw new IllegalStateException("Unknown version encountered while parsing cleanup token");
            }
            StoreKeyFactory storeKeyFactory = Utils.getObj("com.github.ambry.commons.BlobIdFactory", map);
            FindTokenFactory factory = Utils.getObj("com.github.ambry.store.StoreFindTokenFactory", storeKeyFactory);
            FindToken startToken = factory.getFindToken(stream);
            // read past the end token.
            factory.getFindToken(stream);
            ByteBuffer bytebufferToken = ByteBuffer.wrap(startToken.toBytes());
            short tokenVersion = bytebufferToken.getShort();
            if (tokenVersion != 0) {
                throw new IllegalArgumentException("token version: " + tokenVersion + " is unknown");
            }
            int sessionIdsize = bytebufferToken.getInt();
            bytebufferToken.position(bytebufferToken.position() + sessionIdsize);
            parsedTokenValue = bytebufferToken.getLong();
            if (parsedTokenValue == -1) {
                /* Index based token, get index start offset */
                parsedTokenValue = bytebufferToken.getLong();
            }
            /* Just read the remaining fields and verify that the crc matches. We don't really need the fields for this
           test */
            int num = stream.readInt();
            List<StoreKey> storeKeyList = new ArrayList<StoreKey>(num);
            for (int i = 0; i < num; i++) {
                // Read BlobReadOptions
                short blobReadOptionsVersion = stream.readShort();
                if (blobReadOptionsVersion != 0) {
                    throw new IllegalStateException("Unknown blobReadOptionsVersion: " + blobReadOptionsVersion);
                }
                long offset = stream.readLong();
                long sz = stream.readLong();
                long ttl = stream.readLong();
                StoreKey key = storeKeyFactory.getStoreKey(stream);
                storeKeyList.add(key);
            }
            for (int i = 0; i < num; i++) {
                int length = stream.readInt();
                short headerVersion = stream.readShort();
                short userMetadataVersion = stream.readShort();
                int userMetadataSize = stream.readInt();
                short blobRecordVersion = stream.readShort();
                long blobStreamSize = stream.readLong();
                StoreKey key = storeKeyFactory.getStoreKey(stream);
                if (!storeKeyList.get(i).equals(key)) {
                    throw new IllegalStateException("Parsed key mismatch");
                }
            }
            long crc = crcStream.getValue();
            if (crc != stream.readLong()) {
                throw new IllegalStateException("Crc mismatch while reading cleanup token");
            }
        } finally {
            stream.close();
        }
    } else {
        throw new IllegalStateException("No cleanup token");
    }
    return parsedTokenValue;
}
Also used : ArrayList(java.util.ArrayList) DataInputStream(java.io.DataInputStream) FindTokenFactory(com.github.ambry.replication.FindTokenFactory) ByteBuffer(java.nio.ByteBuffer) FileInputStream(java.io.FileInputStream) CrcInputStream(com.github.ambry.utils.CrcInputStream) FindToken(com.github.ambry.replication.FindToken)

Example 2 with FindToken

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

the class StoreCopier method copy.

/**
 * Copies data starting from {@code startToken} until all the data is copied.
 * @param startToken the {@link FindToken} to start copying from. It is expected that start token does not cause
 *                   the copier to attempt to copy blobs that have already been copied. If that happens, the boolean
 *                   in the return value will be {@code true}.
 * @return a {@link Pair} of the {@link FindToken} until which data has been copied and a {@link Boolean} indicating
 * whether the source had problems that were skipped over - like duplicates ({@code true} indicates that there were).
 * @throws Exception if there is any exception during processing
 */
public Pair<FindToken, Boolean> copy(FindToken startToken) throws Exception {
    boolean sourceHasProblems = false;
    FindToken lastToken;
    FindToken token = startToken;
    do {
        lastToken = token;
        FindInfo findInfo = src.findEntriesSince(lastToken, fetchSizeInBytes, null, null);
        List<MessageInfo> messageInfos = findInfo.getMessageEntries();
        for (Transformer transformer : transformers) {
            transformer.warmup(messageInfos);
        }
        for (MessageInfo messageInfo : messageInfos) {
            logger.trace("Processing {} - isDeleted: {}, isExpired {}", messageInfo.getStoreKey(), messageInfo.isDeleted(), messageInfo.isExpired());
            if (!messageInfo.isExpired() && !messageInfo.isDeleted()) {
                if (tgt.findMissingKeys(Collections.singletonList(messageInfo.getStoreKey())).size() == 1) {
                    StoreInfo storeInfo = src.get(Collections.singletonList(messageInfo.getStoreKey()), EnumSet.allOf(StoreGetOptions.class));
                    MessageReadSet readSet = storeInfo.getMessageReadSet();
                    if (readSet.sizeInBytes(0) > Integer.MAX_VALUE) {
                        throw new IllegalStateException("Cannot copy blobs whose size > Integer.MAX_VALUE");
                    }
                    int size = (int) readSet.sizeInBytes(0);
                    byte[] buf = new byte[size];
                    readSet.writeTo(0, new ByteBufferChannel(ByteBuffer.wrap(buf)), 0, size);
                    Message message = new Message(storeInfo.getMessageReadSetInfo().get(0), new ByteArrayInputStream(buf));
                    for (Transformer transformer : transformers) {
                        TransformationOutput tfmOutput = transformer.transform(message);
                        if (tfmOutput.getException() != null) {
                            throw tfmOutput.getException();
                        } else {
                            message = tfmOutput.getMsg();
                        }
                        if (message == null) {
                            break;
                        }
                    }
                    if (message == null) {
                        logger.trace("Dropping {} because the transformers did not return a message", messageInfo.getStoreKey());
                        continue;
                    }
                    MessageFormatWriteSet writeSet = new MessageFormatWriteSet(message.getStream(), Collections.singletonList(message.getMessageInfo()), false);
                    tgt.put(writeSet);
                    MessageInfo tgtMsgInfo = message.getMessageInfo();
                    if (tgtMsgInfo.isTtlUpdated()) {
                        MessageInfo updateMsgInfo = new MessageInfo(tgtMsgInfo.getStoreKey(), 0, false, true, tgtMsgInfo.getExpirationTimeInMs(), tgtMsgInfo.getAccountId(), tgtMsgInfo.getContainerId(), tgtMsgInfo.getOperationTimeMs());
                        tgt.updateTtl(Collections.singletonList(updateMsgInfo));
                    }
                    logger.trace("Copied {} as {}", messageInfo.getStoreKey(), tgtMsgInfo.getStoreKey());
                } else if (!messageInfo.isTtlUpdated()) {
                    logger.warn("Found a duplicate entry for {} while copying data", messageInfo.getStoreKey());
                    sourceHasProblems = true;
                }
            }
        }
        token = findInfo.getFindToken();
        double percentBytesRead = src.isEmpty() ? 100.0 : token.getBytesRead() * 100.0 / src.getSizeInBytes();
        logger.info("[{}] [{}] {}% copied", Thread.currentThread().getName(), storeId, df.format(percentBytesRead));
    } while (!token.equals(lastToken));
    return new Pair<>(token, sourceHasProblems);
}
Also used : ByteBufferChannel(com.github.ambry.utils.ByteBufferChannel) ByteArrayInputStream(java.io.ByteArrayInputStream) FindToken(com.github.ambry.replication.FindToken) MessageFormatWriteSet(com.github.ambry.messageformat.MessageFormatWriteSet) Pair(com.github.ambry.utils.Pair)

Example 3 with FindToken

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

the class CloudBlobStoreTest method testFindEntriesSince.

/**
 * Test the CloudBlobStore findEntriesSince method.
 */
@Test
public void testFindEntriesSince() throws Exception {
    setupCloudStore(false, true, defaultCacheLimit, true);
    long maxTotalSize = 1000000;
    // 1) start with empty token, call find, return some data
    long blobSize = 200000;
    int numBlobsFound = 5;
    CosmosChangeFeedFindToken cosmosChangeFeedFindToken = new CosmosChangeFeedFindToken(blobSize * numBlobsFound, "start", "end", 0, numBlobsFound, UUID.randomUUID().toString());
    // create a list of 10 blobs with total size less than maxSize, and return it as part of query ChangeFeed
    when(dest.findEntriesSince(anyString(), any(CosmosChangeFeedFindToken.class), anyLong())).thenReturn(new FindResult(Collections.emptyList(), cosmosChangeFeedFindToken));
    CosmosChangeFeedFindToken startToken = new CosmosChangeFeedFindToken();
    // remote node host name and replica path are not really used by cloud store, it's fine to keep them null
    FindInfo findInfo = store.findEntriesSince(startToken, maxTotalSize, null, null);
    CosmosChangeFeedFindToken outputToken = (CosmosChangeFeedFindToken) findInfo.getFindToken();
    assertEquals(blobSize * numBlobsFound, outputToken.getBytesRead());
    assertEquals(numBlobsFound, outputToken.getTotalItems());
    assertEquals(0, outputToken.getIndex());
    // 2) call find with new token, return more data including lastBlob, verify token updated
    cosmosChangeFeedFindToken = new CosmosChangeFeedFindToken(blobSize * 2 * numBlobsFound, "start2", "end2", 0, numBlobsFound, UUID.randomUUID().toString());
    when(dest.findEntriesSince(anyString(), any(CosmosChangeFeedFindToken.class), anyLong())).thenReturn(new FindResult(Collections.emptyList(), cosmosChangeFeedFindToken));
    findInfo = store.findEntriesSince(outputToken, maxTotalSize, null, null);
    outputToken = (CosmosChangeFeedFindToken) findInfo.getFindToken();
    assertEquals(blobSize * 2 * numBlobsFound, outputToken.getBytesRead());
    assertEquals(numBlobsFound, outputToken.getTotalItems());
    assertEquals(0, outputToken.getIndex());
    // 3) call find with new token, no more data, verify token unchanged
    when(dest.findEntriesSince(anyString(), any(CosmosChangeFeedFindToken.class), anyLong())).thenReturn(new FindResult(Collections.emptyList(), outputToken));
    findInfo = store.findEntriesSince(outputToken, maxTotalSize, null, null);
    assertTrue(findInfo.getMessageEntries().isEmpty());
    FindToken finalToken = findInfo.getFindToken();
    assertEquals(outputToken, finalToken);
}
Also used : CosmosChangeFeedFindToken(com.github.ambry.cloud.azure.CosmosChangeFeedFindToken) MockFindToken(com.github.ambry.replication.MockFindToken) CosmosChangeFeedFindToken(com.github.ambry.cloud.azure.CosmosChangeFeedFindToken) FindToken(com.github.ambry.replication.FindToken) FindInfo(com.github.ambry.store.FindInfo) ReplicationTest(com.github.ambry.replication.ReplicationTest) Test(org.junit.Test)

Example 4 with FindToken

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

the class IndexTest method findEntriesSinceIncarnationIdTest.

/**
 * Tests behaviour of {@link PersistentIndex#findEntriesSince(FindToken, long)} relating to incarnationId
 * @throws StoreException
 */
@Test
public void findEntriesSinceIncarnationIdTest() throws StoreException {
    Offset lastRecordOffset = state.index.journal.getLastOffset();
    state.appendToLog(2 * CuratedLogIndexState.PUT_RECORD_SIZE);
    // will be recovered
    FileSpan firstRecordFileSpan = state.log.getFileSpanForMessage(state.index.getCurrentEndOffset(), CuratedLogIndexState.PUT_RECORD_SIZE);
    // will not be recovered
    FileSpan secondRecordFileSpan = state.log.getFileSpanForMessage(firstRecordFileSpan.getEndOffset(), CuratedLogIndexState.PUT_RECORD_SIZE);
    UUID oldSessionId = state.sessionId;
    UUID oldIncarnationId = state.incarnationId;
    final MockId newId = state.getUniqueId();
    short accountId = Utils.getRandomShort(TestUtils.RANDOM);
    short containerId = Utils.getRandomShort(TestUtils.RANDOM);
    long operationTimeMs = state.time.milliseconds();
    // add to allKeys() so that doFindEntriesSinceTest() works correctly.
    IndexValue putValue = new IndexValue(CuratedLogIndexState.PUT_RECORD_SIZE, firstRecordFileSpan.getStartOffset(), Utils.Infinite_Time, operationTimeMs, accountId, containerId);
    state.allKeys.computeIfAbsent(newId, k -> new TreeSet<>()).add(putValue);
    state.recovery = (read, startOffset, endOffset, factory) -> Collections.singletonList(new MessageInfo(newId, CuratedLogIndexState.PUT_RECORD_SIZE, accountId, containerId, operationTimeMs));
    // change in incarnationId
    state.incarnationId = UUID.randomUUID();
    state.reloadIndex(true, true);
    long bytesRead = state.index.getAbsolutePositionInLogForOffset(firstRecordFileSpan.getEndOffset());
    // create a token that will be past the index end offset on startup after recovery with old incarnationId
    StoreFindToken startToken = new StoreFindToken(secondRecordFileSpan.getEndOffset(), oldSessionId, oldIncarnationId, false, null, null, UNINITIALIZED_RESET_KEY_VERSION);
    // token should get reset internally, all keys should be returned and the returned token should be pointing to
    // start offset of firstRecordFileSpan.
    IndexSegment segmentOfToken = state.index.getIndexSegments().floorEntry(firstRecordFileSpan.getStartOffset()).getValue();
    StoreFindToken expectedEndToken = new StoreFindToken(firstRecordFileSpan.getStartOffset(), state.sessionId, state.incarnationId, false, segmentOfToken.getResetKey(), segmentOfToken.getResetKeyType(), segmentOfToken.getResetKeyLifeVersion());
    expectedEndToken.setBytesRead(bytesRead);
    doFindEntriesSinceTest(startToken, Long.MAX_VALUE, state.allKeys.keySet(), expectedEndToken);
    // create a token that is not past the index end offset on startup after recovery with old incarnationId.
    // token should get reset internally, all keys should be returned and the returned token should be be pointing to
    // start offset of firstRecordFileSpan.
    startToken = new StoreFindToken(lastRecordOffset, oldSessionId, oldIncarnationId, false, null, null, UNINITIALIZED_RESET_KEY_VERSION);
    expectedEndToken = new StoreFindToken(firstRecordFileSpan.getStartOffset(), state.sessionId, state.incarnationId, false, segmentOfToken.getResetKey(), segmentOfToken.getResetKeyType(), segmentOfToken.getResetKeyLifeVersion());
    expectedEndToken.setBytesRead(bytesRead);
    doFindEntriesSinceTest(startToken, Long.MAX_VALUE, state.allKeys.keySet(), expectedEndToken);
}
Also used : Arrays(java.util.Arrays) ScheduledFuture(java.util.concurrent.ScheduledFuture) ArgumentMatchers(org.mockito.ArgumentMatchers) LoggerFactory(org.slf4j.LoggerFactory) Future(java.util.concurrent.Future) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) TestUtils(com.github.ambry.utils.TestUtils) Map(java.util.Map) After(org.junit.After) EnumSet(java.util.EnumSet) Parameterized(org.junit.runners.Parameterized) Container(com.github.ambry.account.Container) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Set(java.util.Set) Utils(com.github.ambry.utils.Utils) ScheduledThreadPoolExecutor(java.util.concurrent.ScheduledThreadPoolExecutor) UUID(java.util.UUID) Collectors(java.util.stream.Collectors) Executors(java.util.concurrent.Executors) CountDownLatch(java.util.concurrent.CountDownLatch) List(java.util.List) Account(com.github.ambry.account.Account) FilenameFilter(java.io.FilenameFilter) RunWith(org.junit.runner.RunWith) HashMap(java.util.HashMap) Callable(java.util.concurrent.Callable) AtomicReference(java.util.concurrent.atomic.AtomicReference) TreeSet(java.util.TreeSet) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) SystemTime(com.github.ambry.utils.SystemTime) Assume(org.junit.Assume) CuratedLogIndexState(com.github.ambry.store.CuratedLogIndexState) Time(com.github.ambry.utils.Time) ExecutorService(java.util.concurrent.ExecutorService) StoreConfig(com.github.ambry.config.StoreConfig) MetricRegistry(com.codahale.metrics.MetricRegistry) Logger(org.slf4j.Logger) Pair(com.github.ambry.utils.Pair) Iterator(java.util.Iterator) VerifiableProperties(com.github.ambry.config.VerifiableProperties) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper) IOException(java.io.IOException) Test(org.junit.Test) File(java.io.File) TimeUnit(java.util.concurrent.TimeUnit) Mockito(org.mockito.Mockito) ConcurrentSkipListMap(java.util.concurrent.ConcurrentSkipListMap) TreeMap(java.util.TreeMap) FindToken(com.github.ambry.replication.FindToken) Assert(org.junit.Assert) StoreFindToken(com.github.ambry.store.StoreFindToken) Collections(java.util.Collections) TreeSet(java.util.TreeSet) StoreFindToken(com.github.ambry.store.StoreFindToken) UUID(java.util.UUID) Test(org.junit.Test)

Example 5 with FindToken

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

the class IndexTest method findEntriesSinceOnRestartTest.

/**
 * Tests behaviour of {@link PersistentIndex#findEntriesSince(FindToken, long)} on crash-restart of index and some
 * recovery. Specifically tests cases where tokens have been handed out before the "crash" failure.
 * @throws IOException
 * @throws StoreException
 */
@Test
public void findEntriesSinceOnRestartTest() throws IOException, StoreException {
    Offset lastRecordOffset = state.index.journal.getLastOffset();
    state.appendToLog(2 * CuratedLogIndexState.PUT_RECORD_SIZE);
    // this record will be recovered.
    FileSpan firstRecordFileSpan = state.log.getFileSpanForMessage(state.index.getCurrentEndOffset(), CuratedLogIndexState.PUT_RECORD_SIZE);
    // this record will not be recovered.
    FileSpan secondRecordFileSpan = state.log.getFileSpanForMessage(firstRecordFileSpan.getEndOffset(), CuratedLogIndexState.PUT_RECORD_SIZE);
    // if there is no bad shutdown but the store token is past the index end offset, it is an error state
    StoreFindToken startToken = new StoreFindToken(secondRecordFileSpan.getStartOffset(), new UUID(1, 1), state.incarnationId, false, null, null, UNINITIALIZED_RESET_KEY_VERSION);
    doFindEntriesSinceFailureTest(startToken, StoreErrorCodes.Unknown_Error);
    UUID oldSessionId = state.sessionId;
    final MockId newId = state.getUniqueId();
    short accountId = Utils.getRandomShort(TestUtils.RANDOM);
    short containerId = Utils.getRandomShort(TestUtils.RANDOM);
    long operationTimeMs = state.time.milliseconds();
    // add to allKeys() so that doFindEntriesSinceTest() works correctly.
    IndexValue putValue = new IndexValue(CuratedLogIndexState.PUT_RECORD_SIZE, firstRecordFileSpan.getStartOffset(), Utils.Infinite_Time, operationTimeMs, accountId, containerId);
    state.allKeys.computeIfAbsent(newId, k -> new TreeSet<>()).add(putValue);
    state.recovery = (read, startOffset, endOffset, factory) -> Collections.singletonList(new MessageInfo(newId, CuratedLogIndexState.PUT_RECORD_SIZE, accountId, containerId, operationTimeMs));
    state.reloadIndex(true, true);
    // If there is no incarnationId in the incoming token, for backwards compatibility purposes we consider it as valid
    // and proceed with session id validation and so on.
    UUID[] incarnationIds = new UUID[] { state.incarnationId, null };
    for (UUID incarnationIdToTest : incarnationIds) {
        long bytesRead = state.index.getAbsolutePositionInLogForOffset(firstRecordFileSpan.getEndOffset());
        // create a token that will be past the index end offset on startup after recovery.
        if (incarnationIdToTest == null) {
            startToken = getTokenWithNullIncarnationId(new StoreFindToken(secondRecordFileSpan.getEndOffset(), oldSessionId, state.incarnationId, false, null, null, UNINITIALIZED_RESET_KEY_VERSION));
            assertNull("IncarnationId is expected to be null ", startToken.getIncarnationId());
        } else {
            startToken = new StoreFindToken(secondRecordFileSpan.getEndOffset(), oldSessionId, incarnationIdToTest, false, null, null, UNINITIALIZED_RESET_KEY_VERSION);
        }
        // token should get reset internally, no keys should be returned and the returned token should be correct (offset
        // in it will be the current log end offset = firstRecordFileSpan.getEndOffset()). The returned token should have correct reset key info.
        IndexSegment segmentOfToken = state.index.getIndexSegments().floorEntry(firstRecordFileSpan.getEndOffset()).getValue();
        StoreFindToken expectedEndToken = new StoreFindToken(firstRecordFileSpan.getEndOffset(), state.sessionId, state.incarnationId, true, segmentOfToken.getResetKey(), segmentOfToken.getResetKeyType(), segmentOfToken.getResetKeyLifeVersion());
        expectedEndToken.setBytesRead(bytesRead);
        doFindEntriesSinceTest(startToken, Long.MAX_VALUE, Collections.emptySet(), expectedEndToken);
        // create a token that is not past the index end offset on startup after recovery. Should work as expected
        if (incarnationIdToTest == null) {
            startToken = getTokenWithNullIncarnationId(new StoreFindToken(lastRecordOffset, oldSessionId, state.incarnationId, false, null, null, UNINITIALIZED_RESET_KEY_VERSION));
            assertNull("IncarnationId is expected to be null ", startToken.getIncarnationId());
        } else {
            startToken = new StoreFindToken(lastRecordOffset, oldSessionId, incarnationIdToTest, false, null, null, UNINITIALIZED_RESET_KEY_VERSION);
        }
        segmentOfToken = state.index.getIndexSegments().floorEntry(firstRecordFileSpan.getStartOffset()).getValue();
        expectedEndToken = new StoreFindToken(firstRecordFileSpan.getStartOffset(), state.sessionId, state.incarnationId, false, segmentOfToken.getResetKey(), segmentOfToken.getResetKeyType(), segmentOfToken.getResetKeyLifeVersion());
        expectedEndToken.setBytesRead(bytesRead);
        doFindEntriesSinceTest(startToken, Long.MAX_VALUE, Collections.singleton(newId), expectedEndToken);
    }
}
Also used : Arrays(java.util.Arrays) ScheduledFuture(java.util.concurrent.ScheduledFuture) ArgumentMatchers(org.mockito.ArgumentMatchers) LoggerFactory(org.slf4j.LoggerFactory) Future(java.util.concurrent.Future) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) TestUtils(com.github.ambry.utils.TestUtils) Map(java.util.Map) After(org.junit.After) EnumSet(java.util.EnumSet) Parameterized(org.junit.runners.Parameterized) Container(com.github.ambry.account.Container) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Set(java.util.Set) Utils(com.github.ambry.utils.Utils) ScheduledThreadPoolExecutor(java.util.concurrent.ScheduledThreadPoolExecutor) UUID(java.util.UUID) Collectors(java.util.stream.Collectors) Executors(java.util.concurrent.Executors) CountDownLatch(java.util.concurrent.CountDownLatch) List(java.util.List) Account(com.github.ambry.account.Account) FilenameFilter(java.io.FilenameFilter) RunWith(org.junit.runner.RunWith) HashMap(java.util.HashMap) Callable(java.util.concurrent.Callable) AtomicReference(java.util.concurrent.atomic.AtomicReference) TreeSet(java.util.TreeSet) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) SystemTime(com.github.ambry.utils.SystemTime) Assume(org.junit.Assume) CuratedLogIndexState(com.github.ambry.store.CuratedLogIndexState) Time(com.github.ambry.utils.Time) ExecutorService(java.util.concurrent.ExecutorService) StoreConfig(com.github.ambry.config.StoreConfig) MetricRegistry(com.codahale.metrics.MetricRegistry) Logger(org.slf4j.Logger) Pair(com.github.ambry.utils.Pair) Iterator(java.util.Iterator) VerifiableProperties(com.github.ambry.config.VerifiableProperties) ObjectMapper(com.fasterxml.jackson.databind.ObjectMapper) IOException(java.io.IOException) Test(org.junit.Test) File(java.io.File) TimeUnit(java.util.concurrent.TimeUnit) Mockito(org.mockito.Mockito) ConcurrentSkipListMap(java.util.concurrent.ConcurrentSkipListMap) TreeMap(java.util.TreeMap) FindToken(com.github.ambry.replication.FindToken) Assert(org.junit.Assert) StoreFindToken(com.github.ambry.store.StoreFindToken) Collections(java.util.Collections) StoreFindToken(com.github.ambry.store.StoreFindToken) TreeSet(java.util.TreeSet) UUID(java.util.UUID) Test(org.junit.Test)

Aggregations

FindToken (com.github.ambry.replication.FindToken)12 PartitionId (com.github.ambry.clustermap.PartitionId)5 FindTokenFactory (com.github.ambry.replication.FindTokenFactory)5 ArrayList (java.util.ArrayList)5 MetricRegistry (com.codahale.metrics.MetricRegistry)3 ReplicaType (com.github.ambry.clustermap.ReplicaType)3 VerifiableProperties (com.github.ambry.config.VerifiableProperties)3 StoreFindToken (com.github.ambry.store.StoreFindToken)3 Pair (com.github.ambry.utils.Pair)3 DataInputStream (java.io.DataInputStream)3 IOException (java.io.IOException)3 HashMap (java.util.HashMap)3 Map (java.util.Map)3 TreeMap (java.util.TreeMap)3 Test (org.junit.Test)3 ObjectMapper (com.fasterxml.jackson.databind.ObjectMapper)2 Account (com.github.ambry.account.Account)2 Container (com.github.ambry.account.Container)2 CloudBlobMetadata (com.github.ambry.cloud.CloudBlobMetadata)2 FindResult (com.github.ambry.cloud.FindResult)2