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

org.springframework.kafka.core.ProducerFactoryUtils Maven / Gradle / Ivy

There is a newer version: 3.1.4
Show newest version
/*
 * Copyright 2002-2020 the original author or authors.
 *
 * 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
 *
 *      https://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 org.springframework.kafka.core;

import java.time.Duration;

import org.apache.kafka.clients.producer.Producer;

import org.springframework.lang.Nullable;
import org.springframework.transaction.support.ResourceHolderSynchronization;
import org.springframework.transaction.support.TransactionSynchronization;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.util.Assert;

/**
 * Helper class for managing a Spring based Kafka {@link DefaultKafkaProducerFactory}
 * in particular for obtaining transactional Kafka resources for a given ProducerFactory.
 *
 * 

* Mainly for internal use within the framework. * * @author Gary Russell */ public final class ProducerFactoryUtils { /** * The default close timeout (5 seconds). */ public static final Duration DEFAULT_CLOSE_TIMEOUT = Duration.ofSeconds(5); private ProducerFactoryUtils() { } /** * Obtain a Producer that is synchronized with the current transaction, if any. * @param producerFactory the ProducerFactory to obtain a Channel for * @param the key type. * @param the value type. * @return the resource holder. */ public static KafkaResourceHolder getTransactionalResourceHolder( final ProducerFactory producerFactory) { return getTransactionalResourceHolder(producerFactory, null, DEFAULT_CLOSE_TIMEOUT); } /** * Obtain a Producer that is synchronized with the current transaction, if any. * @param producerFactory the ProducerFactory to obtain a Channel for * @param closeTimeout the producer close timeout. * @param the key type. * @param the value type. * @return the resource holder. * @since 2.1.14 */ public static KafkaResourceHolder getTransactionalResourceHolder( final ProducerFactory producerFactory, Duration closeTimeout) { return getTransactionalResourceHolder(producerFactory, null, closeTimeout); } /** * Obtain a Producer that is synchronized with the current transaction, if any. * @param producerFactory the ProducerFactory to obtain a Channel for * @param txIdPrefix the transaction id prefix; if null, the producer factory * prefix is used. * @param closeTimeout the producer close timeout. * @param the key type. * @param the value type. * @return the resource holder. * @since 2.3 */ public static KafkaResourceHolder getTransactionalResourceHolder( final ProducerFactory producerFactory, @Nullable String txIdPrefix, Duration closeTimeout) { Assert.notNull(producerFactory, "ProducerFactory must not be null"); @SuppressWarnings("unchecked") KafkaResourceHolder resourceHolder = (KafkaResourceHolder) TransactionSynchronizationManager .getResource(producerFactory); if (resourceHolder == null) { Producer producer = producerFactory.createProducer(txIdPrefix); try { producer.beginTransaction(); } catch (RuntimeException e) { producer.close(closeTimeout); throw e; } resourceHolder = new KafkaResourceHolder(producer, closeTimeout); bindResourceToTransaction(resourceHolder, producerFactory); } return resourceHolder; } public static void releaseResources(@Nullable KafkaResourceHolder resourceHolder) { if (resourceHolder != null) { resourceHolder.close(); } } private static void bindResourceToTransaction(KafkaResourceHolder resourceHolder, ProducerFactory producerFactory) { TransactionSynchronizationManager.bindResource(producerFactory, resourceHolder); resourceHolder.setSynchronizedWithTransaction(true); if (TransactionSynchronizationManager.isSynchronizationActive()) { TransactionSynchronizationManager .registerSynchronization(new KafkaResourceSynchronization(resourceHolder, producerFactory)); } } /** * Callback for resource cleanup at the end of a non-native Kafka transaction (e.g. when participating in a * JtaTransactionManager transaction). * @see org.springframework.transaction.jta.JtaTransactionManager */ private static final class KafkaResourceSynchronization extends ResourceHolderSynchronization, Object> { private final KafkaResourceHolder resourceHolder; KafkaResourceSynchronization(KafkaResourceHolder resourceHolder, Object resourceKey) { super(resourceHolder, resourceKey); this.resourceHolder = resourceHolder; } @Override protected boolean shouldReleaseBeforeCompletion() { return false; } @Override public void afterCompletion(int status) { try { if (status == TransactionSynchronization.STATUS_COMMITTED) { this.resourceHolder.commit(); } else { this.resourceHolder.rollback(); } } finally { super.afterCompletion(status); } } @Override protected void releaseResource(KafkaResourceHolder holder, Object resourceKey) { ProducerFactoryUtils.releaseResources(holder); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy