Commit 2b88ae79 authored by 郝彦辉's avatar 郝彦辉

人行报送项目初始化

parents
Pipeline #562 canceled with stages
HELP.md
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**
!**/src/test/**
### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
### VS Code ###
.vscode/
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://maven.apache.org/POM/4.0.0"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.quantgroup</groupId>
<artifactId>renhang-report</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>renhang-report</name>
<parent>
<groupId>cn.quantgroup</groupId>
<artifactId>commons-parent</artifactId>
<version>0.2.5.4</version>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<resource.delimiter>@</resource.delimiter>
<java.version>1.8</java.version>
<fastjson.version>1.2.21</fastjson.version>
<maven.test.skip>true</maven.test.skip>
<mysql.version>5.1.44</mysql.version>
</properties>
<build>
<resources>
<resource>
<filtering>true</filtering>
<directory>src/main/resources/</directory>
<includes>
<include>
*.properties
</include>
</includes>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
<resource>
<directory>${project.basedir}/src/main/resources</directory>
</resource>
<resource>
<directory>${project.build.directory}/generated-resources</directory>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
<encoding>${project.build.sourceEncoding}</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.5</version>
</plugin>
</plugins>
</build>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.16.16</version>
</dependency>
<!--spring-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.1.1</version>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.1.2</version>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>
<!--google-->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.5</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.2.2</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>24.0-jre</version>
</dependency>
<!--db-->
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
<version>${hikaricp.version}</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<!-- mybatis 生成器-->
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.3.5</version>
</dependency>
<!--json -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.46</version>
</dependency>
<dependency>
<groupId>org.dom4j</groupId>
<artifactId>dom4j</artifactId>
<version>2.1.0</version>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>net.logstash.logback</groupId>
<artifactId>logstash-logback-encoder</artifactId>
<version>4.9</version>
</dependency>
<dependency>
<groupId>com.ctrip.framework.apollo</groupId>
<artifactId>apollo-client</artifactId>
<version>0.10.2</version>
</dependency>
<dependency>
<groupId>cn.quantgroup</groupId>
<artifactId>quantgroup-user-sdk</artifactId>
<version>1.0.15-SNAPSHOT</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-redis</artifactId>
<version>1.4.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>com.quantgroup</groupId>
<artifactId>brApi-shaded</artifactId>
<version>201808071146-Release</version>
</dependency>
<!--SpringBoot, Cloud基础的依赖-->
<dependency>
<groupId>cn.quantgroup</groupId>
<artifactId>commons-spring</artifactId>
</dependency>
<!--暂时是空的.....-->
<dependency>
<groupId>cn.quantgroup</groupId>
<artifactId>commons-core</artifactId>
</dependency>
<!--优雅停机, 不再强制停机-->
<dependency>
<groupId>cn.quantgroup</groupId>
<artifactId>shutdown-spring-boot-starter</artifactId>
</dependency>
<!--调用链追踪. 开启吧, 以后的监控,数据统计. 都从这里出数-->
<dependency>
<groupId>cn.quantgroup</groupId>
<artifactId>brave-spring-boot-starter</artifactId>
</dependency>
<!--全局唯一的IDGenerator, 试运行阶段. 百度开发者+刘志国结合量化派场景, 倾情定制.-->
<dependency>
<groupId>cn.quantgroup</groupId>
<artifactId>idgenerator-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.dangdang</groupId>
<artifactId>elastic-job-lite-spring-shaded</artifactId>
<version>2.1.5</version>
</dependency>
<dependency>
<groupId>cn.quantgroup</groupId>
<artifactId>enoch-agent-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.8</version>
</dependency>
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi-ooxml</artifactId>
<version>3.8</version>
</dependency>
<dependency>
<groupId>joda-time</groupId>
<artifactId>joda-time</artifactId>
</dependency>
<dependency>
<groupId>ant</groupId>
<artifactId>ant</artifactId>
<version>1.6.5</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Camden.SR5</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
package cn.quantgroup.report;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
/**
* Created by Miraculous on 15/7/12.
*/
@Component
public class ApplicationContextHolder implements ApplicationContextAware {
/**
* Spring应用上下文环境
*/
private static ApplicationContext applicationContext;
@Autowired
public ApplicationContextHolder(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
/**
* 获取一个ApplicationContext.
*
* @return ApplicationContext
*/
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
/**
* 实现ApplicationContextAware接口的回调方法,设置上下文环境.
*
* @param applicationContext Spring ApplicationContext上下文
*/
public void setApplicationContext(ApplicationContext applicationContext) {
ApplicationContextHolder.applicationContext = applicationContext;
}
/**
* 根据名称获取一个对象.
*
* @param name bean名称
* @return Object 指定的bean
* @throws BeansException 如果找不到bean
*/
public static <T> T getBean(String name) throws BeansException {
return (T) applicationContext.getBean(name);
}
/**
* 获取名称为name的bean,自动转为所需类型.
*
* @param <T> 需求的bean类型
* @param name bean名称
* @param requiredType 需求的bean类型
* @return 指定类型的bean
* @throws BeansException 如果找不到匹配的类型,或是类型不能被转换,或是bean实例化失败
*/
public static <T> T getBean(String name, Class<T> requiredType) throws BeansException {
return applicationContext.getBean(name, requiredType);
}
/**
* 获取类型为requiredType的对象.
*
* @param <T> 需求的bean类型
* @param requiredType 需求的bean类型
* @return 指定类型的bean
* @throws BeansException 如果找不到匹配的类型
*/
public static <T> T getBean(Class<T> requiredType) throws BeansException {
return applicationContext.getBean(requiredType);
}
/**
* 检测一个bean是否已经被定义.
*
* @param name bean名称
* @return boolean 如果bean已经被定义,则返回true,否则返回false
*/
public static boolean containsBean(String name) {
return applicationContext.containsBean(name);
}
/**
* 判断以给定名字注册的bean定义是一个singleton还是一个prototype.
*
* @param name bean名称
* @return boolean 如果是singleton则返回true
* @throws NoSuchBeanDefinitionException 如果bean名称不存在
*/
public static boolean isSingleton(String name) throws NoSuchBeanDefinitionException {
return applicationContext.isSingleton(name);
}
/**
* 获取给定名字的bean的类型.
*
* @param name bean名称
* @return Class bean类型
* @throws NoSuchBeanDefinitionException 如果bean名称不存在
*/
public static Class getType(String name) throws NoSuchBeanDefinitionException {
return applicationContext.getType(name);
}
/**
* 取出指定bean的别名列表.
*
* @param name bean名称
* @return 如果有别名,返回别名,否则返回空数组.
* @throws NoSuchBeanDefinitionException 如果bean名称不存在
*/
public static String[] getAliases(String name) throws NoSuchBeanDefinitionException {
return applicationContext.getAliases(name);
}
}
package cn.quantgroup.report;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.ctrip.framework.apollo.spring.annotation.EnableApolloConfig;
import com.ctrip.framework.apollo.spring.config.ApolloPropertySourceInitializer;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.transaction.annotation.EnableTransactionManagement;
//@ComponentScan(basePackages = {"cn.quantgroup.report"})
@EnableTransactionManagement
@EnableConfigurationProperties
@EnableCaching
@EnableScheduling
@EnableAsync
@EnableAspectJAutoProxy
@Slf4j
@EnableApolloConfig
@EnableDiscoveryClient
@SpringBootApplication
public class RenhangReportApplication {
public static void main(String[] args) {
JSON.DEFAULT_GENERATE_FEATURE |= SerializerFeature.WriteEnumUsingToString.getMask();
SpringApplication springApplication = new SpringApplication(RenhangReportApplication.class);
springApplication.addInitializers(new ApolloPropertySourceInitializer());
springApplication.run(args);
log.info(">>>renhang-report start server OK...");
}
}
package cn.quantgroup.report.cmpt;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.apache.http.HttpStatus;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
@Slf4j
@Component
public class CommonAlarmCmpt {
@Value("${isDebug}")
private Boolean isDebug;
private static ThreadPoolExecutor pool = new ThreadPoolExecutor(10, 50, 200,
TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(200), new ThreadPoolExecutor.DiscardPolicy());
static {
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
if (pool != null) pool.shutdown();
}));
}
@Value("${alarm.interface.url}")
private String ALARM_INTERFACE_URL;
RequestConfig config = RequestConfig.custom()
.setSocketTimeout(6000)
.setConnectTimeout(6000)
.setConnectionRequestTimeout(6000)
.build();
CloseableHttpClient httpclient = HttpClients.createDefault();
public void alarm(String alarmLevel, String msgTitle, String msgContent) {
if(isDebug) return;
pool.execute(new Runnable() {
@Override
public void run() {
HttpPost httppost = new HttpPost(ALARM_INTERFACE_URL);
httppost.setConfig(config);
List<BasicNameValuePair> params = new ArrayList<>();
params.add(new BasicNameValuePair("bizType", "RISK_DATASOURCE"));
params.add(new BasicNameValuePair("alarmLevel", alarmLevel));
params.add(new BasicNameValuePair("msgTitle", msgTitle));
params.add(new BasicNameValuePair("msgContent", msgContent));
CloseableHttpResponse response = null;
try {
httppost.setEntity(new UrlEncodedFormEntity(params, "UTF-8"));
response = httpclient.execute(httppost);
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode != 200) {
log.error("告警失败,statusCode : {}", statusCode);
}
} catch (Exception e) {
log.error("告警发送异常", e);
} finally {
if(response != null) {
EntityUtils.consumeQuietly(response.getEntity());
}
IOUtils.closeQuietly(response);
}
}
});
}
public void alarmAtman(String mobile, Long content){
HttpPost httppost = new HttpPost("https://oapi.dingtalk.com/robot/send?access_token=5c787094003bb2bd5ed763dd7afa96f9bf984b4871e2f47369626c493dcb320e");
httppost.setConfig(config);
httppost.addHeader("Content-Type", "application/json; charset=utf-8");
String textMsg = "{\"msgtype\":\"text\",\"text\":{\"content\":\"探知数据调用量:"+content+", @"+mobile+" 是不一样的烟火\"},\"at\":{\"atMobiles\":[\""+mobile+"\"],\"isAtAll\":false}}";
StringEntity se = new StringEntity(textMsg, "utf-8");
httppost.setEntity(se);
CloseableHttpResponse response = null;
try{
response = httpclient.execute(httppost);
if (response.getStatusLine().getStatusCode()== HttpStatus.SC_OK){
String result= EntityUtils.toString(response.getEntity(), "utf-8");
System.out.println(result);
}
}catch(Exception e){
log.error("告警发送异常", e);
}finally {
if(response != null) {
EntityUtils.consumeQuietly(response.getEntity());
}
IOUtils.closeQuietly(response);
}
}
}
package cn.quantgroup.report.cmpt;
import cn.quantgroup.report.constant.KeyConstant;
import cn.quantgroup.report.enums.RequestUrlType;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* Created by Alan on6/14.
*/
@Slf4j
@Component
public class MonitorCmpt {
private static ThreadPoolExecutor pool = new ThreadPoolExecutor(5, 50, 200,
TimeUnit.MILLISECONDS, new LinkedBlockingQueue<>(500), new ThreadPoolExecutor.DiscardPolicy());
private static String[] notAlarm = {
/*RequestUrlType.BaiRongSpecialList_c.name(),
RequestUrlType.QianHaiQueryBlackList.name(),
RequestUrlType.TongDunHitRuleDetail.name(),
RequestUrlType.JDBlacklist.name(),
RequestUrlType.CreditXFraud.name(),
RequestUrlType.ShuMeiOverdue.name(),
RequestUrlType.HaoAnBlackList.name(),
RequestUrlType.BaiDuBlackList.name(),
RequestUrlType.TianXingHuiBlackList.name(),
RequestUrlType.FaHaiJudicial.name(),*/
};
private static List<String> URL_NOT_ALARM = Arrays.asList(notAlarm);
static {
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
if (pool != null) pool.shutdown();
}));
}
@Autowired
private RedisTemplate<String,String> redisTemplate;
@Autowired
private CommonAlarmCmpt commonAlarmCmpt;
/**
* 命中率统计
* @param urlType
* @param flag 0:查询失败,1,查询命中
*/
public void statisticHitRate(String urlType, int flag){
pool.execute(new Runnable() {
@Override
public void run() {
try {
String dayKey = KeyConstant.HIT_RATE + KeyConstant.ONE_DAY + urlType + ":" + flag;
String heapKey = KeyConstant.HIT_RATE + KeyConstant.HEAP + urlType + ":" + 0;
redisTemplate.opsForValue().increment(dayKey, 1);
//黑名单不告警
if(URL_NOT_ALARM.contains(urlType)){
return;
}
if (flag == 1) {
redisTemplate.delete(heapKey);
return;
}
Long heapCount = redisTemplate.opsForValue().increment(heapKey, 1);
log.info("三方数据源: {} , 连续未命中次数 : {} ",urlType,heapCount);
if (heapCount >= 15 && (heapCount - 15) % 10 == 0) {
String alarmLevel = "Warn";
if (heapCount == 85 || heapCount == 165) {
alarmLevel = "Emergency";
}
commonAlarmCmpt.alarm(alarmLevel, "三方数据源告警", "数据源【" + urlType + "】查询连续" + heapCount + "次未命中");
}
}catch (Exception e){
log.error("三方数据源统计查询命中率异常, urlType: {} ",urlType ,e);
}
}
});
}
}
/**
*
*/
package cn.quantgroup.report.config.aop;
import java.lang.annotation.*;
/**
*
* @author renfeng
*
*/
@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface DistributedLock {
}
/**
*
*/
package cn.quantgroup.report.config.aop;
import com.google.common.base.Joiner;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import java.util.Arrays;
import java.util.concurrent.TimeUnit;
/**
* 对数据源请求加锁,不包含transactionId(第一个入参), 如:method(transactionId, a, b), 锁 key 为 qry_lock_a_b
*/
@Aspect
@Component
public class DistributedLockAspect {
private static final Logger LOGGER = LoggerFactory.getLogger(DistributedLockAspect.class);
private static final String USER_LOCK = "qry_lock_";
@Autowired
private RedisTemplate redisTemplate;
@Pointcut("@annotation(cn.quantgroup.report.config.aop.DistributedLock)")
private void userQryPointCut() {
}
@Around("userQryPointCut()")
public Object process(ProceedingJoinPoint point) throws Throwable {
String key = null;
Object proceed = null;
try{
String methodName = point.getSignature().getName();
Object[] args = point.getArgs();
if(args.length <= 1){
LOGGER.info("切面获取参数问题, method: {}, args: {}", methodName, args);
proceed = point.proceed();
return proceed;
}
//不包含transactionID的其他参数
Object[] newarr= Arrays.copyOfRange(args, 1, args.length);
key = Joiner.on("_").useForNull("!").join(newarr);
key = new StringBuffer().append(USER_LOCK).append(methodName).append("_").append(key).toString();
boolean flag = true;
int count = 1;
while(!setIfAbsent(key, "1", 3, TimeUnit.SECONDS)){
if(flag) {
LOGGER.info("查询命中锁, key: {}, args: {}", key, args);
flag =false;
}
Thread.sleep(100);
if(count>30){
redisTemplate.delete(key);
}
count++;
}
proceed = point.proceed();
}catch(Exception e){
proceed = point.proceed();
}finally{
if(key != null) {
redisTemplate.delete(key);
}
}
return proceed;
}
public boolean setIfAbsent(String key,String value,long time, TimeUnit timeUnit) {
try{
Boolean setIfAbsent = redisTemplate.opsForValue().setIfAbsent(key, value);
if(setIfAbsent)
redisTemplate.expire(key, time, timeUnit);
return setIfAbsent;
}catch(Exception e){
LOGGER.error("REDIS原子性操作异常!",e);
}
return true;
}
}
/**
*
*/
package cn.quantgroup.report.config.aop;
import java.lang.annotation.*;
@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Monitor {
/** 监控类型 */
MonitorType[] value();
}
/**
*
*/
package cn.quantgroup.report.config.aop;
import cn.quantgroup.report.cmpt.CommonAlarmCmpt;
import cn.quantgroup.report.cmpt.MonitorCmpt;
import cn.quantgroup.report.constant.TransactionCodeEnum;
import cn.quantgroup.report.response.TransactionResult;
import cn.quantgroup.report.service.thirdpartymonitor.ThirdpartyApiMonitorService;
import cn.quantgroup.report.utils.StringUtil;
import cn.quantgroup.report.enums.RequestUrlType;
import cn.quantgroup.report.response.GlobalResponse;
import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
/**
* 1.监控数据源
* 2.统一结果处理
*/
@Slf4j
@Aspect
@Component
public class MonitorAspect {
protected static ExecutorService dbLogPool = new ThreadPoolExecutor(20,50,200, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
@Autowired
private ThirdpartyApiMonitorService thirdpartyApiMonitorService;
@Autowired
private CommonAlarmCmpt iMonitorAlarmService;
@Autowired
protected MonitorCmpt monitorCmpt;
@Pointcut("@annotation(cn.quantgroup.report.config.aop.Monitor)")
private void userQryPointCut() {
}
@Around("userQryPointCut()")
public Object process(ProceedingJoinPoint point) throws Throwable {
log.info("enter MonitorAspect point : {}", point);
long begin = System.currentTimeMillis();
Object result = point.proceed();
long timeConsume = System.currentTimeMillis()- begin;
dbLogPool.execute(()-> {
try {
Signature sig = point.getSignature();
if (!(sig instanceof MethodSignature)) {
log.warn("process msig :{}", sig);
return;
}
MethodSignature msig = (MethodSignature) sig;
Object target = point.getTarget();
Method currentMethod = target.getClass().getMethod(msig.getName(), msig.getParameterTypes());
Monitor annotation = currentMethod.getAnnotation(Monitor.class);
MonitorType[] monitorTypes = annotation.value();
if (!(result instanceof GlobalResponse)) return;
GlobalResponse response = (GlobalResponse) result;
log.info("handle response : {}" , StringUtil.shortPrintLog(response.toString()));
Arrays.stream(monitorTypes).forEach(o -> {
try {
switch (o) {
case FEE:
handleFee(response);
break;
case EXCEPTION:
handleException(response, point.getArgs(), timeConsume);
break;
case RESULT:
handleResult(response);
break;
case HIT:
handleHitStat(response);
break;
}
}catch (Exception e){
log.error("处理结果异常", e);
}
});
}catch (Exception e){
log.error("统一处理异常", e);
}
});
return result;
}
/**
* 统计查询命中情况并告警
* @param response
*/
private void handleHitStat(GlobalResponse response) {
log.info("handleHitStat start transactionId {}", response.getTransactionId());
List<TransactionResult> transactionResults = response.getTransactionResult();
transactionResults.stream().forEach(o -> {
TransactionCodeEnum tansactionCode = o.getTansactionCode();
if (TransactionCodeEnum.SuccessAndMiss.equals(tansactionCode)) {
monitorCmpt.statisticHitRate(o.getUrlType().name(), 0);
} else if(TransactionCodeEnum.SuccessAndHit.equals(tansactionCode)){
monitorCmpt.statisticHitRate(o.getUrlType().name(), 1);
}
});
}
/**
* 处理查询结果,记录查询
*/
private void handleResult(GlobalResponse response) {
String transactionId = response.getTransactionId();
log.info("handleResult start transactionId {}", transactionId);
List<TransactionResult> transactionResults = response.getTransactionResult();
for (TransactionResult transactionResult : transactionResults) {
RequestUrlType urlType = transactionResult.getUrlType();
TransactionCodeEnum tansactionCode = transactionResult.getTansactionCode();
if(StringUtils.isNotBlank(response.getUuid())) {
thirdpartyApiMonitorService.saveTransactionLog(urlType, transactionId, response.getUuid(), tansactionCode);
} else if(StringUtils.isNotBlank(response.getIdentity())) {
thirdpartyApiMonitorService.saveTransactionLogByIdentifyNumber(urlType, transactionId, response.getIdentity(), tansactionCode);
}else if(StringUtils.isNotBlank(response.getPhone())) {
thirdpartyApiMonitorService.saveTransactionLogByPhone(urlType, transactionId, response.getPhone(), tansactionCode);
} else {
thirdpartyApiMonitorService.saveTransactionLog(urlType, transactionId, null, tansactionCode);
}
}
}
/**
* 处理异常,统一告警
*/
private void handleException(GlobalResponse response, Object[] args, long timeConsume) {
log.info("handleception start transactionId {}, url_type, timeConsume {}", response.getTransactionId(), timeConsume, response.getTransactionResult());
List<TransactionResult> transactionResult = response.getTransactionResult();
transactionResult.stream().forEach(o -> {
TransactionCodeEnum tansactionCode = o.getTansactionCode();
if(TransactionCodeEnum.Fail.equals(tansactionCode)){
int code = response.getCode();
String error = response.getError();
boolean isReadCache = (boolean) args[args.length-1];
if(!isReadCache){
iMonitorAlarmService.alarm("WARN","数据源告警 : " + o.getUrlType().getUrlName(),"code : " + code + "; msg : " + error + " args : " + Arrays.toString(args));
}else{
log.info("handleException is ReadCache: {} ", JSON.toJSONString(args));
}
} else {
//超时告警
if(timeConsume > 60000){
iMonitorAlarmService.alarm("WARN","数据源调用超时 : " + o.getUrlType().getUrlName(),JSON.toJSONString(args)+"耗时 : " + timeConsume + "ms");
}
}
});
}
/**
* record fee
*/
private void handleFee(GlobalResponse response) {
// log.info("handleFee response transactionId: {}" , response.getTransactionId());
// if(response.getIsBilling()){
// List<TransactionResult> transactionResult = response.getTransactionResult();
// transactionResult.stream().forEach(o -> {
// thirdpartyApiMonitorService.recordCost(o.getUrlType(), o.getUrlType().getSourceName());
// }
// );
// }
}
}
package cn.quantgroup.report.config.aop;
public enum MonitorType {
/** 监控所有异常 */
EXCEPTION,
/** 监控费用 */
FEE,
/** 监控结果 */
RESULT,
/** 监控命中情况 */
HIT
}
package cn.quantgroup.report.config.datasource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.TaskScheduler;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ConcurrentTaskScheduler;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Executor;
/**
* Created by suh on 2018/1/15.
*/
@Configuration
@EnableAsync
public class ExecutorConfig {
private int corePoolSize = 2;
private int maxPoolSize = 10;
private int queueCapacity = 50;
@Bean(name = "DianHuaBangCallBack")
public Executor DianHuaBangCallBack() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(corePoolSize);
executor.setMaxPoolSize(maxPoolSize);
executor.setQueueCapacity(queueCapacity);
executor.setThreadNamePrefix("DianHuaBangCallBack-");
executor.initialize();
return executor;
}
@Bean
public TaskScheduler taskScheduler() {
return new ConcurrentTaskScheduler();
}
}
package cn.quantgroup.report.config.datasource;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.CacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisNode;
import org.springframework.data.redis.connection.RedisSentinelConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import redis.clients.jedis.JedisPoolConfig;
import java.util.HashSet;
import java.util.Set;
/**
* Created by ocean on 2017/5/27.
*/
@Configuration
public class RedisConfig {
@Value("${risk.data.redis.defaultExpiration}")
private Long defaultExpiration;
@Value("${risk.redis.master.host}")
private String masterHost;
@Value("${risk.redis.master.port}")
private int masterPort;
@Value("${risk.redis.master.name}")
private String masterName;
@Value("${risk.redis.sentinel1.host}")
private String sentinel1Host;
@Value("${risk.redis.sentinel1.port}")
private int sentinel1port;
@Value("${risk.redis.sentinel2.host}")
private String sentinel2Host;
@Value("${risk.redis.sentinel2.port}")
private int sentinel2port;
@Value("${risk.redis.sentinel3.host}")
private String sentinel3Host;
@Value("${risk.redis.sentinel3.port}")
private int sentinel3port;
private RedisConnectionFactory generateDevConnectionFactory() {
JedisConnectionFactory factory = new JedisConnectionFactory();
factory.setHostName(masterHost);
factory.setPort(masterPort);
factory.setUsePool(true);
factory.setConvertPipelineAndTxResults(true);
JedisPoolConfig poolConfig = generatePoolConfig();
factory.setPoolConfig(poolConfig);
factory.afterPropertiesSet();
return factory;
}
private RedisConnectionFactory generateReleaseConnectionFactory() {
RedisSentinelConfiguration sentinelConfiguration = new RedisSentinelConfiguration();
RedisNode master = new RedisNode(masterHost, masterPort);
master.setName(masterName);
Set<RedisNode> sentinels = new HashSet<>();
RedisNode sentinel1 = new RedisNode(sentinel1Host, sentinel1port);
RedisNode sentinel2 = new RedisNode(sentinel2Host, sentinel2port);
RedisNode sentinel3 = new RedisNode(sentinel3Host, sentinel3port);
sentinels.add(sentinel1);
sentinels.add(sentinel2);
sentinels.add(sentinel3);
sentinelConfiguration.setMaster(master);
sentinelConfiguration.setSentinels(sentinels);
JedisPoolConfig poolConfig = generatePoolConfig();
JedisConnectionFactory factory = new JedisConnectionFactory(sentinelConfiguration, poolConfig);
factory.setHostName(masterHost);
factory.setPort(masterPort);
factory.setTimeout(10000);
factory.setUsePool(true);
factory.setConvertPipelineAndTxResults(true);
factory.afterPropertiesSet();
return factory;
}
private JedisPoolConfig generatePoolConfig() {
JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.setMinIdle(20);
poolConfig.setMaxTotal(300);
poolConfig.setMaxWaitMillis(5000);
poolConfig.setTestOnBorrow(true);
return poolConfig;
}
@Bean(name = "redisConnectionFactory")
RedisConnectionFactory factory() {
if (StringUtils.isEmpty(masterName)) {
return generateDevConnectionFactory();
} else {
return generateReleaseConnectionFactory();
}
}
@Bean(name = "redisTemplate")
public RedisTemplate<String, Object> redisTemplate(
RedisConnectionFactory factory) {
final RedisTemplate<String, Object> template = new RedisTemplate<>();
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
JdkSerializationRedisSerializer jdkSerializationRedisSerializer =
new JdkSerializationRedisSerializer();
template.setEnableTransactionSupport(false);
template.setKeySerializer(stringRedisSerializer);
template.setHashKeySerializer(stringRedisSerializer);
template.setValueSerializer(jdkSerializationRedisSerializer);
template.setDefaultSerializer(jdkSerializationRedisSerializer);
template.setConnectionFactory(factory);
return template;
}
@Bean(name = "stringRedisTemplate")
public RedisTemplate<String, String> stringRedisTemplate(
RedisConnectionFactory factory) {
final RedisTemplate<String, String> template = new RedisTemplate<>();
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
template.setEnableTransactionSupport(false);
template.setKeySerializer(stringRedisSerializer);
template.setHashKeySerializer(stringRedisSerializer);
template.setValueSerializer(stringRedisSerializer);
template.setDefaultSerializer(stringRedisSerializer);
template.setConnectionFactory(factory);
return template;
}
@Bean(name = "cacheManager")
public CacheManager cacheManager(RedisTemplate<String, Object> redisTemplate) {
RedisCacheManager cacheManager = new RedisCacheManager(redisTemplate);
cacheManager.setDefaultExpiration(defaultExpiration);
cacheManager.setUsePrefix(true);
return cacheManager;
}
}
package cn.quantgroup.report.config.datasource.baihang;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import javax.sql.DataSource;
@Import(BaiHangDataSourcePreperties.class)
@Configuration
@Slf4j
@MapperScan(basePackages = BaiHangDataSourceConfig.PACKAGE, sqlSessionFactoryRef = "baihangSqlSessionFactory")
public class BaiHangDataSourceConfig {
static final String PACKAGE = "cn.quantgroup.report.mapper.baihang";
@Value("${baihang.mapper-locations}")
private String mapperLocations;
@Value("${baihang.type-aliases-package}")
private String typeAliasesPackage;
@Value("${config-location}")
private String configLocation;
@Autowired
private BaiHangDataSourcePreperties baiHangDataSourcePreperties;
@Bean(name = "baihangDataSource")
@Primary
public DataSource baihangDataSource() {
HikariConfig config = new HikariConfig();
config.setJdbcUrl(baiHangDataSourcePreperties.getJdbcUrl());
log.info("百行征信数据库地址:{}", baiHangDataSourcePreperties.getJdbcUrl());
config.setPassword(baiHangDataSourcePreperties.getPassword());
config.setUsername(baiHangDataSourcePreperties.getUsername());
config.setMaximumPoolSize(baiHangDataSourcePreperties.getMaxPoolSize());
config.setMinimumIdle(baiHangDataSourcePreperties.getMinPoolSize());
config.addDataSourceProperty("cachePrepStmts", "true");
config.addDataSourceProperty("prepStmtCacheSize", "250");
config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
return new HikariDataSource(config);
}
@Bean(name = "baihangTransactionManager")
@Primary
public DataSourceTransactionManager baihangTransactionManager(@Qualifier("baihangDataSource") DataSource baihangDataSource) {
return new DataSourceTransactionManager(baihangDataSource);
}
@Bean(name = "baihangSqlSessionFactory")
@Primary
public SqlSessionFactory baihangSqlSessionFactory(@Qualifier("baihangDataSource") DataSource baihangDataSource) throws Exception {
final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
sessionFactory.setDataSource(baihangDataSource);
sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver()
.getResources(mapperLocations));
sessionFactory.setTypeAliasesPackage(typeAliasesPackage);
sessionFactory.setConfigLocation(new PathMatchingResourcePatternResolver()
.getResource(configLocation));
return sessionFactory.getObject();
}
@Bean(name = "baihangSqlSessionTemplate")
@Primary
public SqlSessionTemplate baihangSqlSessionTemplate(@Qualifier("baihangSqlSessionFactory") SqlSessionFactory baihangSqlSessionFactory) throws Exception {
return new SqlSessionTemplate(baihangSqlSessionFactory);
}
}
package cn.quantgroup.report.config.datasource.baihang;
import lombok.Getter;
import lombok.Setter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
@Setter
@Getter
@Configuration
public class BaiHangDataSourcePreperties {
@Value("${db.driver}")
private String driverClass;
@Value("${baihang.db.minPoolSize}")
private int minPoolSize;
@Value("${baihang.db.maxPoolSize}")
private int maxPoolSize;
@Value("${data.source.baihang.jdbcUrl}")
private String jdbcUrl;
//private String jdbcUrl = "jdbc:mysql://172.20.6.29:4010/rc_real_time_data_pool?useUnicode=true&characterEncoding=UTF8&useSSL=false";
//private String jdbcUrl = "jdbc:mysql://172.20.6.21:4010/rc_real_time_data_pool?useUnicode=true&characterEncoding=UTF8&useSSL=false";
@Value("${data.source.baihang.username}")
private String username;
@Value("${data.source.baihang.password}")
private String password;
}
package cn.quantgroup.report.config.datasource.history;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import javax.sql.DataSource;
@Import(XyqbHistoryDataSourcePreperties.class)
@Configuration
@Slf4j
@MapperScan(basePackages = XyqbHistoryDataSourceConfig.PACKAGE, sqlSessionFactoryRef = "xyqbHistorySqlSessionFactory")
public class XyqbHistoryDataSourceConfig {
static final String PACKAGE = "cn.quantgroup.report.mapper.history";
//@Value("${baihang.mapper-locations}")
private String mapperLocations = "classpath:cn/quantgroup/report/mapper/history/*.xml";
//@Value("${baihang.type-aliases-package}")
private String typeAliasesPackage = "cn.quantgroup.report.mapper.history";
@Value("${config-location}")
private String configLocation;
@Autowired
private XyqbHistoryDataSourcePreperties xyqbHistoryDataSourcePreperties;
@Bean(name = "xyqbHistoryDataSource")
public DataSource xyqbHistoryDataSource() {
HikariConfig config = new HikariConfig();
config.setJdbcUrl(xyqbHistoryDataSourcePreperties.getJdbcUrl());
log.info("xyqb历史数据库地址:{}", xyqbHistoryDataSourcePreperties.getJdbcUrl());
config.setPassword(xyqbHistoryDataSourcePreperties.getPassword());
config.setUsername(xyqbHistoryDataSourcePreperties.getUsername());
config.setMaximumPoolSize(xyqbHistoryDataSourcePreperties.getMaxPoolSize());
config.setMinimumIdle(xyqbHistoryDataSourcePreperties.getMinPoolSize());
config.addDataSourceProperty("cachePrepStmts", "true");
config.addDataSourceProperty("prepStmtCacheSize", "250");
config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
return new HikariDataSource(config);
}
@Bean(name = "xyqbHistoryTransactionManager")
public DataSourceTransactionManager xyqbHistoryTransactionManager(@Qualifier("xyqbHistoryDataSource") DataSource xyqbHistoryDataSource) {
return new DataSourceTransactionManager(xyqbHistoryDataSource);
}
/* @Bean(name = "xyqbHistorySqlSessionFactory")
public SqlSessionFactory xyqbHistorySqlSessionFactory(@Qualifier("xyqbHistoryDataSource") DataSource xyqbHistoryDataSource) throws Exception {
final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
sessionFactory.setDataSource(xyqbHistoryDataSource);
sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver()
.getResources(mapperLocations));
sessionFactory.setTypeAliasesPackage(typeAliasesPackage);
sessionFactory.setConfigLocation(new PathMatchingResourcePatternResolver()
.getResource(configLocation));
return sessionFactory.getObject();
}*/
/*
@Bean(name = "xyqbHistorySqlSessionTemplate")
public SqlSessionTemplate xyqbHistorySqlSessionTemplate(@Qualifier("xyqbHistorySqlSessionFactory") SqlSessionFactory xyqbHistorySqlSessionFactory) throws Exception {
return new SqlSessionTemplate(xyqbHistorySqlSessionFactory);
}*/
@Bean(name = "xyqbHistoryJdbcTemplate")
public JdbcTemplate primaryJdbcTemplate(@Qualifier("xyqbHistoryDataSource") DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
}
package cn.quantgroup.report.config.datasource.history;
import lombok.Getter;
import lombok.Setter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
@Setter
@Getter
@Configuration
public class XyqbHistoryDataSourcePreperties {
@Value("${db.driver}")
private String driverClass;
@Value("${baihang.db.minPoolSize}")
private int minPoolSize;
@Value("${baihang.db.maxPoolSize}")
private int maxPoolSize;
//@Value("${data.source.baihang.jdbcUrl}")
//private String jdbcUrl="jdbc:mysql://172.20.6.29:4010/rc_real_time_data_pool?useUnicode=true&characterEncoding=UTF8&useSSL=false";
private String jdbcUrl = "jdbc:mysql://172.20.6.21:4010/rc_real_time_data_pool?useUnicode=true&characterEncoding=UTF8&useSSL=false";
//@Value("${data.source.baihang.username}")
private String username="xyqb_history_w";
//@Value("${data.source.baihang.password}")
private String password="KDb18asPu6iEz5lg";
}
package cn.quantgroup.report.config.datasource.master;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import javax.sql.DataSource;
/**
* Desc:
* User: HaiNan.Wang
* Date: 2017/5/2
*/
@Import(RiskDatasourceProperties.class)
@Configuration
@MapperScan(basePackages = RiskDataSourceConfig.PACKAGE, sqlSessionFactoryRef = "masterSqlSessionFactory")
public class RiskDataSourceConfig {
static final String PACKAGE = "cn.quantgroup.report.mapper.master";
@Value("${master.mapper-locations}")
private String mapperLocations;
@Value("${master.type-aliases-package}")
private String typeAliasesPackage;
@Value("${config-location}")
private String configLocation;
@Value("${db.driver:com.mysql.jdbc.Driver}")
private String driverClass;
@Autowired
private RiskDatasourceProperties repaymentPlanProperties;
@Bean(name = "masterDataSource")
public DataSource masterDataSource() {
HikariConfig config = new HikariConfig();
config.setJdbcUrl(repaymentPlanProperties.getRiskDatasourceJdbcUrl());
config.setPassword(repaymentPlanProperties.getRiskDatasourcePassword());
config.setUsername(repaymentPlanProperties.getRiskDatasourceUsername());
config.setMaximumPoolSize(repaymentPlanProperties.getMaxPoolSize());
config.setMinimumIdle(repaymentPlanProperties.getMinPoolSize());
config.addDataSourceProperty("cachePrepStmts", "true");
config.addDataSourceProperty("prepStmtCacheSize", "250");
config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
return new HikariDataSource(config);
}
@Bean(name = "masterTransactionManager")
public DataSourceTransactionManager repaymentPlanDataSourceTransactionManager(@Qualifier("masterDataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
@Bean(name = "masterSqlSessionFactory")
public SqlSessionFactory masterSqlSessionFactory(@Qualifier("masterDataSource") DataSource masterDataSource) throws Exception {
final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
sessionFactory.setDataSource(masterDataSource);
sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver()
.getResources(mapperLocations));
sessionFactory.setTypeAliasesPackage(typeAliasesPackage);
sessionFactory.setConfigLocation(new PathMatchingResourcePatternResolver()
.getResource(configLocation));
return sessionFactory.getObject();
}
@Bean(name = "masterSqlSessionTemplate")
public SqlSessionTemplate masterSqlSessionTemplate(@Qualifier("masterSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}
@Bean(name = "riskDatasourceJdbcTemplate")
public JdbcTemplate primaryJdbcTemplate(@Qualifier("masterDataSource") DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
}
package cn.quantgroup.report.config.datasource.master;
import lombok.Getter;
import lombok.Setter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
/**
* Desc:
* User: HaiNan.Wang
* Date: 2017/5/2
*/
@Getter
@Setter
@Configuration
public class RiskDatasourceProperties {
@Value("${db.driver}")
private String driverClass;
@Value("${db.minPoolSize}")
private int minPoolSize;
@Value("${db.maxPoolSize}")
private int maxPoolSize;
/**
* repaymentplan
*/
@Value("${db.risk_datasource.url}")
private String riskDatasourceJdbcUrl;
@Value("${db.risk_datasource.username}")
private String riskDatasourceUsername;
@Value("${db.risk_datasource.password}")
private String riskDatasourcePassword;
}
package cn.quantgroup.report.config.datasource.tidbrisk;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import javax.sql.DataSource;
/**
* -----------------------------------------------------------------------------<br>
* 描述: tidb中call_record日志表 <br>
* 作者:yanhui.Hao <br>
* 时间:2019.12.30 <br>
* 授权: (C) Copyright (c) 2017 <br>
* 公司: 北京众信利民信息技术有限公司 <br>
* -----------------------------------------------------------------------------
*/
@Import(TidbRiskDatasourceProperties.class)
@Configuration
@Slf4j
@MapperScan(basePackages = TidbRiskDataSourceConfig.PACKAGE, sqlSessionFactoryRef = "tidbRiskSqlSessionFactory")
public class TidbRiskDataSourceConfig {
static final String PACKAGE = "cn.quantgroup.report.mapper.tidbrisk";
//@Value("${tidb.risk_datasource.mapper-locations}")
private String mapperLocations="classpath:cn/quantgroup/report/mapper/tidbrisk/*.xml";//resources *.xml
//@Value("${tidb.risk_datasource.type-aliases-package}")
private String typeAliasesPackage="cn.quantgroup.report.domain.tidbrisk";//实体pojo
@Value("${config-location}")
private String configLocation;
@Autowired
private TidbRiskDatasourceProperties tidbRiskDatasourceProperties;
@Bean(name = "tidbRiskDataSource")
public DataSource tidbRiskDataSource() {
HikariConfig config = new HikariConfig();
log.info("tidb.risk_datasource数据库地址:{}",tidbRiskDatasourceProperties.getTidbRiskDatasourceJdbcUrl());
config.setJdbcUrl(tidbRiskDatasourceProperties.getTidbRiskDatasourceJdbcUrl());
config.setPassword(tidbRiskDatasourceProperties.getTidbRiskDatasourcePassword());
config.setUsername(tidbRiskDatasourceProperties.getTidbRiskDatasourceUsername());
config.setMaximumPoolSize(tidbRiskDatasourceProperties.getMaxPoolSize());
config.setMinimumIdle(tidbRiskDatasourceProperties.getMinPoolSize());
config.addDataSourceProperty("cachePrepStmts", "true");
config.addDataSourceProperty("prepStmtCacheSize", "250");
config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
return new HikariDataSource(config);
}
@Bean(name = "tidbRiskTransactionManager")
public DataSourceTransactionManager tidbRiskTransactionManager(@Qualifier("tidbRiskDataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
@Bean(name = "tidbRiskSqlSessionFactory")
public SqlSessionFactory tidbRiskSqlSessionFactory(@Qualifier("tidbRiskDataSource") DataSource tidbRiskDataSource) throws Exception {
final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
sessionFactory.setDataSource(tidbRiskDataSource);
sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver()
.getResources(mapperLocations));
sessionFactory.setTypeAliasesPackage(typeAliasesPackage);
sessionFactory.setConfigLocation(new PathMatchingResourcePatternResolver()
.getResource(configLocation));
return sessionFactory.getObject();
}
@Bean(name = "tidbRiskSqlSessionTemplate")
public SqlSessionTemplate tidbRiskSqlSessionTemplate(@Qualifier("tidbRiskSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
return new SqlSessionTemplate(sqlSessionFactory);
}
@Bean(name = "tidbRiskJdbcTemplate")
public JdbcTemplate tidbRiskJdbcTemplate(@Qualifier("tidbRiskDataSource") DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
}
package cn.quantgroup.report.config.datasource.tidbrisk;
import lombok.Getter;
import lombok.Setter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
/**
* -----------------------------------------------------------------------------<br>
* 描述: tidb中call_record日志表 <br>
* 作者:yanhui.Hao <br>
* 时间:2019.12.30 <br>
* 授权: (C) Copyright (c) 2017 <br>
* 公司: 北京众信利民信息技术有限公司 <br>
* -----------------------------------------------------------------------------
*/
@Getter
@Setter
@Configuration
public class TidbRiskDatasourceProperties {
@Value("${db.driver}")
private String driverClass;
@Value("${db.minPoolSize}")
private int minPoolSize;
@Value("${db.maxPoolSize}")
private int maxPoolSize;
/**
* tidb.risk_datasource
*/
@Value("${db.tidb.risk_datasource.fullurl}")
private String tidbRiskDatasourceJdbcUrl;
//private String tidbRiskDatasourceJdbcUrl="jdbc:mysql://fengkong-tidb.quantgroups.com:4010/risk_datasource?useUnicode=true&characterEncoding=UTF8";
@Value("${db.tidb.risk_datasource.username}")
private String tidbRiskDatasourceUsername;
//private String tidbRiskDatasourceUsername="risk_datasource_w";
@Value("${db.tidb.risk_datasource.password}")
private String tidbRiskDatasourcePassword;
//private String tidbRiskDatasourcePassword="50GjQLd6hUOSeTMB";
}
package cn.quantgroup.report.config.datasource.xyqbuser;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import javax.sql.DataSource;
/**
* Desc:
* User: HaiNan.Wang
* Date: 2017/5/2
*/
@Import(XyqbUserDatasourceProperties.class)
@Configuration
@Slf4j
@MapperScan(basePackages = XyqbUserDataSourceConfig.PACKAGE, sqlSessionFactoryRef = "xyqbUserSqlSessionFactory")
public class XyqbUserDataSourceConfig {
static final String PACKAGE = "cn.quantgroup.report.mapper.xyqbuser";
@Value("${xyqb_user.mapper-locations}")
private String mapperLocations;
@Value("${xyqb_user.type-aliases-package}")
private String typeAliasesPackage;
@Value("${config-location}")
private String configLocation;
@Autowired
private XyqbUserDatasourceProperties xyqbUserDatasourceProperties;
@Bean(name = "xyqbUserDataSource")
public DataSource xyqbUserDataSource() {
HikariConfig config = new HikariConfig();
config.setJdbcUrl(xyqbUserDatasourceProperties.getJdbcUrl());
log.info("数据库地址:{}", xyqbUserDatasourceProperties.getJdbcUrl());
config.setPassword(xyqbUserDatasourceProperties.getPassword());
config.setUsername(xyqbUserDatasourceProperties.getUsername());
config.setMaximumPoolSize(xyqbUserDatasourceProperties.getMaxPoolSize());
config.setMinimumIdle(xyqbUserDatasourceProperties.getMinPoolSize());
config.addDataSourceProperty("cachePrepStmts", "true");
config.addDataSourceProperty("prepStmtCacheSize", "250");
config.addDataSourceProperty("prepStmtCacheSqlLimit", "2048");
return new HikariDataSource(config);
}
@Bean(name = "xyqbUserTransactionManager")
public DataSourceTransactionManager xyqbUserTransactionManager(@Qualifier("xyqbUserDataSource") DataSource xyqbUserDataSource) {
return new DataSourceTransactionManager(xyqbUserDataSource);
}
@Bean(name = "xyqbUserSqlSessionFactory")
public SqlSessionFactory xyqbUserSqlSessionFactory(@Qualifier("xyqbUserDataSource") DataSource xyqbUserDataSource) throws Exception {
final SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
sessionFactory.setDataSource(xyqbUserDataSource);
sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver()
.getResources(mapperLocations));
sessionFactory.setTypeAliasesPackage(typeAliasesPackage);
sessionFactory.setConfigLocation(new PathMatchingResourcePatternResolver()
.getResource(configLocation));
return sessionFactory.getObject();
}
@Bean(name = "xyqbUserSqlSessionTemplate")
public SqlSessionTemplate xyqbUserSqlSessionTemplate(@Qualifier("xyqbUserSqlSessionFactory") SqlSessionFactory xyqbUserSqlSessionFactory) throws Exception {
return new SqlSessionTemplate(xyqbUserSqlSessionFactory);
}
}
package cn.quantgroup.report.config.datasource.xyqbuser;
import lombok.Getter;
import lombok.Setter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
/**
* Desc:
* User: HaiNan.Wang
* Date: 2017/5/2
*/
@Getter
@Setter
@Configuration
public class XyqbUserDatasourceProperties {
@Value("${db.driver}")
private String driverClass;
@Value("${db.minPoolSize}")
private int minPoolSize;
@Value("${db.maxPoolSize}")
private int maxPoolSize;
@Value("${db.xyqb_user.url}")
private String jdbcUrl;
@Value("${db.xyqb_user.username}")
private String username;
@Value("${db.xyqb_user.password}")
private String password;
}
package cn.quantgroup.report.config.filter;
import cn.quantgroup.report.fastjson.CustomValueFilter;
import com.google.common.collect.Sets;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class ValueFilterConfig {
@Bean("qianHaiMaskedValueFilter")
public CustomValueFilter qianHaiMaskedValueFilter() {
return new CustomValueFilter(Sets.newHashSet("idNo", "idType", "name"));
}
@Bean("jdMaskedValueFilter")
public CustomValueFilter jdMaskedValueFilter() {
return new CustomValueFilter(Sets.newHashSet("mobile", "c_mobile", "address", "cust_id"));
}
@Bean("creditXMaskedValueFilter")
public CustomValueFilter creditXMaskedValueFilter() {
return new CustomValueFilter(Sets.newHashSet("id", "user_name", "mobile_number", "identity_number"));
}
@Bean("baiRongMaskedValueFilter")
public CustomValueFilter baiRongMaskedValueFilter() {
return new CustomValueFilter(Sets.newHashSet("id", "name", "cell", "bank_id"));
}
@Bean("shuMeiMaskedValueFilter")
public CustomValueFilter shuMeiMaskedValueFilter() {
return new CustomValueFilter(Sets.newHashSet("phone", "imei", "idfa", "name", "prcid", "cardid"));
}
@Bean("tongDunMaskedValueFilter")
public CustomValueFilter tongDunMaskedValueFilter() {
return new CustomValueFilter(Sets.newHashSet("account_name", "id_number", "account_mobile"));
}
@Bean("zhiMaMaskedValueFilter")
public CustomValueFilter zhiMaMaskedValueFilter() {
return new CustomValueFilter(Sets.newHashSet("address", "bankCard", "certNo", "bank_card", "cert_no", "mobile"));
}
@Bean("qCloudMaskedValueFilter")
public CustomValueFilter qCloudMaskedValueFilter() {
return new CustomValueFilter(Sets.newHashSet("idNumber", "phoneNumber", "name","uid","userIp"));
}
@Bean("zhengXin91MaskedValueFilter")
public CustomValueFilter zhengXin91MaskedValueFilter() {
return new CustomValueFilter(Sets.newHashSet("realName", "idCard"));
}
@Bean("haoAnMaskedValueFilter")
public CustomValueFilter haoAnMaskedValueFilter() {
return new CustomValueFilter(Sets.newHashSet("name", "id", "appkey", "phone"));
}
@Bean("baiDuMaskedValueFilter")
public CustomValueFilter baiDuMaskedValueFilter() {
return new CustomValueFilter(Sets.newHashSet("name", "identity", "appkey", "phone", "sp_no"));
}
@Bean("intelliCreditMaskedValueFilter")
public CustomValueFilter intelliCreditMaskedValueFilter() {
return new CustomValueFilter(Sets.newHashSet("name", "pid", "mobile"));
}
@Bean("baiQiShiMaskedValueFilter")
public CustomValueFilter baiQiShiMaskedValueFilter() {
return new CustomValueFilter(Sets.newHashSet("name", "identity","phone","verifyKey","partnerId"));
}
@Bean("dianHuaBangMaskedValueFilter")
public CustomValueFilter dianHuaBangMaskedValueFilter() {
return new CustomValueFilter(Sets.newHashSet("phone"));
}
@Bean("rong360MaskedValueFilter")
public CustomValueFilter rong360MaskedValueFilter() {
return new CustomValueFilter(Sets.newHashSet("orderNo"));
}
@Bean("unionPayMaskedValueFilter")
public CustomValueFilter unionPayMaskedValueFilter() {
return new CustomValueFilter(Sets.newHashSet("bankCardNo","name","identityNo","phone"));
}
@Bean("chengAnMaskedValueFilter")
public CustomValueFilter chengAnMaskedValueFilter() {
return new CustomValueFilter(Sets.newHashSet("name","idCard","mobiel"));
}
@Bean("shengDunMaskedValueFilter")
public CustomValueFilter shengDunMaskedValueFilter() {
return new CustomValueFilter(Sets.newHashSet("name","identityNumber","phone"));
}
@Bean("xinYanMaskedValueFilter")
public CustomValueFilter xinYanMaskedValueFilter() {
return new CustomValueFilter(Sets.newHashSet("name","identity","phone","bankCard"));
}
@Bean("elevenBeiMaskedValueFilter")
public CustomValueFilter elevenBeiMaskedValueFilter() {
return new CustomValueFilter(Sets.newHashSet("identity"));
}
@Bean("tianXingHuiMaskedValueFilter")
public CustomValueFilter tianXingHuiMaskedValueFilter() {
return new CustomValueFilter(Sets.newHashSet("name","identity","phone"));
}
@Bean("zhongChengXinMaskedValueFilter")
public CustomValueFilter zhongChengXinMaskedValueFilter() {
return new CustomValueFilter(Sets.newHashSet("name","identityNumber"));
}
@Bean("jiGuangMaskedValueFilter")
public CustomValueFilter jiGuangMaskedValueFilter() {
return new CustomValueFilter(Sets.newHashSet("name","id_number","phone"));
}
@Bean("kaNiuMaskedValueFilter")
public CustomValueFilter kaNiuMaskedValueFilter() {
return new CustomValueFilter(Sets.newHashSet("name"));
}
@Bean("shuChuangMaskedValueFilter")
public CustomValueFilter shuChuangMaskedValueFilter() {
return new CustomValueFilter(Sets.newHashSet("mobile"));
}
@Bean("faHaiMaskedValueFilter")
public CustomValueFilter faHaiMaskedValueFilter() {
return new CustomValueFilter(Sets.newHashSet("name", "idCard"));
}
@Bean("tianChuangMaskedValueFilter")
public CustomValueFilter tianChuangMaskedValueFilter() {
return new CustomValueFilter(Sets.newHashSet("name", "identity", "phone"));
}
@Bean("tanZhiMaskedValueFilter")
public CustomValueFilter tanZhiMaskedValueFilter() {
return new CustomValueFilter(Sets.newHashSet("name", "identity", "phone"));
}
@Bean("jiAoMaskedValueFilter")
public CustomValueFilter jiAoMaskedValueFilter() {
return new CustomValueFilter(Sets.newHashSet("name", "idCard"));
}
@Bean("bingJianMaskedValueFilter")
public CustomValueFilter bingJianMaskedValueFilter() {
return new CustomValueFilter(Sets.newHashSet("name", "id", "phone", "bankCard"));
}
@Bean("anLiangMaskedValueFilter")
public CustomValueFilter anLiangMaskedValueFilter() {
return new CustomValueFilter(Sets.newHashSet("name", "idCard", "mobile", "bankCard"));
}
@Bean("zhiShuMaskedValueFilter")
public CustomValueFilter zhiShuMaskedValueFilter() {
return new CustomValueFilter(Sets.newHashSet("name", "idCard", "mobile"));
}
@Bean("ficoMaskedValueFilter")
public CustomValueFilter ficoMaskedValueFilter() {
return new CustomValueFilter(Sets.newHashSet("mobile", "idCard"));
}
}
\ No newline at end of file
/**
*
*/
package cn.quantgroup.report.config.http;
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpRequest;
import org.apache.http.NoHttpResponseException;
import org.apache.http.client.HttpRequestRetryHandler;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.config.Registry;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.conn.ConnectionKeepAliveStrategy;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultConnectionKeepAliveStrategy;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.protocol.HttpContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.net.ssl.*;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.net.UnknownHostException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
/**
* @author guowei.wei
* @time 2018-05-30 10:11
*/
@Configuration
public class HttpClientConfig {
@Bean(name = "httpClient")
public CloseableHttpClient httpClient() throws NoSuchAlgorithmException, KeyManagementException {
/**
* 忽略证书
*/
HostnameVerifier ignoreHostnameVerifier = new HostnameVerifier(){
@Override
public boolean verify(String hostname, SSLSession session) {
return true;
}
};
/**
* 创建TrustManager
*/
X509TrustManager xtm = new X509TrustManager(){
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {}
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {}
public X509Certificate[] getAcceptedIssuers() { return null; }
public boolean isServerTrusted(
X509Certificate[] certs) {
return true;
}
public boolean isClientTrusted(
X509Certificate[] certs) {
return true;
}
};
SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
sslContext.init(null, new TrustManager[]{xtm}, new SecureRandom());
SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(sslContext,ignoreHostnameVerifier);
Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory>create()
.register("http", PlainConnectionSocketFactory.getSocketFactory())
.register("https", sslsf)
.build();
// connection manager
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
connectionManager.setMaxTotal(10000);
connectionManager.setDefaultMaxPerRoute(1000);
HttpRequestRetryHandler retryHandler = new HttpRequestRetryHandler() {
@Override
public boolean retryRequest(IOException arg0, int retryTimes, HttpContext arg2) {
if (retryTimes >= 2)
return false;
if (arg0 instanceof UnknownHostException || arg0 instanceof ConnectTimeoutException
|| !(arg0 instanceof SSLException) || arg0 instanceof NoHttpResponseException || arg0 instanceof InterruptedIOException)
return true;
HttpClientContext clientContext = HttpClientContext.adapt(arg2);
HttpRequest request = clientContext.getRequest();
if (!(request instanceof HttpEntityEnclosingRequest)) // 如果请求被认为是幂等的,那么就重试。即重复执行不影响程序其他效果的
return true;
return false;
}
};
// keep alive strategy
ConnectionKeepAliveStrategy keepAliveStrategy = new DefaultConnectionKeepAliveStrategy();
// httpclient
return HttpClients.custom()
.setConnectionManager(connectionManager)
.setRetryHandler(retryHandler)
.setKeepAliveStrategy(keepAliveStrategy)
.build();
}
}
package cn.quantgroup.report.constant;/**
* -----------------------------------------------------------------------------<br>
* 描述: <br>
* 作者: Administrator <br>
* 时间: 2019.11.14 10:56 <br>
* 授权: (C) Copyright (c) 2017 <br>
* 公司: 北京众信利民信息技术有限公司 <br>
* -----------------------------------------------------------------------------
*/
/**
* -----------------------------------------------------------------------------<br>
* 描述: <br>
* 作者:yanhui.Hao <br>
* 时间:2019.11.14 <br>
* 授权: (C) Copyright (c) 2017 <br>
* 公司: 北京众信利民信息技术有限公司 <br>
* -----------------------------------------------------------------------------
*/
public class BaiHangHistoryConstant {
public static final int MAX_COMMIT_COUT = 24000;//大于2万条会出现事务提交过长报错
public static final String SQL_COMMONE_TEMPLATE_HISTORY = "INSERT xyqb_i_loan_a_m_history_bak " +
" select * from xyqb_i_loan_application_manifest_history b " +
" where b.funding_corp_id in (420,520,580,650,670,810,240,640,700) " +
" and b.created_at >= '##STARTTIME##' and b.created_at < '##ENDTIME##'; ";
//报送查询 b.loan_paid_at<@t2 公司打款时间
public static final String SQL_COMMONE_TEMPLATE_PLAN = "INSERT xyqb_i_repayment_plan_bak " +
"select a.* from xyqb_i_repayment_plan a " +
" join xyqb_i_loan_a_m_history_bak b " +
" on a.loan_application_history_id = b.loan_application_history_id " +
"where b.created_at >= '##STARTTIME##' and b.created_at < '##ENDTIME##'; ";
//报送查询 a.repaid_at>=@t2 还款时间
//---------------------根据id去同步---------------------------
public static final String SQL_COMMONE_TEMPLATE_HISTORY_BAK_MAX_ID = "select MAX(b.id) as bakMaxId from xyqb_i_loan_a_m_history_bak b; ";
public static final String SQL_COMMONE_TEMPLATE_HISTORY_MAX_ID = " select MAX(b2.id) from xyqb_i_loan_application_manifest_history b2 " +
" where b2.funding_corp_id in (420,520,580,650,670,810,240,640,700) ";
//借款清单表xyqb_i_loan_application_manifest_history
public static final String SQL_COMMONE_TEMPLATE_HISTORY_SYN_COUNT = "select count(b.id) from xyqb_i_loan_application_manifest_history b " +
" where b.funding_corp_id in (420,520,580,650,670,810,240,640,700) " +
" and b.id > ##BAKMAXID## AND b.id <= ##NEWMAXID## ;";
public static final String SQL_COMMONE_TEMPLATE_HISTORY_SYN_DATA = "REPLACE INTO xyqb_i_loan_a_m_history_bak " + //"INSERT xyqb_i_loan_a_m_history_bak "
" select b.* from xyqb_i_loan_application_manifest_history b " +
" where b.funding_corp_id in (420,520,580,650,670,810,240,640,700) " +
" and b.id > ##STARTID## ";//AND b.id <= ##ENDID##
//还款计划表还款计划表xyqb_i_repayment_plan
public static final String SQL_COMMONE_TEMPLATE_PLAN_SYN_COUNT = "select count(a.id) from xyqb_i_repayment_plan a " +
" join xyqb_i_loan_a_m_history_bak b on a.loan_application_history_id = b.loan_application_history_id " +
" where b.id > ##BAKMAXID## AND b.id <= ##NEWMAXID## ;";
public static final String SQL_COMMONE_TEMPLATE_PLAN_SYN_DATA = "REPLACE INTO xyqb_i_repayment_plan_bak " + //"INSERT xyqb_i_repayment_plan_bak "
"select a.* from xyqb_i_repayment_plan a " +
" join xyqb_i_loan_a_m_history_bak b on a.loan_application_history_id = b.loan_application_history_id " +
" where b.id > ##STARTID## ";//AND b.id <= ##ENDID##
public static final String SQL_TEMPLATE_HISTORY_P2P = "REPLACE INTO xyqb_i_loan_a_m_history_p2p_bak " +
" select * from xyqb_i_loan_application_manifest_history b " +
" where b.funding_corp_id in (210,540) " +
" and b.loan_paid_at >= '##STARTTIME##' and b.loan_paid_at < '##ENDTIME##'; ";
public static final String SQL_TEMPLATE_PLAN_P2P = "REPLACE INTO xyqb_i_repayment_plan_p2p_bak " +
" select a.* from xyqb_i_repayment_plan a " +
" join xyqb_i_loan_a_m_history_p2p_bak b on a.loan_application_history_id = b.loan_application_history_id " +
" where b.loan_paid_at >= '##STARTTIME##' and b.loan_paid_at < '##ENDTIME##'; ";
}
package cn.quantgroup.report.constant;
/**
* Created by Alan on 2018/6/14.
*/
public class KeyConstant {
public static final String PROJECT_NAME = "risk_datasource:";
public static final String STAT = PROJECT_NAME + "stat:";
public static final String ONE_DAY = "one_day:";
public static final String ONE_HOUR = "one_hour:";
public static final String HEAP = "heap:";
public static final String HIT_RATE = STAT + "hit_rate:";
}
package cn.quantgroup.report.constant;
public enum TransactionCodeEnum {
SuccessAndHit("请求成功且命中", 1001),
SuccessAndMiss("请求成功且未命中", 1002),
Fail("请求失败", 1003),
HitInHbase("命中HBase", 1004);
private String name;
private int code;
TransactionCodeEnum(String name, int code){
this.name = name;
this.code = code;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getCode() {
return code;
}
public void setCode(int code) {
this.code = code;
}
}
package cn.quantgroup.report.controller;
import cn.quantgroup.report.response.GlobalResponse;
import cn.quantgroup.report.service.cache.CacheService;
import cn.quantgroup.report.service.DataSourceCacheConfigService;
import cn.quantgroup.report.service.common.CommonQueryService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Slf4j
@RestController
@RequestMapping(value = "/cache")
public class CacheController {
@Autowired
private CacheService cacheService;
@Autowired
private DataSourceCacheConfigService cacheConfigService;
@Autowired
private CommonQueryService commonQueryService;
@Autowired
private RedisTemplate redisTemplate;
@RequestMapping("/clear_huadao_token")
public GlobalResponse clearHuadaoToken(){
try{
redisTemplate.delete("NEW_HUADAO_QUERY_TOKEN_KEY");
log.info("清除华道缓存token成功");
return GlobalResponse.generate("清除华道缓存token成功");
}catch(Exception e){
log.info("清除华道缓存token异常");
return GlobalResponse.generate("清除华道缓存token异常");
}
}
@RequestMapping("/get_huadao_token")
public GlobalResponse getHuadaoToken(){
try{
String token = String.valueOf(redisTemplate.opsForValue().get("NEW_HUADAO_QUERY_TOKEN_KEY"));
log.info("获取华道缓存token结果, token : {} ", token);
return GlobalResponse.generate(token);
}catch(Exception e){
log.info("获取华道缓存token异常");
return GlobalResponse.generate("获取华道缓存token异常");
}
}
@RequestMapping("/reload")
public GlobalResponse reload(){
try{
cacheConfigService.init();
log.info("刷新数据源缓存时间完成");
return GlobalResponse.generate("Ok");
}catch(Exception e){
log.info("刷新数据源缓存时间异常", e);
return GlobalResponse.generate(e.getMessage());
}
}
@RequestMapping("/config/clear")
public GlobalResponse clearConfigCache(String configName) {
try{
cacheService.clearCache(configName);
log.info("刷新缓存配置成功, configName: {} ", configName);
return GlobalResponse.generate("OK");
}catch (Exception e){
log.error("刷新缓存异常, {} , {} , {} ", configName, e.getMessage(), e);
return GlobalResponse.generate(e.getMessage());
}
}
@RequestMapping("/lock/clear")
public GlobalResponse clearLock(String lockName) {
try{
cacheService.clearLock(lockName);
return GlobalResponse.generate("OK");
}catch (Exception e){
log.error("{}", e.getMessage(), e);
return GlobalResponse.generate(e.getMessage());
}
}
}
package cn.quantgroup.report.controller;
import com.alibaba.fastjson.JSON;
import com.google.common.collect.ImmutableMap;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
/**
* @Author fengjunkai
*/
@Slf4j
@RestController
@RequestMapping("/")
public class CheckController {
private static Map<String,String> map = new ConcurrentHashMap<>();
@ResponseBody
@RequestMapping(value="check")
public ResponseEntity<String> check(){
if(map!=null && map.size()>0){
return new ResponseEntity<String>(HttpStatus.NOT_FOUND);
}else{
return new ResponseEntity<String>(HttpStatus.OK);
}
}
@ResponseBody
@RequestMapping(value="/online")
public Map<String, String> online(){
log.info("应用上线,流量开始切入....");
map.clear();
return responseOk();
}
@ResponseBody
@RequestMapping(value="/offline")
public Map<String, String> offline(){
log.info("应用下线,流量不再切入....");
map.put("status", "offline");
return responseOk();
}
@ResponseBody
@RequestMapping(value="/test")
public Map<String, String> test() {
log.info("CheckController测试!map = {}", map);
return ImmutableMap.of("code", "0", "msg", JSON.toJSONString(map));
}
public static Map<String, String> responseOk() {
return ImmutableMap.of("code", "0", "msg", "ok");
}
@RequestMapping("/getuuid")
public String getUuid(String param){
return UUID.nameUUIDFromBytes(param.getBytes()).toString();
}
}
package cn.quantgroup.report.controller;
import com.netflix.discovery.DiscoveryManager;
import com.netflix.discovery.EurekaClient;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @Author fengjunkai
*/
@Slf4j
@RestController
@RequestMapping("/")
public class DiscoveryManagerController {
@Autowired
@Qualifier("eurekaClient")
private EurekaClient eurekaClient;
@RequestMapping("clientShutdown")
public void clientShutdown(){
try{
eurekaClient.shutdown();
log.info("百行报送项目通知eureka下线成功");
}catch(Exception e){
log.error("百行报送项目通知eureka下线异常", e);
}
}
@RequestMapping("test1")
public String test(){
try {
log.info("开始执行");
Thread.sleep(10000);
log.info("执行结束");
} catch (InterruptedException e) {
e.printStackTrace();
}
return "hello world !!!";
}
}
package cn.quantgroup.report.controller;
import cn.quantgroup.report.response.GlobalResponse;
import cn.quantgroup.report.service.common.CommonQueryService;
import cn.quantgroup.report.service.manualTool.CleanningTransactionLogService;
import cn.quantgroup.report.service.manualTool.ManualToolService;
import com.alibaba.fastjson.JSON;
import com.google.common.collect.ImmutableMap;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
@Slf4j
@RestController
@RequestMapping(value = "/manualtool")
public class ManualToolController {
@Autowired
private ManualToolService manualToolService;
@Autowired
private CommonQueryService queryService;
@Autowired
private CleanningTransactionLogService cleanningTransactionLogService;
@RequestMapping("/send/baihang")
public String sendBaihang(String p1,String p2,String p3,String p4,String p5,String secretKey, String isSend,String errorCode, String isProduct, String sendIncludeType) {
try{
Map<String,String> resultMap = manualToolService.sendBaiHangData(p1,p2,p3,p4,p5,secretKey,isSend,errorCode, isProduct, sendIncludeType);
return JSON.toJSONString(resultMap);
}catch (Exception e){
log.error("众信利民助贷模式To百行征信手动报送异常, {} , {} ", e.getMessage(), e);
return "众信利民助贷模式To百行征信手动报送异常";
}
}
/**
* 描述: 放款信息 D2 <br/>
* 参数: [jsonFile] <br/>
* 返回值: GlobalResponse <br/>
* 创建人: yanhui.Hao <br/>
* 创建时间: 2019.09.27 <br/>
*/
@RequestMapping("/build/d2")
public GlobalResponse buildLoanInfoD2(String jsonFile) {
try{
return manualToolService.buildLoanInfoD2(jsonFile);
}catch (Exception e){
log.error("百行征信手动报送异常, {} , {} ", e.getMessage(), e);
return GlobalResponse.generate(e.getMessage());
}
}
@RequestMapping("/dealWithExcelData")
public GlobalResponse dealWithExcelData(String filePath,String type){
return manualToolService.dealWithExcelData(filePath,type);
}
@RequestMapping("/removeD3LoanIdChunfu")
public String remove_D3_loanId_chunfu(String oldDataFile, String cfLoanIdLogFile, String newFileName, String rmIdFileName,String rmPhoneFileName){
return manualToolService.remove_D3_loanId_chunfu(oldDataFile,cfLoanIdLogFile,newFileName,rmIdFileName,rmPhoneFileName);
}
@RequestMapping("/checkD3loanIdInD2")
public String check_D3loanId_InD2(String d3LoanIdFile, String d2File, String inFileName, String notInFileName){
return manualToolService.check_D3loanId_InD2(d3LoanIdFile,d2File,inFileName,notInFileName);
}
@RequestMapping("/checkD2loanIdInD3WanJie")
public String check_D2loanId_InD3WanJie(String d3LoanIdFile, String d2File, String notWJFileName){
return manualToolService.check_D2loanId_InD3WanJie(d3LoanIdFile,d2File,notWJFileName);
}
@RequestMapping("/newD3ReplaceReqId")
public String newD3ReplaceReqId(String newD3FilePath, String newD3FileNames, String oldD3ReqIdFile, String mapNotEmptyFile){
manualToolService.newD3ReplaceReqId(newD3FilePath,newD3FileNames,oldD3ReqIdFile,mapNotEmptyFile);
return "调用结束";
}
@RequestMapping("/d2_saveLog")
public String d2_saveLog(String d2JsonFileName,String reqIdFileName,String no_reqId_start, String isHaveRecordId){
manualToolService.d2_saveLog(d2JsonFileName,reqIdFileName,no_reqId_start,isHaveRecordId);
return "d2_saveLog调用结束";
}
@RequestMapping("/d3_saveLog")
public String d3_saveLog(String d3FilePath, String d3JsonFileNames, String reqIdLogName, String no_reqId_start, String isHaveRecordId){
manualToolService.d3_saveLog(d3FilePath,d3JsonFileNames,reqIdLogName,no_reqId_start,isHaveRecordId);
return "d3_saveLog调用结束";
}
@RequestMapping("/synCallRecordNew")
public String synCallRecordNew(String newYnrTime,String isExecuteOnce){
cleanningTransactionLogService.synCallRecordNew(newYnrTime,isExecuteOnce);
return "synCallRecordNew调度完成";
}
@RequestMapping("/checkCallRecordCF")
public String checkCallRecordCF(String newYnrTime,String isExecuteOnce){
cleanningTransactionLogService.checkCallRecordCF(newYnrTime,isExecuteOnce);
return "checkCallRecordCF调度完成";
}
@RequestMapping("/checkTransactionLogCF")
public String checkTransactionLogCF(String newYnrTime,String isExecuteOnce){
cleanningTransactionLogService.checkTransactionLogCF(newYnrTime,isExecuteOnce);
return "checkTransactionLogCF调度完成";
}
@RequestMapping("/checkCallRecordCFByTransactionLog")
public String checkCallRecordCFByTransactionLog(String newYnrTime,String isExecuteOnce){
cleanningTransactionLogService.checkCallRecordCFByTransactionLog(newYnrTime,isExecuteOnce);
return "checkCallRecordCFByTransactionLog调度完成";
}
@RequestMapping("/checkCallRecordCFByTransactionLog2")
public String checkCallRecordCFByTransactionLog2(String newYnrTime,String isExecuteOnce){
cleanningTransactionLogService.checkCallRecordCFByTransactionLog2(newYnrTime,isExecuteOnce);
return "checkCallRecordCFByTransactionLog2调度完成";
}
@RequestMapping("/deleteTidbCallRecordCF")
public String deleteTidbCallRecordCF(String cfFileName, String bakFileName){
cleanningTransactionLogService.deleteTidbCallRecordCF(cfFileName,bakFileName);
return "deleteTidbCallRecordCF调度完成";
}
@RequestMapping("/deleteRedisKey")
public Map<String,Object> deleteRedisKey(String key1, String key2, String key3){
try{
manualToolService.deleteRedisKey(key1, key2, key3);
return ImmutableMap.of("code", 0, "msg", "手动删除redisKey成功");
}catch(Exception e){
return ImmutableMap.of("code", 1, "msg", "手动设置redisKey异常");
}
}
@RequestMapping("/getRedisVal")
public String getRedisVal(String key){
try{
return manualToolService.getRedisVal(key);
}catch(Exception e){
return "获取redis值异常";
}
}
}
package cn.quantgroup.report.controller.external;
import cn.quantgroup.report.service.baihang.BaiHangQueryService;
import cn.quantgroup.report.service.common.CommonQueryService;
import cn.quantgroup.report.utils.IdUtils;
import com.alibaba.fastjson.JSON;
import com.google.common.collect.ImmutableMap;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.util.Map;
/**
* Created by fengjunkai on 2018/8/13 0013 下午 4:48
**/
@Slf4j
@RestController
@RequestMapping(value = "/ex/common", method = RequestMethod.POST)
public class CommonSourceController {
@Autowired
private CommonQueryService queryService;
@Autowired
private BaiHangQueryService baiHangQueryService;
@RequestMapping("/query")
public Object commonQuery(String source_types, String uuid, String name, String phone, String identity, String backDate, String business_type, String order_id, boolean isReadCache){
Object object = queryService.commonQuery(source_types, uuid, name, phone, identity, backDate, business_type, order_id, isReadCache);
return object;
}
/**
* -----------------------------------------------------------------------------<br>
* 描 述: 百行个人征信报告查询 <br>
* 创建人: yanhui.Hao <br>
* 创建时间: 2020.05.13 16:53 <br>
* 最后修改人: <br>
* 最后修改时间: 2020.05.13 16:53 <br>
* 入参说明: [transactionId, uuid, identity, phone, name, queryReason, loanId] <br>
* 出参说明: java.lang.String <br>
* -----------------------------------------------------------------------------
*/
@RequestMapping("/zxlmbh/persionCreditReport")
public String persionCreditReport(String key, String transactionId, String uuid, String identity, String phone, String name, String queryReason, String loanId) {
Map<String, Object> resultMap = null;
if(StringUtils.isEmpty(key) || !"b5140fb2-2c85-4b5a-abcf-3e97528014db".equals(key)){
resultMap = ImmutableMap.of("code", "301", "msg", "权限参数不能为空!");
}
if (StringUtils.isAnyBlank(identity, name, queryReason)) {
resultMap = ImmutableMap.of("code", "301", "msg", "业务参数不能为空!");
}else{
if (StringUtils.isEmpty(transactionId)) {
transactionId = IdUtils.getUuid();
}
resultMap = baiHangQueryService.queryBaiHangQ1OfZxlm(transactionId, uuid, identity, phone, name, queryReason, loanId);
}
return JSON.toJSONString(resultMap);
}
}
package cn.quantgroup.report.domain.baihang;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* 申请贷款信息
*
* @Author fengjunkai
* @Date 2019-03-26 14:32
*/
@Data
public class ApplyLoanInfo {
private String reqID;
private String uploadTs;
private String name;
private String pid;
private String mobile;
private String queryReason;
private String guaranteeType;
private String loanPurpose;
private String customType;
private String applyAmount;
private String loanId;
}
package cn.quantgroup.report.domain.baihang;
import java.math.BigDecimal;
import lombok.Data;
/**
* 申请贷款信息
*
* @Author fengjunkai
* @Date 2019-03-26 14:32
*/
@Data
public class ApplyLoanInfoZhuDai {
private String reqID;
private String opCode;//操作代码A-增加 M-修改
private String uploadTs;
private int isFinTechAgencyBusiness;//是否是助贷业务 N
private String applyDate;
private String applyId;
private int applyType;
private String name;
private int idType;
private String pid;
private String mobile;
private String emailAddress; //电子邮箱
private int eduBackground;//学历
private int degree;//学位
private int guaranteeType;//信贷业务担保类型
private int loanPurpose;//贷款用途 Y/N
private int customType; //客户类型
private BigDecimal applyAmount; //申请贷款金额
private String businessOrgCreditCode;//业务发生机构代码 Y/N
//private String homeAddress; //N
//private String homePhone; //N
//private String workName; //N
//private String workAddress; //N
//private String workPhone; //N
//private String idAddress; //N
//private String mailAddress; //N
private int livingCondition;//居住状况
private int marriageStatus; //婚姻状况
private String spouseName;//配偶姓名 Y/N
//private Integer spouseIdType;
//private String spousePid;
//private String spouseMobile;
//private String spouseWorkName;
//private String firstContactsName; //第一联系人姓名 Y/N
//private Integer firstContactsRelationship;
//private Integer firstContactsIdType;
//private String firstContactsPid;
//private String firstContactsMobile; //第一联系人手机号码 Y/N
//private String firstContactsTelephone;
//private String firstContactsWorkName;
//private String secondContactsName;//第二联系人姓名 Y/N
//private Integer secondContactsRelationship;
//private Integer secondContactsIdType;
//private String secondContactsPid;
//private String secondContactsMobile;//第二联系人手机号码 Y/N
//private String secondContactsTelephone;
//private String secondContactsWorkName;
//device;
//deviceType;
//imei;
//mac;
//ipAddress;
//osName;
}
package cn.quantgroup.report.domain.baihang;
import lombok.Builder;
import lombok.Data;
/**
* @Author fengjunkai
* @Date 2019-04-24 15:46
*/
@Builder
@Data
public class BaiHangName {
private String loanId;
}
package cn.quantgroup.report.domain.baihang;
import lombok.Data;
/**
* @Author fengjunkai
* @Date 2019-04-24 15:46
*/
@Data
public class BaiHangNameResult {
private String name;
private String mobile;
private String pid;
}
package cn.quantgroup.report.domain.baihang;
import lombok.Builder;
import lombok.Data;
/**
* @Author fengjunkai
* @Date 2019-04-20 13:30
*/
@Data
@Builder
public class BaiHangRepayment {
private String sendDate;
private String loanId;
private int termNo;
}
package cn.quantgroup.report.domain.baihang;
import lombok.Builder;
import lombok.Data;
/**
* @Author fengjunkai
* @Date 2019-07-12 18:44
*/
@Builder
@Data
public class BaiHangThreeElements {
private String name;
private String idCard;
private String phone;
}
package cn.quantgroup.report.domain.baihang;
import lombok.Builder;
import lombok.Data;
/**
* @Author fengjunkai
* @Date 2019-04-16 16:29
*/
@Builder
@Data
public class BaiHangTimeRecord {
private String startTime;
private String endTime;
}
package cn.quantgroup.report.domain.baihang;
import lombok.Builder;
import lombok.Data;
/**
* @Author fengjunkai
* @Date 2019-04-16 20:11
*/
@Builder
@Data
public class BaiHangUpDateRecord {
private String enable;
private String recordId;
private String opCode;
}
package cn.quantgroup.report.domain.baihang;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* 放款-资金合作方信息
*
* @Author fengjunkai
* @Date 2019-03-26 14:49
*/
@Data
public class FinTechAgencyBusinessZhuDai implements Serializable {
private static final long serialVersionUID = 7293591774673907983L;
private String institutionalFundingPartner; //资金合作方名称
private String institutionalFundingPartnerID; //资金合作方代码
private String relationID; //助贷机构与资金合作方的关联码
private String institutionalFundingPartnerLoanID; //资金合作方贷款/授信账户编号 N
private String orderID; //助贷业务贷款订单编号
private BigDecimal preCreditLimit; //预授信额度 N
}
package cn.quantgroup.report.domain.baihang;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* 放款用户信息
*
* @Author fengjunkai
* @Date 2019-03-26 14:49
*/
@Data
public class LoanInfoZhuDai extends FinTechAgencyBusinessZhuDai implements Serializable {
private static final long serialVersionUID = 7293591774673907983L;
private String reqID; //记录唯一ID
private String opCode; //操作代码A-增加 M-修改
private String uploadTs; //记录生成时间 ISO 8601格式 LocalDateTime生成 2016-03-08T10:03:10
//businessOrgCreditCod 业务发生机构代码 Y/N 实际开展本信贷业务的机构的代码。
private String name; //姓名
private String pid; //身份证好
private String mobile; //手机号
private String loanId; //贷款编号
//originalLoanId
private int guaranteeType; //贷款担保类型
private int loanPurpose; //借款用途
private String applyDate;// 贷款申请时间
private String accountOpenDate; //账户开立时间
private String issueDate; //贷款放款时间
private String dueDate; //贷款到期日期 YYYY-MM-DD
private BigDecimal loanAmount; //贷款金额
private int totalTerm; //还款总期数
private int targetRepayDateType; //账单日类型
private int termPeriod;//每期还款周期
private String firstRepaymentDate; //首次应还款日期 YYYY-MM-DD
private int gracePeriod; //宽限日
private String targetRepayDateList; //账单日列表
private String recordId;
}
package cn.quantgroup.report.domain.baihang;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* 放款用户信息
*
* @Author fengjunkai
* @Date 2019-03-26 14:49
*/
@Data
public class LoanInfoZhuDaiVo implements Serializable {
private static final long serialVersionUID = 7293591774673907983L;
private String reqID; //记录唯一ID
private String opCode; //操作代码A-增加 M-修改
private String uploadTs; //记录生成时间 ISO 8601格式 LocalDateTime生成 2016-03-08T10:03:10
private String name; //姓名
private String pid; //身份证好
private String mobile; //手机号
private String loanId; //贷款编号
//originalLoanId
private int guaranteeType; //贷款担保类型
private int loanPurpose; //借款用途
private String applyDate;// 贷款申请时间
private String accountOpenDate; //账户开立时间
private String issueDate; //贷款放款时间
private String dueDate; //贷款到期日期 YYYY-MM-DD
private BigDecimal loanAmount; //贷款金额
private int totalTerm; //还款总期数
private int targetRepayDateType; //账单日类型
private int termPeriod;//每期还款周期
private String firstRepaymentDate; //首次应还款日期 YYYY-MM-DD
private int gracePeriod; //宽限日
private String targetRepayDateList; //账单日列表
private FinTechAgencyBusinessZhuDai finTechAgencyBusiness; //资金合作方信息
//可以为空
/*"device": {
"deviceType": 1,
"imei": "ABCDEFG12345678",
"mac": "ABCD12345678",
"ipAddress": "139.129.1.54",
"osName": 2
}*/
}
package cn.quantgroup.report.domain.baihang;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* 还款用户信息
*
* @Author fengjunkai
* @Date 2019-03-26 15:13
*/
@Data
public class RepaymentInfoZhuDai implements Serializable {
private static final long serialVersionUID = 8722959335665582382L;
private String reqID; //记录唯一标示
private String opCode; //操作CODE a-增加 m-修改
private String uploadTs; //记录生成时间 ISO 8601
private String loanId; //贷款ID
private String name;
private String pid;
private String mobile;
private int termNo; //当前还款期数
private String termStatus; //本期还款状态
private String targetRepaymentDate; //本期应还款日 YYYY-MM-DD
private String realRepaymentDate; //实际还款日期ISO 8601 Y/N
private BigDecimal plannedPayment; //本期计划应还款金额
private BigDecimal targetRepayment; //本期剩余应还款金额
private BigDecimal realRepayment; // 本次还款金额
private String overdueStatus; //当前逾期天数
private String statusConfirmAt;//本期还款状态确认时间
private BigDecimal overdueAmount; //当前逾期总金额
private BigDecimal remainingAmount; //贷款余额
private int loanStatus; //本笔贷款状态
//businessOrgCreditCode 业务发生机构代码string Y/N
private String recordId;
}
package cn.quantgroup.report.domain.baihang;
import lombok.Data;
import java.io.Serializable;
import java.math.BigDecimal;
/**
* 还款用户信息
*
* @Author fengjunkai
* @Date 2019-03-26 15:13
*/
@Data
public class RepaymentLoanInfoLog implements Serializable {
private static final long serialVersionUID = 8722959335665582382L;
private String reqID; //记录唯一标示
private String opCode; //操作CODE a-增加 m-修改
private String uploadTs; //记录生成时间 ISO 8601
private String loanId; //贷款ID
private String name;
private String pid;
private String mobile;
private int termNo; //当前还款期数
private String termStatus; //本期还款状态
private String targetRepaymentDate; //本期应还款日 YYYY-MM-DD
private String realRepaymentDate; //实际还款日期ISO 8601
private BigDecimal plannedPayment; //本期计划应还款金额
private BigDecimal targetRepayment; //本期剩余应还款金额
private BigDecimal realRepayment; // 本次还款金额
private String overdueStatus; //当前逾期天数
private String statusConfirmAt;//本期还款状态确认时间
private BigDecimal overdueAmount; //当前逾期总金额
private BigDecimal remainingAmount; //贷款余额
private int loanStatus; //本笔贷款状态
private String recordId;
private Long id;
private Integer enable;
private String createdAt;
private String updatedAt;
}
package cn.quantgroup.report.domain.master;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.math.BigDecimal;
@Builder
@Data
@AllArgsConstructor
@NoArgsConstructor
public class AccountPO implements Serializable{
/**
*
* This field was generated by MyBatis Generator.
* This field corresponds to the database column account.id
*
* @mbg.generated
*/
private Integer id;
/**
*
* This field was generated by MyBatis Generator.
* This field corresponds to the database column account.source_name
*
* @mbg.generated
*/
private String sourceName;
/**
*
* This field was generated by MyBatis Generator.
* This field corresponds to the database column account.blance
*
* @mbg.generated
*/
private BigDecimal blance;
private BigDecimal thershold;
/**
*
* This field was generated by MyBatis Generator.
* This field corresponds to the database column account.status
*
* @mbg.generated
*/
private String status;
}
\ No newline at end of file
package cn.quantgroup.report.domain.master;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.util.Date;
@Builder
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ApiRequestLogPO implements Serializable{
/**
*
* This field was generated by MyBatis Generator.
* This field corresponds to the database column api_request_log_201805.id
*
* @mbg.generated
*/
private Long id;
/**
*
* This field was generated by MyBatis Generator.
* This field corresponds to the database column api_request_log_201805.url_type
*
* @mbg.generated
*/
private String urlType;
/**
*
* This field was generated by MyBatis Generator.
* This field corresponds to the database column api_request_log_201805.res_code
*
* @mbg.generated
*/
private String resCode;
/**
*
* This field was generated by MyBatis Generator.
* This field corresponds to the database column api_request_log_201805.res_msg
*
* @mbg.generated
*/
private String resMsg;
private String hitFlag;
/**
*
* This field was generated by MyBatis Generator.
* This field corresponds to the database column api_request_log_201805.time_elapse
*
* @mbg.generated
*/
private Integer timeElapse;
/**
*
* This field was generated by MyBatis Generator.
* This field corresponds to the database column api_request_log_201805.create_time
*
* @mbg.generated
*/
private Date createTime;
/**
* yyyymm --- 201805
*/
private String suffix;
}
\ No newline at end of file
package cn.quantgroup.report.domain.master;
import lombok.Data;
import java.io.Serializable;
import java.sql.Timestamp;
/**
* @Author fengjunkai
*/
@Data
public class CallRecord1 implements Serializable {
private static final long serialVersionUID = 3380282142711506937L;
private String transactionId;
private String uuid;
private String urlType;
private String code;
private Timestamp created_at;
private Timestamp updated_at;
}
package cn.quantgroup.report.domain.master;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Date;
/**
* Created by suh on 2018/3/28.
*/
@Builder
@Data
@AllArgsConstructor
@NoArgsConstructor
public class CommonWithBillingApiRequestEvent {
private String userId;
private Date timeCreated;
private String responseCode;
private String responseMessage;
private Integer mills;
private String requestUrlType;
private String isBilling;
}
package cn.quantgroup.report.domain.master;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
@Builder
@Data
@AllArgsConstructor
@NoArgsConstructor
public class CostRecordPO implements Serializable {
/**
*
* This field was generated by MyBatis Generator.
* This field corresponds to the database column cost_record.id
*
* @mbg.generated
*/
private Integer id;
/**
*
* This field was generated by MyBatis Generator.
* This field corresponds to the database column cost_record.source_name
*
* @mbg.generated
*/
private String sourceName;
/**
*
* This field was generated by MyBatis Generator.
* This field corresponds to the database column cost_record.url_type
*
* @mbg.generated
*/
private String urlType;
/**
*
* This field was generated by MyBatis Generator.
* This field corresponds to the database column cost_record.invoke_times
*
* @mbg.generated
*/
private Integer invokeTimes;
/**
*
* This field was generated by MyBatis Generator.
* This field corresponds to the database column cost_record.cost
*
* @mbg.generated
*/
private BigDecimal cost;
/**
*
* This field was generated by MyBatis Generator.
* This field corresponds to the database column cost_record.balance
*
* @mbg.generated
*/
private BigDecimal balance;
/**
*
* This field was generated by MyBatis Generator.
* This field corresponds to the database column cost_record.create_time
*
* @mbg.generated
*/
private Date createTime;
/**
* yyyymm --- 201805
*/
private String suffix;
}
\ No newline at end of file
package cn.quantgroup.report.domain.master;
import lombok.*;
import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
@Builder
@Data
@Getter
@AllArgsConstructor
@NoArgsConstructor
public class DataPriceConfigPO implements Serializable {
/**
*
* This field was generated by MyBatis Generator.
* This field corresponds to the database column data_price_config.id
*
* @mbg.generated
*/
private Integer id;
/**
*
* This field was generated by MyBatis Generator.
* This field corresponds to the database column data_price_config.source_name
*
* @mbg.generated
*/
private String sourceName;
/**
*
* This field was generated by MyBatis Generator.
* This field corresponds to the database column data_price_config.data_type
*
* @mbg.generated
*/
private String dataType;
/**
*
* This field was generated by MyBatis Generator.
* This field corresponds to the database column data_price_config.url_type
*
* @mbg.generated
*/
private String urlType;
/**
*
* This field was generated by MyBatis Generator.
* This field corresponds to the database column data_price_config.price
*
* @mbg.generated
*/
private BigDecimal price;
private Integer frequency;
/**
*
* This field was generated by MyBatis Generator.
* This field corresponds to the database column data_price_config.status
*
* @mbg.generated
*/
private String status;
/**
*
* This field was generated by MyBatis Generator.
* This field corresponds to the database column data_price_config.create_time
*
* @mbg.generated
*/
private Date createTime;
}
\ No newline at end of file
package cn.quantgroup.report.domain.master;
import lombok.Data;
import java.io.Serializable;
import java.sql.Timestamp;
/**
* @Author fengjunkai
* @Date 2019-06-19 14:07
*/
@Data
public class DataSourceCacheConfig implements Serializable {
private static final long serialVersionUID = -8145976034591357518L;
private String productType;
private String productName;
private Integer productCacheTime;
private Integer productTestCacheTime;
private String dataSourceName;
}
package cn.quantgroup.report.domain.master;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* -----------------------------------------------------------------------------<br>
* 描述: 三方数据源项目通过uuid白名单将返回500的转换成400配置表 <br>
* 作者:yanhui.Hao <br>
* 时间:2019.10.22 <br>
* 授权: (C) Copyright (c) 2017 <br>
* 公司: 北京众信利民信息技术有限公司 <br>
* -----------------------------------------------------------------------------
*/
@Builder
@Data
@AllArgsConstructor
@NoArgsConstructor
public class DsSpecialUserHandle {
private Long id;//主键id
private String methodName;//三方数据源实际方法名
private String serviceName;//三方数据源实际service名称
private String uuid;//用户的uuid
private Boolean enable; //数据是否可用, 默认1 true
}
package cn.quantgroup.report.domain.master;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Date;
/**
* Created by suh on 2018/3/28.
*/
@Builder
@Data
@AllArgsConstructor
@NoArgsConstructor
public class ElevenBeiApiRequestEvent {
private String identity;
private Date timeCreated;
private String responseCode;
private String responseMessage;
private Integer mills;
private String requestUrlType;
private String isBilling;
}
package cn.quantgroup.report.domain.master;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
import java.util.Date;
@Data
@NoArgsConstructor
public class IntelliCreditLoanIssue {
private Long id;
private String name;
private String pid;
private String mobile;
private String loanType;
private Long accountOpenDate;
private Long applyDate;
private Long issueDate;
private BigDecimal loanAmount;
private Long loanId;
private Integer totalTerm;
private Long firstRepaymentDate;
private Integer termPeriod;
private Integer planCount;
private Integer status;
private Date timeCreated;
private String device;
@Builder
public IntelliCreditLoanIssue(Long id, String name, String pid, String mobile, String loanType, Long accountOpenDate, Long applyDate, Long issueDate, BigDecimal loanAmount, Long loanId, Integer totalTerm, Long firstRepaymentDate, Integer termPeriod, Integer planCount, Integer status, String device) {
this.name = name;
this.pid = pid;
this.mobile = mobile;
this.loanType = loanType;
this.accountOpenDate = accountOpenDate;
this.applyDate = applyDate;
this.issueDate = issueDate == null ? 0l : issueDate;
this.loanAmount = loanAmount == null ? BigDecimal.ZERO : loanAmount;
this.loanId = loanId;
this.totalTerm = totalTerm == null ? 0 : totalTerm;
this.firstRepaymentDate = firstRepaymentDate == null ? 0 : firstRepaymentDate;
this.termPeriod = termPeriod == null ? 0 : termPeriod;
this.planCount = planCount == null ? 0 : planCount;
this.status = status;
this.timeCreated = new Date();
this.device = device;
}
}
\ No newline at end of file
package cn.quantgroup.report.domain.master;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.math.BigDecimal;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class IntelliCreditLoanTrace {
private Long id;
private Long loanId;
private Long repaymentPlanId;
private Integer termNo;
private String termStatus;
private Long targetRepaymentDate;
private Long realRepaymentDate;
private BigDecimal targetRepayment;
private BigDecimal realRepayment;
private Long statusConfirmAt;
private String overdueStatus;
private Integer status;
}
\ No newline at end of file
package cn.quantgroup.report.domain.master;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Date;
@Data
@NoArgsConstructor
public class IntelliCreditRequestEvent {
private Long id;
private String uuid;
private Date timeCreated;
private Integer httpCode;
private String responseMessage;
private Integer mills;
@Builder
public IntelliCreditRequestEvent(Long id, String uuid, Integer httpCode, String responseMessage, Integer mills) {
this.uuid = uuid;
this.id = id;
this.httpCode = httpCode;
this.responseMessage = responseMessage;
this.mills = mills;
this.timeCreated = new Date();
}
}
\ No newline at end of file
package cn.quantgroup.report.domain.master;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Date;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class JdApiRequestEvent {
private Long id;
private String uuid;
private Date timeCreated;
private String responseCode;
private String responseMessage;
private String businessCode;
private Integer mills;
private String requestUrlType;
}
\ No newline at end of file
package cn.quantgroup.report.domain.master;
import lombok.Data;
import java.io.Serializable;
/**
* -----------------------------------------------------------------------------<br>
* 描述: 百行报送逾期还款白名单表 <br>
* 作者:yanhui.Hao <br>
* 时间:2020.02.05 <br>
* 授权: (C) Copyright (c) 2017 <br>
* 公司: 北京众信利民信息技术有限公司 <br>
* -----------------------------------------------------------------------------
*/
@Data
//@Builder
public class RepaymentLoanWhiteList implements Serializable {
private static final long serialVersionUID = 8722959335665582382L;
private Long id;
private String pid;
private String mobile;
private String loanId; //贷款ID
private Integer type; //报送业务类型(1:广达小贷;2:众信利民助贷)
private Integer enable; //是否可用,0:不可用;1:可用
private String createdAt;
}
package cn.quantgroup.report.domain.master;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.util.Date;
@Builder
@Data
@AllArgsConstructor
@NoArgsConstructor
public class TransactionLogPO implements Serializable {
private String transactionId;
private String uuid;
private String urlType;
private Integer code;
private Date timeCreated;
}
package cn.quantgroup.report.domain.master;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Date;
/**
* Created by suh on 2018/2/11.
*/
@Builder
@Data
@AllArgsConstructor
@NoArgsConstructor
public class UnionPayApiRequestEvent {
private String bankCardNo;
private Date timeCreated;
private Integer mills;
private String businessCode;
private String requestUrlType;
}
package cn.quantgroup.report.domain.sdk;
import lombok.Data;
import java.io.Serializable;
@Data
public class SdkUser implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
private Long id;
private String idNo;
private String name;
private String phoneNo;
private Long registerFrom;
private String uuid;
/**phoneNo md5加密 2019.10.10*/
private String phoneNoMd5;
/**idNo md5加密 2019.10.10*/
private String idNoMd5;
}
package cn.quantgroup.report.domain.tidbrisk;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
/**
* -----------------------------------------------------------------------------<br>
* 描述: 调用日志实体bean <br>
* 作者:yanhui.Hao <br>
* 时间:2019.12.30 <br>
* 授权: (C) Copyright (c) 2017 <br>
* 公司: 北京众信利民信息技术有限公司 <br>
* -----------------------------------------------------------------------------
*/
@Setter
@Getter
@Builder
public class CallRecord2 {
private String channelType;//数据源调用批次号
private String requestUrl;//数据源调用批次号
private String channelId;//渠道号, 融360-333, 国美-159843
private String transactionId;//数据源调用批次号
private String uuid;//用户uuid
private String urlType;//数据源, QCloud43Md5AntiFraud-腾讯43版反欺诈模型分
private Integer code;//1001:请求成功且命中;1002:请求成功且未命中;1003:请求失败;1004:命中HBase;
//private String createdAt;//创建时间
}
package cn.quantgroup.report.domain.tidbrisk;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.sql.Timestamp;
/**
* -----------------------------------------------------------------------------<br>
* 描述: 调用日志实体bean <br>
* 作者:yanhui.Hao <br>
* 时间:2019.12.30 <br>
* 授权: (C) Copyright (c) 2017 <br>
* 公司: 北京众信利民信息技术有限公司 <br>
* -----------------------------------------------------------------------------
*/
@Builder
@Data
@AllArgsConstructor
@NoArgsConstructor
public class CallRecord3 implements Serializable {
private String channelType;//数据源调用批次号
private String requestUrl;//数据源调用批次号
private String channelId;//渠道号, 融360-333, 国美-159843
private String transactionId;//数据源调用批次号
private String uuid;//用户uuid
private String urlType;//数据源, QCloud43Md5AntiFraud-腾讯43版反欺诈模型分
private Integer code;//1001:请求成功且命中;1002:请求成功且未命中;1003:请求失败;1004:命中HBase;
private Timestamp createdAt;
private Timestamp updatedAt;
private Long id;
}
package cn.quantgroup.report.domain.xyqbuser;
import lombok.Data;
import java.util.Date;
@Data
public class User {
private Long id;
private String phoneNo;
private String uuid;
private Date createdAt;
}
\ No newline at end of file
package cn.quantgroup.report.domain.xyqbuser;
import lombok.Data;
import java.util.Date;
@Data
public class UserDetail {
private Long id;
private Long userId;
private String phoneNo;
private String name;
private String idNo;
private Integer idType;
private Boolean isAuthenticated;
private Integer gender;
private String email;
private String qq;
private Date createdAt;
private Date updatedAt;
}
\ No newline at end of file
package cn.quantgroup.report.enums;
public enum RequestUrlType {
CreditCardRecord("信用卡", "信用卡消费记录"), //信用卡消费记录
BaiHangPersionalCreditReport("百行征信", "百行个人征信报告"),
BaiHangCreditReport("百行征信", "百行个人征信报告"),
LhpBlackListLevel("量化派", "量化派数据产品输出黑名等级"),
;
private String sourceName;
private String urlName;
RequestUrlType(String sourceName, String urlName) {
this.sourceName = sourceName;
this.urlName = urlName;
}
public String getSourceName() {
return sourceName;
}
public void setSourceName(String sourceName) {
this.sourceName = sourceName;
}
public String getUrlName() {
return urlName;
}
public void setUrlName(String urlName) {
this.urlName = urlName;
}
}
\ No newline at end of file
/*
* Copyright 2014-present Miyou tech inc. All Rights Reserved.
*/
package cn.quantgroup.report.error;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.net.SocketTimeoutException;
import java.util.Arrays;
public class QGException extends RuntimeException {
private static final Logger LOGGER = LoggerFactory.getLogger(QGException.class);
public QGExceptionType qgExceptionType;
public boolean isToastFormat = false;
public String detail;
public QGException(String detail, QGExceptionType qgExceptionType, Object... args) {
super(detail);
try {
if (StringUtils.isNoneBlank(qgExceptionType.frontEndToastTemplate)) {
isToastFormat = true;
initException(String.format(qgExceptionType.frontEndToastTemplate, args), qgExceptionType);
} else {
initException(qgExceptionType);
}
} catch (Exception e) {
LOGGER.error("format front end toast err, " + qgExceptionType + ", args: " + Arrays.toString(args), e);
initException(QGExceptionType.COMMON_SERVER_ERROR);
}
}
public QGException(QGExceptionType qgExceptionType, Object... args) {
super(qgExceptionType.text);
try {
if (StringUtils.isNoneBlank(qgExceptionType.frontEndToastTemplate)) {
isToastFormat = true;
initException(String.format(qgExceptionType.frontEndToastTemplate, args), qgExceptionType);
} else {
initException(qgExceptionType);
}
} catch (Exception e) {
LOGGER.error("format front end toast err, " + qgExceptionType + ", args: " + Arrays.toString(args), e);
initException(QGExceptionType.COMMON_SERVER_ERROR);
}
}
public QGException(String detail, Throwable cause, QGExceptionType qgExceptionType) {
super(detail, cause);
this.initException(detail, qgExceptionType);
}
public QGException(String detail, QGExceptionType qgExceptionType) {
super(detail);
initException(detail, qgExceptionType);
}
public QGException(QGExceptionType qgExceptionType) {
super(qgExceptionType.text);
initException(qgExceptionType);
}
public QGException(Throwable cause, QGExceptionType qgExceptionType, Object... args) {
super(qgExceptionType.text, cause);
try {
if (StringUtils.isNoneBlank(qgExceptionType.frontEndToastTemplate)) {
isToastFormat = true;
initException(String.format(qgExceptionType.frontEndToastTemplate, args), qgExceptionType);
} else {
initException(qgExceptionType);
}
} catch (Exception e) {
LOGGER.error("format front end toast err, " + qgExceptionType + ", args: " + Arrays.toString(args), e);
initException(QGExceptionType.COMMON_SERVER_ERROR);
}
}
public static QGException wrap(Throwable e) {
return wrap(e, QGExceptionType.COMMON_SERVER_ERROR);
}
public static QGException wrap(Throwable e, QGExceptionType exceptionType) {
if (e instanceof QGException) {
return (QGException) e;
}
if (e instanceof SocketTimeoutException)
return new QGException(QGExceptionType.COMMON_THIRD_PARTY_TIMEOUT);
return new QGException(e, exceptionType);
}
public static QGException wrap(Throwable e, QGExceptionType exceptionType, Object... args) {
if (e instanceof QGException) {
return (QGException) e;
}
if (e instanceof SocketTimeoutException)
return new QGException(QGExceptionType.COMMON_THIRD_PARTY_TIMEOUT);
return new QGException(e, exceptionType, args);
}
private void initException(QGExceptionType QGExceptionType) {
this.initException(QGExceptionType.text, QGExceptionType);
}
private void initException(String detail, QGExceptionType QGExceptionType) {
this.qgExceptionType = QGExceptionType;
this.detail = detail;
}
}
\ No newline at end of file
This diff is collapsed.
package cn.quantgroup.report.error;
public class QGPreconditions {
private QGPreconditions() {
}
public static void checkArgument(boolean expression) {
checkArgument(expression, QGExceptionType.COMMON_ILLEGAL_PARAM);
}
public static void checkArgument(boolean expression, Object errorMessage) {
checkArgument(expression, QGExceptionType.COMMON_ILLEGAL_PARAM, errorMessage);
}
public static void checkArgument(boolean expression,
String errorMessageTemplate, Object... errorMessageArgs) {
checkArgument(expression, QGExceptionType.COMMON_ILLEGAL_PARAM, errorMessageTemplate, errorMessageArgs);
}
public static void checkArgument(boolean expression, QGExceptionType exceptionType) {
if (!expression) {
throw new QGException(exceptionType);
}
}
public static void checkArgument(boolean expression, QGExceptionType exceptionType, Object... errorMessage) {
if (!expression) {
throw new QGException(exceptionType, errorMessage);
}
}
}
package cn.quantgroup.report.fastjson;
import cn.quantgroup.report.utils.MaskedUtils;
import com.alibaba.fastjson.serializer.ValueFilter;
import com.google.common.base.Joiner;
import org.apache.commons.lang3.StringUtils;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
public class CustomValueFilter implements ValueFilter {
private final Set<String> Masked_KEYS;
public CustomValueFilter(Set<String> masked_KEYS) {
Masked_KEYS = masked_KEYS;
}
@Override
public Object process(Object o, String s, Object o1) {
if (Masked_KEYS == null || o1 == null || StringUtils.isBlank(s) || !Masked_KEYS.contains(s)) {
return o1;
}
if (o1 instanceof String[]) {
List<String> maskedStrings = Arrays.stream(((String[]) o1)).map(string -> MaskedUtils.buildMaskedCommonString(string)).collect(Collectors.toList());
return Joiner.on(",").join(maskedStrings);
}
return MaskedUtils.buildMaskedCommonString(o1 instanceof String ? ((String) o1) : o1.toString());
}
}
\ No newline at end of file
package cn.quantgroup.report.job;
import cn.quantgroup.report.service.baihang.BaiHangZhuDaiService;
import cn.quantgroup.report.service.baihang.constant.Constant;
import cn.quantgroup.report.utils.dingtalk.DingTalk;
import com.google.common.base.Stopwatch;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.TimeUnit;
/**
* -----------------------------------------------------------------------------<br>
* 描述: 量化派助贷模式(非循环贷) -
* (贷款申请/放款/还款(逾期)三类实时批量数据)-To百行报送<br>
* 每日凌晨5点报送 <br>
* 作者:yanhui.Hao <br>
* 时间:2019.10.25 <br>
* 授权: (C) Copyright (c) 2017 <br>
* 公司: 北京众信利民信息技术有限公司 <br>
* -----------------------------------------------------------------------------
*/
@Component
public class QuantGroupZhuDaiReportToBaiHang {
private static final Logger log = LoggerFactory.getLogger(QuantGroupZhuDaiReportToBaiHang.class);
@Autowired
private RedisTemplate<String,String> redisTemplate;
@Autowired
private BaiHangZhuDaiService baiHangZhuDaiService;
@Autowired
private SynLoanInfoHistoryTask synLoanInfoHistoryTask;
@Autowired
private DingTalk dingTalk;
@Async
@Scheduled(cron = "0 0 05 * * ?")
public void startZhuDaiReport(){
if(increment()){
redisTemplate.expire(Constant.QG_ZHU_DAI_REPORT_LOCK_KEY, 10, TimeUnit.SECONDS);
Stopwatch stopwatch = Stopwatch.createStarted();
boolean tableIsSyn = synLoanInfoHistoryTask.syn_historyAndplan_by_id();
if(tableIsSyn){
try{
//yyyy-MM-dd
String startnyr = LocalDateTime.now().plusDays(-1).format(DateTimeFormatter.ISO_DATE);
String endnyr = LocalDateTime.now().format(DateTimeFormatter.ISO_DATE);
log.info("量化派-助贷模式报送贷款信息开始, newTime: {} , startnyr: {} , endnyr: {} ", LocalDateTime.now(), startnyr, endnyr);
String msg_A1 = baiHangZhuDaiService.sendZhuDaiApplyToBaiHang(startnyr,endnyr); //生产 助贷-贷款申请 报送T+1 暂时先不报送C1 因为百行还没有开放查询接口
dingTalk.talk("Info","报送"+startnyr+"申请A1结束",msg_A1);
if(msg_A1.indexOf("[false]")!=-1){
dingTalk.talk_ToUser("申请A1报送失败", "报送"+startnyr+"申请A1有部分失败,请尽快手动处理!");
}
String msg_D2 = baiHangZhuDaiService.sendZhuDaiLoanToBaiHang(startnyr,endnyr); //生产 助贷-放款信息 报送T+1
dingTalk.talk("Info","报送"+startnyr+"放款D2结束",msg_D2);
if(msg_D2.indexOf("[false]")!=-1){
dingTalk.talk_ToUser("放款D2报送失败", "报送"+startnyr+"放款D2有部分失败,请尽快手动处理!");
}
String msg_D3 =baiHangZhuDaiService.sendZhuDaiRepaymentToBaiHang(startnyr,endnyr); //生产 助贷-还款&逾期信息 报送T+1
dingTalk.talk("Info","报送"+startnyr+"还款D3结束",msg_D3);
if(msg_D3.indexOf("[false]")!=-1){
dingTalk.talk_ToUser("还款D3报送失败", "报送"+startnyr+"还款D3有部分失败,请尽快手动处理!");
}
log.info("量化派-助贷模式报送贷款信息结束, newTime: {}, 耗时: {} , msg: {} ", LocalDateTime.now(), stopwatch.stop().elapsed(TimeUnit.MILLISECONDS), (msg_A1 + msg_D2 + msg_D3));
}catch (Exception e){
log.error("量化派-助贷模式报送贷款信息异常, newTime: {}, 耗时: {} ", LocalDateTime.now(), stopwatch.stop().elapsed(TimeUnit.MILLISECONDS), e);
dingTalk.talk("Error","报送服务内部异常", e);
dingTalk.talk_ToUser("数据报送异常", "报送服务内部异常,请尽快手动处理!");
}
}else{
log.error("量化派-助贷模式报送贷款信息失败, 原因是同步历史表数据返回false, 请尽快人工处理, newTime: {} ", LocalDateTime.now());
}
}
}
public Boolean increment(){
Long increment = redisTemplate.opsForValue().increment(Constant.QG_ZHU_DAI_REPORT_LOCK_KEY, 1);
return increment <= 1;
}
}
This diff is collapsed.
package cn.quantgroup.report.mapper.baihang;
import cn.quantgroup.report.domain.baihang.ApplyLoanInfoZhuDai;
import cn.quantgroup.report.domain.baihang.BaiHangTimeRecord;
import org.springframework.stereotype.Repository;
import java.util.List;
/**
* -----------------------------------------------------------------------------<br>
* 描述: 贷款申请信息查询mapper <br>
* 作者:yanhui.Hao <br>
* 时间:2019.11.06 <br>
* 授权: (C) Copyright (c) 2017 <br>
* 公司: 北京众信利民信息技术有限公司 <br>
* -----------------------------------------------------------------------------
*/
@Repository
public interface ApplyLoanInfoMapper {
//广达小贷-申请实时
//List<ApplyLoanInfo> findApplyLoanInfo();
//广达小贷-申请存量
//List<ApplyLoanInfo> findStockApplyLoanInfo();
/**
* 描述: 百行-助贷申请存量数据 <br/>
* 参数: 日期 BaiHangTimeRecord: startTime和endsTime <br/>
* 返回值: <br/>
* 创建人: yanhui.Hao <br/>
* 创建时间: 2019.10.23 <br/>
*/
@Deprecated
List<ApplyLoanInfoZhuDai> queryStockApplyLoanInfoZhuDai(BaiHangTimeRecord baiHangTimeRecord);
/**
* 描述: 1.1百行助贷-非联合贷 实时申请 <br/>
* 参数: 日期 BaiHangTimeRecord: startTime和endsTime <br/>
* 返回值: <br/>
* 创建人: yanhui.Hao <br/>
* 创建时间: 2019.10.28 <br/>
*/
List<ApplyLoanInfoZhuDai> findRealTimeApplyLoanZhuDai(BaiHangTimeRecord timeRecord);
/**
* 描述: 1.2百行助贷-联合贷 实时申请 <br/>
* 参数: 日期 BaiHangTimeRecord: startTime和endsTime <br/>
* 返回值: <br/>
* 创建人: yanhui.Hao <br/>
* 创建时间: 2019.10.28 <br/>
*/
List<ApplyLoanInfoZhuDai> findRealTimeApplyLoanZhuDaiLh(BaiHangTimeRecord timeRecord);
}
package cn.quantgroup.report.mapper.baihang;
import cn.quantgroup.report.domain.baihang.BaiHangTimeRecord;
import cn.quantgroup.report.domain.baihang.LoanInfoZhuDai;
import org.springframework.stereotype.Repository;
import java.util.List;
/**
* 放款信息查询
*
* @Author fengjunkai
* @Date 2019-03-26 15:26
*/
@Repository
public interface LoanInfoMapper {
//报送实时放款数据(广达百行征信报送)
//List<LoanInfoZhuDai> findLoanInfo();
//List<LoanInfoZhuDai> findLoanInfoByTime(BaiHangTimeRecord baiHangTimeRecord);
//List<LoanInfoZhuDai> stockLoanInfo();
/**
* 描述: 根据loan_application_history_id查询xyqb_i_repayment_plan表最晚还款日 <br/>
* 参数: loan_application_history_id <br/>
* 返回值: <br/>
* 创建人: yanhui.Hao <br/>
* 创建时间: 2019.11.06 <br/>
*/
List<String> findTargetRepaymentDayList(String reqId);
/**
* 描述: 根据order_no查询 loan_application_history_id <br/>
* 参数: orderNoArray<br/>
* 返回值: String <br/>
* 创建人: yanhui.Hao <br/>
* 创建时间: 2019.09.24 <br/>
*/
List<String> findHistoryIdByOrderNo(String[] orderNoArray);
/**
* 描述: 根据loan_application_history_id查询手动报送的bean <br/>
* 参数: loanApplicationHistoryId <br/>
* 返回值: LoanInfoZhuDai <br/>
* 创建人: yanhui.Hao <br/>
* 创建时间: 2019.09.25 <br/>
*/
LoanInfoZhuDai findLoanInfoD2ByHistoryId(String loanApplicationHistoryId);
/**
* 描述: 百行-助贷放款存量数据 <br/>
* 参数: 日期 BaiHangTimeRecord: startTime和endsTime <br/>
* 返回值: <br/>
* 创建人: yanhui.Hao <br/>
* 创建时间: 2019.10.23 <br/>
*/
@Deprecated
List<LoanInfoZhuDai> queryStockLoanInfoZhuDai(BaiHangTimeRecord baiHangTimeRecord);
/**
* 描述: 2.1百行助贷-非联合贷 实时放款数据 <br/>
* 参数: <br/>
* 返回值: <br/>
* 创建人: yanhui.Hao <br/>
* 创建时间: 2019.10.28 <br/>
*/
List<LoanInfoZhuDai> findRealTimeLoanInfoZhuDai(BaiHangTimeRecord timeRecord);
/**
* 描述: 2.2百行助贷-联合贷 实时放款数据 <br/>
* 参数: <br/>
* 返回值: <br/>
* 创建人: yanhui.Hao <br/>
* 创建时间: 2019.10.28 <br/>
*/
List<LoanInfoZhuDai> findRealTimeLoanInfoZhuDaiLh(BaiHangTimeRecord timeRecord);
}
package cn.quantgroup.report.mapper.baihang;
import cn.quantgroup.report.domain.baihang.BaiHangTimeRecord;
import cn.quantgroup.report.domain.baihang.RepaymentInfoZhuDai;
import org.springframework.stereotype.Repository;
import java.util.List;
/**
* 还款信息查询
*
* @Author fengjunkai
* @Date 2019-03-26 15:27
*/
@Repository
public interface RepaymentLoanInfoMapper {
//实时还款(广达百行征信报送)
//List<RepaymentInfoZhuDai> findRepayMentLoanInfo(BaiHangTimeRecord baiHangTimeRecord);
//实时逾期还款(广达百行征信报送)
//List<RepaymentInfoZhuDai> findRepayMentLoanInfoOverdue(BaiHangTimeRecord baiHangTimeRecord);
///List<RepaymentInfoZhuDai> findStockRepayMentLoanInfo(BaiHangTimeRecord baiHangTimeRecord);
//List<RepaymentInfoZhuDai> findStockRepayMentLoanInfoOverdue(BaiHangTimeRecord baiHangTimeRecord);
//BaiHangNameResult findName(BaiHangName baiHangName);
/**
* 描述: 百行-助贷逾期还款存量数据 整理 <br/>
* 参数: 日期 BaiHangTimeRecord: startTime和endsTime <br/>
* 返回值: <br/>
* 创建人: yanhui.Hao <br/>
* 创建时间: 2019.10.23 <br/>
*/
@Deprecated
List<RepaymentInfoZhuDai> queryStockRepayMentInfoOverdueZhuDai(BaiHangTimeRecord baiHangTimeRecord);
/**
* 描述: 百行-助贷还款存量数据 整理 <br/>
* 参数: 日期 BaiHangTimeRecord: startTime和endsTime <br/>
* 返回值: <br/>
* 创建人: yanhui.Hao <br/>
* 创建时间: 2019.10.23 <br/>
*/
@Deprecated
List<RepaymentInfoZhuDai> queryStockRepayMentInfoZhuDai(BaiHangTimeRecord baiHangTimeRecord);
/**
* 描述: 3.1百行助贷-非联合贷 实时还款 <br/>
* 参数: 日期 BaiHangTimeRecord: startTime和endsTime <br/>
* 返回值: <br/>
* 创建人: yanhui.Hao <br/>
* 创建时间: 2019.10.28 <br/>
*/
List<RepaymentInfoZhuDai> findRealTimeRepayMentInfo(BaiHangTimeRecord baiHangTimeRecord);
/**
* 描述: 3.2百行助贷-联合贷 实时还款 <br/>
* 参数: 日期 BaiHangTimeRecord: startTime和endsTime <br/>
* 返回值: <br/>
* 创建人: yanhui.Hao <br/>
* 创建时间: 2019.10.28 <br/>
*/
List<RepaymentInfoZhuDai> findRealTimeRepayMentInfoLh(BaiHangTimeRecord baiHangTimeRecord);
/**
* 描述: 4.1百行助贷-非联合贷 实时逾期还款 <br/>
* 参数: 日期 BaiHangTimeRecord: startTime和endsTime <br/>
* 返回值: <br/>
* 创建人: yanhui.Hao <br/>
* 创建时间: 2019.10.28 <br/>
*/
List<RepaymentInfoZhuDai> findRealTimeRepayMentOverdue(BaiHangTimeRecord baiHangTimeRecord);
/**
* 描述: 4.2百行助贷-联合贷 实时逾期还款 <br/>
* 参数: 日期 BaiHangTimeRecord: startTime和endsTime <br/>
* 返回值: <br/>
* 创建人: yanhui.Hao <br/>
* 创建时间: 2019.10.28 <br/>
*/
List<RepaymentInfoZhuDai> findRealTimeRepayMentOverdueLh(BaiHangTimeRecord baiHangTimeRecord);
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment