use of com.github.ambry.store.IdUndeletedStoreException in project ambry by linkedin.
the class AmbryRequests method handleUndeleteRequest.
@Override
public void handleUndeleteRequest(NetworkRequest request) throws IOException, InterruptedException {
UndeleteRequest undeleteRequest;
if (request instanceof LocalChannelRequest) {
// This is a case where handleUndeleteRequest is called when frontends are talking to 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.
undeleteRequest = (UndeleteRequest) ((LocalChannelRequest) request).getRequestInfo().getRequest();
} else {
undeleteRequest = UndeleteRequest.readFrom(new DataInputStream(request.getInputStream()), clusterMap);
}
long requestQueueTime = SystemTime.getInstance().milliseconds() - request.getStartTimeInMs();
long totalTimeSpent = requestQueueTime;
metrics.undeleteBlobRequestQueueTimeInMs.update(requestQueueTime);
metrics.undeleteBlobRequestRate.mark();
long startTime = SystemTime.getInstance().milliseconds();
UndeleteResponse response = null;
Store storeToUndelete;
StoreKey convertedStoreKey;
try {
convertedStoreKey = getConvertedStoreKeys(Collections.singletonList(undeleteRequest.getBlobId())).get(0);
ServerErrorCode error = validateRequest(undeleteRequest.getBlobId().getPartition(), RequestOrResponseType.UndeleteRequest, false);
if (error != ServerErrorCode.No_Error) {
logger.error("Validating undelete request failed with error {} for request {}", error, undeleteRequest);
response = new UndeleteResponse(undeleteRequest.getCorrelationId(), undeleteRequest.getClientId(), error);
} else {
BlobId convertedBlobId = (BlobId) convertedStoreKey;
MessageInfo info = new MessageInfo.Builder(convertedBlobId, -1, convertedBlobId.getAccountId(), convertedBlobId.getContainerId(), undeleteRequest.getOperationTimeMs()).isUndeleted(true).lifeVersion(MessageInfo.LIFE_VERSION_FROM_FRONTEND).build();
storeToUndelete = storeManager.getStore(undeleteRequest.getBlobId().getPartition());
short lifeVersion = storeToUndelete.undelete(info);
response = new UndeleteResponse(undeleteRequest.getCorrelationId(), undeleteRequest.getClientId(), lifeVersion);
if (notification != null) {
notification.onBlobReplicaUndeleted(currentNode.getHostname(), currentNode.getPort(), convertedStoreKey.getID(), BlobReplicaSourceType.PRIMARY);
}
}
} 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_Permanently) {
metrics.idDeletedError.inc();
} else if (e.getErrorCode() == StoreErrorCodes.Life_Version_Conflict) {
metrics.lifeVersionConflictError.inc();
} else if (e.getErrorCode() == StoreErrorCodes.ID_Not_Deleted) {
metrics.idNotDeletedError.inc();
} else if (e.getErrorCode() == StoreErrorCodes.ID_Undeleted) {
metrics.idUndeletedError.inc();
} else if (e.getErrorCode() == StoreErrorCodes.Authorization_Failure) {
metrics.undeleteAuthorizationFailure.inc();
} else {
logInErrorLevel = true;
metrics.unExpectedStoreUndeleteError.inc();
}
if (logInErrorLevel) {
logger.error("Store exception on a undelete with error code {} for request {}", e.getErrorCode(), undeleteRequest, e);
} else {
logger.trace("Store exception on a undelete with error code {} for request {}", e.getErrorCode(), undeleteRequest, e);
}
if (e.getErrorCode() == StoreErrorCodes.ID_Undeleted) {
if (e instanceof IdUndeletedStoreException) {
response = new UndeleteResponse(undeleteRequest.getCorrelationId(), undeleteRequest.getClientId(), ((IdUndeletedStoreException) e).getLifeVersion(), ServerErrorCode.Blob_Already_Undeleted);
} else {
response = new UndeleteResponse(undeleteRequest.getCorrelationId(), undeleteRequest.getClientId(), MessageInfo.LIFE_VERSION_FROM_FRONTEND, ServerErrorCode.Blob_Already_Undeleted);
}
} else {
response = new UndeleteResponse(undeleteRequest.getCorrelationId(), undeleteRequest.getClientId(), ErrorMapping.getStoreErrorMapping(e.getErrorCode()));
}
} catch (Exception e) {
logger.error("Unknown exception for undelete request {}", undeleteRequest, e);
response = new UndeleteResponse(undeleteRequest.getCorrelationId(), undeleteRequest.getClientId(), ServerErrorCode.Unknown_Error);
metrics.unExpectedStoreUndeleteError.inc();
} finally {
long processingTime = SystemTime.getInstance().milliseconds() - startTime;
totalTimeSpent += processingTime;
publicAccessLogger.info("{} {} processingTime {}", undeleteRequest, response, processingTime);
metrics.undeleteBlobProcessingTimeInMs.update(processingTime);
}
requestResponseChannel.sendResponse(response, request, new ServerNetworkResponseMetrics(metrics.undeleteBlobResponseQueueTimeInMs, metrics.undeleteBlobSendTimeInMs, metrics.undeleteBlobTotalTimeInMs, null, null, totalTimeSpent));
}
use of com.github.ambry.store.IdUndeletedStoreException in project ambry by linkedin.
the class AmbryServerRequestsTest method miscUndeleteFailuresTest.
/**
* Exercises various failure paths for UNDELETEs
* @throws Exception
*/
private void miscUndeleteFailuresTest() throws Exception {
PartitionId id = clusterMap.getWritablePartitionIds(DEFAULT_PARTITION_CLASS).get(0);
// store exceptions
for (StoreErrorCodes code : StoreErrorCodes.values()) {
MockStorageManager.storeException = code == StoreErrorCodes.ID_Undeleted ? new IdUndeletedStoreException("expected", (short) 1) : new StoreException("expected", code);
ServerErrorCode expectedErrorCode = ErrorMapping.getStoreErrorMapping(code);
sendAndVerifyOperationRequest(RequestOrResponseType.UndeleteRequest, Collections.singletonList(id), expectedErrorCode, true, null);
MockStorageManager.storeException = null;
}
// runtime exception
MockStorageManager.runtimeException = new RuntimeException("expected");
sendAndVerifyOperationRequest(RequestOrResponseType.UndeleteRequest, Collections.singletonList(id), ServerErrorCode.Unknown_Error, true, null);
MockStorageManager.runtimeException = null;
// store is not started/is stopped/otherwise unavailable - Replica_Unavailable
storageManager.returnNullStore = true;
sendAndVerifyOperationRequest(RequestOrResponseType.UndeleteRequest, Collections.singletonList(id), ServerErrorCode.Replica_Unavailable, false, null);
storageManager.returnNullStore = false;
// PartitionUnknown is hard to simulate without betraying knowledge of the internals of MockClusterMap.
// disk down
ReplicaId replicaId = findReplica(id);
clusterMap.onReplicaEvent(replicaId, ReplicaEventType.Disk_Error);
sendAndVerifyOperationRequest(RequestOrResponseType.UndeleteRequest, Collections.singletonList(id), ServerErrorCode.Disk_Unavailable, false, null);
clusterMap.onReplicaEvent(replicaId, ReplicaEventType.Disk_Ok);
// request disabled is checked in request control tests
}
Aggregations