Search in sources :

Example 11 with StoreException

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

the class LatchBasedInMemoryCloudDestination method deleteBlob.

@Override
public boolean deleteBlob(BlobId blobId, long deletionTime, short lifeVersion, CloudUpdateValidator cloudUpdateValidator) throws CloudStorageException {
    StoreErrorCodes serverError = hardError != null ? hardError : serverErrors.size() > 0 ? serverErrors.poll() : null;
    if (serverError != null) {
        throw new CloudStorageException("deleteBlob simulated error", new StoreException("deleteBlob simulated error", serverError));
    }
    if (!map.containsKey(blobId)) {
        return false;
    }
    // get the legit lifeVersion before we can write undelete record to log segment.
    if (!MessageInfo.hasLifeVersion(lifeVersion)) {
        lifeVersion = map.get(blobId).getFirst().getLifeVersion();
    }
    map.get(blobId).getFirst().setDeletionTime(deletionTime);
    map.get(blobId).getFirst().setLifeVersion(lifeVersion);
    map.get(blobId).getFirst().setLastUpdateTime(System.currentTimeMillis());
    changeFeed.add(blobId);
    return true;
}
Also used : StoreErrorCodes(com.github.ambry.store.StoreErrorCodes) StoreException(com.github.ambry.store.StoreException)

Example 12 with StoreException

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

the class LatchBasedInMemoryCloudDestination method updateBlobExpiration.

@Override
public short updateBlobExpiration(BlobId blobId, long expirationTime, CloudUpdateValidator cloudUpdateValidator) throws CloudStorageException {
    StoreErrorCodes serverError = hardError != null ? hardError : serverErrors.size() > 0 ? serverErrors.poll() : null;
    if (serverError != null) {
        throw new CloudStorageException("updateBlobExpiration simulated error", new StoreException("updateBlobExpiration simulated error", serverError));
    }
    if (map.containsKey(blobId)) {
        map.get(blobId).getFirst().setExpirationTime(expirationTime);
        map.get(blobId).getFirst().setLastUpdateTime(System.currentTimeMillis());
        changeFeed.add(blobId);
        return map.get(blobId).getFirst().getLifeVersion();
    }
    throw new CloudStorageException(String.format("Blob %s not found", blobId.getID()));
}
Also used : StoreErrorCodes(com.github.ambry.store.StoreErrorCodes) StoreException(com.github.ambry.store.StoreException)

Example 13 with StoreException

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

the class CloudBlobStoreIntegrationTest method testDeleteFromFrontend.

/**
 * Test {@link CloudBlobStore#delete} method from frontend.
 */
public void testDeleteFromFrontend() throws StoreException {
    // First upload a blob with a life version 2
    MockMessageWriteSet messageWriteSet = new MockMessageWriteSet();
    addBlobToMessageSet(messageWriteSet, Utils.Infinite_Time, accountId, containerId, partitionId, operationTime, (short) -1);
    cloudBlobStore.put(messageWriteSet);
    // verify that the blob was uploaded with expected metadata.
    StoreInfo storeInfo = cloudBlobStore.get(messageWriteSet.getMessageSetInfo().stream().map(MessageInfo::getStoreKey).collect(Collectors.toList()), EnumSet.allOf(StoreGetOptions.class));
    assertEquals("Unexpected live version", 0, storeInfo.getMessageReadSetInfo().get(0).getLifeVersion());
    assertEquals("Unexpected delete status", messageWriteSet.getMessageSetInfo().get(0).isDeleted(), storeInfo.getMessageReadSetInfo().get(0).isDeleted());
    // Deleting again should fail with ID_Deleted exception.
    MessageInfo messageInfo = messageWriteSet.getMessageSetInfo().get(0);
    MessageInfo deleteMessageInfo = new MessageInfo(messageInfo.getStoreKey(), messageInfo.getSize(), messageInfo.isDeleted(), messageInfo.isTtlUpdated(), messageInfo.isUndeleted(), messageInfo.getExpirationTimeInMs(), messageInfo.getCrc(), messageInfo.getAccountId(), messageInfo.getContainerId(), messageInfo.getOperationTimeMs(), (short) -1);
    try {
        cloudBlobStore.delete(Collections.singletonList(deleteMessageInfo));
    } catch (StoreException ex) {
        assertEquals("Unexpected error code", ex.getErrorCode(), StoreErrorCodes.ID_Deleted);
    }
    storeInfo = cloudBlobStore.get(messageWriteSet.getMessageSetInfo().stream().map(MessageInfo::getStoreKey).collect(Collectors.toList()), EnumSet.allOf(StoreGetOptions.class));
    assertEquals("Unexpected live version", 0, storeInfo.getMessageReadSetInfo().get(0).getLifeVersion());
    assertTrue("Unexpected delete status", storeInfo.getMessageReadSetInfo().get(0).isDeleted());
    // Restart cloud blob store to clear cache. Deleting again should still fail with ID_Deleted Store Exception.
    cloudBlobStore.shutdown();
    cloudBlobStore.start();
    deleteMessageInfo = new MessageInfo(messageInfo.getStoreKey(), messageInfo.getSize(), messageInfo.isDeleted(), messageInfo.isTtlUpdated(), messageInfo.isUndeleted(), messageInfo.getExpirationTimeInMs(), messageInfo.getCrc(), messageInfo.getAccountId(), messageInfo.getContainerId(), messageInfo.getOperationTimeMs(), (short) 3);
    try {
        cloudBlobStore.delete(Collections.singletonList(deleteMessageInfo));
    } catch (StoreException ex) {
        assertEquals("Unexpected error code", ex.getErrorCode(), StoreErrorCodes.ID_Deleted);
    }
    storeInfo = cloudBlobStore.get(messageWriteSet.getMessageSetInfo().stream().map(MessageInfo::getStoreKey).collect(Collectors.toList()), EnumSet.allOf(StoreGetOptions.class));
    assertEquals("Unexpected live version", 3, storeInfo.getMessageReadSetInfo().get(0).getLifeVersion());
    assertTrue("Unexpected delete status", storeInfo.getMessageReadSetInfo().get(0).isDeleted());
}
Also used : MockMessageWriteSet(com.github.ambry.store.MockMessageWriteSet) StoreGetOptions(com.github.ambry.store.StoreGetOptions) StoreInfo(com.github.ambry.store.StoreInfo) MessageInfo(com.github.ambry.store.MessageInfo) StoreException(com.github.ambry.store.StoreException)

Example 14 with StoreException

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

the class CloudBlobStoreIntegrationTest method testUndelete.

/**
 * Test {@link CloudBlobStore#undelete} method.
 */
@Test
public void testUndelete() throws StoreException {
    MockMessageWriteSet messageWriteSet = new MockMessageWriteSet();
    addBlobToMessageSet(messageWriteSet, Utils.Infinite_Time, accountId, containerId, partitionId, operationTime, initLifeVersion(isVcr));
    cloudBlobStore.put(messageWriteSet);
    // Attempt to undelete a blob that is not deleted. Should fail silently for vcr and throw exception for frontend.
    MessageInfo messageInfo = messageWriteSet.getMessageSetInfo().get(0);
    MessageInfo undeleteMessageInfo = new MessageInfo(messageInfo.getStoreKey(), messageInfo.getSize(), messageInfo.isDeleted(), messageInfo.isTtlUpdated(), messageInfo.isUndeleted(), messageInfo.getExpirationTimeInMs(), messageInfo.getCrc(), messageInfo.getAccountId(), messageInfo.getContainerId(), messageInfo.getOperationTimeMs(), (isVcr ? (short) 1 : -1));
    try {
        cloudBlobStore.undelete(undeleteMessageInfo);
        if (!isVcr) {
            fail("Undelete from frontend of a not deleted blob should throw exception.");
        }
    } catch (StoreException ex) {
        if (isVcr) {
            fail("Undelete for the vcr should fail silently");
        }
        assertEquals("Unexpected error message", StoreErrorCodes.ID_Not_Deleted, ex.getErrorCode());
    }
    // delete the blob.
    MessageInfo deleteMessageInfo = new MessageInfo(messageInfo.getStoreKey(), messageInfo.getSize(), messageInfo.isDeleted(), messageInfo.isTtlUpdated(), messageInfo.isUndeleted(), messageInfo.getExpirationTimeInMs(), messageInfo.getCrc(), messageInfo.getAccountId(), messageInfo.getContainerId(), messageInfo.getOperationTimeMs(), (short) (isVcr ? 1 : -1));
    cloudBlobStore.delete(Collections.singletonList(deleteMessageInfo));
    // Attempt to undelete should pass
    short lifeVersion = cloudBlobStore.undelete(undeleteMessageInfo);
    assertEquals("Unexpected life version after undelete", lifeVersion, 1);
}
Also used : MockMessageWriteSet(com.github.ambry.store.MockMessageWriteSet) MessageInfo(com.github.ambry.store.MessageInfo) StoreException(com.github.ambry.store.StoreException) Test(org.junit.Test)

Example 15 with StoreException

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

the class AmbryRequests method handleGetRequest.

@Override
public void handleGetRequest(NetworkRequest request) throws IOException, InterruptedException {
    GetRequest getRequest;
    if (request instanceof LocalChannelRequest) {
        // This is a case where handleGetRequest is called when frontends are reading from Azure. In this case, this method
        // is called by request handler threads running within the frontend router itself. So, the request can be directly
        // referenced as java objects without any need for deserialization.
        getRequest = (GetRequest) ((LocalChannelRequest) request).getRequestInfo().getRequest();
    } else {
        getRequest = GetRequest.readFrom(new DataInputStream(request.getInputStream()), clusterMap);
    }
    Histogram responseQueueTime = null;
    Histogram responseSendTime = null;
    Histogram responseTotalTime = null;
    long requestQueueTime = SystemTime.getInstance().milliseconds() - request.getStartTimeInMs();
    long totalTimeSpent = requestQueueTime;
    boolean isReplicaRequest = getRequest.getClientId().startsWith(GetRequest.Replication_Client_Id_Prefix);
    if (getRequest.getMessageFormatFlag() == MessageFormatFlags.Blob) {
        metrics.getBlobRequestQueueTimeInMs.update(requestQueueTime);
        metrics.getBlobRequestRate.mark();
        responseQueueTime = metrics.getBlobResponseQueueTimeInMs;
        responseSendTime = metrics.getBlobSendTimeInMs;
        responseTotalTime = metrics.getBlobTotalTimeInMs;
    } else if (getRequest.getMessageFormatFlag() == MessageFormatFlags.BlobProperties) {
        metrics.getBlobPropertiesRequestQueueTimeInMs.update(requestQueueTime);
        metrics.getBlobPropertiesRequestRate.mark();
        responseQueueTime = metrics.getBlobPropertiesResponseQueueTimeInMs;
        responseSendTime = metrics.getBlobPropertiesSendTimeInMs;
        responseTotalTime = metrics.getBlobPropertiesTotalTimeInMs;
    } else if (getRequest.getMessageFormatFlag() == MessageFormatFlags.BlobUserMetadata) {
        metrics.getBlobUserMetadataRequestQueueTimeInMs.update(requestQueueTime);
        metrics.getBlobUserMetadataRequestRate.mark();
        responseQueueTime = metrics.getBlobUserMetadataResponseQueueTimeInMs;
        responseSendTime = metrics.getBlobUserMetadataSendTimeInMs;
        responseTotalTime = metrics.getBlobUserMetadataTotalTimeInMs;
    } else if (getRequest.getMessageFormatFlag() == MessageFormatFlags.BlobInfo) {
        metrics.getBlobInfoRequestQueueTimeInMs.update(requestQueueTime);
        metrics.getBlobInfoRequestRate.mark();
        responseQueueTime = metrics.getBlobInfoResponseQueueTimeInMs;
        responseSendTime = metrics.getBlobInfoSendTimeInMs;
        responseTotalTime = metrics.getBlobInfoTotalTimeInMs;
    } else if (getRequest.getMessageFormatFlag() == MessageFormatFlags.All) {
        if (isReplicaRequest) {
            metrics.getBlobAllByReplicaRequestQueueTimeInMs.update(requestQueueTime);
            metrics.getBlobAllByReplicaRequestRate.mark();
            responseQueueTime = metrics.getBlobAllByReplicaResponseQueueTimeInMs;
            responseSendTime = metrics.getBlobAllByReplicaSendTimeInMs;
            responseTotalTime = metrics.getBlobAllByReplicaTotalTimeInMs;
        } else {
            metrics.getBlobAllRequestQueueTimeInMs.update(requestQueueTime);
            metrics.getBlobAllRequestRate.mark();
            responseQueueTime = metrics.getBlobAllResponseQueueTimeInMs;
            responseSendTime = metrics.getBlobAllSendTimeInMs;
            responseTotalTime = metrics.getBlobAllTotalTimeInMs;
        }
    }
    long startTime = SystemTime.getInstance().milliseconds();
    GetResponse response = null;
    try {
        List<Send> messagesToSendList = new ArrayList<>(getRequest.getPartitionInfoList().size());
        List<PartitionResponseInfo> partitionResponseInfoList = new ArrayList<>(getRequest.getPartitionInfoList().size());
        for (PartitionRequestInfo partitionRequestInfo : getRequest.getPartitionInfoList()) {
            ServerErrorCode error = validateRequest(partitionRequestInfo.getPartition(), RequestOrResponseType.GetRequest, false);
            if (error != ServerErrorCode.No_Error) {
                logger.error("Validating get request failed for partition {} with error {}", partitionRequestInfo.getPartition(), error);
                PartitionResponseInfo partitionResponseInfo = new PartitionResponseInfo(partitionRequestInfo.getPartition(), error);
                partitionResponseInfoList.add(partitionResponseInfo);
            } else {
                try {
                    Store storeToGet = storeManager.getStore(partitionRequestInfo.getPartition());
                    EnumSet<StoreGetOptions> storeGetOptions = EnumSet.noneOf(StoreGetOptions.class);
                    // Currently only one option is supported.
                    if (getRequest.getGetOption() == GetOption.Include_Expired_Blobs) {
                        storeGetOptions = EnumSet.of(StoreGetOptions.Store_Include_Expired);
                    }
                    if (getRequest.getGetOption() == GetOption.Include_Deleted_Blobs) {
                        storeGetOptions = EnumSet.of(StoreGetOptions.Store_Include_Deleted);
                    }
                    if (getRequest.getGetOption() == GetOption.Include_All) {
                        storeGetOptions = EnumSet.of(StoreGetOptions.Store_Include_Deleted, StoreGetOptions.Store_Include_Expired);
                    }
                    List<StoreKey> convertedStoreKeys = getConvertedStoreKeys(partitionRequestInfo.getBlobIds());
                    List<StoreKey> dedupedStoreKeys = convertedStoreKeys.size() > 1 ? convertedStoreKeys.stream().distinct().collect(Collectors.toList()) : convertedStoreKeys;
                    StoreInfo info = storeToGet.get(dedupedStoreKeys, storeGetOptions);
                    MessageFormatSend blobsToSend = new MessageFormatSend(info.getMessageReadSet(), getRequest.getMessageFormatFlag(), messageFormatMetrics, storeKeyFactory);
                    PartitionResponseInfo partitionResponseInfo = new PartitionResponseInfo(partitionRequestInfo.getPartition(), info.getMessageReadSetInfo(), blobsToSend.getMessageMetadataList());
                    messagesToSendList.add(blobsToSend);
                    partitionResponseInfoList.add(partitionResponseInfo);
                } catch (StoreException e) {
                    boolean logInErrorLevel = false;
                    if (e.getErrorCode() == StoreErrorCodes.ID_Not_Found) {
                        metrics.idNotFoundError.inc();
                    } else if (e.getErrorCode() == StoreErrorCodes.TTL_Expired) {
                        metrics.ttlExpiredError.inc();
                    } else if (e.getErrorCode() == StoreErrorCodes.ID_Deleted) {
                        metrics.idDeletedError.inc();
                    } else if (e.getErrorCode() == StoreErrorCodes.Authorization_Failure) {
                        metrics.getAuthorizationFailure.inc();
                    } else {
                        metrics.unExpectedStoreGetError.inc();
                        logInErrorLevel = true;
                    }
                    if (logInErrorLevel) {
                        logger.error("Store exception on a get with error code {} for partition {}", e.getErrorCode(), partitionRequestInfo.getPartition(), e);
                    } else {
                        logger.trace("Store exception on a get with error code {} for partition {}", e.getErrorCode(), partitionRequestInfo.getPartition(), e);
                    }
                    PartitionResponseInfo partitionResponseInfo = new PartitionResponseInfo(partitionRequestInfo.getPartition(), ErrorMapping.getStoreErrorMapping(e.getErrorCode()));
                    partitionResponseInfoList.add(partitionResponseInfo);
                } catch (MessageFormatException e) {
                    logger.error("Message format exception on a get with error code {} for partitionRequestInfo {}", e.getErrorCode(), partitionRequestInfo, e);
                    if (e.getErrorCode() == MessageFormatErrorCodes.Data_Corrupt) {
                        metrics.dataCorruptError.inc();
                    } else if (e.getErrorCode() == MessageFormatErrorCodes.Unknown_Format_Version) {
                        metrics.unknownFormatError.inc();
                    }
                    PartitionResponseInfo partitionResponseInfo = new PartitionResponseInfo(partitionRequestInfo.getPartition(), ErrorMapping.getMessageFormatErrorMapping(e.getErrorCode()));
                    partitionResponseInfoList.add(partitionResponseInfo);
                }
            }
        }
        CompositeSend compositeSend = new CompositeSend(messagesToSendList);
        response = new GetResponse(getRequest.getCorrelationId(), getRequest.getClientId(), partitionResponseInfoList, compositeSend, ServerErrorCode.No_Error);
    } catch (Exception e) {
        logger.error("Unknown exception for request {}", getRequest, e);
        response = new GetResponse(getRequest.getCorrelationId(), getRequest.getClientId(), ServerErrorCode.Unknown_Error);
    } finally {
        long processingTime = SystemTime.getInstance().milliseconds() - startTime;
        totalTimeSpent += processingTime;
        publicAccessLogger.info("{} {} processingTime {}", getRequest, response, processingTime);
        long responseSize = response != null ? response.sizeInBytes() : 0;
        if (getRequest.getMessageFormatFlag() == MessageFormatFlags.Blob) {
            metrics.getBlobProcessingTimeInMs.update(processingTime);
            metrics.updateGetBlobProcessingTimeBySize(responseSize, processingTime);
        } else if (getRequest.getMessageFormatFlag() == MessageFormatFlags.BlobProperties) {
            metrics.getBlobPropertiesProcessingTimeInMs.update(processingTime);
        } else if (getRequest.getMessageFormatFlag() == MessageFormatFlags.BlobUserMetadata) {
            metrics.getBlobUserMetadataProcessingTimeInMs.update(processingTime);
        } else if (getRequest.getMessageFormatFlag() == MessageFormatFlags.BlobInfo) {
            metrics.getBlobInfoProcessingTimeInMs.update(processingTime);
        } else if (getRequest.getMessageFormatFlag() == MessageFormatFlags.All) {
            if (isReplicaRequest) {
                metrics.getBlobAllByReplicaProcessingTimeInMs.update(processingTime);
                // client id now has dc name at the end, for example: ClientId=replication-fetch-abc.example.com[dc1]
                String[] clientStrs = getRequest.getClientId().split("\\[");
                if (clientStrs.length > 1) {
                    String clientDc = clientStrs[1].substring(0, clientStrs[1].length() - 1);
                    if (!currentNode.getDatacenterName().equals(clientDc)) {
                        metrics.updateCrossColoFetchBytesRate(clientDc, responseSize);
                    }
                }
            } else {
                metrics.getBlobAllProcessingTimeInMs.update(processingTime);
                metrics.updateGetBlobProcessingTimeBySize(responseSize, processingTime);
            }
        }
    }
    sendGetResponse(requestResponseChannel, response, request, responseQueueTime, responseSendTime, responseTotalTime, totalTimeSpent, response.sizeInBytes(), getRequest.getMessageFormatFlag(), metrics);
}
Also used : Histogram(com.codahale.metrics.Histogram) ArrayList(java.util.ArrayList) Store(com.github.ambry.store.Store) StoreInfo(com.github.ambry.store.StoreInfo) MessageFormatSend(com.github.ambry.messageformat.MessageFormatSend) Send(com.github.ambry.network.Send) MessageFormatException(com.github.ambry.messageformat.MessageFormatException) StoreGetOptions(com.github.ambry.store.StoreGetOptions) MessageFormatSend(com.github.ambry.messageformat.MessageFormatSend) DataInputStream(java.io.DataInputStream) StoreKey(com.github.ambry.store.StoreKey) ServerErrorCode(com.github.ambry.server.ServerErrorCode) IdUndeletedStoreException(com.github.ambry.store.IdUndeletedStoreException) StoreException(com.github.ambry.store.StoreException) IOException(java.io.IOException) MessageFormatException(com.github.ambry.messageformat.MessageFormatException) IdUndeletedStoreException(com.github.ambry.store.IdUndeletedStoreException) StoreException(com.github.ambry.store.StoreException) LocalChannelRequest(com.github.ambry.network.LocalRequestResponseChannel.LocalChannelRequest)

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