|
@@ -4,6 +4,7 @@ import com.alibaba.fastjson2.JSON;
|
|
|
import com.nokia.common.http.R;
|
|
|
import com.nokia.sms.dao.SmsDao;
|
|
|
import com.nokia.sms.pojo.Sms;
|
|
|
+import com.nokia.sms.pojo.SmsReport;
|
|
|
import com.nokia.sms.sgip.message.SendResult;
|
|
|
import com.nokia.sms.sgip.mt.client.MTClient;
|
|
|
import lombok.Data;
|
|
@@ -12,11 +13,15 @@ import org.springframework.boot.context.properties.ConfigurationProperties;
|
|
|
import org.springframework.stereotype.Service;
|
|
|
|
|
|
import javax.annotation.PostConstruct;
|
|
|
+import java.util.ArrayList;
|
|
|
import java.util.Arrays;
|
|
|
import java.util.Date;
|
|
|
+import java.util.LinkedHashMap;
|
|
|
+import java.util.List;
|
|
|
import java.util.UUID;
|
|
|
import java.util.concurrent.CompletableFuture;
|
|
|
import java.util.concurrent.LinkedBlockingQueue;
|
|
|
+import java.util.stream.Collectors;
|
|
|
|
|
|
@Slf4j
|
|
|
@Service
|
|
@@ -25,14 +30,16 @@ import java.util.concurrent.LinkedBlockingQueue;
|
|
|
public class SgipSmsService {
|
|
|
static final LinkedBlockingQueue<Sms> QUEUE = new LinkedBlockingQueue<>();
|
|
|
private final SmsDao smsDao;
|
|
|
+ private final MTClient mtClient;
|
|
|
|
|
|
/**
|
|
|
* 最大重试次数
|
|
|
*/
|
|
|
private Integer maxRetry;
|
|
|
|
|
|
- public SgipSmsService(SmsDao smsDao) {
|
|
|
+ public SgipSmsService(SmsDao smsDao, MTClient mtClient) {
|
|
|
this.smsDao = smsDao;
|
|
|
+ this.mtClient = mtClient;
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -42,27 +49,39 @@ public class SgipSmsService {
|
|
|
* @return {@link R}
|
|
|
*/
|
|
|
public R offer(Sms sms) {
|
|
|
- if (QUEUE.offer(sms)) {
|
|
|
- return R.ok();
|
|
|
- } else {
|
|
|
+ if (!QUEUE.offer(sms)) {
|
|
|
log.error("入队失败");
|
|
|
return R.error();
|
|
|
}
|
|
|
+ return R.ok();
|
|
|
}
|
|
|
|
|
|
public void sendMessage(Sms sms) {
|
|
|
+ List<SmsReport> smsReportList = new ArrayList<>();
|
|
|
+ LinkedHashMap<String, String> sendResultMap = new LinkedHashMap<>();
|
|
|
try {
|
|
|
log.debug("准备发送短信: {}", JSON.toJSONString(sms));
|
|
|
- sms.setId(UUID.randomUUID().toString());
|
|
|
+ String id = UUID.randomUUID().toString();
|
|
|
+ sms.setId(id);
|
|
|
sms.setSendTime(new Date());
|
|
|
- // 获取单例的MTClient
|
|
|
- MTClient client = MTClient.getInstance();
|
|
|
- // 发送短信
|
|
|
- SendResult[] results = client.sendMessage(sms.getPhoneNumbers(), sms.getContent(), sms.getScheduleTime());
|
|
|
- log.debug("短信已成功发送, 发送结果: {}", Arrays.toString(results));
|
|
|
- // 销毁应用
|
|
|
- client.dispose();
|
|
|
- sms.setResult(Arrays.toString(results));
|
|
|
+ for (String phoneNumber : sms.getPhoneNumbers()) {
|
|
|
+ // 发送短信
|
|
|
+ SendResult[] results = mtClient.sendMessage(phoneNumber, sms.getContent(), sms.getScheduleTime());
|
|
|
+ String resultString = Arrays.toString(results);
|
|
|
+ log.debug("{}短信已成功发送, 发送结果: {}", phoneNumber, resultString);
|
|
|
+ sendResultMap.put(phoneNumber, resultString);
|
|
|
+ sms.setResult(JSON.toJSONString(sendResultMap));
|
|
|
+ for (SendResult result : results) {
|
|
|
+ String flowId = Arrays.stream(result.getFlowId())
|
|
|
+ .mapToObj(Integer::toString).collect(Collectors.joining("-"));
|
|
|
+ SmsReport smsReport = new SmsReport();
|
|
|
+ smsReport.setId(id);
|
|
|
+ smsReport.setPhone(phoneNumber);
|
|
|
+ smsReport.setSendTime(new Date());
|
|
|
+ smsReport.setFlowId(flowId);
|
|
|
+ smsReportList.add(smsReport);
|
|
|
+ }
|
|
|
+ }
|
|
|
// if (ThreadLocalRandom.current().nextBoolean()) {
|
|
|
// throw new RuntimeException("异常测试");
|
|
|
// }
|
|
@@ -70,15 +89,14 @@ public class SgipSmsService {
|
|
|
log.info("短信发送成功: {}", JSON.toJSONString(sms));
|
|
|
} catch (Exception e) {
|
|
|
sms.setStatus("发送到短信网关失败");
|
|
|
- log.error("短信发送失败, 短信: {}, 错误信息: {}", sms, e.getMessage());
|
|
|
- log.error(e.getMessage(), e);
|
|
|
+ log.error("短信发送失败, 短信: {}, 错误信息: {}", sms, e.getMessage(), e);
|
|
|
// 重试次数小于最大重试次数进行重试
|
|
|
if (sms.getCount().getAndIncrement() < maxRetry) {
|
|
|
retry(sms);
|
|
|
}
|
|
|
} finally {
|
|
|
smsDao.insert(sms);
|
|
|
- log.debug("insert: {}", JSON.toJSONString(sms));
|
|
|
+ smsDao.insertBatchSmsReport(smsReportList);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -86,20 +104,38 @@ public class SgipSmsService {
|
|
|
* 消费队列发送短信
|
|
|
*/
|
|
|
@PostConstruct
|
|
|
- public void consumer() {
|
|
|
+ public void consumerSendQueue() {
|
|
|
CompletableFuture.runAsync(() -> {
|
|
|
while (true) {
|
|
|
- Sms sms = null;
|
|
|
try {
|
|
|
- sms = QUEUE.take();
|
|
|
+ Sms sms = QUEUE.take();
|
|
|
+ sendMessage(sms);
|
|
|
} catch (InterruptedException e) {
|
|
|
Thread.currentThread().interrupt();
|
|
|
log.error(e.getMessage(), e);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error(e.getMessage(), e);
|
|
|
}
|
|
|
- if (sms == null) {
|
|
|
- continue;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 消费短信报告队列更新数据库
|
|
|
+ */
|
|
|
+ @PostConstruct
|
|
|
+ public void consumerReportQueue() {
|
|
|
+ CompletableFuture.runAsync(() -> {
|
|
|
+ while (true) {
|
|
|
+ try {
|
|
|
+ SmsReport smsReport = SmsReport.take();
|
|
|
+ smsDao.updateSmsReport(smsReport);
|
|
|
+ } catch (InterruptedException e) {
|
|
|
+ Thread.currentThread().interrupt();
|
|
|
+ log.error(e.getMessage(), e);
|
|
|
+ } catch (Exception e) {
|
|
|
+ log.error(e.getMessage(), e);
|
|
|
}
|
|
|
- sendMessage(sms);
|
|
|
}
|
|
|
});
|
|
|
}
|