Search in sources :

Example 11 with ApiVersion

use of org.apache.kafka.common.message.ApiVersionsResponseData.ApiVersion in project kafka by apache.

the class RequestResponseTest method testApiVersionResponseWithUnsupportedError.

@Test
public void testApiVersionResponseWithUnsupportedError() {
    for (short version : API_VERSIONS.allVersions()) {
        ApiVersionsRequest request = new ApiVersionsRequest.Builder().build(version);
        ApiVersionsResponse response = request.getErrorResponse(0, Errors.UNSUPPORTED_VERSION.exception());
        assertEquals(Errors.UNSUPPORTED_VERSION.code(), response.data().errorCode());
        ApiVersion apiVersion = response.data().apiKeys().find(API_VERSIONS.id);
        assertNotNull(apiVersion);
        assertEquals(API_VERSIONS.id, apiVersion.apiKey());
        assertEquals(API_VERSIONS.oldestVersion(), apiVersion.minVersion());
        assertEquals(API_VERSIONS.latestVersion(), apiVersion.maxVersion());
    }
}
Also used : ApiVersion(org.apache.kafka.common.message.ApiVersionsResponseData.ApiVersion) Test(org.junit.jupiter.api.Test)

Example 12 with ApiVersion

use of org.apache.kafka.common.message.ApiVersionsResponseData.ApiVersion in project kafka by apache.

the class TransactionManagerTest method testAbortTransactionAndResetSequenceNumberOnUnknownProducerId.

@Test
public void testAbortTransactionAndResetSequenceNumberOnUnknownProducerId() throws InterruptedException {
    // Set the InitProducerId version such that bumping the epoch number is not supported. This will test the case
    // where the sequence number is reset on an UnknownProducerId error, allowing subsequent transactions to
    // append to the log successfully
    apiVersions.update("0", new NodeApiVersions(Arrays.asList(new ApiVersion().setApiKey(ApiKeys.INIT_PRODUCER_ID.id).setMinVersion((short) 0).setMaxVersion((short) 1), new ApiVersion().setApiKey(ApiKeys.PRODUCE.id).setMinVersion((short) 0).setMaxVersion((short) 7))));
    doInitTransactions();
    transactionManager.beginTransaction();
    transactionManager.maybeAddPartition(tp1);
    Future<RecordMetadata> successPartitionResponseFuture = appendToAccumulator(tp1);
    prepareAddPartitionsToTxnResponse(Errors.NONE, tp1, epoch, producerId);
    prepareProduceResponse(Errors.NONE, producerId, epoch, tp1);
    runUntil(successPartitionResponseFuture::isDone);
    assertTrue(transactionManager.isPartitionAdded(tp1));
    transactionManager.maybeAddPartition(tp0);
    Future<RecordMetadata> responseFuture0 = appendToAccumulator(tp0);
    prepareAddPartitionsToTxnResponse(Errors.NONE, tp0, epoch, producerId);
    prepareProduceResponse(Errors.NONE, producerId, epoch);
    runUntil(responseFuture0::isDone);
    assertTrue(transactionManager.isPartitionAdded(tp0));
    Future<RecordMetadata> responseFuture1 = appendToAccumulator(tp0);
    prepareProduceResponse(Errors.NONE, producerId, epoch);
    runUntil(responseFuture1::isDone);
    Future<RecordMetadata> responseFuture2 = appendToAccumulator(tp0);
    client.prepareResponse(produceRequestMatcher(producerId, epoch, tp0), produceResponse(tp0, 0, Errors.UNKNOWN_PRODUCER_ID, 0, 0));
    runUntil(responseFuture2::isDone);
    assertTrue(transactionManager.hasAbortableError());
    TransactionalRequestResult abortResult = transactionManager.beginAbort();
    prepareEndTxnResponse(Errors.NONE, TransactionResult.ABORT, producerId, epoch);
    runUntil(abortResult::isCompleted);
    assertTrue(abortResult.isSuccessful());
    abortResult.await();
    // make sure we are ready for a transaction now.
    assertTrue(transactionManager.isReady());
    transactionManager.beginTransaction();
    transactionManager.maybeAddPartition(tp0);
    prepareAddPartitionsToTxnResponse(Errors.NONE, tp0, epoch, producerId);
    runUntil(() -> transactionManager.isPartitionAdded(tp0));
    assertEquals(0, transactionManager.sequenceNumber(tp0).intValue());
    assertEquals(1, transactionManager.sequenceNumber(tp1).intValue());
}
Also used : RecordMetadata(org.apache.kafka.clients.producer.RecordMetadata) ApiVersion(org.apache.kafka.common.message.ApiVersionsResponseData.ApiVersion) NodeApiVersions(org.apache.kafka.clients.NodeApiVersions) Test(org.junit.jupiter.api.Test)

Example 13 with ApiVersion

use of org.apache.kafka.common.message.ApiVersionsResponseData.ApiVersion in project kafka by apache.

the class TransactionManagerTest method testTransitionToFatalErrorWhenRetriedBatchIsExpired.

@Test
public void testTransitionToFatalErrorWhenRetriedBatchIsExpired() throws InterruptedException {
    apiVersions.update("0", new NodeApiVersions(Arrays.asList(new ApiVersion().setApiKey(ApiKeys.INIT_PRODUCER_ID.id).setMinVersion((short) 0).setMaxVersion((short) 1), new ApiVersion().setApiKey(ApiKeys.PRODUCE.id).setMinVersion((short) 0).setMaxVersion((short) 7))));
    doInitTransactions();
    transactionManager.beginTransaction();
    transactionManager.maybeAddPartition(tp0);
    Future<RecordMetadata> responseFuture = appendToAccumulator(tp0);
    assertFalse(responseFuture.isDone());
    prepareAddPartitionsToTxnResponse(Errors.NONE, tp0, epoch, producerId);
    assertFalse(transactionManager.transactionContainsPartition(tp0));
    assertFalse(transactionManager.isSendToPartitionAllowed(tp0));
    // Check that only addPartitions was sent.
    runUntil(() -> transactionManager.transactionContainsPartition(tp0));
    assertTrue(transactionManager.isSendToPartitionAllowed(tp0));
    prepareProduceResponse(Errors.NOT_LEADER_OR_FOLLOWER, producerId, epoch);
    runUntil(() -> !client.hasPendingResponses());
    assertFalse(responseFuture.isDone());
    TransactionalRequestResult commitResult = transactionManager.beginCommit();
    // Sleep 10 seconds to make sure that the batches in the queue would be expired if they can't be drained.
    time.sleep(10000);
    // Disconnect the target node for the pending produce request. This will ensure that sender will try to
    // expire the batch.
    Node clusterNode = metadata.fetch().nodes().get(0);
    client.disconnect(clusterNode.idString());
    client.backoff(clusterNode, 100);
    // We should try to flush the produce, but expire it instead without sending anything.
    runUntil(responseFuture::isDone);
    try {
        // make sure the produce was expired.
        responseFuture.get();
        fail("Expected to get a TimeoutException since the queued ProducerBatch should have been expired");
    } catch (ExecutionException e) {
        assertTrue(e.getCause() instanceof TimeoutException);
    }
    runUntil(commitResult::isCompleted);
    // the commit should have been dropped.
    assertFalse(commitResult.isSuccessful());
    assertTrue(transactionManager.hasFatalError());
    assertFalse(transactionManager.hasOngoingTransaction());
}
Also used : RecordMetadata(org.apache.kafka.clients.producer.RecordMetadata) ApiVersion(org.apache.kafka.common.message.ApiVersionsResponseData.ApiVersion) NodeApiVersions(org.apache.kafka.clients.NodeApiVersions) Node(org.apache.kafka.common.Node) ExecutionException(java.util.concurrent.ExecutionException) TimeoutException(org.apache.kafka.common.errors.TimeoutException) Test(org.junit.jupiter.api.Test)

Example 14 with ApiVersion

use of org.apache.kafka.common.message.ApiVersionsResponseData.ApiVersion in project kafka by apache.

the class SaslAuthenticatorTest method testApiVersionsRequestWithServerUnsupportedVersion.

/**
 * 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 testApiVersionsRequestWithServerUnsupportedVersion() 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(new RequestHeaderData().setRequestApiKey(ApiKeys.API_VERSIONS.id).setRequestApiVersion(Short.MAX_VALUE).setClientId("someclient").setCorrelationId(1), (short) 2);
    ApiVersionsRequest request = new ApiVersionsRequest.Builder().build();
    selector.send(new NetworkSend(node, request.toSend(header)));
    ByteBuffer responseBuffer = waitForResponse();
    ResponseHeader.parse(responseBuffer, ApiKeys.API_VERSIONS.responseHeaderVersion((short) 0));
    ApiVersionsResponse response = ApiVersionsResponse.parse(responseBuffer, (short) 0);
    assertEquals(Errors.UNSUPPORTED_VERSION.code(), response.data().errorCode());
    ApiVersion apiVersion = response.data().apiKeys().find(ApiKeys.API_VERSIONS.id);
    assertNotNull(apiVersion);
    assertEquals(ApiKeys.API_VERSIONS.id, apiVersion.apiKey());
    assertEquals(ApiKeys.API_VERSIONS.oldestVersion(), apiVersion.minVersion());
    assertEquals(ApiKeys.API_VERSIONS.latestVersion(), apiVersion.maxVersion());
    // Send ApiVersionsRequest with a supported version. This should succeed.
    sendVersionRequestReceiveResponse(node);
    // Test that client can authenticate successfully
    sendHandshakeRequestReceiveResponse(node, handshakeVersion);
    authenticateUsingSaslPlainAndCheckConnection(node, handshakeVersion > 0);
}
Also used : ApiVersionsResponse(org.apache.kafka.common.requests.ApiVersionsResponse) ApiVersion(org.apache.kafka.common.message.ApiVersionsResponseData.ApiVersion) RequestHeaderData(org.apache.kafka.common.message.RequestHeaderData) SecurityProtocol(org.apache.kafka.common.security.auth.SecurityProtocol) RequestHeader(org.apache.kafka.common.requests.RequestHeader) NetworkSend(org.apache.kafka.common.network.NetworkSend) ApiVersionsRequest(org.apache.kafka.common.requests.ApiVersionsRequest) ByteBuffer(java.nio.ByteBuffer) Test(org.junit.jupiter.api.Test)

Example 15 with ApiVersion

use of org.apache.kafka.common.message.ApiVersionsResponseData.ApiVersion in project kafka by apache.

the class ApiVersionsResponse method intersect.

public static Optional<ApiVersion> intersect(ApiVersion thisVersion, ApiVersion other) {
    if (thisVersion == null || other == null)
        return Optional.empty();
    if (thisVersion.apiKey() != other.apiKey())
        throw new IllegalArgumentException("thisVersion.apiKey: " + thisVersion.apiKey() + " must be equal to other.apiKey: " + other.apiKey());
    short minVersion = (short) Math.max(thisVersion.minVersion(), other.minVersion());
    short maxVersion = (short) Math.min(thisVersion.maxVersion(), other.maxVersion());
    return minVersion > maxVersion ? Optional.empty() : Optional.of(new ApiVersion().setApiKey(thisVersion.apiKey()).setMinVersion(minVersion).setMaxVersion(maxVersion));
}
Also used : ApiVersion(org.apache.kafka.common.message.ApiVersionsResponseData.ApiVersion)

Aggregations

ApiVersion (org.apache.kafka.common.message.ApiVersionsResponseData.ApiVersion)28 Test (org.junit.jupiter.api.Test)12 ParameterizedTest (org.junit.jupiter.params.ParameterizedTest)9 ApiKeys (org.apache.kafka.common.protocol.ApiKeys)7 ApiVersionCollection (org.apache.kafka.common.message.ApiVersionsResponseData.ApiVersionCollection)6 ApiVersionsResponse (org.apache.kafka.common.requests.ApiVersionsResponse)6 NodeApiVersions (org.apache.kafka.clients.NodeApiVersions)5 ApiVersionsResponseData (org.apache.kafka.common.message.ApiVersionsResponseData)4 RecordMetadata (org.apache.kafka.clients.producer.RecordMetadata)3 EnumSource (org.junit.jupiter.params.provider.EnumSource)3 ByteBuffer (java.nio.ByteBuffer)2 Node (org.apache.kafka.common.Node)2 DeleteGroupsResponseData (org.apache.kafka.common.message.DeleteGroupsResponseData)2 DeletableGroupResult (org.apache.kafka.common.message.DeleteGroupsResponseData.DeletableGroupResult)2 DeletableGroupResultCollection (org.apache.kafka.common.message.DeleteGroupsResponseData.DeletableGroupResultCollection)2 ListenerName (org.apache.kafka.common.network.ListenerName)2 NioEchoServer (org.apache.kafka.common.network.NioEchoServer)2 SaslChannelBuilder (org.apache.kafka.common.network.SaslChannelBuilder)2 ApiVersionsRequest (org.apache.kafka.common.requests.ApiVersionsRequest)2 DeleteGroupsResponse (org.apache.kafka.common.requests.DeleteGroupsResponse)2