use of com.github.ambry.server.ServerErrorCode in project ambry by linkedin.
the class AdminResponse method readFrom.
/**
* Reads from a stream and constructs an {@link AdminResponse}.
* @param stream the {@link DataInputStream} to read from.
* @return {@link AdminResponse} that is deserialized from the {@code stream}.
* @throws IOException if there is an I/O error reading from {@code stream}
*/
public static AdminResponse readFrom(DataInputStream stream) throws IOException {
RequestOrResponseType type = RequestOrResponseType.values()[stream.readShort()];
if (type != RequestOrResponseType.AdminResponse) {
throw new IllegalArgumentException("The type of request response is not compatible (is " + type + ")");
}
Short versionId = stream.readShort();
if (!versionId.equals(ADMIN_RESPONSE_VERSION_V1)) {
throw new IllegalStateException("Unrecognized version for AdminResponse: " + versionId);
}
int correlationId = stream.readInt();
String clientId = Utils.readIntString(stream);
ServerErrorCode error = ServerErrorCode.values()[stream.readShort()];
// ignore version for now
return new AdminResponse(correlationId, clientId, error);
}
use of com.github.ambry.server.ServerErrorCode in project ambry by linkedin.
the class GetResponse method readFrom.
public static GetResponse readFrom(DataInputStream stream, ClusterMap map) throws IOException {
short typeval = stream.readShort();
RequestOrResponseType type = RequestOrResponseType.values()[typeval];
if (type != RequestOrResponseType.GetResponse) {
throw new IllegalArgumentException("The type of request response is not compatible");
}
Short versionId = stream.readShort();
// ignore version for now
int correlationId = stream.readInt();
String clientId = Utils.readIntString(stream);
ServerErrorCode error = ServerErrorCode.values()[stream.readShort()];
if (error != ServerErrorCode.No_Error) {
return new GetResponse(correlationId, clientId, error);
} else {
int partitionResponseInfoCount = stream.readInt();
ArrayList<PartitionResponseInfo> partitionResponseInfoList = new ArrayList<PartitionResponseInfo>(partitionResponseInfoCount);
for (int i = 0; i < partitionResponseInfoCount; i++) {
PartitionResponseInfo partitionResponseInfo = PartitionResponseInfo.readFrom(stream, map, versionId);
partitionResponseInfoList.add(partitionResponseInfo);
}
return new GetResponse(correlationId, clientId, partitionResponseInfoList, stream, error);
}
}
use of com.github.ambry.server.ServerErrorCode in project ambry by linkedin.
the class ReplicaMetadataResponseInfo method readFrom.
public static ReplicaMetadataResponseInfo readFrom(DataInputStream stream, FindTokenHelper helper, ClusterMap clusterMap, short replicaMetadataResponseVersion) throws IOException {
PartitionId partitionId = clusterMap.getPartitionIdFromStream(stream);
ReplicaType replicaType;
if (replicaMetadataResponseVersion == ReplicaMetadataResponse.REPLICA_METADATA_RESPONSE_VERSION_V_6) {
replicaType = ReplicaType.values()[stream.readShort()];
} else {
// before REPLICA_METADATA_RESPONSE_VERSION_V_6 there were only disk based replicas
replicaType = ReplicaType.DISK_BACKED;
}
ServerErrorCode error = ServerErrorCode.values()[stream.readShort()];
if (error != ServerErrorCode.No_Error) {
return new ReplicaMetadataResponseInfo(partitionId, replicaType, error, replicaMetadataResponseVersion);
} else {
FindTokenFactory findTokenFactory = helper.getFindTokenFactoryFromReplicaType(replicaType);
FindToken token = findTokenFactory.getFindToken(stream);
MessageInfoAndMetadataListSerde messageInfoAndMetadataList = MessageInfoAndMetadataListSerde.deserializeMessageInfoAndMetadataList(stream, clusterMap, getMessageInfoAndMetadataListSerDeVersion(replicaMetadataResponseVersion));
long remoteReplicaLag = stream.readLong();
return new ReplicaMetadataResponseInfo(partitionId, replicaType, token, messageInfoAndMetadataList.getMessageInfoList(), remoteReplicaLag, replicaMetadataResponseVersion);
}
}
use of com.github.ambry.server.ServerErrorCode in project ambry by linkedin.
the class DeleteOperation method handleResponse.
/**
* Handles a response for a delete operation. It determines whether the request was successful,
* updates operation tracker, and notifies the response handler for failure detection.
* can be different cases during handling a response. For the same delete operation, it is possible
* that different {@link ServerErrorCode} are received from different replicas. These error codes
* are eventually resolved to a single {@link RouterErrorCode}.
* @param responseInfo The {@link ResponseInfo} to be handled.
* @param deleteResponse The {@link DeleteResponse} associated with this response.
*/
void handleResponse(ResponseInfo responseInfo, DeleteResponse deleteResponse) {
DeleteRequest deleteRequest = (DeleteRequest) responseInfo.getRequestInfo().getRequest();
DeleteRequestInfo deleteRequestInfo = deleteRequestInfos.remove(deleteRequest.getCorrelationId());
// metric is updated here, as corresponding metrics have been updated when the request was timed out.
if (deleteRequestInfo == null) {
return;
}
ReplicaId replica = deleteRequestInfo.replica;
long requestLatencyMs = time.milliseconds() - deleteRequestInfo.startTimeMs;
routerMetrics.routerRequestLatencyMs.update(requestLatencyMs);
routerMetrics.getDataNodeBasedMetrics(replica.getDataNodeId()).deleteRequestLatencyMs.update(requestLatencyMs);
// Check the error code from NetworkClient.
if (responseInfo.getError() != null) {
logger.trace("DeleteRequest with response correlationId {} timed out for replica {} ", deleteRequest.getCorrelationId(), replica.getDataNodeId());
onErrorResponse(replica, new RouterException("Operation to delete " + blobId + " timed out because of " + responseInfo.getError() + " at DataNode " + responseInfo.getDataNode(), RouterErrorCode.OperationTimedOut));
} else {
if (deleteResponse == null) {
logger.trace("DeleteRequest with response correlationId {} received UnexpectedInternalError on response deserialization for replica {} ", deleteRequest.getCorrelationId(), replica.getDataNodeId());
onErrorResponse(replica, new RouterException("Response deserialization received an unexpected error", RouterErrorCode.UnexpectedInternalError));
} else {
// not for its original request. We will immediately fail this operation.
if (deleteResponse.getCorrelationId() != deleteRequest.getCorrelationId()) {
logger.error("The correlation id in the DeleteResponse {} is not the same as the correlation id in the associated DeleteRequest: {}", deleteResponse.getCorrelationId(), deleteRequest.getCorrelationId());
routerMetrics.unknownReplicaResponseError.inc();
onErrorResponse(replica, new RouterException("Received wrong response that is not for the corresponding request.", RouterErrorCode.UnexpectedInternalError));
} else {
ServerErrorCode serverError = deleteResponse.getError();
if (serverError == ServerErrorCode.No_Error || serverError == ServerErrorCode.Blob_Deleted) {
operationTracker.onResponse(replica, TrackedRequestFinalState.SUCCESS);
if (RouterUtils.isRemoteReplica(routerConfig, replica)) {
logger.trace("Cross colo request successful for remote replica {} in {} ", replica.getDataNodeId(), replica.getDataNodeId().getDatacenterName());
routerMetrics.crossColoSuccessCount.inc();
}
} else if (serverError == ServerErrorCode.Disk_Unavailable) {
logger.trace("Replica {} returned Disk_Unavailable for a delete request with correlationId : {} ", replica, deleteRequest.getCorrelationId());
operationTracker.onResponse(replica, TrackedRequestFinalState.DISK_DOWN);
setOperationException(new RouterException("Server returned: " + serverError, RouterErrorCode.AmbryUnavailable));
routerMetrics.routerRequestErrorCount.inc();
routerMetrics.getDataNodeBasedMetrics(replica.getDataNodeId()).deleteRequestErrorCount.inc();
} else {
logger.trace("Replica {} returned an error {} for a delete request with response correlationId : {} ", replica, serverError, deleteRequest.getCorrelationId());
RouterErrorCode routerErrorCode = processServerError(serverError);
if (serverError == ServerErrorCode.Blob_Authorization_Failure) {
// this is a successful response and one that completes the operation regardless of whether the
// success target has been reached or not.
operationCompleted = true;
}
// any server error code that is not equal to ServerErrorCode.No_Error, the onErrorResponse should be invoked
onErrorResponse(replica, new RouterException("Server returned: " + serverError, routerErrorCode));
}
}
}
}
checkAndMaybeComplete();
}
use of com.github.ambry.server.ServerErrorCode in project ambry by linkedin.
the class NonBlockingRouterTest method testResponseHandling.
/**
* Response handling related tests for all operation managers.
*/
@Test
public void testResponseHandling() throws Exception {
try {
Properties props = getNonBlockingRouterProperties("DC1");
VerifiableProperties verifiableProperties = new VerifiableProperties((props));
setOperationParams();
final List<ReplicaId> failedReplicaIds = new ArrayList<>();
final AtomicInteger successfulResponseCount = new AtomicInteger(0);
final AtomicBoolean invalidResponse = new AtomicBoolean(false);
ResponseHandler mockResponseHandler = new ResponseHandler(mockClusterMap) {
@Override
public void onEvent(ReplicaId replicaId, Object e) {
if (e instanceof ServerErrorCode) {
if (e == ServerErrorCode.No_Error) {
successfulResponseCount.incrementAndGet();
} else {
invalidResponse.set(true);
}
} else {
failedReplicaIds.add(replicaId);
}
}
};
// Instantiate a router just to put a blob successfully.
MockServerLayout mockServerLayout = new MockServerLayout(mockClusterMap);
setRouter(props, mockServerLayout, new LoggingNotificationSystem());
setOperationParams();
// More extensive test for puts present elsewhere - these statements are here just to exercise the flow within the
// NonBlockingRouter class, and to ensure that operations submitted to a router eventually completes.
String blobIdStr = router.putBlob(putBlobProperties, putUserMetadata, putChannel, new PutBlobOptionsBuilder().build()).get();
BlobId blobId = RouterUtils.getBlobIdFromString(blobIdStr, mockClusterMap);
router.close();
for (MockServer mockServer : mockServerLayout.getMockServers()) {
mockServer.setServerErrorForAllRequests(ServerErrorCode.No_Error);
}
SocketNetworkClient networkClient = new MockNetworkClientFactory(verifiableProperties, mockSelectorState, MAX_PORTS_PLAIN_TEXT, MAX_PORTS_SSL, CHECKOUT_TIMEOUT_MS, mockServerLayout, mockTime).getNetworkClient();
cryptoJobHandler = new CryptoJobHandler(CryptoJobHandlerTest.DEFAULT_THREAD_COUNT);
KeyManagementService localKMS = new MockKeyManagementService(new KMSConfig(verifiableProperties), singleKeyForKMS);
putManager = new PutManager(mockClusterMap, mockResponseHandler, new LoggingNotificationSystem(), new RouterConfig(verifiableProperties), new NonBlockingRouterMetrics(mockClusterMap, null), new RouterCallback(networkClient, new ArrayList<>()), "0", localKMS, cryptoService, cryptoJobHandler, accountService, mockTime, MockClusterMap.DEFAULT_PARTITION_CLASS);
OperationHelper opHelper = new OperationHelper(OperationType.PUT);
testFailureDetectorNotification(opHelper, networkClient, failedReplicaIds, null, successfulResponseCount, invalidResponse, -1);
// Test that if a failed response comes before the operation is completed, failure detector is notified.
testFailureDetectorNotification(opHelper, networkClient, failedReplicaIds, null, successfulResponseCount, invalidResponse, 0);
// Test that if a failed response comes after the operation is completed, failure detector is notified.
testFailureDetectorNotification(opHelper, networkClient, failedReplicaIds, null, successfulResponseCount, invalidResponse, PUT_REQUEST_PARALLELISM - 1);
testNoResponseNoNotification(opHelper, failedReplicaIds, null, successfulResponseCount, invalidResponse);
testResponseDeserializationError(opHelper, networkClient, null);
opHelper = new OperationHelper(OperationType.GET);
getManager = new GetManager(mockClusterMap, mockResponseHandler, new RouterConfig(verifiableProperties), new NonBlockingRouterMetrics(mockClusterMap, null), new RouterCallback(networkClient, new ArrayList<BackgroundDeleteRequest>()), localKMS, cryptoService, cryptoJobHandler, mockTime);
testFailureDetectorNotification(opHelper, networkClient, failedReplicaIds, blobId, successfulResponseCount, invalidResponse, -1);
// Test that if a failed response comes before the operation is completed, failure detector is notified.
testFailureDetectorNotification(opHelper, networkClient, failedReplicaIds, blobId, successfulResponseCount, invalidResponse, 0);
// Test that if a failed response comes after the operation is completed, failure detector is notified.
testFailureDetectorNotification(opHelper, networkClient, failedReplicaIds, blobId, successfulResponseCount, invalidResponse, GET_REQUEST_PARALLELISM - 1);
testNoResponseNoNotification(opHelper, failedReplicaIds, blobId, successfulResponseCount, invalidResponse);
testResponseDeserializationError(opHelper, networkClient, blobId);
opHelper = new OperationHelper(OperationType.DELETE);
deleteManager = new DeleteManager(mockClusterMap, mockResponseHandler, accountService, new LoggingNotificationSystem(), new RouterConfig(verifiableProperties), new NonBlockingRouterMetrics(mockClusterMap, null), new RouterCallback(null, new ArrayList<BackgroundDeleteRequest>()), mockTime);
testFailureDetectorNotification(opHelper, networkClient, failedReplicaIds, blobId, successfulResponseCount, invalidResponse, -1);
// Test that if a failed response comes before the operation is completed, failure detector is notified.
testFailureDetectorNotification(opHelper, networkClient, failedReplicaIds, blobId, successfulResponseCount, invalidResponse, 0);
// Test that if a failed response comes after the operation is completed, failure detector is notified.
testFailureDetectorNotification(opHelper, networkClient, failedReplicaIds, blobId, successfulResponseCount, invalidResponse, DELETE_REQUEST_PARALLELISM - 1);
testNoResponseNoNotification(opHelper, failedReplicaIds, blobId, successfulResponseCount, invalidResponse);
testResponseDeserializationError(opHelper, networkClient, blobId);
} finally {
if (putManager != null) {
putManager.close();
}
if (getManager != null) {
getManager.close();
}
if (deleteManager != null) {
deleteManager.close();
}
}
}
Aggregations