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

cn.easylib.domainevent.rocketmq.RocketMqDomainEventManager Maven / Gradle / Ivy

The newest version!
package cn.easylib.domainevent.rocketmq;

import cn.easylib.domain.application.subscriber.*;
import cn.easylib.domain.event.AbstractMQDomainEventManager;
import cn.easylib.domain.event.IDomainEvent;
import cn.easylib.domain.event.PublishEventException;
import cn.easylib.domain.event.RegisterDomainEventException;
import com.alibaba.fastjson.JSON;
import org.apache.rocketmq.client.consumer.MQPushConsumer;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyContext;
import org.apache.rocketmq.client.consumer.listener.ConsumeConcurrentlyStatus;
import org.apache.rocketmq.client.consumer.listener.MessageListenerConcurrently;
import org.apache.rocketmq.client.producer.MQProducer;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.common.message.MessageExt;

import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;


public class RocketMqDomainEventManager extends AbstractMQDomainEventManager implements MessageListenerConcurrently {

    private final Set eventNameUseTopicList = new HashSet<>();
    private final Set sharedTopicList = new HashSet<>();
    private final IConsumerCreator consumerCreator;
    private final IProducerCreator producerCreator;
    private final List mqPushConsumerList = new ArrayList<>();
    private final Map mqProducerMap = new HashMap<>();

    public RocketMqDomainEventManager(IProducerCreator producerCreator, IConsumerCreator consumerCreator, String environmentName) {
        this(producerCreator, consumerCreator, environmentName, new OrderedPerformManager());
    }

    public RocketMqDomainEventManager(IProducerCreator producerCreator,
                                      IConsumerCreator consumerCreator,
                                      String environmentName,
                                      IOrderedPerformManager performManager) {
        super(environmentName, performManager);
        this.consumerCreator = consumerCreator;
        this.producerCreator = producerCreator;
    }

    @Override
    public void registerDomainEvent(Class domainEventType) {
        EventNameInfo eventNameInfo = this.getEventName(domainEventType);

        if (eventNameInfo.useEventName()) {

            if (!this.eventNameUseTopicList.add(eventNameInfo.eventName)) {
                throw new RegisterDomainEventException(eventNameInfo.eventName);
            } else {
                try {

                    MQProducer mqProducer = this.producerCreator.create(eventNameInfo.eventName);
                    mqProducer.start();
                    this.mqProducerMap.put(eventNameInfo.eventName, mqProducer);

                    MQPushConsumer mqPushConsumer = this.consumerCreator.create(eventNameInfo.eventName);
                    mqPushConsumer.subscribe(eventNameInfo.eventName, "*");
                    mqPushConsumer.registerMessageListener(this);
                    mqPushConsumer.start();
                    this.mqPushConsumerList.add(mqPushConsumer);
                } catch (Exception ex) {
                    throw new RegisterDomainEventException(eventNameInfo.eventName, ex);
                }
            }
        } else {
            if (this.sharedTopicList.add(eventNameInfo.shareTopicName)) {
                try {

                    MQProducer mqProducer = this.producerCreator.create(eventNameInfo.shareTopicName);
                    mqProducer.start();
                    this.mqProducerMap.put(eventNameInfo.shareTopicName, mqProducer);

                    MQPushConsumer mqPushConsumer = this.consumerCreator.create(eventNameInfo.shareTopicName);
                    mqPushConsumer.subscribe(eventNameInfo.shareTopicName, "*");
                    mqPushConsumer.registerMessageListener(this);
                    mqPushConsumer.start();
                    this.mqPushConsumerList.add(mqPushConsumer);
                } catch (Exception ex) {
                    throw new RegisterDomainEventException(eventNameInfo.shareTopicName, ex);
                }
            }
        }
    }

    private byte[] stringToByte(String text) {
        try {
            return text.getBytes(StandardCharsets.UTF_8);
        } catch (Exception ex) {
            throw new StringToByteException();
        }
    }

    @Override
    public  void publishEvent(T obj) {

        final String topic = this.getTopicName(obj.getClass());

        final List messages = this.buildSubscribeDataList(obj).stream().map(s -> {
            final String text = JSON.toJSONString(s);
            final byte[] bytes = this.stringToByte(text);
            Message msg = new Message(topic, this.environmentName, obj.getBusinessId(), bytes);
            int delayValue = this.delayLevelParse(s.getDelayLevel());
            if (delayValue > 0) {
                msg.setDelayTimeLevel(delayValue);
            }
            return msg;
        }).collect(Collectors.toList());

        try {
            if (!messages.isEmpty()) {
                for (Message m : messages) {
                    this.mqProducerMap.get(topic).send(m);
                }
            }
        } catch (Exception e) {
            throw new PublishEventException(obj.getBusinessId(), e);
        }
    }

    private int delayLevelParse(SubscriberDelayLevel delayLevel) {
        if (delayLevel == SubscriberDelayLevel.Delay1) {
            return 1;
        } else if (delayLevel == SubscriberDelayLevel.Delay2) {
            return 2;
        } else if (delayLevel == SubscriberDelayLevel.Delay3) {
            return 3;
        }
        return 0;
    }

    @Override
    public  void publishEvent(T obj, String subscriber) {

        this.publishEvent(obj, subscriber, false);
    }

    @Override
    public  void publishEvent(T obj, String subscriber, boolean onlyThis) {

        SubscribeData subscribeData = this.buildSubscribeData(obj, subscriber, onlyThis);
        if (subscribeData == null) {
            return;
        }
        final String topic = this.getTopicName(obj.getClass());
        final String text = JSON.toJSONString(subscribeData);
        final byte[] bytes = this.stringToByte(text);
        Message message = new Message(topic, this.environmentName, obj.getBusinessId(), bytes);

        int delayValue = this.delayLevelParse(subscribeData.getDelayLevel());
        if (delayValue > 0) {
            message.setDelayTimeLevel(delayValue);
        }

        try {
            this.mqProducerMap.get(topic).send(message);
        } catch (Exception e) {
            throw new PublishEventException(obj.getBusinessId(), e);
        }
    }

    @Override
    public ConsumeConcurrentlyStatus consumeMessage(List msgList, ConsumeConcurrentlyContext context) {
        if (msgList == null || msgList.isEmpty()) {
            return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
        }
        for (MessageExt msg : msgList) {
            String data = new String(msg.getBody(), StandardCharsets.UTF_8);
            this.handleEvent(data, msg.getTopic());
        }
        return ConsumeConcurrentlyStatus.CONSUME_SUCCESS;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy