提交 6ec39e24 编写于 作者: 街头小贩's avatar 街头小贩

将Member相关的事件改为RedisQ

上级 809038cc
......@@ -18,6 +18,12 @@
<artifactId>utils</artifactId>
<version>${project.version}</version>
</dependency>
<!-- base redis mq -->
<dependency>
<groupId>com.github.davidmarquis</groupId>
<artifactId>redisq</artifactId>
<version>2.0.0</version>
</dependency>
</dependencies>
<build>
<plugins>
......
package com.apobates.forum.event.elderly.redis;
import com.github.davidmarquis.redisq.RedisMessageQueue;
import com.github.davidmarquis.redisq.persistence.RedisOps;
import com.github.davidmarquis.redisq.producer.DefaultMessageProducer;
import java.io.Serializable;
import java.util.function.Consumer;
public interface RedisEvent<T> extends Serializable {
default Consumer<RedisMessageQueue> use(final RedisOps redisOps){
return (RedisMessageQueue queue)->{
DefaultMessageProducer<T> dmq = new com.github.davidmarquis.redisq.producer.DefaultMessageProducer<>();
dmq.setQueue(queue);
dmq.setRedisOps(redisOps);
dmq.create((T) this).submit();
};
}
}
package com.apobates.forum.event.elderly.redis;
import java.lang.annotation.*;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RedisEventConsumer {
String customerId();
String queue();
Class<?> event();
}
open module Event {
requires org.slf4j;
requires Utils;
requires transitive redisq;
exports com.apobates.forum.event.elderly;
exports com.apobates.forum.event.elderly.redis;
}
\ No newline at end of file
......@@ -73,11 +73,11 @@
<artifactId>member</artifactId>
<version>${project.version}</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.cache/cache-api
<!--
<dependency>
<groupId>javax.cache</groupId>
<artifactId>cache-api</artifactId>
<version>1.1.0</version>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.2</version>
</dependency>-->
</dependencies>
<build>
......
......@@ -19,11 +19,12 @@ import org.springframework.transaction.annotation.EnableTransactionManagement;
@EnableAspectJAutoProxy(proxyTargetClass=true)
@EnableTransactionManagement(proxyTargetClass = true)
@ComponentScan(basePackages={"com.apobates.forum.member.impl"}, useDefaultFilters=false, includeFilters={@Filter(classes={org.springframework.stereotype.Service.class}),@Filter(classes={org.springframework.stereotype.Repository.class}),@Filter(classes={org.springframework.stereotype.Component.class})})
@Import(value={MemberTaskScheduleConfig.class})
@Import(value={MemberTaskScheduleConfig.class, RedisMemberEventConfig.class})
public class MemberAppConfig {
@Bean
public MemberActionAspect buildMa() {
return new com.apobates.forum.member.impl.MemberActionAspect();
}
}
\ No newline at end of file
package com.apobates.forum.member.impl;
import com.apobates.forum.member.impl.event.*;
import com.github.davidmarquis.redisq.RedisMessageQueue;
import com.github.davidmarquis.redisq.consumer.MessageConsumer;
import com.github.davidmarquis.redisq.consumer.MessageListener;
import com.github.davidmarquis.redisq.producer.DefaultMessageProducer;
import com.github.davidmarquis.redisq.producer.MessageProducer;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class RedisMemberEventConfig {
// loop queue
@Bean("signUpEventQueue")
public RedisMessageQueue signUpEventQueue(){
RedisMessageQueue mq = new com.github.davidmarquis.redisq.RedisMessageQueue();
mq.setQueueName("member:SignUpEvent");
return mq;
}
@Bean("signInEventQueue")
public RedisMessageQueue signInEventQueue(){
RedisMessageQueue mq = new com.github.davidmarquis.redisq.RedisMessageQueue();
mq.setQueueName("member:SignInEvent");
return mq;
}
@Bean("signOutEventQueue")
public RedisMessageQueue signOutEventQueue(){
RedisMessageQueue mq = new com.github.davidmarquis.redisq.RedisMessageQueue();
mq.setQueueName("member:SignOutEvent");
return mq;
}
@Bean("penalizeEventQueue")
public RedisMessageQueue penalizeEventQueue(){
RedisMessageQueue mq = new com.github.davidmarquis.redisq.RedisMessageQueue();
mq.setQueueName("member:PenalizeEvent");
return mq;
}
@Bean("vipExchangeEventQueue")
public RedisMessageQueue vipExchangeEventQueue(){
RedisMessageQueue mq = new com.github.davidmarquis.redisq.RedisMessageQueue();
mq.setQueueName("member:VipExchangeEvent");
return mq;
}
// loop Producer
@Bean("memberSignUpProducer")
public MessageProducer<MemberSignUpEvent> signUpProducer(@Qualifier("signUpEventQueue") RedisMessageQueue signUpEventQueue){
DefaultMessageProducer<MemberSignUpEvent> dmq = new com.github.davidmarquis.redisq.producer.DefaultMessageProducer<>();
dmq.setQueue(signUpEventQueue);
return dmq;
}
@Bean("memberSignInProducer")
public MessageProducer<MemberSignInEvent> signInProducer(@Qualifier("signInEventQueue") RedisMessageQueue signInEventQueue){
DefaultMessageProducer<MemberSignInEvent> dmq = new com.github.davidmarquis.redisq.producer.DefaultMessageProducer<>();
dmq.setQueue(signInEventQueue);
return dmq;
}
@Bean("memberSignOutProducer")
public MessageProducer<MemberSignOutEvent> signOutProducer(@Qualifier("signOutEventQueue") RedisMessageQueue signOutEventQueue){
DefaultMessageProducer<MemberSignOutEvent> dmq = new com.github.davidmarquis.redisq.producer.DefaultMessageProducer<>();
dmq.setQueue(signOutEventQueue);
return dmq;
}
@Bean("memberPenalizeProducer")
public MessageProducer<MemberPenalizeEvent> penalizeProducer(@Qualifier("penalizeEventQueue") RedisMessageQueue penalizeEventQueue){
DefaultMessageProducer<MemberPenalizeEvent> dmq = new com.github.davidmarquis.redisq.producer.DefaultMessageProducer<>();
dmq.setQueue(penalizeEventQueue);
return dmq;
}
@Bean("memberVipExchangeProducer")
public MessageProducer<MemberVipExchangeEvent> vipExchangeProducer(@Qualifier("vipExchangeEventQueue") RedisMessageQueue vipExchangeEventQueue){
DefaultMessageProducer<MemberVipExchangeEvent> dmq = new com.github.davidmarquis.redisq.producer.DefaultMessageProducer<>();
dmq.setQueue(vipExchangeEventQueue);
return dmq;
}
//loop Consumer
@Bean
public MessageConsumer<MemberSignUpEvent> promoteRoleConsumer(
@Qualifier("signUpEventQueue") RedisMessageQueue signUpEventQueue,
@Qualifier("promoteRole") MessageListener<MemberSignUpEvent> promoteRole){
MessageConsumer<MemberSignUpEvent> messageConsumer = new com.github.davidmarquis.redisq.consumer.MessageConsumer<>();
messageConsumer.setQueue(signUpEventQueue);
messageConsumer.setConsumerId("SignUpEvent:PromoteRole");
messageConsumer.setMessageListener(promoteRole);
return messageConsumer;
}
@Bean
public MessageConsumer<MemberSignUpEvent> inviteCodeConsumer(
@Qualifier("signUpEventQueue") RedisMessageQueue signUpEventQueue,
@Qualifier("inviteCode") MessageListener<MemberSignUpEvent> inviteCode){
MessageConsumer<MemberSignUpEvent> messageConsumer = new com.github.davidmarquis.redisq.consumer.MessageConsumer<>();
messageConsumer.setQueue(signUpEventQueue);
messageConsumer.setConsumerId("SignUpEvent:InviteCode");
messageConsumer.setMessageListener(inviteCode);
return messageConsumer;
}
@Bean
public MessageConsumer<MemberPenalizeEvent> changeStatusConsumer(
@Qualifier("penalizeEventQueue") RedisMessageQueue penalizeEventQueue,
@Qualifier("changeStatus") MessageListener<MemberPenalizeEvent> changeStatus){
MessageConsumer<MemberPenalizeEvent> messageConsumer = new com.github.davidmarquis.redisq.consumer.MessageConsumer<>();
messageConsumer.setQueue(penalizeEventQueue);
messageConsumer.setConsumerId("PenalizeEvent:ChangeStatus");
messageConsumer.setMessageListener(changeStatus);
return messageConsumer;
}
@Bean
public MessageConsumer<MemberVipExchangeEvent> changeGroupConsumer(
@Qualifier("vipExchangeEventQueue") RedisMessageQueue vipExchangeEventQueue,
@Qualifier("changeGroup") MessageListener<MemberVipExchangeEvent> changeGroup){
MessageConsumer<MemberVipExchangeEvent> messageConsumer = new com.github.davidmarquis.redisq.consumer.MessageConsumer<>();
messageConsumer.setQueue(vipExchangeEventQueue);
messageConsumer.setConsumerId("VipExchangeEvent:ChangeGroup");
messageConsumer.setMessageListener(changeGroup);
return messageConsumer;
}
}
package com.apobates.forum.member.impl.event;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.stereotype.Component;
/**
* 会员模块事件发布器
* @author xiaofanku
* @since 20200516
*/
@Component
public class MemberEventPublisher {
@Autowired
private ApplicationEventPublisher applicationEventPublisher;
/**
* 发布登录事件
* @param memberSignInEvent
*/
public void publishSignInEvent(MemberSignInEvent memberSignInEvent) {
applicationEventPublisher.publishEvent(memberSignInEvent);
}
/**
* 发布注册事件
* @param memberSignUpEvent
*/
public void publishSignUpEvent(MemberSignUpEvent memberSignUpEvent) {
applicationEventPublisher.publishEvent(memberSignUpEvent);
}
/**
* 发布会员惩罚事件
* @param memberPenalizeEvent
*/
public void publishPenalizeEvent(MemberPenalizeEvent memberPenalizeEvent){
applicationEventPublisher.publishEvent(memberPenalizeEvent);
}
/**
* 发布会员注销事件
* @param memberSignOutEvent
*/
public void publishSignOutEvent(MemberSignOutEvent memberSignOutEvent){
applicationEventPublisher.publishEvent(memberSignOutEvent);
}
/**
* 发布VIP会员交易事件
* @param event VIP会员交易事件
*/
public void publishVipExchangeEvent(VipExchangeEvent event){
applicationEventPublisher.publishEvent(event);
}
}
\ No newline at end of file
package com.apobates.forum.member.impl.event;
import com.apobates.forum.member.entity.MemberStatusEnum;
import org.springframework.context.ApplicationEvent;
/**
* 会员惩罚事件
......@@ -9,7 +8,7 @@ import org.springframework.context.ApplicationEvent;
* @author xiaofanku
* @since 20200516
*/
public class MemberPenalizeEvent extends ApplicationEvent {
public class MemberPenalizeEvent {
private static final long serialVersionUID = -8131311352503255701L;
//被惩罚的会员
private final long member;
......@@ -24,8 +23,7 @@ public class MemberPenalizeEvent extends ApplicationEvent {
//惩罚降临的状态
private final MemberStatusEnum arrive;
public MemberPenalizeEvent(Object source, long member, String names, MemberStatusEnum arrive, String duration, long judger, String judgeNames, String reason) {
super(source);
public MemberPenalizeEvent(long member, String names, MemberStatusEnum arrive, String duration, long judger, String judgeNames, String reason) {
this.member = member;
this.names = names;
this.judger = judger;
......
package com.apobates.forum.member.impl.event;
import com.apobates.forum.member.entity.Member;
import org.springframework.context.ApplicationEvent;
/**
* 会员登录事件
......@@ -9,15 +8,14 @@ import org.springframework.context.ApplicationEvent;
* @author xiaofanku
* @since 20200516
*/
public class MemberSignInEvent extends ApplicationEvent {
public class MemberSignInEvent {
private static final long serialVersionUID = 2594623388491543454L;
private final Member member;
private final String ipAddr;
private final String refererURL;
private final String device;
public MemberSignInEvent(Object source, Member member, String ipAddr, String refererURL, String device) {
super(source);
public MemberSignInEvent(Member member, String ipAddr, String refererURL, String device) {
this.member = member;
this.ipAddr = ipAddr;
this.refererURL = refererURL;
......
package com.apobates.forum.member.impl.event;
import com.apobates.forum.member.entity.Member;
import org.springframework.context.ApplicationEvent;
/**
* 会员注销事件
......@@ -9,14 +8,13 @@ import org.springframework.context.ApplicationEvent;
* @author xiaofanku
* @since 20200516
*/
public class MemberSignOutEvent extends ApplicationEvent {
public class MemberSignOutEvent {
private static final long serialVersionUID = -28020595031472116L;
private final Member member;
private final String refererURL;
private final String ipAddr;
public MemberSignOutEvent(Object source, Member member, String refererURL, String ipAddr) {
super(source);
public MemberSignOutEvent(Member member, String refererURL, String ipAddr) {
this.member = member;
this.refererURL = refererURL;
this.ipAddr = ipAddr;
......
package com.apobates.forum.member.impl.event;
import com.apobates.forum.member.entity.Member;
import org.springframework.context.ApplicationEvent;
/**
* 会员注册事件
......@@ -9,12 +8,11 @@ import org.springframework.context.ApplicationEvent;
* @author xiaofanku
* @since 20200516
*/
public class MemberSignUpEvent extends ApplicationEvent {
public class MemberSignUpEvent {
private static final long serialVersionUID = -1170897700743310079L;
private final Member member;
public MemberSignUpEvent(Object source, Member member) {
super(source);
public MemberSignUpEvent(Member member) {
this.member = member;
}
......
package com.apobates.forum.member.impl.event;
import com.apobates.forum.member.entity.MemberVipExchangeRecords;
import org.springframework.context.ApplicationEvent;
/**
* VIP会员交易事件
*
* @author xiaofanku
* @since 20200921
*/
public class VipExchangeEvent extends ApplicationEvent {
public class MemberVipExchangeEvent {
private final MemberVipExchangeRecords record;
public VipExchangeEvent(Object source, MemberVipExchangeRecords record) {
super(source);
public MemberVipExchangeEvent(MemberVipExchangeRecords record) {
this.record = record;
}
......
......@@ -2,10 +2,12 @@ package com.apobates.forum.member.impl.event.listener;
import com.apobates.forum.member.dao.MemberDao;
import com.apobates.forum.member.impl.event.MemberPenalizeEvent;
import com.github.davidmarquis.redisq.Message;
import com.github.davidmarquis.redisq.consumer.MessageListener;
import com.github.davidmarquis.redisq.consumer.retry.RetryableMessageException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
/**
......@@ -13,17 +15,17 @@ import org.springframework.stereotype.Component;
* @author xiaofanku
* @since 20200521
*/
@Component
public class MemberPenalizeChangeStatusListener implements ApplicationListener<MemberPenalizeEvent> {
@Component("changeStatus")
public class MemberPenalizeChangeStatusListener implements MessageListener<MemberPenalizeEvent> {
@Autowired
private MemberDao memberDao;
private final static Logger logger = LoggerFactory.getLogger(MemberPenalizeChangeStatusListener.class);
@Override
public void onApplicationEvent(MemberPenalizeEvent event) {
public void onMessage(Message<MemberPenalizeEvent> event) throws RetryableMessageException {
logger.info("[Event][Member][11]惩罚状态更新开始");
//惩罚开始了吗?,暂不支持预定日期的惩罚,只支持即可生效
memberDao.editMemberStatus(event.getMember(), event.getArrive());
memberDao.editMemberStatus(event.getPayload().getMember(), event.getPayload().getArrive());
logger.info("[Event][Member][11]惩罚状态更新结束");
}
}
\ No newline at end of file
......@@ -3,27 +3,30 @@ package com.apobates.forum.member.impl.event.listener;
import com.apobates.forum.member.dao.RegisteInviteCodeDao;
import com.apobates.forum.member.entity.Member;
import com.apobates.forum.member.impl.event.MemberSignUpEvent;
import com.github.davidmarquis.redisq.Message;
import com.github.davidmarquis.redisq.consumer.MessageListener;
import com.github.davidmarquis.redisq.consumer.retry.RetryableMessageException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
/**
* 会员注册事件侦听器,会员注册后的激活邀请码
*
* @author xiaofanku
* @since 20200521
*/
@Component
public class MemberSignUpInviteCodeListener implements ApplicationListener<MemberSignUpEvent> {
@Component("inviteCode")
public class MemberSignUpInviteCodeListener implements MessageListener<MemberSignUpEvent> {
@Autowired
private RegisteInviteCodeDao registeInviteCodeDao;
private final static Logger logger = LoggerFactory.getLogger(MemberSignUpInviteCodeListener.class);
@Override
public void onApplicationEvent(MemberSignUpEvent event) {
public void onMessage(Message<MemberSignUpEvent> event) throws RetryableMessageException {
logger.info("[Event][Member][3]注册成功后开始激活邀请码");
Member m = event.getMember();
Member m = event.getPayload().getMember();
if (m.getInviteCodeId() > 0) {
registeInviteCodeDao.active(m.getInviteCodeId(), m.getId(), m.getNames());
}
......
......@@ -4,27 +4,30 @@ import com.apobates.forum.member.dao.MemberDao;
import com.apobates.forum.member.entity.Member;
import com.apobates.forum.member.entity.MemberRoleEnum;
import com.apobates.forum.member.impl.event.MemberSignUpEvent;
import com.github.davidmarquis.redisq.Message;
import com.github.davidmarquis.redisq.consumer.MessageListener;
import com.github.davidmarquis.redisq.consumer.retry.RetryableMessageException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
/**
* 将1号员工提升为管理员
*
* @author xiaofanku
* @since 20200521
*/
@Component
public class MemberSignUpPromoteRoleListener implements ApplicationListener<MemberSignUpEvent> {
@Component("promoteRole")
public class MemberSignUpPromoteRoleListener implements MessageListener<MemberSignUpEvent> {
@Autowired
private MemberDao memberDao;
private final static Logger logger = LoggerFactory.getLogger(MemberSignUpPromoteRoleListener.class);
@Override
public void onApplicationEvent(MemberSignUpEvent event) {
public void onMessage(Message<MemberSignUpEvent> event) throws RetryableMessageException {
logger.info("[Event][Member][2]注册成功后发送通知开始");
Member m = event.getMember();
Member m = event.getPayload().getMember();
if (m.getId() == 1) {
memberDao.editMemberRole(1L, MemberRoleEnum.ADMIN);
}
......
......@@ -2,11 +2,13 @@ package com.apobates.forum.member.impl.event.listener;
import com.apobates.forum.member.dao.MemberDao;
import com.apobates.forum.member.entity.MemberGroupEnum;
import com.apobates.forum.member.impl.event.VipExchangeEvent;
import com.apobates.forum.member.impl.event.MemberVipExchangeEvent;
import com.github.davidmarquis.redisq.Message;
import com.github.davidmarquis.redisq.consumer.MessageListener;
import com.github.davidmarquis.redisq.consumer.retry.RetryableMessageException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import org.springframework.stereotype.Component;
/**
* VIP会员交易会员组变更侦听器
......@@ -14,17 +16,18 @@ import org.springframework.stereotype.Component;
* @author xiaofanku
* @since 20200921
*/
@Component
public class MemberVipExchangeGroupListener implements ApplicationListener<VipExchangeEvent> {
@Component("changeGroup")
public class MemberVipExchangeGroupListener implements MessageListener<MemberVipExchangeEvent> {
@Autowired
private MemberDao memberDao;
private final static Logger logger = LoggerFactory.getLogger(MemberVipExchangeGroupListener.class);
@Override
public void onApplicationEvent(VipExchangeEvent event) {
public void onMessage(Message<MemberVipExchangeEvent> event) throws RetryableMessageException {
logger.info("[Event][Member][12]VIP会员的组变更开始");
if (event.getRecord().getId() > 0) {
memberDao.editMemberGroup(event.getRecord().getMemberId(), MemberGroupEnum.VIP);
MemberVipExchangeEvent vee = event.getPayload();
if (vee.getRecord().getId() > 0) {
memberDao.editMemberGroup(vee.getRecord().getMemberId(), MemberGroupEnum.VIP);
}
logger.info("[Event][Member][12]VIP会员的组结束变更");
}
......
......@@ -3,7 +3,6 @@ package com.apobates.forum.member.impl.service;
import com.apobates.forum.member.dao.MemberDao;
import com.apobates.forum.member.dao.MemberPenalizeRecordsDao;
import com.apobates.forum.member.entity.MemberPenalizeRecords;
import com.apobates.forum.member.impl.event.MemberEventPublisher;
import com.apobates.forum.member.impl.event.MemberPenalizeEvent;
import com.apobates.forum.member.service.MemberPenalizeRecordsService;
import com.apobates.forum.utils.DateTimeUtils;
......@@ -11,9 +10,11 @@ import com.apobates.forum.utils.persistence.Page;
import com.apobates.forum.utils.persistence.Pageable;
import java.util.Optional;
import java.util.stream.Stream;
import com.github.davidmarquis.redisq.producer.MessageProducer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
/**
......@@ -27,8 +28,8 @@ public class MemberPenalizeRecordsServiceImpl implements MemberPenalizeRecordsSe
private MemberPenalizeRecordsDao memberPenalizeRecordsDao;
@Autowired
private MemberDao memberDao;
@Autowired
private MemberEventPublisher memberEventPublisher;
@Autowired @Qualifier("memberPenalizeProducer")
private MessageProducer<MemberPenalizeEvent> penalizeProducer;
private final static Logger logger = LoggerFactory.getLogger(MemberPenalizeRecordsServiceImpl.class);
@Override
......@@ -54,15 +55,14 @@ public class MemberPenalizeRecordsServiceImpl implements MemberPenalizeRecordsSe
memberPenalizeRecordsDao.save(entity);
if (entity.getId() > 0) {
// 应该在惩罚生效时发送,暂不支持预定日期的惩罚,只支持即可生效
memberEventPublisher.publishPenalizeEvent(
new MemberPenalizeEvent(this,
entity.getMemberId(),
MemberPenalizeEvent mpe = new MemberPenalizeEvent(entity.getMemberId(),
entity.getMemberNickname(),
entity.getArrive(),
entity.getDuration(),
entity.getJudger(),
entity.getJudgeNickname(),
entity.getReason()));
entity.getReason());
penalizeProducer.create(mpe).submit();
return entity.getId();
}
} catch (Exception e) {
......
......@@ -9,32 +9,30 @@ import com.apobates.forum.member.entity.*;
import com.apobates.forum.member.exception.MemberNamesExistException;
import com.apobates.forum.member.exception.MemberNamesProtectException;
import com.apobates.forum.member.impl.MemberAction;
import com.apobates.forum.member.impl.event.*;
import com.apobates.forum.member.impl.event.MemberSignInEvent;
import com.apobates.forum.member.impl.event.MemberSignOutEvent;
import com.apobates.forum.member.impl.event.MemberSignUpEvent;
import com.apobates.forum.member.impl.event.MemberVipExchangeEvent;
import com.apobates.forum.member.service.MemberLevelService;
import com.apobates.forum.member.service.MemberService;
import com.apobates.forum.utils.Commons;
import com.apobates.forum.utils.DateTimeUtils;
import com.apobates.forum.utils.lang.TriFunction;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.TreeMap;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import com.github.davidmarquis.redisq.producer.MessageProducer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
*
......@@ -58,10 +56,16 @@ public class MemberServiceImpl implements MemberService{
private MemberLevelService memberLevelService;
@Autowired
private MemberVipExchangeRecordsDao memberVipExchangeRecordsDao;
@Autowired
private MemberEventPublisher memberEventPublisher;
@Autowired @Qualifier("memberSignUpProducer")
private MessageProducer<MemberSignUpEvent> signUpProducer;
@Autowired @Qualifier("memberSignInProducer")
private MessageProducer<MemberSignInEvent> signInProducer;
@Autowired @Qualifier("memberSignOutProducer")
private MessageProducer<MemberSignOutEvent> signOutProducer;
@Autowired @Qualifier("memberVipExchangeProducer")
private MessageProducer<MemberVipExchangeEvent> vipExchangeProducer;
private final static Logger logger = LoggerFactory.getLogger(MemberServiceImpl.class);
@Cacheable(key="'avatar_'+#id", unless="#result==null")
@Override
public Optional<String> getMemberAvatar(long id) {
......@@ -169,7 +173,7 @@ public class MemberServiceImpl implements MemberService{
//丢掉了inviteCode相关信息
eventMember.setInviteCodeId(inviteCodeId);
eventMember.setInviteCode(inviteCode);
memberEventPublisher.publishSignUpEvent(new MemberSignUpEvent(this, eventMember));
signUpProducer.create(new MemberSignUpEvent(eventMember)).submit();
}
//
return tmp;
......@@ -214,7 +218,8 @@ public class MemberServiceImpl implements MemberService{
Optional<Member> tmp = securityMember(m);
if (tmp.isPresent()) {
Member member = tmp.get();
memberEventPublisher.publishSignInEvent(new MemberSignInEvent(this, member, actionDescriptor.location().getIpAddr(), actionDescriptor.getReferrer(), actionDescriptor.getDevice()));
MemberSignInEvent sie = new MemberSignInEvent(member, actionDescriptor.location().getIpAddr(), actionDescriptor.getReferrer(), actionDescriptor.getDevice());
signInProducer.create(sie).submit();
return tmp;
}
throw new IllegalStateException("会员不存在或密码错误");
......@@ -235,7 +240,7 @@ public class MemberServiceImpl implements MemberService{
@MemberAction(action = ForumActionEnum.MEMBER_LOGOUT, keyName="memberNames", keyType=String.class)
@Override
public Optional<Boolean> signOut(String memberNames, Member member, MemberActionDescriptor actionDescriptor) { //ASP-M7
memberEventPublisher.publishSignOutEvent(new MemberSignOutEvent(this, member, actionDescriptor.getReferrer(), actionDescriptor.location().getIpAddr()));
signOutProducer.create(new MemberSignOutEvent(member, actionDescriptor.getReferrer(), actionDescriptor.location().getIpAddr())).submit();
return Optional.of(true);
}
......@@ -334,7 +339,7 @@ public class MemberServiceImpl implements MemberService{
}
memberVipExchangeRecordsDao.save(ver);
if(ver.getId()>0) {
memberEventPublisher.publishVipExchangeEvent(new VipExchangeEvent(this, ver));
vipExchangeProducer.create(new MemberVipExchangeEvent(ver)).submit();
return Optional.of(true);
}
}catch(Exception e){
......
......@@ -8,6 +8,9 @@ open module MemberImpl {
requires spring.tx;
requires org.aspectj.runtime;
requires spring.context.support;
requires Event;
exports com.apobates.forum.member.impl;
exports com.apobates.forum.member.impl.event;
exports com.apobates.forum.member.impl.event.listener;
exports com.apobates.forum.member.impl.service;
}
\ No newline at end of file
......@@ -4,12 +4,10 @@ import com.alibaba.druid.pool.DruidDataSource;
import com.apobates.forum.core.impl.CoreAppConfig;
import com.apobates.forum.letterbox.impl.LetterAppConfig;
import com.apobates.forum.member.impl.MemberAppConfig;
import com.apobates.forum.thrones.event.MemberSignInNoticeListener;
import com.apobates.forum.thrones.event.MemberSignUpNoticeListener;
import com.apobates.forum.thrones.event.PostsMoodNoticeListener;
import com.apobates.forum.thrones.event.PostsQuoteNoticeListener;
import com.apobates.forum.thrones.event.PostsReplyNoticeListener;
import com.apobates.forum.thrones.event.TopicMoveNoticeListener;
import com.apobates.forum.member.impl.event.MemberPenalizeEvent;
import com.apobates.forum.member.impl.event.MemberSignInEvent;
import com.apobates.forum.member.impl.event.MemberSignUpEvent;
import com.apobates.forum.member.impl.event.MemberVipExchangeEvent;
import com.apobates.forum.utils.Commons;
import com.apobates.forum.utils.lang.CommonDoubleBean;
import com.apobates.forum.utils.lang.CommonDoubleBeanDeserializer;
......@@ -31,12 +29,14 @@ import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
import javax.persistence.EntityManagerFactory;
import javax.servlet.Filter;
import javax.sql.DataSource;
import com.github.davidmarquis.redisq.RedisMessageQueue;
import com.github.davidmarquis.redisq.consumer.MessageConsumer;
import com.github.davidmarquis.redisq.consumer.MessageListener;
import com.github.davidmarquis.redisq.persistence.RedisOps;
import com.github.davidmarquis.redisq.serialization.PayloadSerializer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableLoadTimeWeaving;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.PropertySource;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.*;
import org.springframework.core.env.Environment;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
......@@ -71,6 +71,7 @@ import redis.clients.jedis.JedisPoolConfig;
@EnableLoadTimeWeaving
@EnableTransactionManagement(proxyTargetClass = true)
@Import(value = {MemberAppConfig.class, LetterAppConfig.class, CoreAppConfig.class, SpringSessionConfig.class})
@ComponentScan(basePackages = {"com.apobates.forum.thrones.event"}, useDefaultFilters = false, includeFilters = {@ComponentScan.Filter(classes = {org.springframework.stereotype.Component.class})})
public class ThronesAppConfig {
@Autowired
private Environment env;
......@@ -175,7 +176,7 @@ public class ThronesAppConfig {
.build();
return new JedisConnectionFactory(redisConfig, clientConfig);
}
@Bean
@Bean("redisTemplate")
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory cf, GenericJackson2JsonRedisSerializer valuesRedisSerializer) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(cf);
......@@ -223,35 +224,56 @@ public class ThronesAppConfig {
public Filter requestTokenParameterFilter() {
return new com.apobates.forum.thrones.controller.helper.RequestTokenParameterFilter();
}
//CORE事件侦听器
//base redis mq
@Bean
public PostsReplyNoticeListener registerReplyNotice() {
return new PostsReplyNoticeListener();
public PayloadSerializer payloadSerializer(){
return new com.github.davidmarquis.redisq.serialization.GsonPayloadSerializer();
}
@Bean
public PostsQuoteNoticeListener registerQuoteNotice() {
return new PostsQuoteNoticeListener();
@Bean("redisOps")
public RedisOps buildRedisMQOps(){
RedisOps ro = new com.github.davidmarquis.redisq.persistence.RedisOps();
return ro;
}
// loop Producer
// loop Consumer
@Bean
public PostsMoodNoticeListener registerMoodNotice() {
return new PostsMoodNoticeListener();
public MessageConsumer<MemberSignUpEvent> registerNoticeConsumer(
@Qualifier("signUpEventQueue") RedisMessageQueue signUpEventQueue,
@Qualifier("registerNotice") MessageListener<MemberSignUpEvent> registerNotice){
MessageConsumer<MemberSignUpEvent> messageConsumer = new com.github.davidmarquis.redisq.consumer.MessageConsumer<>();
messageConsumer.setQueue(signUpEventQueue);
messageConsumer.setConsumerId("SignUpEvent:Notice");
messageConsumer.setMessageListener(registerNotice);
return messageConsumer;
}
@Bean
public TopicMoveNoticeListener registerTopicMoveNotice() {
return new TopicMoveNoticeListener();
public MessageConsumer<MemberSignInEvent> loginNoticeConsumer(
@Qualifier("signInEventQueue") RedisMessageQueue signInEventQueue,
@Qualifier("loginNotice") MessageListener<MemberSignInEvent> loginNotice){
MessageConsumer<MemberSignInEvent> messageConsumer = new com.github.davidmarquis.redisq.consumer.MessageConsumer<>();
messageConsumer.setQueue(signInEventQueue);
messageConsumer.setConsumerId("SignInEvent:Notice");
messageConsumer.setMessageListener(loginNotice);
return messageConsumer;
}
//Member事件侦听器
@Bean
public MemberSignUpNoticeListener registerSignUpNotice() {
return new MemberSignUpNoticeListener();
public MessageConsumer<MemberPenalizeEvent> penalizeNoticeConsumer(
@Qualifier("penalizeEventQueue") RedisMessageQueue penalizeEventQueue,
@Qualifier("penalizeNotice") MessageListener<MemberPenalizeEvent> penalizeNotice){
MessageConsumer<MemberPenalizeEvent> messageConsumer = new com.github.davidmarquis.redisq.consumer.MessageConsumer<>();
messageConsumer.setQueue(penalizeEventQueue);
messageConsumer.setConsumerId("PenalizeEvent:Notice");
messageConsumer.setMessageListener(penalizeNotice);
return messageConsumer;
}
@Bean
public MemberSignInNoticeListener registerSignInNotice() {
return new MemberSignInNoticeListener();
public MessageConsumer<MemberVipExchangeEvent> vipExchangeNoticeConsumer(
@Qualifier("vipExchangeEventQueue") RedisMessageQueue vipExchangeEventQueue,
@Qualifier("vipExchangeNotice") MessageListener<MemberVipExchangeEvent> vipExchangeNotice){
MessageConsumer<MemberVipExchangeEvent> messageConsumer = new com.github.davidmarquis.redisq.consumer.MessageConsumer<>();
messageConsumer.setQueue(vipExchangeEventQueue);
messageConsumer.setConsumerId("VipExchangeEvent:Notice");
messageConsumer.setMessageListener(vipExchangeNotice);
return messageConsumer;
}
}
\ No newline at end of file
package com.apobates.forum.thrones.event;
import com.github.davidmarquis.redisq.Message;
import com.github.davidmarquis.redisq.consumer.MessageListener;
import com.github.davidmarquis.redisq.consumer.retry.RetryableMessageException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import com.apobates.forum.letterbox.entity.ForumLetter;
import com.apobates.forum.letterbox.entity.ForumLetterReceiver;
import com.apobates.forum.letterbox.service.ForumLetterService;
import com.apobates.forum.member.entity.MemberStatusEnum;
import com.apobates.forum.member.impl.event.MemberPenalizeEvent;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* 会员惩罚通知
* @deprecated 暂时只能由管理端发布事件,但前端在不集成消息中间件时无法侦听
*
* @author xiaofanku
* @since 20190804
*/
public class MemberPenalizeNoticeListener implements ApplicationListener<MemberPenalizeEvent> {
@Component("penalizeNotice")
public class MemberPenalizeNoticeListener implements MessageListener<MemberPenalizeEvent> {
@Autowired
private ForumLetterService forumLetterService;
private final static Logger logger = LoggerFactory.getLogger(MemberPenalizeNoticeListener.class);
/*
*
6{
MemberChangeListener[JMS]
MemberRole[Status|Role]ChangeListener.java +3
MemberPenalizeNoticeListener[x]
MemberVipExchangeNoticeListener[x]
ModeratorRecall[Born]NoticeListener +2
}
14(JMS && ActiveMQ)
* */
@Override
public void onApplicationEvent(MemberPenalizeEvent event) {
public void onMessage(Message<MemberPenalizeEvent> event) throws RetryableMessageException {
logger.info("[Event][Member][10]惩罚记录通知开始");
MemberPenalizeEvent mpe = event.getPayload();
forumLetterService.create(
getPenalizeNotic(event.getReason(), event.getArrive(), event.getDuration()),
List.of(new ForumLetterReceiver(event.getMember(), event.getNames())));
getPenalizeNotic(mpe.getReason(), mpe.getArrive(), mpe.getDuration()),
List.of(new ForumLetterReceiver(mpe.getMember(), mpe.getNames())));
logger.info("[Event][Member][10]惩罚记录通知结束");
}
......
......@@ -5,10 +5,12 @@ import com.apobates.forum.event.utils.IpMatcher;
import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;
import com.github.davidmarquis.redisq.Message;
import com.github.davidmarquis.redisq.consumer.MessageListener;
import com.github.davidmarquis.redisq.consumer.retry.RetryableMessageException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationListener;
import com.apobates.forum.letterbox.entity.ForumLetter;
import com.apobates.forum.letterbox.entity.ForumLetterReceiver;
import com.apobates.forum.letterbox.service.ForumLetterService;
......@@ -17,15 +19,19 @@ import com.apobates.forum.member.entity.Member;
import com.apobates.forum.member.entity.MemberActiveRecords;
import com.apobates.forum.member.impl.event.MemberSignInEvent;
import com.apobates.forum.utils.DateTimeUtils;
import org.springframework.stereotype.Component;
import java.util.Optional;
/**
* 会员登录事件侦听器,异地登录通知
*
@Component("loginNotice")
@RedisEventConsumer(customerId="loginNotice", queue="redisMemberQueue", event = MemberSignInEvent.class)
* @author xiaofanku
* @since 20190703
*/
public class MemberSignInNoticeListener implements ApplicationListener<MemberSignInEvent> {
@Component("loginNotice")
public class MemberSignInNoticeListener implements MessageListener<MemberSignInEvent> {
@Autowired
private ForumLetterService forumLetterService;
@Autowired
......@@ -33,10 +39,11 @@ public class MemberSignInNoticeListener implements ApplicationListener<MemberSig
private final static Logger logger = LoggerFactory.getLogger(MemberSignInNoticeListener.class);
@Override
public void onApplicationEvent(MemberSignInEvent event) {
logger.info("[Event][Member][1]登录成功开始执行IP地域对比");
Member m = event.getMember();
String ipAddr = event.getIpAddr();
public void onMessage(Message<MemberSignInEvent> event) throws RetryableMessageException {
logger.info("[Event][Member][4]登录成功开始执行IP地域对比");
MemberSignInEvent mse = event.getPayload();
Member m = mse.getMember();
String ipAddr = mse.getIpAddr();
if (IpMatcher.isLoopbackIp(ipAddr)) {
return; //环回地址不通知
}
......@@ -57,7 +64,7 @@ public class MemberSignInNoticeListener implements ApplicationListener<MemberSig
getLoginAbnormalNotic(m.getNames(), LocalDateTime.now(), p.concat(c)),
List.of(new ForumLetterReceiver(m.getId(), m.getNickname())));
}
logger.info("[Event][Member][1]IP地域对比结束");
logger.info("[Event][Member][4]IP地域对比结束");
}
//登录时IP变更
......
package com.apobates.forum.thrones.event;
import com.github.davidmarquis.redisq.Message;
import com.github.davidmarquis.redisq.consumer.MessageListener;
import com.github.davidmarquis.redisq.consumer.retry.RetryableMessageException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.ApplicationListener;
import com.apobates.forum.letterbox.entity.ForumLetter;
import com.apobates.forum.letterbox.entity.ForumLetterReceiver;
import com.apobates.forum.letterbox.service.ForumLetterService;
import com.apobates.forum.member.entity.Member;
import com.apobates.forum.member.impl.event.MemberSignUpEvent;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* 会员注册事件侦听器,会员注册后的发送问候通知
*
@Component("registerNotice")
@RedisEventConsumer(customerId="registerNotice", queue="redisMemberQueue", event = MemberSignUpEvent.class)
* @author xiaofanku
* @since 20190703
*/
public class MemberSignUpNoticeListener implements ApplicationListener<MemberSignUpEvent> {
@Component("registerNotice")
public class MemberSignUpNoticeListener implements MessageListener<MemberSignUpEvent> {
@Autowired
private ForumLetterService forumLetterService;
@Value("${site.appname}")
private String appName;
private final static Logger logger = LoggerFactory.getLogger(MemberSignUpNoticeListener.class);
@Override
public void onApplicationEvent(MemberSignUpEvent event) {
public void onMessage(Message<MemberSignUpEvent> event) throws RetryableMessageException {
logger.info("[Event][Member][1]注册成功后发送通知开始");
Member m = event.getMember();
Member m = event.getPayload().getMember();
forumLetterService.create(
getRegisterNotice(appName),
List.of(new ForumLetterReceiver(m.getId(), m.getNickname())));
......
package com.apobates.forum.thrones.event;
import com.apobates.forum.letterbox.entity.ForumLetter;
import com.apobates.forum.letterbox.entity.ForumLetterReceiver;
import com.apobates.forum.letterbox.service.ForumLetterService;
import com.apobates.forum.member.entity.ForumCalendarUnitEnum;
import com.apobates.forum.member.entity.MemberVipExchangeRecords;
import com.apobates.forum.member.impl.event.MemberVipExchangeEvent;
import com.apobates.forum.utils.DateTimeUtils;
import com.github.davidmarquis.redisq.Message;
import com.github.davidmarquis.redisq.consumer.MessageListener;
import com.github.davidmarquis.redisq.consumer.retry.RetryableMessageException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.util.List;
@Component("vipExchangeNotice")
public class MemberVipExchangeNoticeListener implements MessageListener<MemberVipExchangeEvent> {
@Autowired
private ForumLetterService forumLetterService;
private final static Logger logger = LoggerFactory.getLogger(MemberVipExchangeNoticeListener.class);
@Override
public void onMessage(Message<MemberVipExchangeEvent> message) throws RetryableMessageException {
logger.info("[Event][Member][13]VIP会员开通通知开始发送");
MemberVipExchangeRecords ver = message.getPayload().getRecord();
forumLetterService.create(
getVipGroupNotic(ver.getMemberNickname(), ver.getActiveDateTime(), ver.getDuration(), ver.getDurationUnit()),
List.of(new ForumLetterReceiver(ver.getMemberId(), ver.getMemberNickname())));
logger.info("[Event][Member][13]VIP会员开通通知发送结束");
}
private ForumLetter getVipGroupNotic(String memberNickname, LocalDateTime activeDateTime, int duration, ForumCalendarUnitEnum durationUnit) {
return ForumLetter.noticeLetter(
"VIP会员开通通知",
String.format("恭喜您: %s, 您的VIP身份从%s开始,有效期: %d(%s)! 如果存在异议您可以联系在线管理员", memberNickname, DateTimeUtils.getRFC3339(activeDateTime), duration, durationUnit.getTitle()));
}
}
......@@ -13,6 +13,8 @@ import com.apobates.forum.letterbox.entity.ForumLetter;
import com.apobates.forum.letterbox.entity.ForumLetterReceiver;
import com.apobates.forum.letterbox.service.ForumLetterService;
import com.apobates.forum.utils.DateTimeUtils;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Optional;
......@@ -22,6 +24,7 @@ import java.util.Optional;
* @author xiaofanku
* @since 20191116
*/
@Component
public class PostsMoodNoticeListener implements ApplicationListener<PostsMoodEvent> {
@Autowired
private PostsService postsService;
......
......@@ -16,6 +16,8 @@ import com.apobates.forum.core.service.PostsService;
import com.apobates.forum.letterbox.entity.ForumLetter;
import com.apobates.forum.letterbox.entity.ForumLetterReceiver;
import com.apobates.forum.letterbox.service.ForumLetterService;
import org.springframework.stereotype.Component;
import java.util.List;
/**
......@@ -24,6 +26,7 @@ import java.util.List;
* @author xiaofanku
* @since 20200301
*/
@Component
public class PostsQuoteNoticeListener implements ApplicationListener<PostsPublishEvent> {
@Autowired
private PostsService postsService;
......
......@@ -13,6 +13,8 @@ import com.apobates.forum.letterbox.entity.ForumLetter;
import com.apobates.forum.letterbox.entity.ForumLetterReceiver;
import com.apobates.forum.letterbox.service.ForumLetterService;
import com.apobates.forum.utils.Commons;
import org.springframework.stereotype.Component;
import java.util.List;
import java.util.Optional;
......@@ -22,6 +24,7 @@ import java.util.Optional;
* @author xiaofanku
* @since 20190703
*/
@Component
public class PostsReplyNoticeListener implements ApplicationListener<PostsPublishEvent> {
@Autowired
private TopicService topicService;
......
......@@ -10,6 +10,8 @@ import com.apobates.forum.letterbox.entity.ForumLetter;
import com.apobates.forum.letterbox.entity.ForumLetterReceiver;
import com.apobates.forum.letterbox.service.ForumLetterService;
import com.apobates.forum.utils.DateTimeUtils;
import org.springframework.stereotype.Component;
import java.util.List;
/**
......@@ -18,6 +20,7 @@ import java.util.List;
* @author xiaofanku
* @since 20191117
*/
@Component
public class TopicMoveNoticeListener implements ApplicationListener<TopicMoveEvent> {
@Autowired
private ForumLetterService forumLetterService;
......
......@@ -59,6 +59,6 @@ jpa.batch.size=1000
# redis cache provider
cache.redis.host=127.0.0.1
cache.redis.port=6379
cache.redis.password=jedisroot
# cache.redis.password=jedisroot
cache.redis.database=1
cache.redis.timeout=60
\ No newline at end of file
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册