All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.kroxylicious.test.client.CorrelationManager Maven / Gradle / Ivy

/*
 * Copyright Kroxylicious Authors.
 *
 * Licensed under the Apache Software License version 2.0, available at http://www.apache.org/licenses/LICENSE-2.0
 */
package io.kroxylicious.test.client;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.CompletableFuture;

import org.apache.kafka.common.protocol.ApiKeys;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Tracks api version for requests
 */
public class CorrelationManager {

    private static final Logger LOGGER = LoggerFactory.getLogger(CorrelationManager.class);

    final Map brokerRequests = new HashMap<>();

    /**
     * Creates an empty CorrelationManager
     */
    public CorrelationManager() {
    }

    /**
     * Allocate and return a correlation id for an outgoing request to the broker.
     *
     * @param apiKey         The API key.
     * @param apiVersion     The API version.
     * @param correlationId  The request's correlation id.
     * @param responseFuture The future to complete with the response
     */
    public void putBrokerRequest(short apiKey,
                                 short apiVersion,
                                 int correlationId, CompletableFuture responseFuture) {
        Correlation existing = this.brokerRequests.put(correlationId, new Correlation(apiKey, apiVersion, responseFuture));
        if (existing != null) {
            LOGGER.error("Duplicate upstream correlation id {}", correlationId);
        }
    }

    /**
     * Find (and remove) the Correlation for an incoming response from the broker
     * @param correlationId The correlation id in the response.
     * @return the correlation
     */
    public Correlation getBrokerCorrelation(int correlationId) {
        return brokerRequests.remove(correlationId);
    }

    public void onChannelClose() {
        List pending = brokerRequests.keySet().stream().toList();
        for (Integer correlation : pending) {
            Correlation corr = brokerRequests.get(correlation);
            if (corr.responseFuture != null) {
                corr.responseFuture.completeExceptionally(new RuntimeException("channel closed before response received!"));
            }
        }
    }

    /**
     * A record for which responses should be decoded, together with their
     * API key and version.
     */
    public record Correlation(short apiKey,
                              short apiVersion,
                              CompletableFuture responseFuture) {

        @Override
        public String toString() {
            return "Correlation(" +
                    "apiKey=" + ApiKeys.forId(apiKey) +
                    ", apiVersion=" + apiVersion +
                    ')';
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) {
                return true;
            }
            if (o == null || getClass() != o.getClass()) {
                return false;
            }
            Correlation that = (Correlation) o;
            return apiKey == that.apiKey && apiVersion == that.apiVersion;
        }

        @Override
        public int hashCode() {
            return Objects.hash(apiKey, apiVersion);
        }

    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy