Search in sources :

Example 11 with ServerErrorCode

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);
}
Also used : ServerErrorCode(com.github.ambry.server.ServerErrorCode)

Example 12 with ServerErrorCode

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);
    }
}
Also used : ArrayList(java.util.ArrayList) ServerErrorCode(com.github.ambry.server.ServerErrorCode)

Example 13 with ServerErrorCode

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);
    }
}
Also used : ReplicaType(com.github.ambry.clustermap.ReplicaType) FindToken(com.github.ambry.replication.FindToken) PartitionId(com.github.ambry.clustermap.PartitionId) FindTokenFactory(com.github.ambry.replication.FindTokenFactory) ServerErrorCode(com.github.ambry.server.ServerErrorCode)

Example 14 with ServerErrorCode

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();
}
Also used : DeleteRequest(com.github.ambry.protocol.DeleteRequest) ReplicaId(com.github.ambry.clustermap.ReplicaId) ServerErrorCode(com.github.ambry.server.ServerErrorCode)

Example 15 with ServerErrorCode

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();
        }
    }
}
Also used : KMSConfig(com.github.ambry.config.KMSConfig) ResponseHandler(com.github.ambry.commons.ResponseHandler) ArrayList(java.util.ArrayList) BlobProperties(com.github.ambry.messageformat.BlobProperties) Properties(java.util.Properties) VerifiableProperties(com.github.ambry.config.VerifiableProperties) VerifiableProperties(com.github.ambry.config.VerifiableProperties) SocketNetworkClient(com.github.ambry.network.SocketNetworkClient) ReplicaId(com.github.ambry.clustermap.ReplicaId) ServerErrorCode(com.github.ambry.server.ServerErrorCode) RouterConfig(com.github.ambry.config.RouterConfig) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) LoggingNotificationSystem(com.github.ambry.commons.LoggingNotificationSystem) JSONObject(org.json.JSONObject) BlobId(com.github.ambry.commons.BlobId) Test(org.junit.Test)

Aggregations

ServerErrorCode (com.github.ambry.server.ServerErrorCode)56 ArrayList (java.util.ArrayList)21 Test (org.junit.Test)20 DataInputStream (java.io.DataInputStream)16 BlobProperties (com.github.ambry.messageformat.BlobProperties)12 IOException (java.io.IOException)11 HashMap (java.util.HashMap)11 BlobId (com.github.ambry.commons.BlobId)10 VerifiableProperties (com.github.ambry.config.VerifiableProperties)10 MessageFormatException (com.github.ambry.messageformat.MessageFormatException)9 NettyByteBufDataInputStream (com.github.ambry.utils.NettyByteBufDataInputStream)9 MockClusterMap (com.github.ambry.clustermap.MockClusterMap)8 LoggingNotificationSystem (com.github.ambry.commons.LoggingNotificationSystem)8 RouterConfig (com.github.ambry.config.RouterConfig)8 Map (java.util.Map)8 Properties (java.util.Properties)8 DataNodeId (com.github.ambry.clustermap.DataNodeId)7 PartitionId (com.github.ambry.clustermap.PartitionId)7 MessageInfo (com.github.ambry.store.MessageInfo)7 IdUndeletedStoreException (com.github.ambry.store.IdUndeletedStoreException)6