Search in sources :

Example 6 with Response

use of com.couchbase.client.core.msg.Response in project couchbase-jvm-clients by couchbase.

the class KeyValueMessageHandler method write.

@Override
@SuppressWarnings({ "unchecked" })
public void write(final ChannelHandlerContext ctx, final Object msg, final ChannelPromise promise) {
    if (msg instanceof KeyValueRequest) {
        KeyValueRequest<Response> request = (KeyValueRequest<Response>) msg;
        int opaque = request.opaque();
        writtenRequests.put(opaque, request);
        try {
            ctx.write(request.encode(ctx.alloc(), opaque, channelContext), promise);
            writtenRequestDispatchTimings.put(opaque, (Long) System.nanoTime());
            if (request.requestSpan() != null) {
                RequestTracer tracer = endpointContext.environment().requestTracer();
                RequestSpan dispatchSpan = tracer.requestSpan(TracingIdentifiers.SPAN_DISPATCH, request.requestSpan());
                if (!isInternalTracer) {
                    setCommonDispatchSpanAttributes(dispatchSpan, ctx.channel().attr(ChannelAttributes.CHANNEL_ID_KEY).get(), ioContext.localHostname(), ioContext.localPort(), endpoint.remoteHostname(), endpoint.remotePort(), null);
                    setNumericOperationId(dispatchSpan, request.opaque());
                    setCommonKVSpanAttributes(dispatchSpan, request);
                }
                writtenRequestDispatchSpans.put(opaque, dispatchSpan);
            }
        } catch (Throwable err) {
            writtenRequests.remove(opaque);
            if (err instanceof CollectionNotFoundException) {
                if (channelContext.collectionsEnabled()) {
                    ConfigurationProvider cp = ioContext.core().configurationProvider();
                    if (cp.collectionRefreshInProgress(request.collectionIdentifier())) {
                        RetryOrchestrator.maybeRetry(ioContext, request, RetryReason.COLLECTION_MAP_REFRESH_IN_PROGRESS);
                    } else if (cp.config().bucketConfig(request.bucket()) instanceof MemcachedBucketConfig) {
                        request.fail(FeatureNotAvailableException.collectionsForMemcached());
                    } else {
                        handleOutdatedCollection(request, RetryReason.COLLECTION_NOT_FOUND);
                    }
                    return;
                }
            }
            request.fail(err);
        }
    } else {
        eventBus.publish(new InvalidRequestDetectedEvent(ioContext, ServiceType.KV, msg));
        ctx.channel().close().addListener(f -> eventBus.publish(new ChannelClosedProactivelyEvent(ioContext, ChannelClosedProactivelyEvent.Reason.INVALID_REQUEST_DETECTED)));
    }
}
Also used : Response(com.couchbase.client.core.msg.Response) KeyValueRequest(com.couchbase.client.core.msg.kv.KeyValueRequest) ChannelClosedProactivelyEvent(com.couchbase.client.core.cnc.events.io.ChannelClosedProactivelyEvent) ConfigurationProvider(com.couchbase.client.core.config.ConfigurationProvider) MemcachedBucketConfig(com.couchbase.client.core.config.MemcachedBucketConfig) RequestTracer(com.couchbase.client.core.cnc.RequestTracer) BaseEndpoint(com.couchbase.client.core.endpoint.BaseEndpoint) CollectionNotFoundException(com.couchbase.client.core.error.CollectionNotFoundException) InvalidRequestDetectedEvent(com.couchbase.client.core.cnc.events.io.InvalidRequestDetectedEvent) RequestSpan(com.couchbase.client.core.cnc.RequestSpan)

Example 7 with Response

use of com.couchbase.client.core.msg.Response in project couchbase-jvm-clients by couchbase.

the class KeyValueMessageHandler method decode.

/**
 * Main method to start dispatching the decode.
 *
 * @param ctx the channel handler context from netty.
 * @param response the response to decode and handle.
 */
private void decode(final ChannelHandlerContext ctx, final ByteBuf response) {
    int opaque = MemcacheProtocol.opaque(response);
    KeyValueRequest<Response> request = writtenRequests.remove(opaque);
    if (request == null) {
        handleUnknownResponseReceived(ctx, response);
        return;
    }
    long serverTime = MemcacheProtocol.parseServerDurationFromResponse(response);
    request.context().serverLatency(serverTime);
    long start = writtenRequestDispatchTimings.remove(opaque);
    request.context().dispatchLatency(System.nanoTime() - start);
    RequestSpan dispatchSpan = writtenRequestDispatchSpans.remove(opaque);
    if (dispatchSpan != null) {
        if (!isInternalTracer) {
            TracingUtils.setServerDurationAttribute(dispatchSpan, serverTime);
        }
        dispatchSpan.end();
    }
    short statusCode = MemcacheProtocol.status(response);
    ResponseStatus status = MemcacheProtocol.decodeStatus(statusCode);
    ErrorMap.ErrorCode errorCode = status != ResponseStatus.SUCCESS ? decodeErrorCode(statusCode) : null;
    if (errorCode != null) {
        request.errorCode(errorCode);
    }
    boolean errorUnknown = false;
    if (status == ResponseStatus.UNKNOWN) {
        errorUnknown = true;
        if (errorCode != null) {
            ioContext.environment().eventBus().publish(new KeyValueErrorMapCodeHandledEvent(ioContext, errorCode));
            status = handleErrorCode(ctx, errorCode);
        }
        ioContext.environment().eventBus().publish(new UnknownResponseStatusReceivedEvent(ioContext, statusCode));
    }
    if (status == ResponseStatus.NOT_MY_VBUCKET) {
        handleNotMyVbucket(request, response);
    } else if (status == ResponseStatus.UNKNOWN_COLLECTION) {
        handleOutdatedCollection(request, RetryReason.KV_COLLECTION_OUTDATED);
    } else if (errorUnknown && errorMapIndicatesRetry(errorCode)) {
        RetryOrchestrator.maybeRetry(ioContext, request, RetryReason.KV_ERROR_MAP_INDICATED);
    } else if (statusIndicatesInvalidChannel(status)) {
        closeChannelWithReason(ioContext, ctx, ChannelClosedProactivelyEvent.Reason.KV_RESPONSE_CONTAINED_CLOSE_INDICATION);
    } else {
        RetryReason retryReason = statusCodeIndicatesRetry(status, request);
        if (retryReason == null) {
            if (!request.completed()) {
                decodeAndComplete(request, response);
            } else {
                ioContext.environment().orphanReporter().report(request);
            }
        } else {
            RetryOrchestrator.maybeRetry(ioContext, request, retryReason);
        }
    }
}
Also used : BaseEndpoint(com.couchbase.client.core.endpoint.BaseEndpoint) RequestSpan(com.couchbase.client.core.cnc.RequestSpan) Response(com.couchbase.client.core.msg.Response) RetryReason(com.couchbase.client.core.retry.RetryReason) ResponseStatus(com.couchbase.client.core.msg.ResponseStatus) UnknownResponseStatusReceivedEvent(com.couchbase.client.core.cnc.events.io.UnknownResponseStatusReceivedEvent) KeyValueErrorMapCodeHandledEvent(com.couchbase.client.core.cnc.events.io.KeyValueErrorMapCodeHandledEvent)

Example 8 with Response

use of com.couchbase.client.core.msg.Response in project couchbase-jvm-clients by couchbase.

the class KeyValueMessageHandler method handleNotMyVbucket.

/**
 * Helper method to handle a "not my vbucket" response.
 *
 * @param request the request to retry.
 * @param response the response to extract the config from, potentially.
 */
private void handleNotMyVbucket(final KeyValueRequest<Response> request, final ByteBuf response) {
    request.indicateRejectedWithNotMyVbucket();
    eventBus.publish(new NotMyVbucketReceivedEvent(ioContext, request.partition()));
    final String origin = request.context().lastDispatchedTo() != null ? request.context().lastDispatchedTo().hostname() : null;
    RetryOrchestrator.maybeRetry(ioContext, request, RetryReason.KV_NOT_MY_VBUCKET);
    body(response).map(b -> b.toString(UTF_8).trim()).filter(c -> c.startsWith("{")).ifPresent(c -> ioContext.core().configurationProvider().proposeBucketConfig(new ProposedBucketConfigContext(request.bucket(), c, origin)));
}
Also used : IoContext(com.couchbase.client.core.io.IoContext) UnsignedLEB128(com.couchbase.client.core.util.UnsignedLEB128) HandlerUtils.closeChannelWithReason(com.couchbase.client.core.io.netty.HandlerUtils.closeChannelWithReason) ReferenceCountUtil(com.couchbase.client.core.deps.io.netty.util.ReferenceCountUtil) Request(com.couchbase.client.core.msg.Request) CompressionConfig(com.couchbase.client.core.env.CompressionConfig) RETRY_NOW(com.couchbase.client.core.io.netty.kv.ErrorMap.ErrorAttribute.RETRY_NOW) EventBus(com.couchbase.client.core.cnc.EventBus) TracingUtils.setCommonKVSpanAttributes(com.couchbase.client.core.io.netty.TracingUtils.setCommonKVSpanAttributes) ServiceType(com.couchbase.client.core.service.ServiceType) CoreContext(com.couchbase.client.core.CoreContext) Map(java.util.Map) TracingUtils.setCommonDispatchSpanAttributes(com.couchbase.client.core.io.netty.TracingUtils.setCommonDispatchSpanAttributes) EndpointContext(com.couchbase.client.core.endpoint.EndpointContext) ITEM_LOCKED(com.couchbase.client.core.io.netty.kv.ErrorMap.ErrorAttribute.ITEM_LOCKED) RequestSpan(com.couchbase.client.core.cnc.RequestSpan) CbTracing(com.couchbase.client.core.cnc.CbTracing) RetryOrchestrator(com.couchbase.client.core.retry.RetryOrchestrator) ChannelHandlerContext(com.couchbase.client.core.deps.io.netty.channel.ChannelHandlerContext) TEMP(com.couchbase.client.core.io.netty.kv.ErrorMap.ErrorAttribute.TEMP) BaseEndpoint(com.couchbase.client.core.endpoint.BaseEndpoint) Set(java.util.Set) KeyValueRequest(com.couchbase.client.core.msg.kv.KeyValueRequest) Collectors(java.util.stream.Collectors) TracingUtils(com.couchbase.client.core.io.netty.TracingUtils) RetryReason(com.couchbase.client.core.retry.RetryReason) ResponseStatus(com.couchbase.client.core.msg.ResponseStatus) DecodingFailureException(com.couchbase.client.core.error.DecodingFailureException) Optional(java.util.Optional) ChannelPromise(com.couchbase.client.core.deps.io.netty.channel.ChannelPromise) Response(com.couchbase.client.core.msg.Response) TracingUtils.setNumericOperationId(com.couchbase.client.core.io.netty.TracingUtils.setNumericOperationId) CollectionNotFoundException(com.couchbase.client.core.error.CollectionNotFoundException) UnsupportedResponseTypeReceivedEvent(com.couchbase.client.core.cnc.events.io.UnsupportedResponseTypeReceivedEvent) HashMap(java.util.HashMap) KeyValueErrorMapCodeHandledEvent(com.couchbase.client.core.cnc.events.io.KeyValueErrorMapCodeHandledEvent) IntObjectMap(com.couchbase.client.core.deps.io.netty.util.collection.IntObjectMap) TracingIdentifiers(com.couchbase.client.core.cnc.TracingIdentifiers) RETRY_LATER(com.couchbase.client.core.io.netty.kv.ErrorMap.ErrorAttribute.RETRY_LATER) NotMyVbucketReceivedEvent(com.couchbase.client.core.cnc.events.io.NotMyVbucketReceivedEvent) MemcachedBucketConfig(com.couchbase.client.core.config.MemcachedBucketConfig) ProposedBucketConfigContext(com.couchbase.client.core.config.ProposedBucketConfigContext) ByteBuf(com.couchbase.client.core.deps.io.netty.buffer.ByteBuf) ChannelDuplexHandler(com.couchbase.client.core.deps.io.netty.channel.ChannelDuplexHandler) CollectionOutdatedHandledEvent(com.couchbase.client.core.cnc.events.io.CollectionOutdatedHandledEvent) RequestTracer(com.couchbase.client.core.cnc.RequestTracer) InvalidRequestDetectedEvent(com.couchbase.client.core.cnc.events.io.InvalidRequestDetectedEvent) ConfigurationProvider(com.couchbase.client.core.config.ConfigurationProvider) UnknownResponseReceivedEvent(com.couchbase.client.core.cnc.events.io.UnknownResponseReceivedEvent) UTF_8(java.nio.charset.StandardCharsets.UTF_8) FeatureNotAvailableException(com.couchbase.client.core.error.FeatureNotAvailableException) UnlockRequest(com.couchbase.client.core.msg.kv.UnlockRequest) CollectionMap(com.couchbase.client.core.io.CollectionMap) ByteBufUtil(com.couchbase.client.core.deps.io.netty.buffer.ByteBufUtil) CONN_STATE_INVALIDATED(com.couchbase.client.core.io.netty.kv.ErrorMap.ErrorAttribute.CONN_STATE_INVALIDATED) UnknownResponseStatusReceivedEvent(com.couchbase.client.core.cnc.events.io.UnknownResponseStatusReceivedEvent) ChannelClosedProactivelyEvent(com.couchbase.client.core.cnc.events.io.ChannelClosedProactivelyEvent) IntObjectHashMap(com.couchbase.client.core.deps.io.netty.util.collection.IntObjectHashMap) AUTH(com.couchbase.client.core.io.netty.kv.ErrorMap.ErrorAttribute.AUTH) MemcacheProtocol.body(com.couchbase.client.core.io.netty.kv.MemcacheProtocol.body) NotMyVbucketReceivedEvent(com.couchbase.client.core.cnc.events.io.NotMyVbucketReceivedEvent) ProposedBucketConfigContext(com.couchbase.client.core.config.ProposedBucketConfigContext)

Example 9 with Response

use of com.couchbase.client.core.msg.Response in project couchbase-jvm-clients by couchbase.

the class NodeTest method retriesIfGlobalServiceNotFound.

@Test
void retriesIfGlobalServiceNotFound() {
    final Service s = mock(Service.class);
    final AtomicReference<Request<?>> retried = new AtomicReference<>();
    Node node = new Node(CTX, mock(NodeIdentifier.class), NO_ALTERNATE) {

        @Override
        protected Service createService(ServiceType serviceType, int port, Optional<String> bucket) {
            when(s.state()).thenReturn(ServiceState.CONNECTED);
            when(s.states()).thenReturn(DirectProcessor.create());
            when(s.type()).thenReturn(serviceType);
            return s;
        }

        @Override
        protected <R extends Request<? extends Response>> void sendIntoRetry(R request) {
            retried.set(request);
        }
    };
    QueryRequest r = mock(QueryRequest.class);
    when(r.serviceType()).thenReturn(ServiceType.QUERY);
    node.send(r);
    verify(s, never()).send(eq(r));
    assertEquals(r, retried.get());
}
Also used : Response(com.couchbase.client.core.msg.Response) Optional(java.util.Optional) QueryRequest(com.couchbase.client.core.msg.query.QueryRequest) ServiceType(com.couchbase.client.core.service.ServiceType) QueryRequest(com.couchbase.client.core.msg.query.QueryRequest) Request(com.couchbase.client.core.msg.Request) KeyValueRequest(com.couchbase.client.core.msg.kv.KeyValueRequest) Service(com.couchbase.client.core.service.Service) AtomicReference(java.util.concurrent.atomic.AtomicReference) Test(org.junit.jupiter.api.Test)

Example 10 with Response

use of com.couchbase.client.core.msg.Response in project couchbase-jvm-clients by couchbase.

the class KeyValueMessageHandler method decodeAndComplete.

/**
 * Tries to decode the response and succeed the request.
 * <p>
 * If decoding fails, will fail the underlying request as well.
 *
 * @param request the request to decode and complete.
 * @param response the raw response to decode.
 */
private void decodeAndComplete(final KeyValueRequest<Response> request, final ByteBuf response) {
    try {
        Response decoded = request.decode(response, channelContext);
        request.succeed(decoded);
    } catch (Throwable t) {
        request.fail(new DecodingFailureException(t));
    }
}
Also used : Response(com.couchbase.client.core.msg.Response) DecodingFailureException(com.couchbase.client.core.error.DecodingFailureException)

Aggregations

Response (com.couchbase.client.core.msg.Response)12 ChannelClosedProactivelyEvent (com.couchbase.client.core.cnc.events.io.ChannelClosedProactivelyEvent)4 InvalidRequestDetectedEvent (com.couchbase.client.core.cnc.events.io.InvalidRequestDetectedEvent)4 Request (com.couchbase.client.core.msg.Request)4 KeyValueRequest (com.couchbase.client.core.msg.kv.KeyValueRequest)4 RequestSpan (com.couchbase.client.core.cnc.RequestSpan)3 RequestTracer (com.couchbase.client.core.cnc.RequestTracer)3 UnsupportedResponseTypeReceivedEvent (com.couchbase.client.core.cnc.events.io.UnsupportedResponseTypeReceivedEvent)3 BaseEndpoint (com.couchbase.client.core.endpoint.BaseEndpoint)3 ResponseStatus (com.couchbase.client.core.msg.ResponseStatus)3 RetryReason (com.couchbase.client.core.retry.RetryReason)3 ServiceType (com.couchbase.client.core.service.ServiceType)3 Optional (java.util.Optional)3 KeyValueErrorMapCodeHandledEvent (com.couchbase.client.core.cnc.events.io.KeyValueErrorMapCodeHandledEvent)2 UnknownResponseStatusReceivedEvent (com.couchbase.client.core.cnc.events.io.UnknownResponseStatusReceivedEvent)2 ConfigurationProvider (com.couchbase.client.core.config.ConfigurationProvider)2 MemcachedBucketConfig (com.couchbase.client.core.config.MemcachedBucketConfig)2 FullHttpRequest (com.couchbase.client.core.deps.io.netty.handler.codec.http.FullHttpRequest)2 FullHttpResponse (com.couchbase.client.core.deps.io.netty.handler.codec.http.FullHttpResponse)2 HttpResponse (com.couchbase.client.core.deps.io.netty.handler.codec.http.HttpResponse)2