public ResponseHeader toResponseHeader() { return new ResponseHeader(correlationId); }
@Test public void testResponseHeader() { ResponseHeader header = createResponseHeader(); ByteBuffer buffer = toBuffer(header.toStruct()); ResponseHeader deserialized = ResponseHeader.parse(buffer); assertEquals(header.correlationId(), deserialized.correlationId()); }
private void verifyFetchResponseFullWrite(short apiVersion, FetchResponse fetchResponse) throws Exception { int correlationId = 15; Send send = fetchResponse.toSend("1", new ResponseHeader(correlationId), apiVersion); ByteBufferChannel channel = new ByteBufferChannel(send.size()); send.writeTo(channel); channel.close(); ByteBuffer buf = channel.buffer(); // read the size int size = buf.getInt(); assertTrue(size > 0); // read the header ResponseHeader responseHeader = ResponseHeader.parse(channel.buffer()); assertEquals(correlationId, responseHeader.correlationId()); // read the body Struct responseBody = ApiKeys.FETCH.responseSchema(apiVersion).read(buf); assertEquals(fetchResponse.toStruct(apiVersion), responseBody); assertEquals(size, responseHeader.sizeOf() + responseBody.sizeOf()); }
private void checkSimpleRequestResponse(NetworkClient networkClient) { awaitReady(networkClient, node); // has to be before creating any request, as it may send ApiVersionsRequest and its response is mocked with correlation id 0 ProduceRequest.Builder builder = ProduceRequest.Builder.forCurrentMagic((short) 1, 1000, Collections.emptyMap()); TestCallbackHandler handler = new TestCallbackHandler(); ClientRequest request = networkClient.newClientRequest( node.idString(), builder, time.milliseconds(), true, defaultRequestTimeoutMs, handler); networkClient.send(request, time.milliseconds()); networkClient.poll(1, time.milliseconds()); assertEquals(1, networkClient.inFlightRequestCount()); ResponseHeader respHeader = new ResponseHeader(request.correlationId()); Struct resp = new Struct(ApiKeys.PRODUCE.responseSchema(ApiKeys.PRODUCE.latestVersion())); resp.set("responses", new Object[0]); Struct responseHeaderStruct = respHeader.toStruct(); int size = responseHeaderStruct.sizeOf() + resp.sizeOf(); ByteBuffer buffer = ByteBuffer.allocate(size); responseHeaderStruct.writeTo(buffer); resp.writeTo(buffer); buffer.flip(); selector.completeReceive(new NetworkReceive(node.idString(), buffer)); List<ClientResponse> responses = networkClient.poll(1, time.milliseconds()); assertEquals(1, responses.size()); assertTrue("The handler should have executed.", handler.executed); assertTrue("Should have a response body.", handler.response.hasResponse()); assertEquals("Should be correlated to the original request", request.correlationId(), handler.response.requestHeader().correlationId()); }
@Test public void produceResponseV5Test() { Map<TopicPartition, ProduceResponse.PartitionResponse> responseData = new HashMap<>(); TopicPartition tp0 = new TopicPartition("test", 0); responseData.put(tp0, new ProduceResponse.PartitionResponse(Errors.NONE, 10000, RecordBatch.NO_TIMESTAMP, 100)); ProduceResponse v5Response = new ProduceResponse(responseData, 10); short version = 5; ByteBuffer buffer = v5Response.serialize(version, new ResponseHeader(0)); buffer.rewind(); ResponseHeader.parse(buffer); // throw away. Struct deserializedStruct = ApiKeys.PRODUCE.parseResponse(version, buffer); ProduceResponse v5FromBytes = (ProduceResponse) AbstractResponse.parseResponse(ApiKeys.PRODUCE, deserializedStruct, version); assertEquals(1, v5FromBytes.responses().size()); assertTrue(v5FromBytes.responses().containsKey(tp0)); ProduceResponse.PartitionResponse partitionResponse = v5FromBytes.responses().get(tp0); assertEquals(100, partitionResponse.logStartOffset); assertEquals(10000, partitionResponse.baseOffset); assertEquals(10, v5FromBytes.throttleTimeMs()); assertEquals(responseData, v5Response.responses()); }
ResponseHeader responseHeader = ResponseHeader.parse(responseBuffer); assertEquals(correlationId, responseHeader.correlationId());
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; }
/** * Validate that the response corresponds to the request we expect or else explode */ private static void correlate(RequestHeader requestHeader, ResponseHeader responseHeader) { if (requestHeader.correlationId() != responseHeader.correlationId()) throw new IllegalStateException("Correlation id for response (" + responseHeader.correlationId() + ") does not match request (" + requestHeader.correlationId() + "), request header: " + requestHeader); }
public int sizeOf() { return toStruct().sizeOf(); }
client.send(request, time.milliseconds()); client.poll(1, time.milliseconds()); ResponseHeader respHeader = new ResponseHeader(request.correlationId()); Struct resp = new Struct(ApiKeys.PRODUCE.responseSchema(ApiKeys.PRODUCE.latestVersion())); resp.set("responses", new Object[0]); resp.set(CommonFields.THROTTLE_TIME_MS, 100); Struct responseHeaderStruct = respHeader.toStruct(); int size = responseHeaderStruct.sizeOf() + resp.sizeOf(); ByteBuffer buffer = ByteBuffer.allocate(size);
/** * Tests that unsupported version of ApiVersionsRequest before SASL handshake request * returns error response and does not result in authentication failure. This test * is similar to {@link #testUnauthenticatedApiVersionsRequest(SecurityProtocol, short)} * where a non-SASL client is used to send requests that are processed by * {@link SaslServerAuthenticator} of the server prior to client authentication. */ @Test public void testApiVersionsRequestWithUnsupportedVersion() throws Exception { short handshakeVersion = ApiKeys.SASL_HANDSHAKE.latestVersion(); SecurityProtocol securityProtocol = SecurityProtocol.SASL_PLAINTEXT; configureMechanisms("PLAIN", Arrays.asList("PLAIN")); server = createEchoServer(securityProtocol); // Send ApiVersionsRequest with unsupported version and validate error response. String node = "1"; createClientConnection(SecurityProtocol.PLAINTEXT, node); RequestHeader header = new RequestHeader(ApiKeys.API_VERSIONS, Short.MAX_VALUE, "someclient", 1); ApiVersionsRequest request = new ApiVersionsRequest.Builder().build(); selector.send(request.toSend(node, header)); ByteBuffer responseBuffer = waitForResponse(); ResponseHeader.parse(responseBuffer); ApiVersionsResponse response = ApiVersionsResponse.parse(responseBuffer, (short) 0); assertEquals(Errors.UNSUPPORTED_VERSION, response.error()); // Send ApiVersionsRequest with a supported version. This should succeed. sendVersionRequestReceiveResponse(node); // Test that client can authenticate successfully sendHandshakeRequestReceiveResponse(node, handshakeVersion); authenticateUsingSaslPlainAndCheckConnection(node, handshakeVersion > 0); }
/** * Validate that the response corresponds to the request we expect or else explode */ private void correlate(RequestHeader requestHeader, ResponseHeader responseHeader) { if (requestHeader.correlationId() != responseHeader.correlationId()) throw new IllegalStateException("Correlation id for response (" + responseHeader.correlationId() + ") does not match request (" + requestHeader.correlationId() + ")"); }
/** * Visible for testing, typically {@link #toSend(String, ResponseHeader, short)} should be used instead. */ public ByteBuffer serialize(short version, ResponseHeader responseHeader) { return serialize(responseHeader.toStruct(), toStruct(version)); }
private ResponseHeader createResponseHeader() { return new ResponseHeader(10); }
client.send(request, time.milliseconds()); client.poll(1, time.milliseconds()); ResponseHeader respHeader = new ResponseHeader(request.correlationId()); Struct resp = new Struct(ApiKeys.PRODUCE.responseSchema(ApiKeys.PRODUCE.latestVersion())); resp.set("responses", new Object[0]); resp.set(CommonFields.THROTTLE_TIME_MS, 100); Struct responseHeaderStruct = respHeader.toStruct(); int size = responseHeaderStruct.sizeOf() + resp.sizeOf(); ByteBuffer buffer = ByteBuffer.allocate(size);
/** * 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()) { int source = receive.source(); ClientRequest req = inFlightRequests.completeNext(source); ResponseHeader header = ResponseHeader.parse(receive.payload()); short apiKey = req.request().header().apiKey(); Struct body = (Struct) ProtoUtils.currentResponseSchema(apiKey).read(receive.payload()); correlate(req.request().header(), header); if (apiKey == ApiKeys.METADATA.id) { handleMetadataResponse(req.request().header(), body, now); } else { // need to add body/header to response here responses.add(new ClientResponse(req, now, false, body)); } } }
@Override protected Send toSend(String dest, ResponseHeader responseHeader, short apiVersion) { Struct responseHeaderStruct = responseHeader.toStruct(); Struct responseBodyStruct = toStruct(apiVersion); // write the total size and the response header ByteBuffer buffer = ByteBuffer.allocate(responseHeaderStruct.sizeOf() + 4); buffer.putInt(responseHeaderStruct.sizeOf() + responseBodyStruct.sizeOf()); responseHeaderStruct.writeTo(buffer); buffer.rewind(); Queue<Send> sends = new ArrayDeque<>(); sends.add(new ByteBufferSend(dest, buffer)); addResponseData(responseBodyStruct, throttleTimeMs, dest, sends); return new MultiRecordsSend(dest, sends); }
public static ResponseHeader parse(ByteBuffer buffer) { return new ResponseHeader(SCHEMA.read(buffer)); }
private void setExpectedApiVersionsResponse(ApiVersionsResponse response) { short apiVersionsResponseVersion = response.apiVersion(ApiKeys.API_VERSIONS.id).maxVersion; ByteBuffer buffer = response.serialize(apiVersionsResponseVersion, new ResponseHeader(0)); selector.delayedReceive(new DelayedReceive(node.idString(), new NetworkReceive(node.idString(), buffer))); }