Search in sources :

Example 21 with StoreException

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

the class ReplicaThread method applyUndelete.

/**
 * Applies an undelete to the blob described by {@code messageInfo}.
 * @param messageInfo the {@link MessageInfo} that will be transformed into an undelete
 * @param remoteReplicaInfo The remote replica that is being replicated from
 * @throws StoreException
 */
private void applyUndelete(MessageInfo messageInfo, RemoteReplicaInfo remoteReplicaInfo) throws StoreException {
    DataNodeId remoteNode = remoteReplicaInfo.getReplicaId().getDataNodeId();
    try {
        messageInfo = new MessageInfo.Builder(messageInfo).isUndeleted(true).isDeleted(false).build();
        remoteReplicaInfo.getLocalStore().undelete(messageInfo);
        logger.trace("Remote node: {} Thread name: {} Remote replica: {} Key undelete id: {}", remoteNode, threadName, remoteReplicaInfo.getReplicaId(), messageInfo.getStoreKey());
    } catch (StoreException e) {
        // The blob may be undeleted, which is alright
        if (e.getErrorCode() == StoreErrorCodes.Life_Version_Conflict || e.getErrorCode() == StoreErrorCodes.ID_Undeleted) {
            logger.trace("Remote node: {} Thread name: {} Remote replica: {} Key {}: {}", remoteNode, threadName, remoteReplicaInfo.getReplicaId(), messageInfo.getStoreKey(), e.getErrorCode().name());
        } else {
            throw e;
        }
    }
    // as long as the undelete is guaranteed to have taken effect locally.
    if (notification != null) {
        notification.onBlobReplicaUndeleted(dataNodeId.getHostname(), dataNodeId.getPort(), messageInfo.getStoreKey().getID(), BlobReplicaSourceType.REPAIRED);
    }
}
Also used : DataNodeId(com.github.ambry.clustermap.DataNodeId) StoreException(com.github.ambry.store.StoreException)

Example 22 with StoreException

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

the class ReplicaThread method refreshMissingStoreMessagesForStandbyReplica.

/**
 * Refreshes missing messages found in the exchange metadata response for the input replica by checking in the local store again.
 * @param remoteReplicaInfo remote replica information
 */
private void refreshMissingStoreMessagesForStandbyReplica(RemoteReplicaInfo remoteReplicaInfo) {
    ExchangeMetadataResponse exchangeMetadataResponse = remoteReplicaInfo.getExchangeMetadataResponse();
    Set<MessageInfo> missingStoreMessages = exchangeMetadataResponse.getMissingStoreMessages();
    if (!missingStoreMessages.isEmpty()) {
        Set<MessageInfo> missingStoreMessagesFoundInStore = new HashSet<>();
        try {
            // construct map of message info -> converted non-null local key
            Map<StoreKey, StoreKey> remoteKeyToLocalKeyMap = exchangeMetadataResponse.remoteKeyToLocalKeyMap;
            Map<MessageInfo, StoreKey> remoteMessageToConvertedKeyNonNull = new HashMap<>();
            for (MessageInfo messageInfo : missingStoreMessages) {
                StoreKey convertedKey = remoteKeyToLocalKeyMap.get(messageInfo.getStoreKey());
                if (convertedKey != null) {
                    remoteMessageToConvertedKeyNonNull.put(messageInfo, convertedKey);
                }
            }
            // Find the set of store keys that are still missing in the store
            Set<StoreKey> convertedMissingStoreKeys = remoteReplicaInfo.getLocalStore().findMissingKeys(new ArrayList<>(remoteMessageToConvertedKeyNonNull.values()));
            // Filter the remote messages whose keys are now found in store, i.e. not present in convertedMissingStoreKeys set.
            remoteMessageToConvertedKeyNonNull.forEach((messageInfo, convertedKey) -> {
                if (!convertedMissingStoreKeys.contains(convertedKey)) {
                    missingStoreMessagesFoundInStore.add(messageInfo);
                }
            });
            // update the missing store messages being tracked for this replica
            exchangeMetadataResponse.removeMissingStoreMessages(missingStoreMessagesFoundInStore);
        } catch (StoreException e) {
            logger.error("Exception occurred while checking for missing keys in local store for partition {} and Remote replica: {}", remoteReplicaInfo.getReplicaId().getPartitionId().toPathString(), remoteReplicaInfo.getReplicaId(), e);
            // reset stored metadata response so that metadata request is sent again for this replica
            remoteReplicaInfo.setExchangeMetadataResponse(new ExchangeMetadataResponse(ServerErrorCode.No_Error));
        }
    }
}
Also used : HashMap(java.util.HashMap) StoreKey(com.github.ambry.store.StoreKey) MessageInfo(com.github.ambry.store.MessageInfo) HashSet(java.util.HashSet) StoreException(com.github.ambry.store.StoreException)

Example 23 with StoreException

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

the class ReplicaThread method applyDelete.

/**
 * Applies a delete to the blob described by {@code messageInfo}.
 * @param messageInfo the {@link MessageInfo} that will be transformed into a delete
 * @param remoteReplicaInfo The remote replica that is being replicated from
 * @throws StoreException
 */
private void applyDelete(MessageInfo messageInfo, RemoteReplicaInfo remoteReplicaInfo) throws StoreException {
    DataNodeId remoteNode = remoteReplicaInfo.getReplicaId().getDataNodeId();
    try {
        messageInfo = new MessageInfo.Builder(messageInfo).isDeleted(true).isUndeleted(false).build();
        remoteReplicaInfo.getLocalStore().delete(Collections.singletonList(messageInfo));
        logger.trace("Remote node: {} Thread name: {} Remote replica: {} Key delete: {}", remoteNode, threadName, remoteReplicaInfo.getReplicaId(), messageInfo.getStoreKey());
    } catch (StoreException e) {
        // The blob may be deleted or updated which is alright
        if (e.getErrorCode() == StoreErrorCodes.ID_Deleted || e.getErrorCode() == StoreErrorCodes.Life_Version_Conflict) {
            logger.trace("Remote node: {} Thread name: {} Remote replica: {} Key {}: {}", remoteNode, threadName, remoteReplicaInfo.getReplicaId(), messageInfo.getStoreKey(), e.getErrorCode().name());
        } else {
            throw e;
        }
    }
    // as long as the Delete is guaranteed to have taken effect locally.
    if (notification != null) {
        notification.onBlobReplicaDeleted(dataNodeId.getHostname(), dataNodeId.getPort(), messageInfo.getStoreKey().getID(), BlobReplicaSourceType.REPAIRED);
    }
}
Also used : DataNodeId(com.github.ambry.clustermap.DataNodeId) StoreException(com.github.ambry.store.StoreException)

Example 24 with StoreException

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

the class InMemoryStore method delete.

@Override
public void delete(List<MessageInfo> infos) throws StoreException {
    List<MessageInfo> infosToDelete = new ArrayList<>(infos.size());
    List<InputStream> inputStreams = new ArrayList<>();
    try {
        for (MessageInfo info : infos) {
            short lifeVersion = info.getLifeVersion();
            MessageInfo latestInfo = getMergedMessageInfo(info.getStoreKey(), messageInfos);
            if (latestInfo == null) {
                throw new StoreException("Cannot delete id " + info.getStoreKey() + " since it is not present in the index.", StoreErrorCodes.ID_Not_Found);
            }
            if (lifeVersion == MessageInfo.LIFE_VERSION_FROM_FRONTEND) {
                if (latestInfo.isDeleted()) {
                    throw new StoreException("Cannot delete id " + info.getStoreKey() + " since it is already deleted in the index.", StoreErrorCodes.ID_Deleted);
                }
                lifeVersion = latestInfo.getLifeVersion();
            } else {
                if ((latestInfo.isDeleted() && latestInfo.getLifeVersion() >= info.getLifeVersion()) || (latestInfo.getLifeVersion() > info.getLifeVersion())) {
                    throw new StoreException("Cannot delete id " + info.getStoreKey() + " since it is already deleted in the index.", StoreErrorCodes.Life_Version_Conflict);
                }
                lifeVersion = info.getLifeVersion();
            }
            MessageFormatInputStream stream = new DeleteMessageFormatInputStream(info.getStoreKey(), info.getAccountId(), info.getContainerId(), info.getOperationTimeMs(), lifeVersion);
            infosToDelete.add(new MessageInfo(info.getStoreKey(), stream.getSize(), true, info.isTtlUpdated(), false, info.getExpirationTimeInMs(), null, info.getAccountId(), info.getContainerId(), info.getOperationTimeMs(), lifeVersion));
            inputStreams.add(stream);
        }
        MessageFormatWriteSet writeSet = new MessageFormatWriteSet(new SequenceInputStream(Collections.enumeration(inputStreams)), infosToDelete, false);
        writeSet.writeTo(log);
        messageInfos.addAll(infosToDelete);
    } catch (Exception e) {
        throw (e instanceof StoreException ? (StoreException) e : new StoreException(e, StoreErrorCodes.Unknown_Error));
    }
}
Also used : SequenceInputStream(java.io.SequenceInputStream) DeleteMessageFormatInputStream(com.github.ambry.messageformat.DeleteMessageFormatInputStream) SequenceInputStream(java.io.SequenceInputStream) UndeleteMessageFormatInputStream(com.github.ambry.messageformat.UndeleteMessageFormatInputStream) MessageFormatInputStream(com.github.ambry.messageformat.MessageFormatInputStream) TtlUpdateMessageFormatInputStream(com.github.ambry.messageformat.TtlUpdateMessageFormatInputStream) InputStream(java.io.InputStream) ArrayList(java.util.ArrayList) DeleteMessageFormatInputStream(com.github.ambry.messageformat.DeleteMessageFormatInputStream) DeleteMessageFormatInputStream(com.github.ambry.messageformat.DeleteMessageFormatInputStream) UndeleteMessageFormatInputStream(com.github.ambry.messageformat.UndeleteMessageFormatInputStream) MessageFormatInputStream(com.github.ambry.messageformat.MessageFormatInputStream) TtlUpdateMessageFormatInputStream(com.github.ambry.messageformat.TtlUpdateMessageFormatInputStream) StoreException(com.github.ambry.store.StoreException) IOException(java.io.IOException) MessageInfo(com.github.ambry.store.MessageInfo) StoreException(com.github.ambry.store.StoreException) MessageFormatWriteSet(com.github.ambry.messageformat.MessageFormatWriteSet)

Example 25 with StoreException

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

the class InMemoryStore method updateTtl.

@Override
public void updateTtl(List<MessageInfo> infos) throws StoreException {
    List<MessageInfo> infosToUpdate = new ArrayList<>(infos.size());
    List<InputStream> inputStreams = new ArrayList<>();
    try {
        for (MessageInfo info : infos) {
            if (info.getExpirationTimeInMs() != Utils.Infinite_Time) {
                throw new StoreException("BlobStore only supports removing the expiration time", StoreErrorCodes.Update_Not_Allowed);
            }
            MessageInfo latestInfo = getMergedMessageInfo(info.getStoreKey(), messageInfos);
            if (latestInfo == null) {
                throw new StoreException("Cannot update TTL of " + info.getStoreKey() + " since it's not in the index", StoreErrorCodes.ID_Not_Found);
            } else if (latestInfo.isDeleted()) {
                throw new StoreException("Cannot update TTL of " + info.getStoreKey() + " since it is already deleted in the index.", StoreErrorCodes.ID_Deleted);
            } else if (latestInfo.isTtlUpdated()) {
                throw new StoreException("TTL of " + info.getStoreKey() + " is already updated in the index.", StoreErrorCodes.Already_Updated);
            }
            short lifeVersion = latestInfo.getLifeVersion();
            MessageFormatInputStream stream = new TtlUpdateMessageFormatInputStream(info.getStoreKey(), info.getAccountId(), info.getContainerId(), info.getExpirationTimeInMs(), info.getOperationTimeMs(), lifeVersion);
            infosToUpdate.add(new MessageInfo(info.getStoreKey(), stream.getSize(), false, true, false, info.getExpirationTimeInMs(), null, info.getAccountId(), info.getContainerId(), info.getOperationTimeMs(), lifeVersion));
            inputStreams.add(stream);
        }
        MessageFormatWriteSet writeSet = new MessageFormatWriteSet(new SequenceInputStream(Collections.enumeration(inputStreams)), infosToUpdate, false);
        writeSet.writeTo(log);
        messageInfos.addAll(infosToUpdate);
    } catch (Exception e) {
        throw (e instanceof StoreException ? (StoreException) e : new StoreException(e, StoreErrorCodes.Unknown_Error));
    }
}
Also used : TtlUpdateMessageFormatInputStream(com.github.ambry.messageformat.TtlUpdateMessageFormatInputStream) SequenceInputStream(java.io.SequenceInputStream) DeleteMessageFormatInputStream(com.github.ambry.messageformat.DeleteMessageFormatInputStream) SequenceInputStream(java.io.SequenceInputStream) UndeleteMessageFormatInputStream(com.github.ambry.messageformat.UndeleteMessageFormatInputStream) MessageFormatInputStream(com.github.ambry.messageformat.MessageFormatInputStream) TtlUpdateMessageFormatInputStream(com.github.ambry.messageformat.TtlUpdateMessageFormatInputStream) InputStream(java.io.InputStream) ArrayList(java.util.ArrayList) DeleteMessageFormatInputStream(com.github.ambry.messageformat.DeleteMessageFormatInputStream) UndeleteMessageFormatInputStream(com.github.ambry.messageformat.UndeleteMessageFormatInputStream) MessageFormatInputStream(com.github.ambry.messageformat.MessageFormatInputStream) TtlUpdateMessageFormatInputStream(com.github.ambry.messageformat.TtlUpdateMessageFormatInputStream) StoreException(com.github.ambry.store.StoreException) IOException(java.io.IOException) MessageInfo(com.github.ambry.store.MessageInfo) StoreException(com.github.ambry.store.StoreException) MessageFormatWriteSet(com.github.ambry.messageformat.MessageFormatWriteSet)

Aggregations

StoreException (com.github.ambry.store.StoreException)59 MessageInfo (com.github.ambry.store.MessageInfo)31 IOException (java.io.IOException)22 ArrayList (java.util.ArrayList)17 BlobId (com.github.ambry.commons.BlobId)16 Store (com.github.ambry.store.Store)16 StoreErrorCodes (com.github.ambry.store.StoreErrorCodes)12 StoreKey (com.github.ambry.store.StoreKey)11 MessageFormatException (com.github.ambry.messageformat.MessageFormatException)10 MockMessageWriteSet (com.github.ambry.store.MockMessageWriteSet)10 DataInputStream (java.io.DataInputStream)10 MessageFormatWriteSet (com.github.ambry.messageformat.MessageFormatWriteSet)9 IdUndeletedStoreException (com.github.ambry.store.IdUndeletedStoreException)8 StoreGetOptions (com.github.ambry.store.StoreGetOptions)8 Test (org.junit.Test)8 PartitionId (com.github.ambry.clustermap.PartitionId)7 MessageFormatInputStream (com.github.ambry.messageformat.MessageFormatInputStream)7 StoreInfo (com.github.ambry.store.StoreInfo)7 DeleteMessageFormatInputStream (com.github.ambry.messageformat.DeleteMessageFormatInputStream)6 ServerNetworkResponseMetrics (com.github.ambry.network.ServerNetworkResponseMetrics)6