| @@ -20,6 +20,16 @@ | |||||
| <artifactId>framework</artifactId> | <artifactId>framework</artifactId> | ||||
| <version>1.0-SNAPSHOT</version> | <version>1.0-SNAPSHOT</version> | ||||
| </dependency> | </dependency> | ||||
| <dependency> | |||||
| <groupId>net.sf.dozer</groupId> | |||||
| <artifactId>dozer</artifactId> | |||||
| <version>5.5.1</version> | |||||
| </dependency> | |||||
| <dependency> | |||||
| <groupId>com.aliyun.openservices</groupId> | |||||
| <artifactId>ons-client</artifactId> | |||||
| <version>1.8.4.Final</version> | |||||
| </dependency> | |||||
| <!-- MySql数据库驱动 --> | <!-- MySql数据库驱动 --> | ||||
| <dependency> | <dependency> | ||||
| <groupId>mysql</groupId> | <groupId>mysql</groupId> | ||||
| @@ -0,0 +1,75 @@ | |||||
| package com.neusoft.smart.pos.mq; | |||||
| import java.util.Properties; | |||||
| import javax.annotation.PostConstruct; | |||||
| import org.springframework.beans.factory.annotation.Value; | |||||
| import org.springframework.context.annotation.Profile; | |||||
| import org.springframework.stereotype.Service; | |||||
| import com.alibaba.fastjson.JSON; | |||||
| import com.aliyun.openservices.ons.api.Action; | |||||
| import com.aliyun.openservices.ons.api.ConsumeContext; | |||||
| import com.aliyun.openservices.ons.api.Consumer; | |||||
| import com.aliyun.openservices.ons.api.Message; | |||||
| import com.aliyun.openservices.ons.api.MessageListener; | |||||
| import com.aliyun.openservices.ons.api.ONSFactory; | |||||
| import com.aliyun.openservices.ons.api.PropertyKeyConst; | |||||
| import com.aliyun.openservices.ons.api.bean.ConsumerBean; | |||||
| import lombok.extern.slf4j.Slf4j; | |||||
| @Slf4j | |||||
| @Service | |||||
| @Profile(MQConfig.Impl.ALIYUN_ROCKET_MQ) | |||||
| public class AliyunRocketMqConsumer extends MqBaseConsumer { | |||||
| @Value("${spring.aliyunRocketmq.accessKeyId}") | |||||
| private String accessKeyId; | |||||
| @Value("${spring.aliyunRocketmq.accessKeySecret}") | |||||
| private String accessKeySecret; | |||||
| @Value("${spring.aliyunRocketmq.groupId}") | |||||
| private String groupId; | |||||
| @Value("${spring.aliyunRocketmq.namesrvAddr}") | |||||
| private String namesrvAddr; | |||||
| @PostConstruct | |||||
| public void init() { | |||||
| for (EnumMsgMqTopic topic: EnumMsgMqTopic.values()) { | |||||
| Properties properties = new Properties(); | |||||
| // 您在控制台创建的 Group ID | |||||
| properties.put(PropertyKeyConst.GROUP_ID, topic.getGroupId()); | |||||
| // AccessKey 阿里云身份验证,在阿里云服务器管理控制台创建 | |||||
| properties.put(PropertyKeyConst.AccessKey, accessKeyId); | |||||
| // SecretKey 阿里云身份验证,在阿里云服务器管理控制台创建 | |||||
| properties.put(PropertyKeyConst.SecretKey, accessKeySecret); | |||||
| // 设置 TCP 接入域名,到控制台的实例基本信息中查看 | |||||
| properties.put(PropertyKeyConst.NAMESRV_ADDR,namesrvAddr); | |||||
| // 集群订阅方式(默认) | |||||
| // properties.put(PropertyKeyConst.MessageModel, PropertyValueConst.CLUSTERING); | |||||
| // 广播订阅方式 | |||||
| // properties.put(PropertyKeyConst.MessageModel, PropertyValueConst.BROADCASTING); | |||||
| Consumer consumer = ONSFactory.createConsumer(properties); | |||||
| consumer.subscribe(topic.getCode(), "*", new MessageListener() { //订阅多个 Tag | |||||
| public Action consume(Message message, ConsumeContext context) { | |||||
| try { | |||||
| System.out.println("Receive: " + message); | |||||
| doMessage(new String(message.getBody())); | |||||
| return Action.CommitMessage; | |||||
| }catch(Exception e) { | |||||
| log.error("AliyunRocketMqConsumer error:",e); | |||||
| return Action.ReconsumeLater; | |||||
| } | |||||
| } | |||||
| }); | |||||
| consumer.start(); | |||||
| log.info(" aliyunrocketMq consumer start success! "+JSON.toJSONString(consumer)); | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,118 @@ | |||||
| package com.neusoft.smart.pos.mq; | |||||
| import java.util.Date; | |||||
| import java.util.HashMap; | |||||
| import java.util.Map; | |||||
| import java.util.Properties; | |||||
| import javax.annotation.PostConstruct; | |||||
| import org.slf4j.Logger; | |||||
| import org.slf4j.LoggerFactory; | |||||
| import org.springframework.beans.factory.annotation.Value; | |||||
| import org.springframework.context.annotation.Profile; | |||||
| import org.springframework.stereotype.Service; | |||||
| import com.alibaba.fastjson.JSON; | |||||
| import com.aliyun.openservices.ons.api.Message; | |||||
| import com.aliyun.openservices.ons.api.ONSFactory; | |||||
| import com.aliyun.openservices.ons.api.Producer; | |||||
| import com.aliyun.openservices.ons.api.PropertyKeyConst; | |||||
| import com.aliyun.openservices.ons.api.SendResult; | |||||
| /** | |||||
| * @Auther: zfy 阿里云rocketmq | |||||
| * @Date: 2019-01-31 | |||||
| * @Description: RocketMQ消息生产者 | |||||
| */ | |||||
| @Service | |||||
| @Profile(MQConfig.Impl.ALIYUN_ROCKET_MQ) | |||||
| public class AliyunRocketMqMessageProducer implements MqProducer { | |||||
| private final Logger log = LoggerFactory.getLogger(this.getClass()); | |||||
| @Value("${spring.aliyunRocketmq.accessKeyId}") | |||||
| private String accessKeyId; | |||||
| @Value("${spring.aliyunRocketmq.accessKeySecret}") | |||||
| private String accessKeySecret; | |||||
| @Value("${spring.aliyunRocketmq.groupId}") | |||||
| private String groupId; | |||||
| @Value("${spring.aliyunRocketmq.namesrvAddr}") | |||||
| private String namesrvAddr; | |||||
| //@Autowired | |||||
| //private WxMsgRecordMapper wxMsgRecordMapper; | |||||
| //@Autowired | |||||
| //private WxMsgRecordService wxMsgRecordService; | |||||
| private static Map<String,Producer> producerMap = null; | |||||
| @PostConstruct | |||||
| public void init() { | |||||
| producerMap = new HashMap<String,Producer>(); | |||||
| for (EnumMsgMqTopic topic: EnumMsgMqTopic.values()) { | |||||
| Properties properties = new Properties(); | |||||
| properties.setProperty(PropertyKeyConst.GROUP_ID, topic.getGroupId()); | |||||
| // AccessKey 阿里云身份验证,在阿里云服务器管理控制台创建 | |||||
| properties.put(PropertyKeyConst.AccessKey,accessKeyId); | |||||
| // SecretKey 阿里云身份验证,在阿里云服务器管理控制台创建 | |||||
| properties.put(PropertyKeyConst.SecretKey, accessKeySecret); | |||||
| //设置发送超时时间,单位毫秒 | |||||
| properties.setProperty(PropertyKeyConst.SendMsgTimeoutMillis, "3000"); | |||||
| // 设置 TCP 接入域名,到控制台的实例基本信息中查看 | |||||
| properties.put(PropertyKeyConst.NAMESRV_ADDR,namesrvAddr); | |||||
| Producer producer = ONSFactory.createProducer(properties); | |||||
| // 在发送消息前,必须调用 start 方法来启动 Producer,只需调用一次即可 | |||||
| producer.start(); | |||||
| log.info("aliyunrocketmq producer info :"+JSON.toJSONString(producer)); | |||||
| producerMap.put(topic.getCode(), producer); | |||||
| } | |||||
| } | |||||
| @Override | |||||
| public void sendMessage(Object data, String topic, String tags, String keys) { | |||||
| Producer producer = producerMap.get(topic); | |||||
| if (null == producer) { | |||||
| log.error("topic :"+topic+" has no AliyunRocketMqMessageProducer."); | |||||
| return; | |||||
| } | |||||
| if (producer.isClosed()) { | |||||
| producer.start(); | |||||
| } | |||||
| //循环发送消息 | |||||
| Message msg = new Message( // | |||||
| // Message 所属的 Topic | |||||
| topic, | |||||
| // Message Tag 可理解为 Gmail 中的标签,对消息进行再归类,方便 Consumer 指定过滤条件在 MQ 服务器过滤 | |||||
| tags, | |||||
| // Message Body 可以是任何二进制形式的数据, MQ 不做任何干预, | |||||
| // 需要 Producer 与 Consumer 协商好一致的序列化和反序列化方式 | |||||
| JsonUtil.obj2Json(data).getBytes()); | |||||
| // 设置代表消息的业务关键属性,请尽可能全局唯一。 | |||||
| // 以方便您在无法正常收到消息情况下,可通过阿里云服务器管理控制台查询消息并补发 | |||||
| // 注意:不设置也不会影响消息正常收发 | |||||
| msg.setKey(keys); | |||||
| try { | |||||
| SendResult sendResult = producer.send(msg); | |||||
| // 同步发送消息,只要不抛异常就是成功 | |||||
| if (sendResult != null) { | |||||
| System.out.println(new Date() + " Send mq message success. Topic is:" + msg.getTopic() + " msgId is: " + sendResult.getMessageId()); | |||||
| } | |||||
| } | |||||
| catch (Exception e) { | |||||
| // 消息发送失败,需要进行重试处理,可重新发送这条消息或持久化这条数据进行补偿处理 | |||||
| System.out.println(new Date() + " Send mq message failed. Topic is:" + msg.getTopic()); | |||||
| e.printStackTrace(); | |||||
| } | |||||
| // 在应用退出前,销毁 Producer 对象 | |||||
| // 注意:如果不销毁也没有问题 | |||||
| //producer.shutdown(); | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,45 @@ | |||||
| package com.neusoft.smart.pos.mq; | |||||
| /** | |||||
| * Created by luozukai | |||||
| */ | |||||
| public enum EnumMsgMqTopic { | |||||
| DEFAULT("topic-1","GID_P_1", "默认"), | |||||
| STOCK("stock","GID_P_2","库存"), | |||||
| ; | |||||
| public static EnumMsgMqTopic getEnum(String code) { | |||||
| for (EnumMsgMqTopic value : values()) { | |||||
| if (value.getCode().equals(code)) { | |||||
| return value; | |||||
| } | |||||
| } | |||||
| return null; | |||||
| } | |||||
| private String code; | |||||
| private String message; | |||||
| private String groupId; | |||||
| EnumMsgMqTopic(String code, String groupId,String message) { | |||||
| this.code = code; | |||||
| this.message = message; | |||||
| this.groupId = groupId; | |||||
| } | |||||
| public String getCode() { | |||||
| return code; | |||||
| } | |||||
| public String getMessage() { | |||||
| return message; | |||||
| } | |||||
| public String getGroupId() { | |||||
| return groupId; | |||||
| } | |||||
| public void setGroupId(String groupId) { | |||||
| this.groupId = groupId; | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,128 @@ | |||||
| package com.neusoft.smart.pos.mq; | |||||
| import com.fasterxml.jackson.annotation.JsonInclude; | |||||
| import com.fasterxml.jackson.core.JsonGenerator; | |||||
| import com.fasterxml.jackson.core.JsonParser; | |||||
| import com.fasterxml.jackson.core.JsonProcessingException; | |||||
| import com.fasterxml.jackson.databind.DeserializationFeature; | |||||
| import com.fasterxml.jackson.databind.JsonSerializer; | |||||
| import com.fasterxml.jackson.databind.ObjectMapper; | |||||
| import com.fasterxml.jackson.databind.SerializerProvider; | |||||
| import com.fasterxml.jackson.databind.module.SimpleModule; | |||||
| import org.slf4j.Logger; | |||||
| import org.slf4j.LoggerFactory; | |||||
| import java.io.IOException; | |||||
| import java.text.SimpleDateFormat; | |||||
| import java.util.HashMap; | |||||
| import java.util.Iterator; | |||||
| import java.util.Map; | |||||
| public final class JsonUtil { | |||||
| private static Logger log = LoggerFactory.getLogger(JsonUtil.class); | |||||
| public static final ObjectMapper mapper = new ObjectMapper(); | |||||
| private JsonUtil() { | |||||
| } | |||||
| public static String obj2Json(Object obj) { | |||||
| if(obj != null) { | |||||
| try { | |||||
| return mapper.writeValueAsString(obj); | |||||
| } catch (JsonProcessingException var2) { | |||||
| throw new RuntimeException(var2); | |||||
| } | |||||
| } else { | |||||
| return null; | |||||
| } | |||||
| } | |||||
| public static byte[] obj2Byte(Object obj) { | |||||
| if(obj != null) { | |||||
| try { | |||||
| return mapper.writeValueAsBytes(obj); | |||||
| } catch (JsonProcessingException var2) { | |||||
| var2.printStackTrace(); | |||||
| } | |||||
| } | |||||
| return new byte[0]; | |||||
| } | |||||
| public static Object readValue(String json, Class<?> clazz) { | |||||
| Object t = null; | |||||
| try { | |||||
| return mapper.readValue(json, clazz); | |||||
| } catch (Exception var4) { | |||||
| log.info("解析对象:{}", json); | |||||
| log.error("json解析错误:{}", var4.getMessage(), var4); | |||||
| return t; | |||||
| } | |||||
| } | |||||
| // public static <T> T readValue(String json, TypeReference type) { | |||||
| // Object object = null; | |||||
| // | |||||
| // try { | |||||
| // object = mapper.readValue(json, type); | |||||
| // } catch (Exception var4) { | |||||
| // log.info("解析对象:{}", json); | |||||
| // log.error("json解析错误:{}", var4.getMessage(), var4); | |||||
| // } | |||||
| // | |||||
| // return object; | |||||
| // } | |||||
| // | |||||
| // public static <T> T readValue(byte[] json, TypeReference type) { | |||||
| // Object object = null; | |||||
| // | |||||
| // try { | |||||
| // object = mapper.readValue(json, type); | |||||
| // } catch (Exception var4) { | |||||
| // log.info("解析对象:{}", json); | |||||
| // log.error("json解析错误:{}", var4.getMessage(), var4); | |||||
| // } | |||||
| // | |||||
| // return object; | |||||
| // } | |||||
| // | |||||
| // public static Map<String, Object> readValueAsMap(String json) { | |||||
| // return (Map)readValue(json, new TypeReference<HashMap<String, Object>>() { | |||||
| // }); | |||||
| // } | |||||
| static { | |||||
| mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); | |||||
| mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_CONTROL_CHARS, true); | |||||
| mapper.configure(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT, true); | |||||
| mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); | |||||
| mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")); | |||||
| SimpleModule module = new SimpleModule(); | |||||
| module.addSerializer(HashMap.class, new JsonUtil.HashMapSerializer()); | |||||
| mapper.registerModule(module); | |||||
| } | |||||
| public static class HashMapSerializer extends JsonSerializer<HashMap> { | |||||
| public HashMapSerializer() { | |||||
| } | |||||
| public void serialize(HashMap value, JsonGenerator jgen, SerializerProvider provider) throws IOException { | |||||
| jgen.writeStartObject(); | |||||
| Iterator var4 = value.entrySet().iterator(); | |||||
| while(var4.hasNext()) { | |||||
| Object entry = var4.next(); | |||||
| if(entry instanceof Map.Entry) { | |||||
| Map.Entry en = (Map.Entry)entry; | |||||
| if(en.getValue() != null && en.getKey() != null) { | |||||
| jgen.writeObjectField(en.getKey().toString(), en.getValue()); | |||||
| } | |||||
| } | |||||
| } | |||||
| jgen.writeEndObject(); | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,9 @@ | |||||
| package com.neusoft.smart.pos.mq; | |||||
| public class MQConfig { | |||||
| public static class Impl { | |||||
| public static final String RABBIT_MQ = "rabbitMQ"; | |||||
| public static final String ROCKET_MQ = "rocketMQ"; | |||||
| public static final String ALIYUN_ROCKET_MQ = "aliyunRocketMQ"; | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,7 @@ | |||||
| package com.neusoft.smart.pos.mq; | |||||
| public interface MqProducer { | |||||
| public void sendMessage(Object data, String topic, String tags, String keys); | |||||
| } | |||||