소스 검색

20220716 发短信和存短信基本已完成,尚缺接口层

lifuquan 2 년 전
부모
커밋
7da4dd7a05

+ 4 - 0
pom.xml

@@ -27,6 +27,10 @@
             <groupId>commons-configuration</groupId>
             <artifactId>commons-configuration</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.mybatis.spring.boot</groupId>
+            <artifactId>mybatis-spring-boot-starter</artifactId>
+        </dependency>
         <dependency>
             <groupId>org.postgresql</groupId>
             <artifactId>postgresql</artifactId>

+ 71 - 0
src/main/java/com/nokia/common/mybatis/JsonTypeHandler.java

@@ -0,0 +1,71 @@
+package com.nokia.common.mybatis;
+
+import java.sql.CallableStatement;
+import java.sql.PreparedStatement;
+import java.sql.ResultSet;
+import java.sql.SQLException;
+
+import org.apache.ibatis.type.BaseTypeHandler;
+import org.apache.ibatis.type.JdbcType;
+
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.ObjectMapper;
+
+/**
+ * 用于在mybatis中将java类型转化成json字符串存入数据库和从数据库读取json数据转化为java类型
+ * 无法转化集合类型
+ */
+public class JsonTypeHandler<T extends Object> extends BaseTypeHandler<T> {
+
+    private static final ObjectMapper MAPPER = new ObjectMapper();
+    private Class<T> clz;
+
+    public JsonTypeHandler(Class<T> clz) {
+        this.clz = clz;
+    }
+
+    @Override
+    public T getNullableResult(ResultSet resultSet, String columnName) throws SQLException {
+        if (columnName == null || columnName.isEmpty()) {
+            return null;
+        }
+        return (T) toObject(resultSet.getString(columnName), clz);
+    }
+
+    @Override
+    public T getNullableResult(ResultSet resultSet, int columnIndex) throws SQLException {
+        return (T) toObject(resultSet.getString(columnIndex), clz);
+    }
+
+    @Override
+    public T getNullableResult(CallableStatement callableStatement, int columnIndex) throws SQLException {
+        return (T) toObject(callableStatement.getString(columnIndex), clz);
+    }
+
+    @Override
+    public void setNonNullParameter(PreparedStatement preparedStatement, int columnIndex, T parameter,
+            JdbcType jdbcType)
+            throws SQLException {
+        preparedStatement.setString(columnIndex, toJson(parameter));
+    }
+
+    private String toJson(T parameter) {
+        try {
+            return MAPPER.writeValueAsString(parameter);
+        } catch (JsonProcessingException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+    private T toObject(String content, Class<T> clz) {
+        if (content == null || content.isEmpty()) {
+            return null;
+        }
+        try {
+            return (T) MAPPER.readValue(content, clz);
+        } catch (JsonProcessingException e) {
+            throw new RuntimeException(e);
+        }
+    }
+
+}

+ 10 - 0
src/main/java/com/nokia/sms/controller/SmsController.java

@@ -0,0 +1,10 @@
+package com.nokia.sms.controller;
+
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+
+@RestController
+@RequestMapping("/api/sms")
+public class SmsController {
+    
+}

+ 37 - 0
src/main/java/com/nokia/sms/dao/SmsDao.java

@@ -0,0 +1,37 @@
+package com.nokia.sms.dao;
+
+import org.apache.ibatis.annotations.Insert;
+import org.apache.ibatis.annotations.Mapper;
+import org.apache.ibatis.annotations.Result;
+import org.apache.ibatis.annotations.Results;
+import org.apache.ibatis.annotations.Select;
+import org.apache.ibatis.type.JdbcType;
+
+import com.nokia.common.mybatis.JsonTypeHandler;
+import com.nokia.sms.pojo.Sms;
+
+@Mapper
+public interface SmsDao {
+
+        @Insert("insert into sqmdb_rpt.sms_record (id, from_system, login_names, phone_numbers, content, schedule_time, sms_type, internal_id, result, send_time, status)"
+                        + " values (#{id}, #{fromSystem}, #{loginNames, jdbcType=VARCHAR, typeHandler=com.nokia.common.mybatis.JsonTypeHandler},"
+                        + " #{phoneNumbers, jdbcType=VARCHAR, typeHandler=com.nokia.common.mybatis.JsonTypeHandler}, #{content},"
+                        + " #{scheduleTime}, #{smsType}, #{internalId}, #{result}, #{sendTime}, #{status})")
+        void insert(Sms sms);
+
+        @Results({
+                        @Result(column = "id", property = "id"),
+                        @Result(column = "from_system", property = "fromSystem"),
+                        @Result(column = "login_names", property = "loginNames", jdbcType = JdbcType.VARCHAR, javaType = String[].class, typeHandler = JsonTypeHandler.class),
+                        @Result(column = "phone_numbers", property = "phoneNumbers", jdbcType = JdbcType.VARCHAR, javaType = String[].class, typeHandler = JsonTypeHandler.class),
+                        @Result(column = "content", property = "content"),
+                        @Result(column = "schedule_time", property = "scheduleTime"),
+                        @Result(column = "sms_type", property = "smsType"),
+                        @Result(column = "internal_id", property = "internalId"),
+                        @Result(column = "result", property = "result"),
+                        @Result(column = "send_time", property = "sendTime"),
+                        @Result(column = "status", property = "status"),
+        })
+        @Select("select * from sqmdb_rpt.sms_record where id = #{id}")
+        Sms selectById(String id);
+}

+ 9 - 3
src/main/java/com/nokia/sms/pojo/Sms.java

@@ -1,5 +1,6 @@
 package com.nokia.sms.pojo;
 
+import java.util.Date;
 import lombok.Data;
 
 @Data
@@ -7,8 +8,13 @@ public class Sms {
 
     private String id;
     private String fromSystem;
-    private String phone;
-    private String message;
-    private String messageType;
+    private String[] loginNames;
+    private String[] phoneNumbers;
+    private String content;
+    private Date scheduleTime;
+    private String smsType;
     private String internalId;
+    private String result;
+    private Date sendTime;
+    private String status;
 }

+ 50 - 0
src/main/java/com/nokia/sms/service/SgipSmsService.java

@@ -0,0 +1,50 @@
+package com.nokia.sms.service;
+
+import java.util.Arrays;
+import java.util.Date;
+import java.util.UUID;
+
+import org.springframework.stereotype.Service;
+
+import com.nokia.sms.dao.SmsDao;
+import com.nokia.sms.pojo.Sms;
+import com.nokia.sms.sgip.message.SendResult;
+import com.nokia.sms.sgip.mt.client.MTClient;
+
+import lombok.extern.slf4j.Slf4j;
+
+@Slf4j
+@Service
+public class SgipSmsService {
+
+    private final SmsDao smsDao;
+
+    public SgipSmsService(SmsDao smsDao) {
+        this.smsDao = smsDao;
+    }
+
+    public boolean sendMessage(Sms sms) {
+        log.info("准备发送短信: {}", sms);
+        sms.setId(UUID.randomUUID().toString());
+        sms.setSendTime(new Date());
+        try {
+            // 获取单例的MTClient
+            MTClient client = MTClient.getInstance();
+            // 发送短信
+            SendResult[] results = client.sendMessage(sms.getPhoneNumbers(), sms.getContent(), sms.getScheduleTime());
+            log.info("短信已成功发送, 发送结果: {}", Arrays.toString(results));
+            // 销毁应用
+            client.dispose();
+            sms.setResult(Arrays.toString(results));
+            sms.setStatus("已发送到短信网关");
+            return true;
+        } catch (Exception e) {
+            log.error("短信发送失败, 短信: {}, 错误信息: {}", sms, e.getMessage());
+            sms.setStatus("发送到短信网关失败");
+            e.printStackTrace();
+            return false;
+        } finally {
+            smsDao.insert(sms);
+        }
+    }
+}

+ 0 - 45
src/main/java/com/nokia/sms/service/SmsService.java

@@ -1,45 +0,0 @@
-package com.nokia.sms.service;
-
-import java.util.Arrays;
-
-import org.springframework.stereotype.Service;
-
-import com.nokia.sms.pojo.Sms;
-import com.nokia.sms.sgip.message.SendResult;
-import com.nokia.sms.sgip.mo.server.MOServer;
-import com.nokia.sms.sgip.mt.client.MTClient;
-
-import lombok.extern.slf4j.Slf4j;
-
-@Slf4j
-@Service
-public class SmsService {
-
-    public boolean sendMessage(Sms sms) {
-        log.debug("准备发送短信: {}", sms);
-        // 获取单例的MO服务端 必须在应用启动的时候就调用,用于启动上行和报告消息的监听端口,需要调用一次就行了
-        // 不调用该代码,会导致无法接受上行和报告短信
-        MOServer server = MOServer.getInstance();
-
-        // 获取单例的MTClient
-        MTClient client = MTClient.getInstance();
-
-        // 发送短信
-        SendResult[] results = client.sendMessage("8613231899751", "这是一条测试短信");
-        for (SendResult sendResult : results) {
-            log.debug("短信已成功发送, 短信序号为: {} , 发送结果: {}", Arrays.toString(sendResult.getFlowId()), sendResult.getResult());
-        }
-
-        try {
-            // 网关的报告消息需要一定时间才发送到,sleep一下等待报告消息
-            Thread.sleep(10000);
-        } catch (InterruptedException e) {
-            e.printStackTrace();
-        }
-
-        // 销毁应用
-        server.dispose();
-        client.dispose();
-        return true;
-    }
-}

+ 0 - 18
src/main/java/com/nokia/sms/sgip/message/BindMessage.java

@@ -79,22 +79,4 @@ public class BindMessage extends SgipMessage {
         return "BindMessage [head=" + this.head + ", loginName=" + this.loginName + ", loginPassword="
                 + this.loginPassword + ", loginType=" + this.loginType + ", reserve=" + this.reserve + "]";
     }
-
-    public static void main(String[] args) {
-        BindMessage message = new BindMessage();
-        message.setLoginName("aaa");
-        message.setLoginPassword("bbb");
-        message.setLoginType((byte) 1);
-        IoBuffer buffer = message.getBuffer();
-        System.out.println(buffer.limit());
-        BindMessage message2 = new BindMessage();
-        Head head = new Head();
-        head.parse(buffer);
-        try {
-            message2.parse(head, buffer);
-        } catch (IOException e) {
-            e.printStackTrace();
-        }
-        System.out.println(message2);
-    }
 }

+ 32 - 10
src/main/java/com/nokia/sms/sgip/mt/client/MTClient.java

@@ -2,6 +2,7 @@ package com.nokia.sms.sgip.mt.client;
 
 import java.io.UnsupportedEncodingException;
 import java.net.InetSocketAddress;
+import java.text.DateFormat;
 import java.text.SimpleDateFormat;
 import java.util.Date;
 import java.util.concurrent.ExecutionException;
@@ -41,7 +42,7 @@ public class MTClient {
     private IoConnector connector;
     private CompositeConfiguration config = SgipConfig.getConfig();
     private static MTClient sgipClient;
-    private static final SimpleDateFormat dateForamt = new SimpleDateFormat("yyMMddHHmmss032+");
+    private static final DateFormat dateForamt = new SimpleDateFormat("yyMMddHHmmss032+");
     private IoSession session;
 
     public static synchronized MTClient getInstance() {
@@ -77,7 +78,7 @@ public class MTClient {
         this.connector.getFilterChain().addLast("exceutor", new ExecutorFilter(executor));
 
         MessageUtil.setNodeId((int) this.config.getLong("sgip_mt_node_id"));
-        log.info("Inited!");
+        log.debug("Inited!");
     }
 
     private synchronized IoSession getSession() {
@@ -129,7 +130,7 @@ public class MTClient {
 
                 WriteFuture write = this.session.write(bind);
                 write.awaitUninterruptibly();
-                log.info("Write:" + bind);
+                log.debug("Write:" + bind);
                 RespCaller caller = new RespCaller();
                 FutureTask<Byte> task = new FutureTask<>(caller);
                 String flowId = bind.getHead().getStrFlowId();
@@ -184,7 +185,7 @@ public class MTClient {
             log.error("Fail to get session!");
         } else {
             session.write(message);
-            log.info("{}", message);
+            log.debug("{}", message);
             RespCaller caller = new RespCaller();
             FutureTask<Byte> task = new FutureTask<>(caller);
             String flowId = message.getHead().getStrFlowId();
@@ -219,7 +220,7 @@ public class MTClient {
         }
         SendResult messageResult = new SendResult(message.getHead().getFlowId(), result);
 
-        log.info("{}", messageResult);
+        log.debug("{}", messageResult);
         return messageResult;
     }
 
@@ -227,27 +228,52 @@ public class MTClient {
         return sendMessage(null, new String[] { userNumber }, content, null);
     }
 
+    public SendResult[] sendMessage(String userNumber, String content, Date scheduleTime) {
+        return sendMessage(null, new String[] { userNumber }, content, scheduleTime);
+    }
+
     public SendResult[] sendMessage(String extendPort, String userNumber, String content, Date scheduleTime) {
         return sendMessage(extendPort, new String[] { userNumber }, content, scheduleTime);
     }
 
+    public SendResult[] sendMessage(String[] userNumbers, String content) {
+        return sendMessage(null, userNumbers, content, null);
+    }
+
+    public SendResult[] sendMessage(String[] userNumbers, String content, Date scheduleTime) {
+        return sendMessage(null, userNumbers, content, scheduleTime);
+    }
+
+    /**
+     * 发送短信
+     * 
+     * @param extendPort   字符串,接入号尾号,如果传入会添加在接入号的末尾
+     * @param userNumber   字符串数组, 发送
+     * @param content      短信内容
+     * @param scheduleTime 发送时间
+     * @return 发送结果
+     */
     public SendResult[] sendMessage(String extendPort, String[] userNumber, String content, Date scheduleTime) {
+        // 用于添加签名
         String signature = this.config.getString("sms_signature", null);
         if ((signature != null) && (!"".equals(signature))) {
             content = content + signature;
         }
         byte[] messageContent = null;
         try {
+            // 转换编码方式为 UnicodeBigUnmarked
             messageContent = content.getBytes("UnicodeBigUnmarked");
         } catch (UnsupportedEncodingException e) {
             log.error("Fail to getByte by UnicodeBigUnmarked!" + e.getMessage());
         }
+        // 预定发送时间
         String strScheduleTime = null;
         if (scheduleTime != null) {
             strScheduleTime = dateForamt.format(scheduleTime);
         }
         SubmitMessage message = new SubmitMessage();
         initSumitMessage(message);
+        // 如果传入extendPort会添加到接入号末尾
         if (extendPort == null) {
             message.setSpNumber(this.config.getString("sgip_mt_sp_number"));
         } else {
@@ -345,14 +371,10 @@ public class MTClient {
             service.shutdownNow();
         }
         sgipClient = null;
-        log.info("Disposed!");
+        log.debug("Disposed!");
     }
 
     public void sendUnBindMessage() {
         getSession().write(new UnBindMessage());
     }
-
-    public static void main(String[] args)
-            throws UnsupportedEncodingException {
-    }
 }

+ 15 - 0
src/main/java/com/nokia/sms/vo/MultiNumberSms.java

@@ -0,0 +1,15 @@
+package com.nokia.sms.vo;
+
+import java.util.Date;
+
+import lombok.Data;
+
+@Data
+public class MultiNumberSms {
+    private String fromSystem;
+    private String[] phoneNumbers;
+    private String content;
+    private Date scheduleTime;
+    private String smsType;
+    private String internalId;
+}

+ 15 - 0
src/main/java/com/nokia/sms/vo/SingleNumberSms.java

@@ -0,0 +1,15 @@
+package com.nokia.sms.vo;
+
+import java.util.Date;
+
+import lombok.Data;
+
+@Data
+public class SingleNumberSms {
+    private String fromSystem;
+    private String phoneNumber;
+    private String content;
+    private Date scheduleTime;
+    private String smsType;
+    private String internalId;
+}

+ 9 - 1
src/main/resources/application.properties

@@ -1 +1,9 @@
-server.port=12080
+server.port=12080
+
+logging.file.name=logs/sms_server.log
+
+# 正式环境数据源GP数据库配置
+spring.datasource.driver-class-name=org.postgresql.Driver
+spring.datasource.url=jdbc:postgresql://192.168.70.109:5432/sqmmt
+spring.datasource.username=sqmdb
+spring.datasource.password=sqmdb_1QAZ

+ 12 - 8
src/main/resources/sgipConfig.properties

@@ -1,6 +1,7 @@
 #=======与网关的连接配置信息========
 # 网关ip
-sgip_mt_server_ip=133.96.90.123
+# sgip_mt_server_ip=133.96.90.123
+sgip_mt_server_ip=10.17.141.26
 # 网关端口
 sgip_mt_server_port=8801
 # 连接最大空闲时间,建议值50
@@ -9,7 +10,7 @@ sgip_mt_client_max_idle_time=50
 sgip_mt_received_time_out=20
 #======与网关的连接配置信息结束======
 
-#\u4E0B\u884C\u77ED\u4FE1\u7684\u7B7E\u540D(\u53EF\u5305\u542B\u7A7A\u683C),\u5982\u914D\u7F6E\u4E3Asgip_mt_message_signature=--\u5E7F\u4E1C\u8054\u901A\uFF0C\u5219\u4E0B\u53D1\u7684\u77ED\u4FE1\u4F1A\u662F\uFF1A\u201C\u6D4B\u8BD5\u77ED\u4FE1 --\u5E7F\u4E1C\u8054\u901A\u201D\u3002\u7559\u7A7A\u5219\u4E0D\u6DFB\u52A0\u7B7E\u540D
+# 下行短信的签名(可包含空格),如配置为sgip_mt_message_signature=--广东联通,则下发的短信会是:“测试短信 --广东联通”。留空则不添加签名
 # 使用这个配置必须配置文件为UTF-8编码
 sms_signature=
 
@@ -17,16 +18,19 @@ sms_signature=
 # 从sgip_mt_charge_number到sgip_mt_message_type在不清楚含义的情况下不要随意修改
 
 # 网关分配给sp的节点号
-sgip_mt_node_id=14362
+# sgip_mt_node_id=14362
+sgip_mt_node_id=14039
 # sp作为客户绑定网关时的用户名 
-sgip_mt_login_name=14362
+# sgip_mt_login_name=14362
+sgip_mt_login_name=14039
 # sp作为客户绑定网关时的密码
 sgip_mt_login_password=ZXwg20@@
-# 网关分配给sp的主端口号
-sgip_mt_sp_number=1065577000
+# 网关分配给sp的接入号
+# sgip_mt_sp_number=1065577000
+sgip_mt_sp_number=1065572174
 # 企业代码
-sgip_mt_corp_id=14362
-#\u4ED8\u8D39\u53F7\u7801
+# sgip_mt_corp_id=14362
+sgip_mt_corp_id=14039
 # 付费号码
 sgip_mt_charge_number=000000000000000000000
 # 业务代码

+ 36 - 0
src/test/com/nokia/sms/dao/SmsDaoTest.java

@@ -0,0 +1,36 @@
+package com.nokia.sms.dao;
+
+import java.util.Date;
+import java.util.UUID;
+
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.boot.test.context.SpringBootTest;
+
+import com.nokia.sms.pojo.Sms;
+
+@SpringBootTest
+public class SmsDaoTest {
+
+    @Autowired
+    private SmsDao smsDao;
+
+    @Test
+    void testInsert() {
+        Sms sms = new Sms();
+        sms.setId(UUID.randomUUID().toString());
+        sms.setFromSystem("test");
+        sms.setPhoneNumbers(new String[] { "13231899751", "15633560090" });
+        sms.setContent("测试Dao");
+        sms.setScheduleTime(new Date());
+        sms.setSmsType("test");
+        smsDao.insert(sms);
+    }
+
+    @Test
+    void testSelectById() {
+        String id = "5a138699-347a-4b4d-b5f7-f269290f55dc";
+        Sms sms = smsDao.selectById(id);
+        System.out.println(sms);
+    }
+}

+ 21 - 2
src/test/com/nokia/sms/service/SmsServiceTest.java

@@ -1,5 +1,7 @@
 package com.nokia.sms.service;
 
+import java.util.Date;
+
 import org.junit.jupiter.api.Test;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.test.context.SpringBootTest;
@@ -9,11 +11,28 @@ import com.nokia.sms.pojo.Sms;
 @SpringBootTest
 public class SmsServiceTest {
     @Autowired
-    private SmsService service;
+    private SgipSmsService service;
 
+    // 测试批量发送
     @Test
     public void test() {
-        boolean b = service.sendMessage(new Sms());
+        Sms sms = new Sms();
+        sms.setPhoneNumbers(new String[] { "13231899751", "18631181961", "18031151219", "15633560090", "15996582933" });
+        sms.setContent("这是一条测试短信--" + new Date());
+        boolean b = service.sendMessage(sms);
+        System.out.println(b);
+    }
+
+    // 测试定时发送
+    @Test
+    public void test2() {
+        Sms sms = new Sms();
+        sms.setFromSystem("测试");
+        sms.setPhoneNumbers(new String[] { "13231899751" });
+        sms.setContent("这是一条测试短信--" + new Date());
+        // 5分钟后发送
+        sms.setScheduleTime(new Date(System.currentTimeMillis() + 5 * 60 * 1000));
+        boolean b = service.sendMessage(sms);
         System.out.println(b);
     }
 }