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

io.streamnative.pulsar.handlers.kop.KafkaChannelInitializer Maven / Gradle / Ivy

There is a newer version: 4.0.0.4
Show newest version
/**
 * Copyright (c) 2019 - 2024 StreamNative, Inc.. All Rights Reserved.
 */
/**
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package io.streamnative.pulsar.handlers.kop;

import static io.streamnative.pulsar.handlers.kop.KafkaProtocolHandler.TLS_HANDLER;

import com.google.common.annotations.VisibleForTesting;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.codec.LengthFieldPrepender;
import io.netty.handler.ssl.SslHandler;
import io.netty.handler.timeout.IdleStateHandler;
import io.streamnative.pulsar.handlers.kop.lookup.LookupService;
import io.streamnative.pulsar.handlers.kop.storage.ReplicaManager;
import io.streamnative.pulsar.handlers.kop.utils.delayed.DelayedOperation;
import io.streamnative.pulsar.handlers.kop.utils.delayed.DelayedOperationPurgatory;
import io.streamnative.pulsar.handlers.kop.utils.ssl.SSLUtils;
import java.util.concurrent.TimeUnit;
import lombok.Getter;
import org.apache.bookkeeper.common.util.OrderedScheduler;
import org.apache.pulsar.broker.PulsarService;
import org.eclipse.jetty.util.ssl.SslContextFactory;

/**
 * A channel initializer that initialize channels for kafka protocol.
 */
public class KafkaChannelInitializer extends ChannelInitializer {

    public static final int MAX_FRAME_LENGTH = 100 * 1024 * 1024; // 100MB

    @Getter
    private final PulsarService pulsarService;
    @Getter
    private final KafkaServiceConfiguration kafkaConfig;
    @Getter
    private final TenantContextManager tenantContextManager;
    private final ReplicaManager replicaManager;
    private final LookupService lookupService;
    @Getter
    private final KafkaTopicManagerSharedState kafkaTopicManagerSharedState;
    private final KafkaTopicLookupService kafkaTopicLookupService;

    private final AdminManager adminManager;
    private DelayedOperationPurgatory fetchPurgatory;
    @Getter
    private final boolean enableTls;
    @Getter
    private final EndPoint advertisedEndPoint;
    private final boolean skipMessagesWithoutIndex;
    @Getter
    private final SslContextFactory.Server sslContextFactory;
    @Getter
    private final RequestStats requestStats;
    private final OrderedScheduler sendResponseScheduler;

    private final LengthFieldPrepender lengthFieldPrepender;

    public KafkaChannelInitializer(PulsarService pulsarService,
                                   KafkaServiceConfiguration kafkaConfig,
                                   TenantContextManager tenantContextManager,
                                   ReplicaManager replicaManager,
                                   LookupService lookupService,
                                   AdminManager adminManager,
                                   DelayedOperationPurgatory fetchPurgatory,
                                   boolean enableTLS,
                                   EndPoint advertisedEndPoint,
                                   boolean skipMessagesWithoutIndex,
                                   RequestStats requestStats,
                                   OrderedScheduler sendResponseScheduler,
                                   KafkaTopicManagerSharedState kafkaTopicManagerSharedState,
                                   KafkaTopicLookupService kafkaTopicLookupService) {
        super();
        this.pulsarService = pulsarService;
        this.kafkaConfig = kafkaConfig;
        this.tenantContextManager = tenantContextManager;
        this.replicaManager = replicaManager;
        this.lookupService = lookupService;
        this.adminManager = adminManager;
        this.fetchPurgatory = fetchPurgatory;
        this.enableTls = enableTLS;
        this.advertisedEndPoint = advertisedEndPoint;
        this.skipMessagesWithoutIndex = skipMessagesWithoutIndex;
        this.requestStats = requestStats;
        if (enableTls) {
            sslContextFactory = SSLUtils.createSslContextFactory(kafkaConfig);
        } else {
            sslContextFactory = null;
        }
        this.sendResponseScheduler = sendResponseScheduler;
        this.kafkaTopicManagerSharedState = kafkaTopicManagerSharedState;
        this.lengthFieldPrepender = new LengthFieldPrepender(4);
        this.kafkaTopicLookupService = kafkaTopicLookupService;
    }

    @Override
    protected void initChannel(SocketChannel ch) throws Exception {
        ch.pipeline().addLast("idleStateHandler",
                new IdleStateHandler(
                        kafkaConfig.getConnectionMaxIdleMs(),
                        kafkaConfig.getConnectionMaxIdleMs(),
                        0,
                        TimeUnit.MILLISECONDS));
        if (this.enableTls) {
            ch.pipeline().addLast(TLS_HANDLER, new SslHandler(SSLUtils.createSslEngine(sslContextFactory)));
        }
        ch.pipeline().addLast(lengthFieldPrepender);
        ch.pipeline().addLast("frameDecoder",
            new LengthFieldBasedFrameDecoder(MAX_FRAME_LENGTH, 0, 4, 0, 4));
        ch.pipeline().addLast("handler", newCnx());
    }

    @VisibleForTesting
    public KafkaRequestHandler newCnx() throws Exception {
        return new KafkaRequestHandler(pulsarService, kafkaConfig,
                tenantContextManager, replicaManager, lookupService, adminManager, fetchPurgatory,
                enableTls, advertisedEndPoint, skipMessagesWithoutIndex, requestStats, sendResponseScheduler,
                kafkaTopicManagerSharedState, kafkaTopicLookupService);
    }

    @VisibleForTesting
    public KafkaRequestHandler newCnx(final TenantContextManager tenantContextManager) throws Exception {
        return new KafkaRequestHandler(pulsarService, kafkaConfig,
                tenantContextManager, replicaManager, lookupService, adminManager, fetchPurgatory,
                enableTls, advertisedEndPoint, skipMessagesWithoutIndex,
                requestStats,
                sendResponseScheduler,
                kafkaTopicManagerSharedState, kafkaTopicLookupService);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy