master
queyounan 4 years ago
commit eb04337a6d

@ -49,6 +49,12 @@
</exclusion>
</exclusions>
</dependency>
<!-- 工具类 -->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.3.10</version>
</dependency>
</dependencies>
<build>

@ -2,8 +2,10 @@ package com.yuyou.openapi.openapi;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;
@SpringBootApplication
@EnableAsync
public class OpenapiApplication {
public static void main(String[] args) {

@ -0,0 +1,50 @@
package com.yuyou.openapi.openapi.conf;
import org.apache.tomcat.util.threads.ThreadPoolExecutor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Executor;
/**
* 线,线
*/
@Configuration
@EnableAsync
public class ThreadPoolConfig {
/**
* 线
*/
@Value(value = "${ab.customer.thread_pool.corePoolSize}")
private int corePoolSize = 10;
@Value(value = "${ab.customer.thread_pool.maxPoolSize}")
private int maxPoolSize = 200;
@Value(value = "${ab.customer.thread_pool.queueCapacity}")
private int queueCapacity = 10;
@Value(value = "${ab.customer.thread_pool.ThreadNamePrefix}")
private String ThreadNamePrefix = "MyThreadPoolExecutor-";
/**
* AB 线
* @return
*/
@Bean
public Executor abTaskExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(corePoolSize);
executor.setMaxPoolSize(maxPoolSize);
executor.setQueueCapacity(queueCapacity);
executor.setThreadNamePrefix(ThreadNamePrefix);
// rejection-policy当pool已经达到max size的时候如何处理新任务
// CALLER_RUNS不在新线程中执行任务而是有调用者所在的线程来执行
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
executor.initialize();
return executor;
}
}

@ -0,0 +1,32 @@
package com.yuyou.openapi.openapi.exception;
import com.yuyou.openapi.openapi.common.CommonResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
/**
*
*/
@ControllerAdvice
@Slf4j
public class GlobalExceptionHandle {
/**
* Exception
*
* @param exception
* @return
*/
@ExceptionHandler(Exception.class)
@ResponseBody
public CommonResponse customException(Exception exception) {
if (exception != null){
log.error(" =============== [ request error, exception is {} , {}] ===============", exception.getMessage() ,exception);
return CommonResponse.createByErrorMessage(exception.getMessage());
}
return CommonResponse.createByErrorMessage("未知异常错误发生");
}
}

@ -1,6 +1,8 @@
package com.yuyou.openapi.openapi.model.dto;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* Copyright (C), 2012 - 2018, qyx
@ -13,6 +15,8 @@ import lombok.Data;
* x 2020/8/5 v1.0
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ABMessageDTO {
}

@ -0,0 +1,40 @@
package com.yuyou.openapi.openapi.model.dto.convert;
import com.yuyou.openapi.openapi.model.dto.ABMessageDTO;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
/**
*
*
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ABMessageCovDTO {
/**
*
*/
private String app_id;
/**
* (197011,22)
*/
private long nonce_str;
/**
* : sha1(app_id=AppId&nonce_str=time_stamp)
*/
private String signature;
/**
* json
*/
private List<ABMessageDTO> data;
}

@ -2,8 +2,12 @@ package com.yuyou.openapi.openapi.service.impl;
import com.yuyou.openapi.openapi.model.dto.ABMessageDTO;
import com.yuyou.openapi.openapi.service.ABClientService;
import com.yuyou.openapi.openapi.task.ABDownTask;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
/**
* Copyright (C), 2012 - 2018, qyx
* FileName: ABClientServiceImpl
@ -17,8 +21,21 @@ import org.springframework.stereotype.Service;
@Service
public class ABClientServiceImpl implements ABClientService {
@Autowired
private ABDownTask abDownTask;
@Override
public void recordAndSendABClientMsg(ABMessageDTO dto) {
// 调用异步任务进行转发AB单 - 这里是这有一条数据
ArrayList<ABMessageDTO> dtoArrayList = new ArrayList<>();
dtoArrayList.add(dto);
boolean handleResult = abDownTask.doRunTask(dtoArrayList);
// 处理数据模型转换
// 调用接口进行入库
// 返回处理结果
}
}

@ -0,0 +1,100 @@
package com.yuyou.openapi.openapi.task;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.yuyou.openapi.openapi.model.dto.ABMessageDTO;
import com.yuyou.openapi.openapi.model.dto.convert.ABMessageCovDTO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.util.List;
/**
*
*/
@Service
@Slf4j
public class ABDownTask {
/**
*
*/
@Value("${ab.customer.app_id}")
private String appId;
@Value("${ab.customer.url}")
private String customerUrl;
/**
* ,
*
* @return
*/
@Async(value = "abTaskExecutor")
public boolean doRunTask(List<ABMessageDTO> messageDTOList){
Long satrtMilliSecond = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli();
log.info("====== [ task start running, task name is {} ] ======", "ABDownTask");
boolean resultTag = runTask(messageDTOList);
Long endMilliSecond = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli();
log.info("====== [ task start end, task name is {},cost milliSecond is {} ] ======", "ABDownTask", (endMilliSecond-satrtMilliSecond));
return resultTag;
}
/**
*
*
* @return
*/
private boolean runTask(List<ABMessageDTO> messageDTOList){
int count = 0; // 设置请求失败计数
// 数据实体进行映射转换 - 目前是只有一条给
ABMessageCovDTO abMessageCovDTO = new ABMessageCovDTO();
abMessageCovDTO.setData(messageDTOList);
// 补充其他的下游请求字段
abMessageCovDTO.setNonce_str((System.currentTimeMillis()/1000));
abMessageCovDTO.setApp_id(appId);
abMessageCovDTO.setSignature(SecureUtil.sha1("app_id="+abMessageCovDTO.getApp_id()+"&nonce_str="+abMessageCovDTO.getNonce_str()));
// 数据实体转成Json 不忽略空kv 有序
JSONObject jsonObject = JSONUtil.parseObj(abMessageCovDTO, false, true);
// 请求的响应处理
// todo 失败重发请求3次
while (count <= 3){
// 调用HTTP请求发送数据
HttpResponse httpResponse = sendReq(jsonObject);
if (httpResponse.isOk() && httpResponse.body().contains("成功")){
break;
}else{
count ++;
log.info("========== [request fail, response is {} ] ==========", httpResponse.body());
}
}
if (count > 4) {
return Boolean.FALSE;
}
return Boolean.TRUE;
}
/**
* HTTP
*
* @param jsonObject
* @return
*/
private HttpResponse sendReq(JSONObject jsonObject){
HttpResponse httpResponse = HttpRequest
.post(customerUrl)
.body(jsonObject.toString())
.execute();
return httpResponse;
}
}

@ -0,0 +1,8 @@
{
"properties": [
{
"name": "ab.customer.app_id",
"type": "java.lang.String",
"description": "Description for ab.customer.app_id."
}
] }

@ -1,10 +1,49 @@
server:
port: 8090
spring:
profiles:
active: dev
# 序列化忽略null的k-v配置
jackson:
default-property-inclusion: non_null
---
# 端口
server:
port: 8090
# 环境
spring:
profiles: dev
# 数据库相关配置
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/push?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8&useSSL=false
username: root
password: root
# 下游请求配置信息
ab:
customer:
url: https://sandbox.openapi.ppke.com.cn/
app_id: app_id
thread_pool:
corePoolSize:
maxPoolSize:
queueCapacity:
ThreadNamePrefix:
---
# 端口
server:
port: 8090
# 环境
spring:
profiles: prod
# 数据库相关配置
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/push?serverTimezone=UTC&useUnicode=true&characterEncoding=utf8&useSSL=false
username: root
password: Yuyou@2020
# 下游请求配置信息
ab:
customer:
url: https://openapi.ppke.com.cn/
app_id: app_id
Loading…
Cancel
Save