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

com.aliyun.openservices.ons.client.rocketmq.impl.ProducerImpl Maven / Gradle / Ivy

There is a newer version: 2.0.7.Final
Show newest version
package com.aliyun.openservices.ons.client.rocketmq.impl;

import com.aliyun.openservices.ons.api.Message;
import com.aliyun.openservices.ons.api.OnExceptionContext;
import com.aliyun.openservices.ons.api.Producer;
import com.aliyun.openservices.ons.api.PropertyKeyConst;
import com.aliyun.openservices.ons.api.SendCallback;
import com.aliyun.openservices.ons.api.SendResult;
import com.aliyun.openservices.ons.api.exception.ONSClientException;
import com.aliyun.openservices.ons.api.order.OrderProducer;
import com.aliyun.openservices.ons.api.transaction.LocalTransactionChecker;
import com.aliyun.openservices.ons.api.transaction.LocalTransactionExecuter;
import com.aliyun.openservices.ons.api.transaction.TransactionProducer;
import com.aliyun.openservices.ons.api.transaction.TransactionStatus;
import com.aliyun.openservices.ons.client.ClientAbstract;
import com.aliyun.openservices.ons.client.utils.UtilAll;
import java.util.Properties;
import java.util.concurrent.ExecutorService;
import com.aliyun.openservices.ons.shaded.commons.lang3.StringUtils;
import com.aliyun.openservices.ons.shaded.org.apache.rocketmq.client.exception.ClientException;
import com.aliyun.openservices.ons.shaded.org.apache.rocketmq.client.message.MessageExt;
import com.aliyun.openservices.ons.shaded.org.apache.rocketmq.client.producer.DefaultMQProducer;
import com.aliyun.openservices.ons.shaded.org.apache.rocketmq.client.producer.Transaction;
import com.aliyun.openservices.ons.shaded.org.apache.rocketmq.client.producer.TransactionChecker;
import com.aliyun.openservices.ons.shaded.org.apache.rocketmq.client.producer.TransactionResolution;
import com.aliyun.openservices.ons.shaded.org.slf4j.Logger;
import com.aliyun.openservices.ons.shaded.org.slf4j.LoggerFactory;

public class ProducerImpl extends ClientAbstract implements Producer, OrderProducer, TransactionProducer {
    private static final Logger log = LoggerFactory.getLogger(ProducerImpl.class);
    // producer group name here is aims to keep compatibility with the old java sdk, never attempt to modify it.
    private static final String DEFAULT_PRODUCER_GROUP = "__ONS_PRODUCER_DEFAULT_GROUP";

    private static final long DEFAULT_SEND_MSG_TIMEOUT_MILLIS = 5 * 1000L;
    private static final long DEFAULT_TRANSACTION_RESOLVE_DELAY_MILLIS = 5 * 1000L;

    protected final DefaultMQProducer defaultMQProducer;
    protected final String groupId;

    public ProducerImpl(final Properties properties) {
        super(properties);
        this.groupId = properties.getProperty(PropertyKeyConst.GROUP_ID, DEFAULT_PRODUCER_GROUP);
        if (StringUtils.isBlank(groupId)) {
            throw new ONSClientException("Group id is blank, please set it.");
        }
        // group id.
        try {
            this.defaultMQProducer = new DefaultMQProducer(groupId);
        } catch (ClientException e) {
            throw new ONSClientException(e);
        }
        // provider.
        this.defaultMQProducer.setCredentialsProvider(provider);
        // send message timeout.
        long sendMessageTimeoutMillis = DEFAULT_SEND_MSG_TIMEOUT_MILLIS;
        final String sendMessageTimeoutMillisProp = properties.getProperty(PropertyKeyConst.SendMsgTimeoutMillis);
        if (StringUtils.isNoneBlank(sendMessageTimeoutMillisProp)) {
            sendMessageTimeoutMillis = Long.parseLong(sendMessageTimeoutMillisProp);
        }
        this.defaultMQProducer.setSendMessageTimeoutMillis(sendMessageTimeoutMillis);

        long transactionResolveDelayMillis = DEFAULT_TRANSACTION_RESOLVE_DELAY_MILLIS;
        final String transactionResolveDelayMillisProp =
                properties.getProperty(PropertyKeyConst.CheckImmunityTimeInSeconds);
        if (StringUtils.isNoneBlank(transactionResolveDelayMillisProp)) {
            transactionResolveDelayMillis = Long.parseLong(transactionResolveDelayMillisProp);
        }
        // transaction resolve delay time.
        this.defaultMQProducer.setTransactionRecoverDelayMillis(transactionResolveDelayMillis);
        try {
            // name server address.
            this.defaultMQProducer.setNamesrvAddr(nameServerAddr);
        } catch (Throwable t) {
            throw new ONSClientException(t);
        }

        if (null != namespace) {
            this.defaultMQProducer.setNamespace(namespace);
        }
        // message tracing enabled.
        this.defaultMQProducer.setMessageTracingEnabled(messageTracingEnabled);
    }

    public ProducerImpl(final Properties properties, final LocalTransactionChecker localChecker) {
        this(properties);
        final TransactionChecker transactionChecker = new TransactionChecker() {
            @Override
            public TransactionResolution check(MessageExt messageExt) {
                final TransactionStatus status = localChecker.check(UtilAll.msgConvert(messageExt));
                switch (status) {
                    case CommitTransaction:
                        return TransactionResolution.COMMIT;
                    case RollbackTransaction:
                        return TransactionResolution.ROLLBACK;
                    case Unknow:
                    default:
                        return TransactionResolution.UNKNOWN;
                }

            }
        };
        defaultMQProducer.setTransactionChecker(transactionChecker);
    }

    private ONSClientException producerExceptionConvert(String topic, String msgId, Throwable t) {
        log.info("Exception raised for producer, namespace={}, topic={}, messageId={}",
                 defaultMQProducer.getNamespace(), topic, msgId, t);
        return new ONSClientException(t);
    }

    private OnExceptionContext producerExceptionContextConvert(final Message message, Throwable t) {
        final ONSClientException exception = producerExceptionConvert(message.getTopic(), message.getMsgID(), t);
        return new OnExceptionContext(message.getTopic(), message.getMsgID(), exception);
    }

    @Override
    public void start() {
        try {
            if (this.started.compareAndSet(false, true)) {
                log.info("Begin to start the ONS producer.");
                this.defaultMQProducer.start();
                log.info("ONS producer starts successfully.");
                return;
            }
            log.warn("ONS producer has been started before.");
        } catch (Throwable t) {
            log.error("Failed to start the ONS producer.");
            throw new ONSClientException(t);
        }
    }

    @Override
    public void shutdown() {
        try {
            if (this.started.compareAndSet(true, false)) {
                log.info("Begin to shutdown the ONS producer.");
                this.defaultMQProducer.shutdown();
                log.info("Shutdown ONS producer successfully.");
                return;
            }
            log.warn("ONS producer has been shutdown before.");
        } catch (Throwable t) {
            log.error("Failed to shutdown the ONS producer.");
            throw new ONSClientException(t);
        }
    }

    @Override
    public SendResult send(Message message) {
        final com.aliyun.openservices.ons.shaded.org.apache.rocketmq.client.message.Message msg = UtilAll.msgConvert(message);
        try {
            final com.aliyun.openservices.ons.shaded.org.apache.rocketmq.client.producer.SendResult sendResult = defaultMQProducer.send(msg);
            return new SendResult(message.getTopic(), sendResult.getMsgId());
        } catch (Throwable t) {
            throw producerExceptionConvert(message.getTopic(), message.getMsgID(), t);
        }
    }

    @Override
    public void sendOneway(Message message) {
        final com.aliyun.openservices.ons.shaded.org.apache.rocketmq.client.message.Message msg = UtilAll.msgConvert(message);
        try {
            defaultMQProducer.sendOneway(msg);
        } catch (Throwable t) {
            throw producerExceptionConvert(message.getTopic(), message.getMsgID(), t);
        }
    }

    @Override
    public void sendAsync(final Message message, final SendCallback sendCallback) {
        try {
            final com.aliyun.openservices.ons.shaded.org.apache.rocketmq.client.message.Message msg = UtilAll.msgConvert(message);
            defaultMQProducer.send(msg, new com.aliyun.openservices.ons.shaded.org.apache.rocketmq.client.producer.SendCallback() {
                @Override
                public void onSuccess(com.aliyun.openservices.ons.shaded.org.apache.rocketmq.client.producer.SendResult mqSendResult) {
                    SendResult sendResult = new SendResult(message.getTopic(), mqSendResult.getMsgId());
                    sendCallback.onSuccess(sendResult);
                }

                @Override
                public void onException(Throwable t) {
                    final OnExceptionContext context = producerExceptionContextConvert(message, t);
                    sendCallback.onException(context);
                }
            });
        } catch (Throwable t) {
            throw producerExceptionConvert(message.getTopic(), message.getMsgID(), t);
        }
    }


    @Override
    public void setCallbackExecutor(ExecutorService callbackExecutor) {
        this.defaultMQProducer.setCallbackExecutor(callbackExecutor);
    }

    @Override
    public SendResult send(Message message, String shardingKey) {
        final com.aliyun.openservices.ons.shaded.org.apache.rocketmq.client.message.Message msg = UtilAll.msgConvert(message);
        try {
            final com.aliyun.openservices.ons.shaded.org.apache.rocketmq.client.producer.SendResult sendResult = defaultMQProducer.send(msg, shardingKey);
            return new SendResult(message.getTopic(), sendResult.getMsgId());
        } catch (Throwable t) {
            throw producerExceptionConvert(message.getTopic(), message.getMsgID(), t);
        }
    }

    @Override
    public SendResult send(Message message, LocalTransactionExecuter executor, Object arg) {
        final com.aliyun.openservices.ons.shaded.org.apache.rocketmq.client.message.Message msg = UtilAll.msgConvert(message);
        if (null == executor) {
            throw new ONSClientException("Local executor is null unexpectedly");
        }
        Transaction transaction;
        SendResult sendResult;
        try {
            transaction = defaultMQProducer.prepare(msg);
            sendResult = new SendResult(message.getTopic(), transaction.getSendResult().getMsgId());
        } catch (Throwable t) {
            throw new ONSClientException(t);
        }
        TransactionStatus status = null;
        try {
            status = executor.execute(message, arg);
            switch (status) {
                case CommitTransaction:
                    transaction.commit();
                    break;
                case RollbackTransaction:
                    transaction.rollback();
                    break;
                default:
                    break;
            }
        } catch (Throwable t) {
            // dirty way to make it compatible with 1.x sdk.
            log.info("Exception raised while execute local executor and end message", t);
        }
        if (TransactionStatus.RollbackTransaction.equals(status)) {
            // dirty way to make it compatible with 1.x sdk.
            throw new ONSClientException("local transaction branch return rollback");
        }
        return sendResult;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy