package com.yanghui.elephant.server.service; import java.util.Date; import java.util.Map; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.alibaba.fastjson.JSON; import com.yanghui.elephant.common.constant.MessageStatus; import com.yanghui.elephant.common.constant.ResponseCode; import com.yanghui.elephant.common.constant.SendStatus; import com.yanghui.elephant.common.message.Message; import com.yanghui.elephant.common.message.MessageType; import com.yanghui.elephant.common.protocol.header.SendMessageRequestHeader; import com.yanghui.elephant.common.utils.StringUtil; import com.yanghui.elephant.mq.producer.ProducerService; import com.yanghui.elephant.remoting.RequestProcessor; import com.yanghui.elephant.remoting.procotol.RemotingCommand; import com.yanghui.elephant.store.entity.MessageEntity; import com.yanghui.elephant.store.manager.MessageEntityManager; import com.yanghui.elephant.store.mapper.MessageEntityMapper; import io.netty.channel.ChannelHandlerContext; import lombok.extern.log4j.Log4j2; @Service @Log4j2 public class MessageRequestProcessor implements RequestProcessor { @Autowired private MessageEntityManager messageEntityManager; @Autowired private MessageEntityMapper messageEntityMapper; @Autowired private ProducerService producerService; @Override public RemotingCommand processRequest(ChannelHandlerContext ctx, RemotingCommand request) { log.info("处理请求消息:{}",request); SendMessageRequestHeader requestHeader = (SendMessageRequestHeader)request.decodeCommandCustomHeader(SendMessageRequestHeader.class); switch (MessageType.valueOf(requestHeader.getMessageType())) { case NORMAL_MESSAGE: return normalMessageHandle(requestHeader,request); case TRANSACTION_PRE_MESSAGE: return transactionMessageHandle(requestHeader,request); default: break; } return null; } private RemotingCommand transactionMessageHandle(SendMessageRequestHeader requestHeader, RemotingCommand request) { RemotingCommand response = RemotingCommand.buildResposeCmd(ResponseCode.SERVER_FAIL, request.getUnique()); MessageEntity entity = buildMessageEntity(request.getBody(), requestHeader, true); int responseCode = saveMessage(entity); response.setCode(responseCode); return response; } private MessageEntity buildMessageEntity(byte[] body,SendMessageRequestHeader requestHeader,boolean isTransaction) { MessageEntity entity = new MessageEntity(); entity.setBody(body); entity.setCreateTime(new Date()); entity.setDestination(requestHeader.getDestination()); entity.setGroup(requestHeader.getProducerGroup()); entity.setMessageId(requestHeader.getMessageId()); entity.setProperties(requestHeader.getProperties()); entity.setSendStatus(SendStatus.WAIT_SEND.getStatus()); entity.setUpdateTime(entity.getCreateTime()); if(isTransaction) { entity.setTransaction(true); entity.setStatus(MessageStatus.CONFIRMING.getStatus()); }else { entity.setTransaction(false); entity.setStatus(MessageStatus.CONFIRMED.getStatus()); } return entity; } private int saveMessage(MessageEntity entity) { try { MessageEntity find = this.messageEntityManager.findByMessageId(entity.getMessageId()); if(find == null) { this.messageEntityMapper.insert(entity); } return ResponseCode.SUCCESS; } catch (Exception e) { log.error("save message exception:{}",e); return ResponseCode.FUSH_DB_FAIL; } } @SuppressWarnings("unchecked") private RemotingCommand normalMessageHandle(SendMessageRequestHeader requestHeader,RemotingCommand request) { RemotingCommand response = RemotingCommand.buildResposeCmd(ResponseCode.SERVER_FAIL, request.getUnique()); MessageEntity entity = buildMessageEntity(request.getBody(), requestHeader, false); int responseCode = saveMessage(entity); if(responseCode != ResponseCode.SUCCESS) { response.setCode(responseCode); return response; } Message message = new Message(); message.setBody(request.getBody()); message.setDestination(requestHeader.getDestination()); message.setMessageId(requestHeader.getMessageId()); if(!StringUtil.isEmpty(requestHeader.getProperties())) { message.setProperties((Map<String, String>)JSON.parseObject(requestHeader.getProperties(),Map.class)); } try { this.producerService.sendMessage(message); } catch (Exception e) { log.error("send mq exception:{}",e); response.setCode(ResponseCode.SEND_MQ_FAIL); return response; } response.setCode(ResponseCode.SUCCESS); try { this.messageEntityManager.updateSendStatusByMessageId(SendStatus.ALREADY_SEND.getStatus(), requestHeader.getMessageId()); } catch (Exception e) { log.error("update message status exception:{}",e); } return response; } }