@Override public Struct toStruct(short version) { return toStruct(version, throttleTimeMs, error, responseData.entrySet().iterator(), sessionId); }
/** * Convenience method to find the size of a response. * * @param version The version of the response to use. * @param partIterator The partition iterator. * @return The response size in bytes. */ public static <T extends BaseRecords> int sizeOf(short version, Iterator<Map.Entry<TopicPartition, PartitionData<T>>> partIterator) { // Since the throttleTimeMs and metadata field sizes are constant and fixed, we can // use arbitrary values here without affecting the result. return 4 + toStruct(version, 0, Errors.NONE, partIterator, INVALID_SESSION_ID).sizeOf(); }
@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); }
@Test public void testFetchResponseV4() { LinkedHashMap<TopicPartition, FetchResponse.PartitionData<MemoryRecords>> responseData = new LinkedHashMap<>(); MemoryRecords records = MemoryRecords.readableRecords(ByteBuffer.allocate(10)); List<FetchResponse.AbortedTransaction> abortedTransactions = asList( new FetchResponse.AbortedTransaction(10, 100), new FetchResponse.AbortedTransaction(15, 50) ); responseData.put(new TopicPartition("bar", 0), new FetchResponse.PartitionData<>(Errors.NONE, 100000, FetchResponse.INVALID_LAST_STABLE_OFFSET, FetchResponse.INVALID_LOG_START_OFFSET, abortedTransactions, records)); responseData.put(new TopicPartition("bar", 1), new FetchResponse.PartitionData<>(Errors.NONE, 900000, 5, FetchResponse.INVALID_LOG_START_OFFSET, null, records)); responseData.put(new TopicPartition("foo", 0), new FetchResponse.PartitionData<>(Errors.NONE, 70000, 6, FetchResponse.INVALID_LOG_START_OFFSET, Collections.emptyList(), records)); FetchResponse<MemoryRecords> response = new FetchResponse<>(Errors.NONE, responseData, 10, INVALID_SESSION_ID); FetchResponse deserialized = FetchResponse.parse(toBuffer(response.toStruct((short) 4)), (short) 4); assertEquals(responseData, deserialized.responseData()); }
@Test public void fetchResponseVersionTest() { LinkedHashMap<TopicPartition, FetchResponse.PartitionData<MemoryRecords>> responseData = new LinkedHashMap<>(); MemoryRecords records = MemoryRecords.readableRecords(ByteBuffer.allocate(10)); responseData.put(new TopicPartition("test", 0), new FetchResponse.PartitionData<>( Errors.NONE, 1000000, FetchResponse.INVALID_LAST_STABLE_OFFSET, 0L, null, records)); FetchResponse<MemoryRecords> v0Response = new FetchResponse<>(Errors.NONE, responseData, 0, INVALID_SESSION_ID); FetchResponse<MemoryRecords> v1Response = new FetchResponse<>(Errors.NONE, responseData, 10, INVALID_SESSION_ID); assertEquals("Throttle time must be zero", 0, v0Response.throttleTimeMs()); assertEquals("Throttle time must be 10", 10, v1Response.throttleTimeMs()); assertEquals("Should use schema version 0", ApiKeys.FETCH.responseSchema((short) 0), v0Response.toStruct((short) 0).schema()); assertEquals("Should use schema version 1", ApiKeys.FETCH.responseSchema((short) 1), v1Response.toStruct((short) 1).schema()); assertEquals("Response data does not match", responseData, v0Response.responseData()); assertEquals("Response data does not match", responseData, v1Response.responseData()); }
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()); }