public short apiVersion() { // Use v0 when serializing an unhandled ApiVersion response if (isUnsupportedApiVersionsRequest()) return 0; return header.apiVersion(); }
private boolean isUnsupportedApiVersionsRequest() { return header.apiKey() == API_VERSIONS && !API_VERSIONS.isVersionSupported(header.apiVersion()); }
public static AbstractResponse parseResponse(ByteBuffer responseBuffer, RequestHeader requestHeader) { Struct responseStruct = parseStructMaybeUpdateThrottleTimeMetrics(responseBuffer, requestHeader, null, 0); return AbstractResponse.parseResponse(requestHeader.apiKey(), responseStruct, requestHeader.apiVersion()); }
private String handleHandshakeRequest(RequestContext context, SaslHandshakeRequest handshakeRequest) throws IOException, UnsupportedSaslMechanismException { String clientMechanism = handshakeRequest.mechanism(); short version = context.header.apiVersion(); if (version >= 1) this.enableKafkaSaslAuthenticateHeaders(true); if (enabledMechanisms.contains(clientMechanism)) { LOG.debug("Using SASL mechanism '{}' provided by client", clientMechanism); sendKafkaResponse(context, new SaslHandshakeResponse(Errors.NONE, enabledMechanisms)); return clientMechanism; } else { LOG.debug("SASL mechanism '{}' requested by client is not supported", clientMechanism); buildResponseOnAuthenticateFailure(context, new SaslHandshakeResponse(Errors.UNSUPPORTED_SASL_MECHANISM, enabledMechanisms)); throw new UnsupportedSaslMechanismException("Unsupported SASL mechanism " + clientMechanism); } }
public RequestAndSize parseRequest(ByteBuffer buffer) { if (isUnsupportedApiVersionsRequest()) { // Unsupported ApiVersion requests are treated as v0 requests and are not parsed ApiVersionsRequest apiVersionsRequest = new ApiVersionsRequest((short) 0, header.apiVersion()); return new RequestAndSize(apiVersionsRequest, 0); } else { ApiKeys apiKey = header.apiKey(); try { short apiVersion = header.apiVersion(); Struct struct = apiKey.parseRequest(apiVersion, buffer); AbstractRequest body = AbstractRequest.parseRequest(apiKey, apiVersion, struct); return new RequestAndSize(body, struct.sizeOf()); } catch (Throwable ex) { throw new InvalidRequestException("Error getting request for apiKey: " + apiKey + ", apiVersion: " + header.apiVersion() + ", connectionId: " + connectionId + ", listenerName: " + listenerName + ", principal: " + principal, ex); } } }
@Override public void onSuccess(ClientResponse resp) { synchronized (Fetcher.this) { @SuppressWarnings("unchecked") FetchResponse<Records> response = (FetchResponse<Records>) resp.responseBody(); FetchSessionHandler handler = sessionHandler(fetchTarget.id()); if (handler == null) { log.error("Unable to find FetchSessionHandler for node {}. Ignoring fetch response.", fetchTarget.id()); return; } if (!handler.handleResponse(response)) { return; } Set<TopicPartition> partitions = new HashSet<>(response.responseData().keySet()); FetchResponseMetricAggregator metricAggregator = new FetchResponseMetricAggregator(sensors, partitions); for (Map.Entry<TopicPartition, FetchResponse.PartitionData<Records>> entry : response.responseData().entrySet()) { TopicPartition partition = entry.getKey(); long fetchOffset = data.sessionPartitions().get(partition).fetchOffset; FetchResponse.PartitionData<Records> fetchData = entry.getValue(); log.debug("Fetch {} at offset {} for partition {} returned fetch data {}", isolationLevel, fetchOffset, partition, fetchData); completedFetches.add(new CompletedFetch(partition, fetchOffset, fetchData, metricAggregator, resp.requestHeader().apiVersion())); } sensors.fetchLatency.record(resp.requestLatencyMs()); } }
private void doSend(ClientRequest clientRequest, boolean isInternalRequest, long now, AbstractRequest request) { String destination = clientRequest.destination(); RequestHeader header = clientRequest.makeHeader(request.version()); if (log.isDebugEnabled()) { int latestClientVersion = clientRequest.apiKey().latestVersion(); if (header.apiVersion() == latestClientVersion) { log.trace("Sending {} {} with correlation id {} to node {}", clientRequest.apiKey(), request, clientRequest.correlationId(), destination); } else { log.debug("Using older server API v{} to send {} {} with correlation id {} to node {}", header.apiVersion(), clientRequest.apiKey(), request, clientRequest.correlationId(), destination); } } Send send = request.toSend(destination, header); InFlightRequest inFlightRequest = new InFlightRequest( clientRequest, header, isInternalRequest, request, send, now); this.inFlightRequests.add(inFlightRequest); selector.send(send); }
/** * Handle any completed receives and update the response list with the responses received. * * @param responses The list of responses to update * @param now The current time */ private void handleCompletedReceives(List<ClientResponse> responses, long now) { for (NetworkReceive receive : this.selector.completedReceives()) { String source = receive.source(); InFlightRequest req = inFlightRequests.completeNext(source); Struct responseStruct = parseStructMaybeUpdateThrottleTimeMetrics(receive.payload(), req.header, throttleTimeSensor, now); if (log.isTraceEnabled()) { log.trace("Completed receive from node {} for {} with correlation id {}, received {}", req.destination, req.header.apiKey(), req.header.correlationId(), responseStruct); } // If the received response includes a throttle delay, throttle the connection. AbstractResponse body = AbstractResponse. parseResponse(req.header.apiKey(), responseStruct, req.header.apiVersion()); maybeThrottle(body, req.header.apiVersion(), req.destination, now); if (req.isInternalRequest && body instanceof MetadataResponse) metadataUpdater.handleCompletedMetadataResponse(req.header, now, (MetadataResponse) body); else if (req.isInternalRequest && body instanceof ApiVersionsResponse) handleApiVersionsResponse(responses, req, now, (ApiVersionsResponse) body); else responses.add(req.completed(body, now)); } }
private static Struct parseStructMaybeUpdateThrottleTimeMetrics(ByteBuffer responseBuffer, RequestHeader requestHeader, Sensor throttleTimeSensor, long now) { ResponseHeader responseHeader = ResponseHeader.parse(responseBuffer); // Always expect the response version id to be the same as the request version id Struct responseBody = requestHeader.apiKey().parseResponse(requestHeader.apiVersion(), responseBuffer); correlate(requestHeader, responseHeader); if (throttleTimeSensor != null && responseBody.hasField(CommonFields.THROTTLE_TIME_MS)) throttleTimeSensor.record(responseBody.get(CommonFields.THROTTLE_TIME_MS), now); return responseBody; }
if (log.isTraceEnabled()) log.trace("{} got response {}", call, response.responseBody().toString(response.requestHeader().apiVersion())); } catch (Throwable t) { if (log.isTraceEnabled())
@Test public void testSerdeControlledShutdownV0() { // Verify that version 0 of controlled shutdown does not include the clientId field int correlationId = 2342; ByteBuffer rawBuffer = ByteBuffer.allocate(32); rawBuffer.putShort(ApiKeys.CONTROLLED_SHUTDOWN.id); rawBuffer.putShort((short) 0); rawBuffer.putInt(correlationId); rawBuffer.flip(); RequestHeader deserialized = RequestHeader.parse(rawBuffer); assertEquals(ApiKeys.CONTROLLED_SHUTDOWN, deserialized.apiKey()); assertEquals(0, deserialized.apiVersion()); assertEquals(correlationId, deserialized.correlationId()); assertEquals("", deserialized.clientId()); Struct serialized = deserialized.toStruct(); ByteBuffer serializedBuffer = toBuffer(serialized); assertEquals(ApiKeys.CONTROLLED_SHUTDOWN.id, serializedBuffer.getShort(0)); assertEquals(0, serializedBuffer.getShort(2)); assertEquals(correlationId, serializedBuffer.getInt(4)); assertEquals(8, serializedBuffer.limit()); }
@Test public void testRequestHeaderWithNullClientId() { RequestHeader header = new RequestHeader(ApiKeys.FIND_COORDINATOR, (short) 1, null, 10); Struct headerStruct = header.toStruct(); ByteBuffer buffer = toBuffer(headerStruct); RequestHeader deserialized = RequestHeader.parse(buffer); assertEquals(header.apiKey(), deserialized.apiKey()); assertEquals(header.apiVersion(), deserialized.apiVersion()); assertEquals(header.correlationId(), deserialized.correlationId()); assertEquals("", deserialized.clientId()); // null defaults to "" }
RequestHeader header = RequestHeader.parse(requestBuffer); ApiKeys apiKey = header.apiKey(); short version = header.apiVersion(); RequestContext requestContext = new RequestContext(header, connectionId, clientAddress(), KafkaPrincipal.ANONYMOUS, listenerName, securityProtocol);
Request(ChannelHandlerContext ctx, ByteBuffer buffer) { this.requestId = buffer.getShort(); buffer.rewind(); header = RequestHeader.parse(buffer); if (header.apiKey() == ApiKeys.API_VERSIONS.id && !Protocol.apiVersionSupported(header.apiKey(), header.apiVersion())) { body = new ApiVersionsRequest(); } else { body = AbstractRequest.getRequest(header.apiKey(), header.apiVersion(), buffer); } this.clientAddress = ((InetSocketAddress) ctx.getChannel().getRemoteAddress()).getAddress(); }
private void handleJoinGroupRequest(ChannelHandlerContext ctx, Request request) { JoinGroupRequest joinGroupRequest = (JoinGroupRequest) request.getBody(); ResponseHeader responseHeader = new ResponseHeader(request.getHeader().correlationId()); List<ProtocolEntry> protocols = joinGroupRequest.groupProtocols().stream().map(protocol -> new ProtocolEntry(protocol.name(), Utils.toArray(protocol.metadata()))).collect(Collectors.toList()); coordinator.handleJoinGroup( joinGroupRequest.groupId(), joinGroupRequest.memberId(), request.getHeader().clientId(), request.getClientAddress().toString(), joinGroupRequest.rebalanceTimeout(), joinGroupRequest.sessionTimeout(), joinGroupRequest.protocolType(), protocols, (joinResult) -> { Map<String, ByteBuffer> members = joinResult.getMembers().entrySet().stream().collect(Collectors.toMap(k -> k.getKey(), k -> ByteBuffer.wrap(k.getValue()))); JoinGroupResponse responseBody = new JoinGroupResponse(request.getHeader().apiVersion(), joinResult.getErrorCode(), joinResult.getGenerationId(), joinResult.getSubProtocol(), joinResult.getMemberId(), joinResult.getLeaderId(), members); logger.trace(String.format("Sending join group response %s for correlation id %d to client %s.", responseBody, request.getHeader().correlationId(), request.getHeader().clientId())); sendResponse(ctx, new Response(responseHeader, responseBody)); } ); }
private void handleMetadataRequest(ChannelHandlerContext ctx, Request request) { short requestVersion = request.getHeader().apiVersion(); sendResponse(ctx, new Response( new ResponseHeader(request.getHeader().correlationId()), new MetadataResponse( coordinator.getAllGroupCoordinators(), "", -1, Lists.newArrayList(), requestVersion ) ) ); }