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;
}
}