2023-12-11更新

master
RENCHAO 2 years ago
parent 8c0766f197
commit 26172f3340

@ -6,78 +6,132 @@ import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpATTRS;
import com.jcraft.jsch.SftpException;
import org.junit.Test;
import org.springframework.beans.BeanUtils;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDate;
import java.util.Arrays;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.Vector;
import java.util.stream.Collectors;
public class SftpDemo {
private static final long KILOBYTE = 1024;
// 执行远程命令通道
public static final String CHANNEL_EXEC = "exec";
// 远程Shell通道
public static final String CHANNEL_SHELL = "shell";
// 直接TCP/IP通道用于建立端口转发
public static final String CHANNEL_DIRECT_TCPIP = "direct-tcpip";
// SFTPSSH文件传输协议通道用于文件传输
public static final String CHANNEL_SFTP = "sftp";
public static void main(String[] args) throws JSchException, SftpException, IOException {
String filePath = "/home/flink/sysfile/sentinel.json";
String str = "我是测试的222666";
byte[] buf = new byte[4194304];
ChannelSftp channel = getSftpChannel();
public static void main(String[] args) throws JSchException, SftpException, IOException {
String rootPath = "/home/flink/zltmp";
String newPath = "bbb";
InputStream is = channel.get(filePath);
int len = is.read(buf);
System.out.println(new String(buf, 0, len, StandardCharsets.UTF_8));
is.close();
ByteArrayInputStream arrayInputStream = new ByteArrayInputStream(str.getBytes(StandardCharsets.UTF_8));
channel.put(arrayInputStream, filePath);
System.out.println("写入成功");
Session session = channel.getSession();
channel.disconnect();
session.disconnect();
}
ChannelSftp channel = (ChannelSftp) getSftpChannel(CHANNEL_SFTP);
@Test
public void test() throws JSchException, SftpException {
String rootPath = "/home/flink/dws-file/2021-05";
// String rootPath = "/home/flink/dws-file/2022-06";
// String rootPath = "/home/flink/dws-file/cc/sysfile";
// String rootPath = "/home/flink/dws-file/aa.txt";
ChannelSftp channel = getSftpChannel();
long l = System.currentTimeMillis();
if (isNotResources(channel, rootPath, newPath)) {
channel.mkdir(rootPath + "/" + newPath);
Vector<ChannelSftp.LsEntry> ls = channel.ls(rootPath);
int deleteYear = getDeleteYear();
for (ChannelSftp.LsEntry entry : ls) {
String filename = entry.getFilename();
if (filename.matches("\\d{4}-\\d{2}") && Integer.parseInt(filename.substring(0,4)) < deleteYear) {
rmdir(channel, rootPath + "/" + filename);
}
}
System.out.println("创建目录,花费时间:" + (System.currentTimeMillis() - l));
// channel.put("C:\\Users\\RENCHAO\\Desktop\\压测.docx", "/home/flink/zltmp/mytest",new SftpProgressMonitorDemo());
// FileInputStream inputStream = new FileInputStream("C:\\Users\\RENCHAO\\Desktop\\压测.zip");
// channel.put(inputStream,"/home/flink/zltmp/mytest/sss/空运危规.zip",new SftpProgressMonitorDemo(),ChannelSftp.RESUME);
//
// System.out.println("文件上传成功!");
System.out.println("耗时:" + (System.currentTimeMillis() - l));
System.out.println("删除成功");
channel.getSession().disconnect();
}
public static boolean isNotResources(ChannelSftp channel, String path, String target) {
// 获取目录下的文件和子目录列表
Vector<ChannelSftp.LsEntry> entries = null;
try {
entries = channel.ls(path);
} catch (SftpException e) {
System.out.println("文件目录不存在");
e.printStackTrace();
private int getDeleteYear() {
LocalDate now = LocalDate.now();
int year = now.getYear();
LocalDate febFirst = LocalDate.of(year, 2, 1);
if (now.isBefore(febFirst)) {
return year - 1;
}
// 判断目录是否存在
if (entries == null) {
return true;
return year;
}
@SuppressWarnings("unchecked")
private void rmdir(ChannelSftp channel, String path) throws SftpException {
SftpATTRS stat = channel.stat(path);
if (!stat.isDir()) {
channel.rm(path);
return;
}
for (ChannelSftp.LsEntry entry : entries) {
if (entry.getFilename().equals(target)) {
return false;
}
Vector<ChannelSftp.LsEntry> ls = channel.ls(path);
List<String> nameList = ls.stream().filter(e -> !".".equals(e.getFilename()) && !"..".equals(e.getFilename()))
.map(ChannelSftp.LsEntry::getFilename).collect(Collectors.toList());
for (String name : nameList) {
rmdir(channel, path + "/" + name);
}
return true;
channel.rmdir(path);
}
public static boolean isNotResources(ChannelSftp channel, String file) throws SftpException {
try {
channel.lstat(file);
return false;
} catch (SftpException e) {
if (e.id == ChannelSftp.SSH_FX_NO_SUCH_FILE) {
return true;
}
throw e;
}
}
private static Channel getSftpChannel(String type) throws JSchException {
private static ChannelSftp getSftpChannel() throws JSchException {
JSch jSch = new JSch();
Session session = jSch.getSession("flink", "172.16.12.108", 22);
session.setPassword("flink123");
@ -85,10 +139,10 @@ public class SftpDemo {
session.connect();
long l = System.currentTimeMillis();
Channel channel = session.openChannel(type);
Channel channel = session.openChannel("sftp");
channel.connect();
System.out.println("获取Channel花费时间" + (System.currentTimeMillis() - l));
return channel;
return (ChannelSftp)channel;
}

@ -0,0 +1,49 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
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>org.example</groupId>
<artifactId>SentinelDemo</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<java.version>1.8</java.version>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-core</artifactId>
<version>1.8.6</version>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-transport-simple-http</artifactId>
<version>1.8.6</version>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-annotation-aspectj</artifactId>
<version>1.8.6</version>
</dependency>
<dependency>
<groupId>com.alibaba.csp</groupId>
<artifactId>sentinel-datasource-extension</artifactId>
<version>1.8.6</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.5.14</version>
</dependency>
</dependencies>
</project>

@ -0,0 +1,95 @@
package com.renchao.local;
import com.alibaba.csp.sentinel.Entry;
import com.alibaba.csp.sentinel.SphU;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.context.ContextUtil;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import java.util.ArrayList;
import java.util.List;
/**
* Demo
*
* @author ren_chao
*/
public class LocalDemo {
public static void main(String[] args) {
// 配置规则.
initFlowRules();
// while (true) {
// // 1.5.0 版本开始可以直接利用 try-with-resources 特性
// try (Entry entry = SphU.entry("HelloWorld")) {
// // 被保护的逻辑
// System.out.println("hello world");
// } catch (BlockException ex) {
// // 处理被流控的逻辑
// System.out.println("blocked!");
// }
// }
while (true) {
System.out.println(test("HelloWorld"));
// System.out.println(test2());
}
}
private static String test2() {
// 1.5.0 版本开始可以直接利用 try-with-resources 特性
try (Entry entry = SphU.entry("HelloWorld")) {
// 被保护的逻辑
return "hello world";
} catch (BlockException ex) {
// 处理被流控的逻辑
return "blocked!";
}
}
private static String test(String resourceName) {
Entry entry = null;
try {
// 定义一个sentinel保护的资源名称为test-sentinel-api
entry = SphU.entry(resourceName);
// 模拟执行被保护的业务逻辑耗时
Thread.sleep(300);
return "正常逻辑";
} catch (BlockException e) {
// 如果被保护的资源被限流或者降级了就会抛出BlockException
return "资源被限流或降级了";
} catch (InterruptedException e) {
return "发生InterruptedException";
} finally {
if (entry != null) {
entry.exit();
}
ContextUtil.exit();
}
}
private static void initFlowRules() {
List<FlowRule> rules = new ArrayList<>();
FlowRule rule = new FlowRule();
rule.setResource("HelloWorld");
rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
// Set limit QPS to 20.
rule.setCount(2);
rules.add(rule);
FlowRuleManager.loadRules(rules);
}
//
// @SentinelResource("HelloWorld")
// public void helloWorld() {
// // 资源中的逻辑
// System.out.println("hello world");
// }
}

@ -0,0 +1,71 @@
package com.renchao.web;
import com.alibaba.csp.sentinel.datasource.FileRefreshableDataSource;
import com.alibaba.csp.sentinel.datasource.FileWritableDataSource;
import com.alibaba.csp.sentinel.datasource.ReadableDataSource;
import com.alibaba.csp.sentinel.datasource.WritableDataSource;
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import com.alibaba.csp.sentinel.transport.util.WritableDataSourceRegistry;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.renchao.web.controller.UserController;
import com.renchao.web.service.UserService;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;
/**
* @author ren_chao
*/
@SpringBootApplication
public class SpringMVCApplication {
public static void main(String[] args) throws FileNotFoundException {
SpringApplication.run(SpringMVCApplication.class, args);
//初始化限流规则
// initFlowQpsRule();
String filePath = "C:\\Users\\RENCHAO\\Desktop\\temp-sss\\sentinel.json";
ReadableDataSource<String, List<FlowRule>> ds = new FileRefreshableDataSource<>(
filePath, source -> JSON.parseObject(source, new TypeReference<List<FlowRule>>() {
})
);
// 将可读数据源注册至 FlowRuleManager.
FlowRuleManager.register2Property(ds.getProperty());
WritableDataSource<List<FlowRule>> wds = new FileWritableDataSource<>(filePath, SpringMVCApplication::encodeJson);
// 将可写数据源注册至 transport 模块的 WritableDataSourceRegistry 中.
// 这样收到控制台推送的规则时Sentinel 会先更新到内存,然后将规则写入到文件中.
WritableDataSourceRegistry.registerFlowDataSource(wds);
}
private static <T> String encodeJson(T t) {
return JSON.toJSONString(t);
}
private static void initFlowQpsRule() {
List<FlowRule> rules = new ArrayList<>();
FlowRule rule = new FlowRule(UserController.RESOURCE_NAME);
// set limit qps to 2
rule.setCount(1);
rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
rule.setLimitApp("default");
rules.add(rule);
FlowRule rule2 = new FlowRule(UserService.RESOURCE_NAME_QUERY_USER_BY_NAME);
// set limit qps to 2
rule2.setCount(1);
rule2.setGrade(RuleConstant.FLOW_GRADE_QPS);
rule2.setLimitApp("default");
rules.add(rule2);
FlowRuleManager.loadRules(rules);
}
}

@ -0,0 +1,16 @@
package com.renchao.web.config;
import com.alibaba.csp.sentinel.annotation.aspectj.SentinelResourceAspect;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* @author ren_chao
*/
@Configuration
public class SentinelConfig {
@Bean
public SentinelResourceAspect sentinelResourceAspect() {
return new SentinelResourceAspect();
}
}

@ -0,0 +1,58 @@
package com.renchao.web.controller;
import com.alibaba.csp.sentinel.Entry;
import com.alibaba.csp.sentinel.SphU;
import com.alibaba.csp.sentinel.Tracer;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.renchao.web.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Collections;
import java.util.List;
/**
* @author ren_chao
*/
@RestController
@RequestMapping("/user")
public class UserController {
//资源名称
public static final String RESOURCE_NAME = "userList";
@Autowired
private UserService userService;
@RequestMapping("/list")
public List<UserService.User> getUserList() {
List<UserService.User> userList = null;
Entry entry = null;
try {
// 被保护的业务逻辑
entry = SphU.entry(RESOURCE_NAME);
userList = userService.getList();
} catch (BlockException e) {
// 资源访问阻止,被限流或被降级
return Collections.singletonList(new UserService.User("xxx", "资源访问被限流", 0));
} catch (Exception e) {
// 若需要配置降级规则,需要通过这种方式记录业务异常
Tracer.traceEntry(e, entry);
} finally {
// 务必保证 exit务必保证每个 entry 与 exit 配对
if (entry != null) {
entry.exit();
}
}
return userList;
}
@GetMapping("/info")
public UserService.User getInfo() {
return userService.queryByUserName("lina");
}
}

@ -0,0 +1,76 @@
package com.renchao.web.service;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
/**
* @author ren_chao
*/
@Service
public class UserService {
public List<User> getList() {
List<User> userList = new ArrayList<>();
userList.add(new User("1", "周慧敏", 18));
userList.add(new User("2", "关之琳", 20));
userList.add(new User("3", "王祖贤", 21));
return userList;
}
//资源名称
public static final String RESOURCE_NAME_QUERY_USER_BY_NAME = "queryUserByUserName";
//value是资源名称是必填项。blockHandler填限流处理的方法名称
@SentinelResource(value = RESOURCE_NAME_QUERY_USER_BY_NAME, blockHandler = "queryUserByUserNameBlock")
public User queryByUserName(String userName) {
return new User("0", userName, 18);
}
//注意细节一定要跟原函数的返回值和形参一致并且形参最后要加个BlockException参数
//否则会报错FlowException: null
public User queryUserByUserNameBlock(String userName, BlockException ex) {
//打印异常
ex.printStackTrace();
return new User("xxx", "用户名称:{" + userName + "},资源访问被限流", 0);
}
public static class User {
private String id;
private String name;
private Integer age;
public User(String id, String name, Integer age) {
this.id = id;
this.name = name;
this.age = age;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
}

@ -0,0 +1,33 @@
package com.renchao;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class CollectorsExample {
public static void main(String[] args) {
List<String> words = Arrays.asList("apple", "banana", "apple", "orange", "banana");
// 不提供合并函数,会抛出 IllegalStateException 异常
try {
Map<String, Integer> wordLengthMap = words.stream()
.collect(Collectors.toMap(
word -> word, // 键映射函数
String::length // 值映射函数
));
} catch (IllegalStateException e) {
System.out.println("IllegalStateException caught: " + e.getMessage());
}
// 提供合并函数,解决相同键冲突
Map<String, Integer> wordLengthMap = words.stream()
.collect(Collectors.toMap(
word -> word, // 键映射函数
String::length, // 值映射函数
(existing, replacement) -> existing // 合并函数,保留已有值
));
System.out.println(wordLengthMap);
}
}

@ -12,10 +12,12 @@ import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.RandomAccessFile;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
@ -23,8 +25,13 @@ import java.nio.file.Paths;
import java.sql.Date;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.Duration;
import java.time.Instant;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
@ -33,13 +40,16 @@ import java.util.Random;
import java.util.Set;
import java.util.StringJoiner;
import java.util.UUID;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
public class Test01 {
public static void main(String[] args) {
public static void main(String[] args) throws InterruptedException {
long l = System.nanoTime();
// String format = String.format("%s-%s", "a", "b");
// String format = "a" + "-" +"b";
@ -48,6 +58,27 @@ public class Test01 {
long duration = System.nanoTime() - l;
System.out.println(duration);
System.out.println(TimeUnit.NANOSECONDS.toMillis(duration));
new Thread(Test01::t2).start();
Thread.sleep(10000000);
}
private static void t2() {
System.out.println("aa-t1-t2");
t1();
}
private static void t1() {
int i = 1;
int k = i + 5;
System.out.println(k);
try {
Thread.sleep(10000000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
@ -96,20 +127,18 @@ public class Test01 {
@Test
public void test07() {
int numRecords = 5000000;
String csvFileName = "C:\\Users\\RENCHAO\\Desktop\\test\\data.csv";
int numRecords = 5;
String csvFileName = "C:\\Users\\RENCHAO\\Desktop\\temp-sss\\data.csv";
try (OutputStreamWriter writer = new OutputStreamWriter(new FileOutputStream(csvFileName, true), StandardCharsets.UTF_8)) {
try (FileWriter writer = new FileWriter(csvFileName)) {
// 写入CSV文件的列名
// writer.append("line_code,line_name,line_status,company_code,company_name,service_type,metric_value\n");
writer.write('\uFEFF');
// 生成随机数据并写入CSV文件
for (int i = 1; i <= numRecords; i++) {
String lineCode = "Line" + i;
String lineName = "LineName" + i;
String lineStatus = "S" + i;
String lineName = "名字" + i;
String lineStatus = "测试" + i;
String companyCode = "Company" + i;
String companyName = "CompanyName" + i;
String serviceType = "T" + i;
@ -118,9 +147,8 @@ public class Test01 {
writer.append(lineCode + "," + lineName + "," + lineStatus + "," + companyCode + ","
+ companyName + "," + serviceType + "," + metricValue + "\n");
}
writer.append("lineCode" + "," + "lineName" + "," + "SS" + "," + "companyCode" + ","
+ "companyName" + "," + "TT" + "," + "990044");
System.out.println(numRecords + " 条数据已生成并保存到 " + csvFileName + " 文件中。");
System.out.println("系统默认编码:" + Charset.defaultCharset().displayName());
} catch (IOException e) {
e.printStackTrace();
}
@ -147,33 +175,10 @@ public class Test01 {
writer.close();
}
/**
* int long
*
*/
@Test
public void test09() {
System.out.println(Integer.MAX_VALUE);
System.out.println(Integer.MIN_VALUE);
System.out.println(Long.MAX_VALUE);
System.out.println(Long.MIN_VALUE);
}
@Test
public void test10() throws IOException {
String property = System.getProperty("user.dir");
System.out.println(property);
Path resolve = Paths.get(property, "Desktop", "test03");
System.out.println(resolve);
File file = resolve.toFile();
System.out.println(file.exists());
System.out.println(file.mkdirs());
resolve = resolve.resolve("data33.csv");
FileWriter writer = new FileWriter(resolve.toFile(), true);
writer.write("zzzz");
writer.close();
}
@Test
public void test11() {
String uri = "C:\\Users\\RENCHAO\\Desktop\\test\\data.csv";
@ -202,30 +207,10 @@ public class Test01 {
}
@Test
public void test12() {
List<String> list = new ArrayList<>();
list.add("2023-02");
list.add("2023-08");
list.add("2023-05");
list.add("2023-01-22");
list.sort(Comparator.comparing(this::toDate));
System.out.println(list);
}
private Date toDate(String str) {
if (str.length() <= 7) {
return Date.valueOf(str + "-01");
}
return Date.valueOf(str);
}
/**
* liststream
*/
@Test
public void test13() {
List<Map<String, Object>> list = new ArrayList<>();
@ -256,21 +241,6 @@ public class Test01 {
}
}
@Test
public void test14() throws IOException {
Path TEMP_PATH = Paths.get("C:\\Users\\RENCHAO\\IdeaProjects\\agile-bacth\\sftp-file");
List<File> fileList = new ArrayList<>();
getFileList(TEMP_PATH.toFile(), fileList);
for (File file : fileList) {
Path path = file.toPath();
Path fileName = path.getParent().getFileName();
System.out.println(fileName);
System.out.println(path.getParent().getName(1));
}
}
/**
*
*
@ -321,7 +291,10 @@ public class Test01 {
}
//
/**
*
*
*/
private void compression(File file) throws IOException {
FileOutputStream outputStream = new FileOutputStream(file.toString().replace("csv", "zip"));
ZipOutputStream zipOut = new ZipOutputStream(outputStream);
@ -360,31 +333,7 @@ public class Test01 {
}
}
@Test
public void test16() throws InterruptedException {
Test01 test01 = new Test01();
new Thread(test01::a1).start();
Thread.sleep(500);
new Thread(test01::a2).start();
Thread.sleep(10000);
}
public synchronized void a1() {
System.out.println("进入到a1,准备开始睡觉");
try {
Thread.sleep(5000);
System.out.println("开始睡觉");
this.wait();
System.out.println("醒啦");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public synchronized void a2() {
System.out.println("进入到a2");
this.notifyAll();
}
}

@ -39,11 +39,15 @@
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<!--动态健康监控 可以用于动态感知配置变化-->
<!-- 健康检查 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.hive/hive-jdbc -->
<dependency>

@ -12,6 +12,8 @@ import org.springframework.core.task.TaskExecutor;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;
@ -27,6 +29,7 @@ import java.util.StringJoiner;
@ConfigurationProperties(prefix = "sync-table")
public class TableProperties {
private static final Logger LOGGER = LoggerFactory.getLogger(TableProperties.class);
public static final Path TEMP_PATH = Paths.get(System.getProperty("user.dir"), "temp");
public static final String HIVE_SQL_TEMPLATE = "select * from %s %s limit ?,?";
private static final String PG_SQL_TEMPLATE = "insert into %s (%s) values(%s)";
/**

@ -1,19 +1,18 @@
package com.jiuyv.sptcc.agile.batch.controller;
import com.jcraft.jsch.SftpException;
import com.jiuyv.sptcc.agile.batch.config.TableProperties;
import com.jiuyv.sptcc.agile.batch.domain.AjaxResult;
import com.jiuyv.sptcc.agile.batch.domain.ReqClearTableDTO;
import com.jiuyv.sptcc.agile.batch.domain.ReqSyncTableDTO;
import com.jiuyv.sptcc.agile.batch.service.BatchService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.jiuyv.sptcc.agile.batch.service.ClearService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
@ -26,61 +25,45 @@ import java.util.List;
@RestController
@RequestMapping("dwsBatch")
public class BatchController {
private static final Logger LOGGER = LoggerFactory.getLogger(BatchController.class);
private final TableProperties tableProperties;
private final ClearService clearService;
public BatchController(TableProperties tableProperties) {
public BatchController(TableProperties tableProperties, ClearService clearService) {
this.tableProperties = tableProperties;
this.clearService = clearService;
}
/**
*
*
*/
@GetMapping("/syncAll")
public AjaxResult<Void> syncAll() {
try {
getService().syncAll();
} catch (SQLException | IOException | InterruptedException e) {
LOGGER.error("同步时发生异常:{}", e.getMessage(), e);
return AjaxResult.error("同步时发生异常,详情请查看同步日志" + e.getMessage());
}
getService().syncAll();
return AjaxResult.success("同步完成");
}
/**
*
*
*/
@PostMapping("/syncByDateAndTableList")
public AjaxResult<Void> syncByDate(@RequestBody List<ReqSyncTableDTO> tableList) {
try {
getService().syncByDate(tableList);
} catch (SQLException | IOException | InterruptedException e) {
LOGGER.error("同步时发生异常:{}", e.getMessage(), e);
return AjaxResult.error("同步时发生异常,详情请查看同步日志" + e.getMessage());
}
getService().syncByDate(tableList);
return AjaxResult.success("同步完成");
}
/**
*
*/
@PostMapping("/syncByDate")
public AjaxResult<Void> syncByDate(@RequestBody ReqSyncTableDTO request) {
try {
List<ReqSyncTableDTO> tableList = new ArrayList<>();
tableList.add(request);
getService().syncByDate(tableList);
} catch (SQLException | IOException | InterruptedException e) {
LOGGER.error("同步时发生异常:{}", e.getMessage(), e);
return AjaxResult.error("同步时发生异常,详情请查看同步日志" + e.getMessage());
}
List<ReqSyncTableDTO> tableList = new ArrayList<>();
tableList.add(request);
getService().syncByDate(tableList);
return AjaxResult.success("同步完成");
}
/**
* pg
*
*/
@PostMapping("/clearTable")
public AjaxResult<Void> clearTable(@RequestBody List<ReqClearTableDTO> tableList) {
@ -90,13 +73,27 @@ public class BatchController {
return AjaxResult.error("非法操作,无权限清空该表:" + table);
}
}
try {
getService().clearTable(tableList);
} catch (SQLException e) {
String message = e.getMessage();
LOGGER.error("清空表时,发生异常{}", message, e);
return AjaxResult.error("清空表时,发生异常{}" + message);
}
getService().clearTable(tableList);
return AjaxResult.success();
}
/**
* Sftp
*
*/
@PostMapping("cleanSftp")
public AjaxResult<Void> cleanSftp() throws SQLException, SftpException {
clearService.clearSftpFile();
return AjaxResult.success();
}
/**
*
*
*/
@PostMapping("cleanLocalTempDir")
public AjaxResult<Void> cleanLocalTempDir() {
clearService.deleteDirectory();
return AjaxResult.success();
}

@ -1,19 +1,23 @@
package com.jiuyv.sptcc.agile.batch.dao;
import org.springframework.stereotype.Repository;
import org.springframework.util.CollectionUtils;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
/**
* Postgre
@ -55,6 +59,7 @@ public class PostgreDAO extends BaseDAO {
*
*/
public void insertSyncRecord(String path, String tableName, int count, Date txnDate) throws SQLException {
deleteSyncRecord(tableName, txnDate);
String sql = "INSERT INTO tbl_prd_sync_record (path,table_name,count,txn_date) VALUES(?,?,?,?)";
try (Connection connection = dataSource.getConnection();
PreparedStatement statement = connection.prepareStatement(sql)) {
@ -81,6 +86,63 @@ public class PostgreDAO extends BaseDAO {
}
}
public void clearTable(String table, String date, String dateColumn) throws SQLException {
String sql = String.format("DELETE FROM %s WHERE %s = '%s'", table, dateColumn, date);
try (Connection connection = dataSource.getConnection();
Statement statement = connection.createStatement()) {
statement.execute(sql);
}
}
/**
*
*
*/
public void deleteMonthFile(int deleteYear) throws SQLException {
String sql = String.format("UPDATE tbl_prd_sync_record SET data_status = '99' WHERE txn_date < '%s-01-01'", deleteYear);
try (Connection connection = dataSource.getConnection();
Statement statement = connection.createStatement()) {
statement.execute(sql);
}
}
/**
*
*
*/
public List<Map<String, Object>> selectAllSyncRecord() throws SQLException {
String sql = "SELECT * FROM tbl_prd_sync_record WHERE data_status = '00'";
try (Connection connection = dataSource.getConnection();
PreparedStatement statement = connection.prepareStatement(sql)) {
ResultSet resultSet = statement.executeQuery();
ResultSetMetaData metaData = resultSet.getMetaData();
List<Map<String, Object>> list = new ArrayList<>();
while (resultSet.next()) {
Map<String, Object> map = new HashMap<>();
for (int i = 1; i <= metaData.getColumnCount(); i++) {
Object value = resultSet.getObject(i);
map.put(metaData.getColumnName(i), value);
}
list.add(map);
}
return list;
}
}
public void deleteDayFile(List<Long> ids) throws SQLException {
if (CollectionUtils.isEmpty(ids)) {
return;
}
String collect = ids.stream().map(Object::toString).collect(Collectors.joining(","));
String sql = String.format("UPDATE tbl_prd_sync_record SET data_status = '99' WHERE id IN (%s)", collect);
try (Connection connection = dataSource.getConnection();
Statement statement = connection.createStatement()) {
statement.execute(sql);
}
}
/**
* SQL
*/
@ -100,11 +162,14 @@ public class PostgreDAO extends BaseDAO {
return fields.toArray(new String[0]);
}
public void clearTable(String table, String date, String dateColumn) throws SQLException {
String sql = String.format("DELETE FROM %s WHERE %s = '%s'", table, dateColumn, date);
private void deleteSyncRecord(String tableName, Date txnDate) throws SQLException {
String sql = String.format("UPDATE tbl_prd_sync_record SET data_status = '99' " +
"WHERE table_name = '%s' AND txn_date = '%s'", tableName, txnDate);
try (Connection connection = dataSource.getConnection();
Statement statement = connection.createStatement()) {
statement.execute(sql);
}
}
}

@ -18,7 +18,7 @@ public class AjaxResult<T> implements Serializable {
/**
*
*/
private int code;
private String code;
/**
*
@ -36,11 +36,11 @@ public class AjaxResult<T> implements Serializable {
public AjaxResult() {
}
public int getCode() {
public String getCode() {
return code;
}
public void setCode(int code) {
public void setCode(String code) {
this.code = code;
}
@ -66,7 +66,7 @@ public class AjaxResult<T> implements Serializable {
* @param code
* @param msg
*/
public AjaxResult(int code, String msg) {
public AjaxResult(String code, String msg) {
this.code = code;
this.msg = msg;
}
@ -78,7 +78,7 @@ public class AjaxResult<T> implements Serializable {
* @param msg
* @param data
*/
public AjaxResult(int code, String msg, T data) {
public AjaxResult(String code, String msg, T data) {
this.code = code;
this.msg = msg;
this.data = data;
@ -121,7 +121,7 @@ public class AjaxResult<T> implements Serializable {
* @return
*/
public static <T> AjaxResult<T> success(String msg, T data) {
return new AjaxResult<>(200, msg, data);
return new AjaxResult<>("success", msg, data);
}
@ -154,13 +154,13 @@ public class AjaxResult<T> implements Serializable {
public static <T> AjaxResult<T> error(String msg, T data) {
logger.error("服务报错:" + msg);
if (msg.contains("Exception")) {
return new AjaxResult<>(500, "系统内部错误", data);
return new AjaxResult<>("failed", "系统内部错误", data);
}
if (msg.contains("script")) {
return new AjaxResult<>(500, "系统参数错误", data);
return new AjaxResult<>("failed", "系统参数错误", data);
}
return new AjaxResult<>(500, msg, data);
return new AjaxResult<>("failed", msg, data);
}
/**
@ -170,7 +170,7 @@ public class AjaxResult<T> implements Serializable {
* @param msg
* @return
*/
public static <T> AjaxResult<T> error(int code, String msg) {
public static <T> AjaxResult<T> error(String code, String msg) {
return new AjaxResult<>(code, msg, null);
}

@ -39,8 +39,7 @@ public class GlobalExceptionHandler {
@ExceptionHandler({ServiceException.class})
public AjaxResult<Void> handleServiceException(ServiceException e) {
LOGGER.error(e.getMessage(), e);
Integer code = e.getCode();
return code != null ? AjaxResult.error(code, e.getMessage()) : AjaxResult.error(e.getMessage());
return AjaxResult.error(e.getMessage());
}
/**

@ -10,6 +10,7 @@ import com.jiuyv.sptcc.agile.batch.domain.DataInfoContainer;
import com.jiuyv.sptcc.agile.batch.domain.ReqClearTableDTO;
import com.jiuyv.sptcc.agile.batch.domain.ReqSyncTableDTO;
import com.jiuyv.sptcc.agile.batch.domain.TableInfo;
import com.jiuyv.sptcc.agile.batch.exception.ServiceException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.task.TaskExecutor;
@ -17,25 +18,22 @@ import org.springframework.core.task.TaskExecutor;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.RandomAccessFile;
import java.nio.file.FileVisitResult;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.sql.Date;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.StringJoiner;
import java.util.Vector;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
@ -45,14 +43,15 @@ import java.util.zip.ZipOutputStream;
*
* @author ren_chao
*/
public final class BatchService {
public class BatchService {
private static final Logger LOGGER = LoggerFactory.getLogger(BatchService.class);
private static final int BATCH_QUANTITY = 50000;
private static final Path TEMP_PATH = Paths.get(System.getProperty("user.dir"), "temp");
private static final Pattern FILE_PATTERN = Pattern.compile("([a-zA-Z_]+)(\\d{4}-\\d{2}-\\d{2})?");
private static final Path TEMP_PATH = TableProperties.TEMP_PATH;
private volatile boolean keepRunning = true;
private volatile byte sync = 0;
private volatile ServiceException exception = null;
private final LinkedBlockingQueue<DataInfoContainer> dataQueue = new LinkedBlockingQueue<>(2);
private final LinkedBlockingQueue<File> fileQueue = new LinkedBlockingQueue<>(2);
@ -65,8 +64,6 @@ public final class BatchService {
private final Map<String, String> fileTypeMap;
private final SftpChannelPool sftpChannelPool;
private final TaskExecutor executor;
private final Thread dataThread;
private final Thread sftpThread;
public BatchService(TableProperties tableProperties) {
this.hiveDAO = tableProperties.getHiveDAO();
@ -77,10 +74,6 @@ public final class BatchService {
this.uploadPath = tableProperties.getUploadPath();
this.sftpChannelPool = tableProperties.getSftpChannelPool();
this.executor = tableProperties.getExecutor();
this.dataThread = new Thread(this::receiveData);
this.sftpThread = new Thread(this::uploadSFTP);
this.dataThread.start();
this.sftpThread.start();
}
@ -88,62 +81,87 @@ public final class BatchService {
*
*
*/
public void syncAll() throws SQLException, IOException, InterruptedException {
sync(new ArrayList<>(tableMapByHive.values()));
public void syncAll() {
initConsumer();
try {
sync(new ArrayList<>(tableMapByHive.values()));
} catch (IOException | SQLException e) {
LOGGER.error("同步时发生异常:{}", e.getMessage(), e);
throw new ServiceException("同步异常,详情查看日志");
} catch (InterruptedException e) {
LOGGER.error("同步时中断异常:{}", e.getMessage(), e);
Thread.currentThread().interrupt();
throw new ServiceException("同步异常,详情查看日志");
} finally {
keepRunning = false;
}
}
/**
*
*
*/
public void syncByDate(List<ReqSyncTableDTO> tableList) throws SQLException, IOException, InterruptedException {
List<ReqClearTableDTO> clearTableDTOList = tableList.stream().map(tableDTO -> {
ReqClearTableDTO clearTableDTO = new ReqClearTableDTO();
clearTableDTO.setPgTable(tableMapByHive.get(tableDTO.getHiveTable()).getPgTable());
clearTableDTO.setDate(tableDTO.getDate());
return clearTableDTO;
}).collect(Collectors.toList());
// 同步前先清理
clearTable(clearTableDTOList);
for (ReqSyncTableDTO tableDTO : tableList) {
String hiveTable = tableDTO.getHiveTable();
TableInfo tableInfo = tableMapByHive.get(hiveTable);
String dateColumn = tableInfo.getDateColumn();
String date = tableDTO.getDate();
if (tableInfo.isPart()) {
Integer count = hiveDAO.getCountByDate(hiveTable, dateColumn, date);
selectData(tableInfo, date, count, 0);
} else {
selectData(tableInfo, date);
public void syncByDate(List<ReqSyncTableDTO> tableList) {
initConsumer();
try {
List<ReqClearTableDTO> clearTableDTOList = tableList.stream().map(tableDTO -> {
ReqClearTableDTO clearTableDTO = new ReqClearTableDTO();
clearTableDTO.setPgTable(tableMapByHive.get(tableDTO.getHiveTable()).getPgTable());
clearTableDTO.setDate(tableDTO.getDate());
return clearTableDTO;
}).collect(Collectors.toList());
// 同步前先清理
clearTable(clearTableDTOList);
for (ReqSyncTableDTO tableDTO : tableList) {
String hiveTable = tableDTO.getHiveTable();
TableInfo tableInfo = tableMapByHive.get(hiveTable);
String dateColumn = tableInfo.getDateColumn();
String date = tableDTO.getDate();
if (tableInfo.isPart()) {
Integer count = hiveDAO.getCountByDate(hiveTable, dateColumn, date);
selectData(tableInfo, date, count, 0);
} else {
selectData(tableInfo, date);
}
}
// 等待完成
waitCompletion();
} catch (SQLException e) {
LOGGER.error("同步时发生异常:{}", e.getMessage(), e);
throw new ServiceException("同步异常,详情查看日志");
} catch (InterruptedException e) {
LOGGER.error("同步时中断异常:{}", e.getMessage(), e);
Thread.currentThread().interrupt();
throw new ServiceException("同步异常,详情查看日志");
} finally {
keepRunning = false;
}
// 等待完成
waitCompletion();
}
/**
* pg
*/
public void clearTable(List<ReqClearTableDTO> tables) throws SQLException {
for (ReqClearTableDTO table : tables) {
String pgTable = table.getPgTable();
TableInfo tableInfo = tableMapByPg.get(pgTable);
String date = table.getDate();
String dateColumn = tableInfo.getDateColumn();
postgreDAO.clearTable(pgTable, date, dateColumn);
public void clearTable(List<ReqClearTableDTO> tables) {
try {
for (ReqClearTableDTO table : tables) {
String pgTable = table.getPgTable();
TableInfo tableInfo = tableMapByPg.get(pgTable);
String date = table.getDate();
String dateColumn = tableInfo.getDateColumn();
postgreDAO.clearTable(pgTable, date, dateColumn);
}
} catch (SQLException e) {
LOGGER.error("清空表时,发生异常{}", e.getMessage(), e);
throw new ServiceException("清空表时,发生异常");
}
}
/**
*
*
*/
private void sync(List<TableInfo> tables) throws SQLException, InterruptedException, IOException {
// 清理临时目录
deleteDirectory();
for (TableInfo table : tables) {
LOGGER.info("====开始同步表:{}", table.getHiveTable());
if (table.isPart()) {
@ -163,12 +181,15 @@ public final class BatchService {
@SuppressWarnings("all")
private void waitCompletion() throws InterruptedException {
LOGGER.info("====所有Hive表查询完毕等待pg表和SFTP同步完成。");
sync = 1;
while (true) {
if (dataThread.getState() == Thread.State.WAITING && sftpThread.getState() == Thread.State.WAITING) {
if (sync == 3) {
if (exception != null) {
LOGGER.info("====同步失败----。");
throw exception;
}
LOGGER.info("====同步完成。");
keepRunning = false;
dataThread.interrupt();
sftpThread.interrupt();
break;
}
Thread.sleep(200);
@ -213,51 +234,88 @@ public final class BatchService {
*
*/
private void receiveData() {
try {
while (keepRunning) {
DataInfoContainer dataInfo = dataQueue.take();
while (keepRunning) {
try {
if (dataQueue.isEmpty() && sync == 1) {
sync = 2;
break;
}
DataInfoContainer dataInfo = dataQueue.poll(200, TimeUnit.MILLISECONDS);
if (dataInfo == null) {
continue;
}
List<Map<String, Object>> dataList = dataInfo.getDataList();
String pgSql = dataInfo.getTableInfo().getPgSql();
String pgTable = dataInfo.getTableInfo().getPgTable();
executor.execute(() -> {
CompletableFuture<Void> pgFuture = CompletableFuture.runAsync(() -> {
try {
postgreDAO.batchInsert(dataList, pgSql);
} catch (SQLException e) {
Thread.currentThread().interrupt();
} catch (SQLException | RuntimeException e) {
keepRunning = false;
exception = new ServiceException(String.format("数据插入表[%s]时出错", pgTable));
sync = 3;
LOGGER.error("数据插入表[{}]时出错:{}", pgTable, e.getMessage(), e);
}
});
executor.execute(() -> {
}, executor);
CompletableFuture<Void> dataFuture = CompletableFuture.runAsync(() -> {
try {
writeFile(dataInfo);
} catch (InterruptedException | IOException e) {
Thread.currentThread().interrupt();
// dws_qa 开头的表不需要保存文件
if (!dataInfo.getTableInfo().getHiveTable().startsWith("dws_qa")) {
writeFile(dataInfo);
}
} catch (IOException | RuntimeException e){
keepRunning = false;
exception = new ServiceException(String.format("数据插入表[%s]时出错", pgTable));
sync = 3;
LOGGER.error("保存表[{}]到文件时出错:{}", pgTable, e.getMessage(), e);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
LOGGER.debug("线程中断异常:{}", e.getMessage(), e);
}
});
}, executor);
CompletableFuture.allOf(pgFuture, dataFuture).join();
} catch (InterruptedException e) {
LOGGER.debug("线程中断:{}", e.getMessage(), e);
Thread.currentThread().interrupt();
}
} catch (InterruptedException e) {
LOGGER.info("dataThread线程结束{}", e.getMessage(), e);
}
}
}
/**
* fileQueueSFTP
*/
@SuppressWarnings("ResultOfMethodCallIgnored")
private void uploadSFTP() {
File file = null;
try {
while (keepRunning) {
file = fileQueue.take();
while (keepRunning || !fileQueue.isEmpty()) {
File file = null;
try {
if (fileQueue.isEmpty() && sync == 2) {
sync = 3;
break;
}
file = fileQueue.poll(200, TimeUnit.MILLISECONDS);
if (file == null) {
continue;
}
zipAndUploadSFTP(file);
} catch (SQLException | SftpException | IOException | RuntimeException e) {
keepRunning = false;
exception = new ServiceException(String.format("文件[%s]上传SFTP出错", file));
sync = 3;
LOGGER.error("文件[{}]上传SFTP出错{}", file, e.getMessage(), e);
} catch (InterruptedException e) {
LOGGER.debug("线程中断异常:{}", e.getMessage(), e);
Thread.currentThread().interrupt();
} finally {
if (file != null) {
file.delete();
}
}
} catch (SQLException | SftpException | IOException e) {
LOGGER.error("文件[{}]上传SFTP出错{}", file, e.getMessage(), e);
} catch (InterruptedException e){
LOGGER.info("sftpThread线程结束{}", e.getMessage(), e);
}
}
/**
@ -278,8 +336,9 @@ public final class BatchService {
for (Map.Entry<String, List<Map<String, Object>>> entry : dateMap.entrySet()) {
String date = entry.getKey();
List<Map<String, Object>> mapList = entry.getValue();
dataQueue.put(new DataInfoContainer(tableInfo, mapList, mapList.size(), date));
LOGGER.info("====表{}放入队列,总数:{},本次范围:{},分区:{}", tableInfo.getHiveTable(), mapList.size(), "0-" + mapList.size(), date);
DataInfoContainer container = new DataInfoContainer(tableInfo, mapList, mapList.size(), date);
putDataQueue(container);
LOGGER.info("====表{}放入队列,总数:{},本次范围:{},日期:{}", tableInfo.getHiveTable(), mapList.size(), "0-" + mapList.size(), date);
}
@ -305,12 +364,12 @@ public final class BatchService {
while (offset < count) {
List<Map<String, Object>> list = hiveDAO.selectList(tableInfo.getHiveSql(), part, offset, BATCH_QUANTITY);
DataInfoContainer container = new DataInfoContainer(tableInfo, list, null, part);
putDataQueue(container);
offset += BATCH_QUANTITY;
if (offset >= count) {
container.setTotal(count);
}
dataQueue.put(container);
LOGGER.info("====表{}放入队列,总数:{},本次范围:{},分区:{}", tableInfo.getHiveTable(), count, offset - BATCH_QUANTITY + "-" + offset, part);
LOGGER.info("====表{}放入队列,总数:{},本次范围:{},日期:{}", tableInfo.getHiveTable(), count, offset - BATCH_QUANTITY + "-" + offset, part);
}
}
@ -324,10 +383,17 @@ public final class BatchService {
List<Map<String, Object>> list = hiveDAO.selectList(tableInfo.getHiveSql(), date, 0, Integer.MAX_VALUE);
int count = list.size();
DataInfoContainer container = new DataInfoContainer(tableInfo, list, count, date);
dataQueue.put(container);
putDataQueue(container);
LOGGER.info("====表{}放入队列,总数:{},本次范围:{},日期:{}", tableInfo.getHiveTable(), count, 0 + "-" + count, date);
}
private void putDataQueue(DataInfoContainer container) throws InterruptedException {
while (!dataQueue.offer(container, 500, TimeUnit.MILLISECONDS)) {
if (!keepRunning) {
throw exception != null ? exception : new ServiceException("同步时发生异常");
}
}
}
/**
*
@ -339,11 +405,19 @@ public final class BatchService {
String[] header = tableInfo.getTableHeader();
String tableName = tableInfo.getHiveTable();
Path path = TEMP_PATH.resolve(date.substring(0, 7));
String fileName = tableName + (date.length() > 7 ? date : "") + ".csv";
File file = path.resolve(fileName).toFile();
Path path;
File file;
if (date.length() > 7) {
path = TEMP_PATH.resolve(date.substring(0, 7)).resolve(date);
} else {
path = TEMP_PATH.resolve(date);
}
file = path.resolve(tableName + ".csv").toFile();
try (FileWriter writer = getFileWriter(file, header)) {
// 构建表头
buildHeader(file, header);
try (FileOutputStream fileOutputStream = new FileOutputStream(file, true);
OutputStreamWriter writer = new OutputStreamWriter(fileOutputStream, StandardCharsets.UTF_8)) {
for (Map<String, Object> map : list) {
StringJoiner sj = new StringJoiner(",");
for (String s : header) {
@ -356,32 +430,35 @@ public final class BatchService {
if (total != null) {
writer.write("\ntotal:" + total);
fileQueue.put(file);
LOGGER.info("====文件{}放入队列,总数:{}分区{}", file.getName(), total, date);
LOGGER.info("====文件{}放入队列,总数:{}日期{}", file.getName(), total, date);
}
}
}
/**
*
*
*
*/
private FileWriter getFileWriter(File file, String[] header) throws IOException {
private void buildHeader(File file, String[] header) throws IOException {
if (file.exists()) {
return;
}
File fileDirectory = file.getParentFile();
if (!fileDirectory.exists()) {
//noinspection ResultOfMethodCallIgnored
fileDirectory.mkdirs();
}
boolean fileExist = file.exists();
FileWriter writer = new FileWriter(file, true);
if (fileExist) {
return writer;
}
StringJoiner sj = new StringJoiner(",");
for (String s : header) {
sj.add(s);
try (FileOutputStream fileOutputStream = new FileOutputStream(file);
OutputStreamWriter writer = new OutputStreamWriter(fileOutputStream, StandardCharsets.UTF_8)) {
writer.write('\uFEFF');
StringJoiner sj = new StringJoiner(",");
for (String s : header) {
sj.add(s);
}
writer.write(sj.toString());
}
writer.write(sj.toString());
return writer;
}
/**
@ -390,34 +467,34 @@ public final class BatchService {
*/
private void zipAndUploadSFTP(File file) throws IOException, SftpException, SQLException {
String fileName = file.getName();
if (fileName.startsWith("dws_qa")) {
return;
}
// 压缩
String zipPathStr = file.toString().replace("csv", "zip");
Path zipPat = Paths.get(zipPathStr);
try(FileOutputStream outputStream = new FileOutputStream(zipPathStr);
ZipOutputStream zipOut = new ZipOutputStream(outputStream);
FileInputStream inputStream = new FileInputStream(file)) {
zipOut.putNextEntry(new ZipEntry(file.getName()));
zipOut.putNextEntry(new ZipEntry(fileName));
byte[] bytes = new byte[1024];
int length;
while ((length = inputStream.read(bytes)) >= 0) {
zipOut.write(bytes, 0, length);
}
}
String yearMonth = file.toPath().getParent().getFileName().toString();
String targetDirectory = uploadPath + "/" + yearMonth;
String sftpFilePath = targetDirectory + "/" + zipPat.getFileName();
Path subPath = zipPat.subpath(TEMP_PATH.getNameCount(), zipPat.getNameCount());
Path sftpFilePath = Paths.get(uploadPath).resolve(subPath);
String sftpFilePathStr = sftpFilePath.toString().replace(File.separator, "/");
// 上传SFTP
ChannelSftp sftpChannel = sftpChannelPool.getSftpChannel();
try {
// 创建目录
if (!isResourceExist(sftpChannel, yearMonth)) {
sftpChannel.mkdir(targetDirectory);
// 创建sftp目录
Path parent = sftpFilePath.getParent();
if (isNotResourceExist(sftpChannel, parent.toString().replace(File.separator, "/"))) {
mkdirs(sftpChannel, parent);
}
// 文件上传
sftpChannel.put(zipPathStr, sftpFilePath);
sftpChannel.put(zipPathStr, sftpFilePathStr);
} finally {
sftpChannelPool.closeChannel(sftpChannel);
}
@ -426,16 +503,11 @@ public final class BatchService {
LOGGER.info("====文件{}上传成功", zipPat.getFileName());
// 保存记录
Matcher matcher = FILE_PATTERN.matcher(fileName);
// noinspection ResultOfMethodCallIgnored
matcher.find();
String tableName = matcher.group(1);
String date = matcher.group(2);
String txnDate = date == null ? yearMonth + "-01" : date;
postgreDAO.insertSyncRecord(sftpFilePath, fileTypeMap.get(tableName), getTotalByFile(file), Date.valueOf(txnDate));
// 插入后,删除文件
Files.delete(file.toPath());
LOGGER.info("====文件{}记录写入数据库成功", file.getName());
String date = subPath.getParent().getFileName().toString();
Date txnDate = Date.valueOf(date.length() > 7 ? date : date + "-01");
String tableName = fileTypeMap.get(fileName.replace(".csv", ""));
postgreDAO.insertSyncRecord(sftpFilePathStr, tableName, getTotalByFile(file), txnDate);
LOGGER.info("====文件{}记录写入数据库成功", fileName);
}
/**
@ -461,50 +533,38 @@ public final class BatchService {
}
/**
*
*
*/
private void deleteDirectory() throws IOException {
if (!Files.exists(TEMP_PATH)) {
return;
}
Files.walkFileTree(TEMP_PATH, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
// 删除文件
Files.delete(file);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
// 删除目录
Files.delete(dir);
return FileVisitResult.CONTINUE;
}
});
}
/**
*
*
* @param channel
* @param resources
* @return true false
* @return true false
*/
@SuppressWarnings("unchecked")
private boolean isResourceExist(ChannelSftp channel, String resources) throws SftpException {
// 获取目录下的文件和子目录列表
Vector<ChannelSftp.LsEntry> entries;
entries = channel.ls(uploadPath);
if (entries == null) {
private boolean isNotResourceExist(ChannelSftp channel, String resources) throws SftpException {
try {
channel.lstat(resources);
return false;
}
for (ChannelSftp.LsEntry entry : entries) {
if (entry.getFilename().equals(resources)) {
} catch (SftpException e) {
if (e.id == ChannelSftp.SSH_FX_NO_SUCH_FILE) {
return true;
}
throw e;
}
return false;
}
/**
*
*
*/
private void mkdirs(ChannelSftp channel, Path dir) throws SftpException {
Path parent = dir.getParent();
if (isNotResourceExist(channel, parent.toString().replace(File.separator, "/"))) {
mkdirs(channel, parent);
}
channel.mkdir(dir.toString().replace(File.separator, "/"));
}
private void initConsumer() {
executor.execute(this::receiveData);
executor.execute(this::uploadSFTP);
}
}

@ -0,0 +1,166 @@
package com.jiuyv.sptcc.agile.batch.service;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.SftpATTRS;
import com.jcraft.jsch.SftpException;
import com.jiuyv.sptcc.agile.batch.config.TableProperties;
import com.jiuyv.sptcc.agile.batch.config.sftp.SftpChannelPool;
import com.jiuyv.sptcc.agile.batch.dao.PostgreDAO;
import com.jiuyv.sptcc.agile.batch.exception.ServiceException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import java.io.IOException;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.sql.Date;
import java.sql.SQLException;
import java.time.LocalDate;
import java.util.List;
import java.util.Map;
import java.util.Vector;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
/**
*
*
* @author ren_chao
*/
@Service
public class ClearService {
private static final Logger LOGGER = LoggerFactory.getLogger(ClearService.class);
private static final Pattern MONTH_PATTERN = Pattern.compile("\\d{4}-\\d{2}");
private static final Pattern DAY_PATTERN = Pattern.compile("\\d{4}-\\d{2}-\\d{2}");
private static final Pattern PATH_PATTERN = Pattern.compile(".+/\\d{4}-\\d{2}/\\d{4}-\\d{2}-\\d{2}/.+");
private final String uploadPath;
private final PostgreDAO postgreDAO;
private final SftpChannelPool sftpChannelPool;
public ClearService(TableProperties tableProperties, PostgreDAO postgreDAO, SftpChannelPool sftpChannelPool) {
this.uploadPath = tableProperties.getUploadPath();
this.postgreDAO = postgreDAO;
this.sftpChannelPool = sftpChannelPool;
}
@SuppressWarnings("unchecked")
public void clearSftpFile() throws SftpException, SQLException {
ChannelSftp sftpChannel = sftpChannelPool.getSftpChannel();
try {
Vector<ChannelSftp.LsEntry> ls = sftpChannel.ls(uploadPath);
LocalDate now = LocalDate.now();
int deleteYear = getDeleteYear(now);
LocalDate deleteDay = now.minusDays(30);
LOGGER.info("当前时间[{}]。月文件清理[{}]年之前的目录。日文件清理[{}]之前的目录", now, deleteYear, deleteDay);
// 清理sftp文件
for (ChannelSftp.LsEntry entry : ls) {
String monthName = entry.getFilename();
if (!MONTH_PATTERN.matcher(monthName).matches()) {
continue;
}
String monthPath = uploadPath + "/" + monthName;
if (Integer.parseInt(monthName.substring(0, 4)) < deleteYear) {
rm(sftpChannel, monthPath);
LOGGER.info("删除目录:{}", monthPath);
} else {
Vector<ChannelSftp.LsEntry> monthLs = sftpChannel.ls(monthPath);
for (ChannelSftp.LsEntry e : monthLs) {
String dayName = e.getFilename();
if (DAY_PATTERN.matcher(dayName).matches() && LocalDate.parse(dayName).isBefore(deleteDay)) {
String dayPath = monthPath + "/" + dayName;
rm(sftpChannel, dayPath);
LOGGER.info("删除目录:{}", dayPath);
}
}
}
}
// 删除月文件记录
postgreDAO.deleteMonthFile(deleteYear);
// 删除日文件记录
List<Map<String, Object>> syncRecord = postgreDAO.selectAllSyncRecord();
List<Long> ids = syncRecord.stream().filter(map -> {
Date txnDate = (Date) map.get("txn_date");
String path = (String) map.get("path");
return txnDate.toLocalDate().isBefore(deleteDay) && PATH_PATTERN.matcher(path).matches();
}).map(map -> (Long) map.get("id")).collect(Collectors.toList());
postgreDAO.deleteDayFile(ids);
} finally {
sftpChannelPool.closeChannel(sftpChannel);
}
}
/**
*
*
*/
public void deleteDirectory() {
if (!Files.exists(TableProperties.TEMP_PATH)) {
return;
}
try {
Files.walkFileTree(TableProperties.TEMP_PATH, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
// 删除文件
Files.delete(file);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
// 删除目录
Files.delete(dir);
return FileVisitResult.CONTINUE;
}
});
} catch (IOException e) {
LOGGER.error("清理目录时发生异常{}", e.getMessage(), e);
throw new ServiceException("清理目录时发生异常");
}
}
/**
* 21
*
*/
private int getDeleteYear(LocalDate now) {
int year = now.getYear();
LocalDate febFirst = LocalDate.of(year, 2, 1);
if (now.isBefore(febFirst)) {
return year - 1;
}
return year;
}
/**
* sftp
*/
@SuppressWarnings("unchecked")
private void rm(ChannelSftp channel, String path) throws SftpException {
SftpATTRS stat = channel.stat(path);
if (!stat.isDir()) {
channel.rm(path);
return;
}
Vector<ChannelSftp.LsEntry> ls = channel.ls(path);
List<String> nameList = ls.stream().filter(e -> !".".equals(e.getFilename()) && !"..".equals(e.getFilename()))
.map(ChannelSftp.LsEntry::getFilename).collect(Collectors.toList());
for (String name : nameList) {
rm(channel, path + "/" + name);
}
channel.rmdir(path);
}
}

@ -1,204 +0,0 @@
package com.jiuyv.sptcc.agile.batch.utils;
import java.nio.charset.StandardCharsets;
import java.security.GeneralSecurityException;
import java.security.InvalidAlgorithmParameterException;
import java.security.InvalidKeyException;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.SecureRandom;
import java.security.Security;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.Mac;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.DecoderException;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.binary.Hex;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.engines.SM4Engine;
import org.bouncycastle.crypto.macs.CBCBlockCipherMac;
import org.bouncycastle.crypto.macs.GMac;
import org.bouncycastle.crypto.modes.GCMBlockCipher;
import org.bouncycastle.crypto.paddings.BlockCipherPadding;
import org.bouncycastle.crypto.paddings.PKCS7Padding;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.crypto.params.ParametersWithIV;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
/**
* Created with IntelliJ IDEA.
*
* @author Shawffer
* @description:
* @date: 2022-07-19
* @time: 17:04
*/
public class Sm4Util {
public static final String ALGORITHM_NAME = "SM4";
public static final String ALGORITHM_NAME_ECB_PADDING = "SM4/ECB/PKCS7Padding";
public static final String ALGORITHM_NAME_ECB_NOPADDING = "SM4/ECB/NoPadding";
public static final String ALGORITHM_NAME_CBC_PADDING = "SM4/CBC/PKCS7Padding";
public static final String ALGORITHM_NAME_CBC_NOPADDING = "SM4/CBC/NoPadding";
/**
* SM412816
*/
public static final int DEFAULT_KEY_SIZE = 128;
static {
Security.addProvider(new BouncyCastleProvider());
}
public static byte[] generateKey() throws GeneralSecurityException {
return generateKey(DEFAULT_KEY_SIZE);
}
public static byte[] generateKey(int keySize) throws GeneralSecurityException {
KeyGenerator kg = KeyGenerator.getInstance(ALGORITHM_NAME, BouncyCastleProvider.PROVIDER_NAME);
kg.init(keySize, new SecureRandom());
return kg.generateKey().getEncoded();
}
public static byte[] encrypt_ECB_Padding(byte[] key, byte[] data) throws GeneralSecurityException {
Cipher cipher = generateECBCipher(ALGORITHM_NAME_ECB_PADDING, Cipher.ENCRYPT_MODE, key);
return cipher.doFinal(data);
}
public static byte[] decrypt_ECB_Padding(byte[] key, byte[] cipherText) throws GeneralSecurityException{
Cipher cipher = generateECBCipher(ALGORITHM_NAME_ECB_PADDING, Cipher.DECRYPT_MODE, key);
return cipher.doFinal(cipherText);
}
public static byte[] encrypt_ECB_NoPadding(byte[] key, byte[] data)
throws GeneralSecurityException {
Cipher cipher = generateECBCipher(ALGORITHM_NAME_ECB_NOPADDING, Cipher.ENCRYPT_MODE, key);
return cipher.doFinal(data);
}
public static byte[] decrypt_ECB_NoPadding(byte[] key, byte[] cipherText)
throws GeneralSecurityException {
Cipher cipher = generateECBCipher(ALGORITHM_NAME_ECB_NOPADDING, Cipher.DECRYPT_MODE, key);
return cipher.doFinal(cipherText);
}
public static byte[] encrypt_CBC_Padding(byte[] key, byte[] iv, byte[] data)
throws GeneralSecurityException {
Cipher cipher = generateCBCCipher(ALGORITHM_NAME_CBC_PADDING, Cipher.ENCRYPT_MODE, key, iv);
return cipher.doFinal(data);
}
public static byte[] decrypt_CBC_Padding(byte[] key, byte[] iv, byte[] cipherText)
throws GeneralSecurityException {
Cipher cipher = generateCBCCipher(ALGORITHM_NAME_CBC_PADDING, Cipher.DECRYPT_MODE, key, iv);
return cipher.doFinal(cipherText);
}
public static byte[] encrypt_CBC_NoPadding(byte[] key, byte[] iv, byte[] data)
throws GeneralSecurityException {
Cipher cipher = generateCBCCipher(ALGORITHM_NAME_CBC_NOPADDING, Cipher.ENCRYPT_MODE, key, iv);
return cipher.doFinal(data);
}
public static byte[] decrypt_CBC_NoPadding(byte[] key, byte[] iv, byte[] cipherText)
throws GeneralSecurityException {
Cipher cipher = generateCBCCipher(ALGORITHM_NAME_CBC_NOPADDING, Cipher.DECRYPT_MODE, key, iv);
return cipher.doFinal(cipherText);
}
public static byte[] doCMac(byte[] key, byte[] data) throws GeneralSecurityException {
Key keyObj = new SecretKeySpec(key, ALGORITHM_NAME);
return doMac("SM4-CMAC", keyObj, data);
}
public static byte[] doGMac(byte[] key, byte[] iv, int tagLength, byte[] data) {
org.bouncycastle.crypto.Mac mac = new GMac(new GCMBlockCipher(new SM4Engine()), tagLength * 8);
return doMac(mac, key, iv, data);
}
/**
* 使PKCS7Padding/PKCS5PaddingCBCMAC
*
* @param key
* @param iv
* @param data
* @return
*/
public static byte[] doCBCMac(byte[] key, byte[] iv, byte[] data) {
SM4Engine engine = new SM4Engine();
org.bouncycastle.crypto.Mac mac = new CBCBlockCipherMac(engine, engine.getBlockSize() * 8, new PKCS7Padding());
return doMac(mac, key, iv, data);
}
/**
* @param key
* @param iv
* @param padding nullnullNoPaddingBlockSize
* @param data
* @return
* @throws Exception
*/
public static byte[] doCBCMac(byte[] key, byte[] iv, BlockCipherPadding padding, byte[] data) throws GeneralSecurityException {
SM4Engine engine = new SM4Engine();
if (padding == null) {
if (data.length % engine.getBlockSize() != 0) {
throw new InvalidAlgorithmParameterException("if no padding, data length must be multiple of SM4 BlockSize");
}
}
org.bouncycastle.crypto.Mac mac = new CBCBlockCipherMac(engine, engine.getBlockSize() * 8, padding);
return doMac(mac, key, iv, data);
}
private static byte[] doMac(org.bouncycastle.crypto.Mac mac, byte[] key, byte[] iv, byte[] data) {
CipherParameters cipherParameters = new KeyParameter(key);
mac.init(new ParametersWithIV(cipherParameters, iv));
mac.update(data, 0, data.length);
byte[] result = new byte[mac.getMacSize()];
mac.doFinal(result, 0);
return result;
}
private static byte[] doMac(String algorithmName, Key key, byte[] data) throws GeneralSecurityException{
Mac mac = Mac.getInstance(algorithmName, BouncyCastleProvider.PROVIDER_NAME);
mac.init(key);
mac.update(data);
return mac.doFinal();
}
private static Cipher generateECBCipher(String algorithmName, int mode, byte[] key)
throws NoSuchAlgorithmException, NoSuchProviderException, NoSuchPaddingException,
InvalidKeyException {
Cipher cipher = Cipher.getInstance(algorithmName, BouncyCastleProvider.PROVIDER_NAME);
Key sm4Key = new SecretKeySpec(key, ALGORITHM_NAME);
cipher.init(mode, sm4Key);
return cipher;
}
private static Cipher generateCBCCipher(String algorithmName, int mode, byte[] key, byte[] iv)
throws GeneralSecurityException {
Cipher cipher = Cipher.getInstance(algorithmName, BouncyCastleProvider.PROVIDER_NAME);
Key sm4Key = new SecretKeySpec(key, ALGORITHM_NAME);
IvParameterSpec ivParameterSpec = new IvParameterSpec(iv);
cipher.init(mode, sm4Key, ivParameterSpec);
return cipher;
}
public static String encryptEcb(String key, String text) throws GeneralSecurityException, DecoderException {
return Base64.encodeBase64String(Sm4Util.encrypt_ECB_Padding(Hex.decodeHex(key), text.getBytes(StandardCharsets.UTF_8)));
}
public static String decryptEcb(String key, String text) throws GeneralSecurityException, DecoderException {
return new String(Sm4Util.decrypt_ECB_Padding(Hex.decodeHex(key), Base64.decodeBase64((text))));
}
public static String generateKeyHex() throws Exception {
return Hex.encodeHexString(Sm4Util.generateKey(DEFAULT_KEY_SIZE));
}
}

@ -1,44 +0,0 @@
#server:
# port: 8081
#
#sftp:
# host: 172.16.12.108
# port: 22
# username: flink
# password: flink123 # 不要加密如果需要加密后面全部交给spring cloud config来处理
# # 连接池最大实例数
# maxTotal: 20
# # 连接池最大空闲数
# maxIdle: 10
# # 连接池最小空闲数
# minIdle: 5
#
#hiveDataSource:
# jdbcUrl: jdbc:hive2://172.16.12.101:10000/sptcc_agile_test;socketTimeout=12000;
# user: flink
# password: flink
# driverClass: org.apache.hive.jdbc.HiveDriver
# initialPoolSize: 15
# minPoolSize: 15
# maxPoolSize: 25
#
#pgDataSource:
# jdbcUrl: jdbc:postgresql://172.16.12.105:5432/keliubao
# user: postgres
# password: postgres
# driverClass: org.postgresql.Driver
# initialPoolSize: 15
# minPoolSize: 15
# maxPoolSize: 25
#
#
#syncTable:
# tables:
# - hiveTable: dws_line_metric_day
# pgTable: tbl_prd_line_metric_day
#
# - hiveTable: dws_line_metric_month
# pgTable: tbl_prd_line_metric_month
#
# - hiveTable: dws_qa_centime_delay
# pgTable: tbl_qa_centime_delay

@ -26,4 +26,4 @@ eureka:
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://172.16.12.109:8761/eureka/
defaultZone: http://172.16.12.107:8761/eureka/

@ -1,51 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>agile-data</artifactId>
<groupId>com.jiuyv.sptcc.agile</groupId>
<version>0.1.13-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<packaging>jar</packaging>
<artifactId>agile-data-api</artifactId>
<dependencies>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
</dependency>
<dependency>
<groupId>com.jiuyv.sptcc.agile</groupId>
<artifactId>agile-common</artifactId>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-core</artifactId>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
</dependency>
</dependencies>
</project>

@ -1,222 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>agile-data</artifactId>
<groupId>com.jiuyv.sptcc.agile</groupId>
<version>0.1.13-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>agile-data-service</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<!--动态健康监控 可以用于动态感知配置变化-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- spring cloud 配置-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>${okhttp3.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>com.jiuyv.sptcc.agile</groupId>
<artifactId>agile-data-api</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional> <!-- 表示依赖不会传递 -->
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
</dependency>
<!-- pool 对象池 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
<dependency>
<groupId>com.jcraft</groupId>
<artifactId>jsch</artifactId>
<version>${jsch.version}</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
</dependency>
<!--Mybatis-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<!-- postgresql连接 -->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- hive库 -->
<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
<version>${caffeine.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>${pageHelper.version}</version>
</dependency>
<!-- word文档打包 -->
<dependency>
<groupId>com.aspose</groupId>
<artifactId>aspose-words</artifactId>
<version>${aspose.version}</version>
<systemPath>${project.basedir}/src/main/resources/lib/aspose-words-20.3.jar</systemPath>
<scope>system</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-deploy-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin>
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<executions>
<execution>
<id>default-prepare-agent</id>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>default-report</id>
<phase>prepare-package</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
<configuration>
<fork>true</fork> <!-- 如果没有该配置de vtools不会生效 -->
<includeSystemScope>true</includeSystemScope>
</configuration>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
<compilerArguments>
<extdirs>lib</extdirs>
</compilerArguments>
</configuration>
</plugin>
</plugins>
</build>
</project>

@ -1,31 +0,0 @@
spring:
application:
name: agile-data-service
cloud:
config:
discovery:
service-id: CONFIG-SERVICE #告诉当前客户端 统一配置中心的服务端服务id
enabled: true #开启客户端根据服务id到注册中心获取配置信息
label: # 指定分支
name: ${spring.application.name} # 指定应用名称
profile: dev # 指定激活环境
devtools:
restart:
enabled: true
# 配置eureka客户端信息
eureka:
instance:
appname: ${spring.application.name}
lease-expiration-duration-in-seconds: 90
lease-renewal-interval-in-seconds: 10
prefer-ip-address: true
instance-id: ${spring.cloud.client.ip-address}:${server.port}
metadata-map:
user.name: ${spring.security.user.name}
user.password: ${spring.security.user.password}
client:
enabled: true
register-with-eureka: true
fetch-registry: true
service-url:
defaultZone: http://172.16.12.107:8761/eureka/

@ -1,179 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<packaging>pom</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.6.7</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<groupId>com.jiuyv.sptcc.agile</groupId>
<artifactId>agile-data</artifactId>
<version>0.1.13-SNAPSHOT</version>
<name>agile-data</name>
<description>agile-data</description>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<maven-jar-plugin.version>3.1.1</maven-jar-plugin.version>
<maven.clean.version>3.1.0</maven.clean.version>
<maven.resource.version>3.1.0</maven.resource.version>
<spring-cloud.version>2021.0.2</spring-cloud.version>
<commons.lang.veriosn>3.3</commons.lang.veriosn>
<hibernate.validator.version>6.2.3.Final</hibernate.validator.version>
<openfeign.version>3.1.0</openfeign.version>
<mybatis.version>1.3.0</mybatis.version>
<agile.service.api>0.1.13-SNAPSHOT</agile.service.api>
<agile-common>0.1.13</agile-common>
<pageHelper.version>1.4.6</pageHelper.version>
<caffeine.version>2.8.5</caffeine.version>
<jsch.version>0.1.55</jsch.version>
<aspose.version>20.3</aspose.version>
<okhttp3.version>3.14.9</okhttp3.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>${mybatis.version}</version>
</dependency>
<dependency>
<groupId>com.jiuyv.sptcc.agile</groupId>
<artifactId>agile-data-api</artifactId>
<version>${agile.service.api}</version>
</dependency>
<dependency>
<groupId>com.jiuyv.sptcc.agile</groupId>
<artifactId>agile-common</artifactId>
<version>${agile-common}</version>
</dependency>
</dependencies>
</dependencyManagement>
<modules>
<module>agile-data-api</module>
<module>agile-data-service</module>
</modules>
<scm>
<connection>scm:svn:http://172.16.12.10/svn/sptcc_agile_etl/src/agile-date-service/src/trunk/agile-dataservice</connection>
<developerConnection>scm:svn:http://172.16.12.10/svn/sptcc_agile_etl/src/agile-date-service/src/trunk/agile-dataservice</developerConnection>
</scm>
<distributionManagement>
<repository>
<id>nexus-releases</id>
<name>Internal Releases</name>
<url>http://172.16.12.11:8082/repository/maven-releases/</url>
</repository>
<snapshotRepository>
<id>nexus-snapshots</id>
<name>Internal Snapshots</name>
<url>http://172.16.12.11:8082/repository/maven-snapshots/</url>
</snapshotRepository>
</distributionManagement>
<repositories>
<repository>
<id>jiuyv</id>
<name>jiuyv</name>
<url>http://172.16.12.11:8082/repository/maven-public/</url>
<snapshots>
<enabled>true</enabled>
<updatePolicy>always</updatePolicy>
</snapshots>
</repository>
<repository>
<id>jboss</id>
<name>jboss</name>
<url>http://repository.jboss.org/maven2/</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>geotools</id>
<name>geotools</name>
<url>http://maven.geotools.fr/repository/</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>jahia</id>
<name>jahia</name>
<url>http://maven.jahia.org/maven2/</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
<repository>
<id>vars</id>
<name>vars</name>
<url>http://vars.sourceforge.net/maven2/</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>jiuyv</id>
<name>jiuyv Plugin Repository</name>
<url>http://172.16.12.11:8082/repository/maven-public/</url>
</pluginRepository>
<pluginRepository>
<id>central</id>
<name>Maven Plugin Repository</name>
<url>http://repo1.maven.org/maven2/</url>
</pluginRepository>
</pluginRepositories>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.19.1</version>
<configuration>
<!-- <skipTests>true</skipTests> &lt;!&ndash;默认关掉单元测试 &ndash;&gt;-->
</configuration>
</plugin>
</plugins>
</build>
</project>

@ -1,40 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>agile-data</artifactId>
<groupId>com.jiuyv</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>agile-data-api</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
</dependency>
<dependency>
<groupId>jakarta.validation</groupId>
<artifactId>jakarta.validation-api</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
</project>

@ -1,29 +0,0 @@
package com.jiuyv.agile.data.api;
import com.jiuyv.agile.data.web.R;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
/**
* API
*
* @author yulei
*/
public interface AgileApi {
/**
*
* @param id
* @return
*/
@PostMapping(value = "/dataApis/{id}/release")
public R<Object> releaseDataApi(@PathVariable Long id);
/**
*
* @param id
* @return
*/
@PostMapping(value = "/dataApis/{id}/cancel")
public R<Object> cancelDataApi(@PathVariable Long id);
}

@ -1,37 +0,0 @@
package com.jiuyv.agile.data.dto.enums;
public enum AlgorithmCrypto {
BASE64("1", "BASE64加密"),
MD5("2", "MD5加密"),
SHA_1("3", "SHA_1加密"),
SHA_256("4", "SHA_256加密"),
AES("5", "AES加密"),
DES("6", "DES加密");
private final String key;
private final String val;
AlgorithmCrypto(String key, String val) {
this.key = key;
this.val = val;
}
public String getKey() {
return key;
}
public String getVal() {
return val;
}
public static AlgorithmCrypto getAlgorithmCrypto(String algorithmCrypt) {
for (AlgorithmCrypto type : AlgorithmCrypto.values()) {
if (type.key.equals(algorithmCrypt)) {
return type;
}
}
return BASE64;
}
}

@ -1,33 +0,0 @@
package com.jiuyv.agile.data.dto.enums;
public enum CipherType {
REGEX("1", "正则替换"),
ALGORITHM("2", "加密算法");
private final String key;
private final String val;
CipherType(String key, String val) {
this.key = key;
this.val = val;
}
public String getKey() {
return key;
}
public String getVal() {
return val;
}
public static CipherType getCipherType(String cipherType) {
for (CipherType type : CipherType.values()) {
if (type.key.equals(cipherType)) {
return type;
}
}
return REGEX;
}
}

@ -1,83 +0,0 @@
package com.jiuyv.agile.data.dto.enums;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
public enum ParamType {
String("1", "字符串"),
Integer("2", "整型"),
Float("3", "浮点型"),
Date("4", "时间"),
List("5", "集合");
private final String key;
private final String val;
ParamType(String key, String val) {
this.key = key;
this.val = val;
}
public String getKey() {
return key;
}
public String getVal() {
return val;
}
public static Object parse(ParamType paramType, Object obj) {
if (obj == null) {
return null;
}
switch (paramType) {
case String:
try {
return (java.lang.String)obj;
} catch (Exception e) {
throw new RuntimeException("参数值[" + obj + "]不是" + String.getVal() + "数据类型]");
}
case Float:
try {
return new BigDecimal(obj.toString()).doubleValue();
} catch (Exception e) {
throw new RuntimeException("参数值[" + obj + "]不是" + Float.getVal() + "数据类型]");
}
case Integer:
try {
return (java.lang.Integer)obj;
} catch (Exception e) {
throw new RuntimeException("参数值[" + obj + "]不是" + Integer.getVal() + "数据类型]");
}
case List:
try {
return (java.util.List<?>)obj;
} catch (Exception e) {
throw new RuntimeException("参数值[" + obj + "]不是" + List.getVal() + "数据类型]");
}
case Date:
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
try {
return sdf.parse(obj.toString());
} catch (Exception e) {
try {
return sdf.parse(obj.toString());
} catch (Exception ex) {
throw new RuntimeException("参数值[" + obj + "]不是" + Date.getVal() + "数据类型]");
}
}
}
return null;
}
public static ParamType getParamType(String paramType) {
for (ParamType type : ParamType.values()) {
if (type.key.equals(paramType)) {
return type;
}
}
return String;
}
}

@ -1,39 +0,0 @@
package com.jiuyv.agile.data.dto.enums;
public enum RegexCrypto {
CHINESE_NAME("1", "中文姓名"),
ID_CARD("2", "身份证号"),
FIXED_PHONE("3", "固定电话"),
MOBILE_PHONE("4", "手机号码"),
ADDRESS("5", "地址"),
EMAIL("6", "电子邮箱"),
BANK_CARD("7", "银行卡号"),
CNAPS_CODE("8", "公司开户银行联号");
private final String key;
private final String val;
RegexCrypto(String key, String val) {
this.key = key;
this.val = val;
}
public String getKey() {
return key;
}
public String getVal() {
return val;
}
public static RegexCrypto getRegexCrypto(String regexCrypt) {
for (RegexCrypto type : RegexCrypto.values()) {
if (type.key.equals(regexCrypt)) {
return type;
}
}
return CHINESE_NAME;
}
}

@ -1,50 +0,0 @@
package com.jiuyv.agile.data.dto.enums;
public enum WhereType {
EQUALS("1", "=", "等于"),
NOT_EQUALS("2", "!=", "不等于"),
LIKE("3", "LIKE", "全模糊查询"),
LIKE_LEFT("4", "LIKE", "左模糊查询"),
LIKE_RIGHT("5", "LIKE", "右模糊查询"),
GREATER_THAN("6", ">", "大于"),
GREATER_THAN_EQUALS("7", ">=", "大于等于"),
LESS_THAN("8", "<", "小于"),
LESS_THAN_EQUALS("9", "<=", "小于等于"),
NULL("10", "IS NULL", "是否为空"),
NOT_NULL("11", "IS NOT NULL", "是否不为空"),
IN("12", "IN", "IN");
private final String type;
private final String key;
private final String desc;
WhereType(String type, String key, String desc) {
this.type = type;
this.key = key;
this.desc = desc;
}
public String getType() {
return type;
}
public String getKey() {
return key;
}
public String getDesc() {
return desc;
}
public static WhereType getWhereType(String whereType) {
for (WhereType type : WhereType.values()) {
if (type.type.equals(whereType)) {
return type;
}
}
return EQUALS;
}
}

@ -1,46 +0,0 @@
package com.jiuyv.agile.data.dto.request;
import java.util.Objects;
/**
* <p>
* API
* </p>
*/
public class ApiMaskQuery extends BaseQueryParams {
private static final long serialVersionUID=1L;
private String maskName;
private Long apiId;
public String getMaskName() {
return maskName;
}
public void setMaskName(String maskName) {
this.maskName = maskName;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
ApiMaskQuery that = (ApiMaskQuery) o;
return maskName.equals(that.maskName) && apiId.equals(that.apiId);
}
@Override
public int hashCode() {
return Objects.hash(maskName, apiId);
}
public Long getApiId() {
return apiId;
}
public void setApiId(Long apiId) {
this.apiId = apiId;
}
}

@ -1,82 +0,0 @@
package com.jiuyv.agile.data.dto.request;
import java.io.Serializable;
import java.util.List;
public class BaseQueryParams implements Serializable {
private static final long serialVersionUID = 1L;
// 关键字
private String keyword;
// 当前页码
private Integer pageNum = 1;
// 分页条数
private Integer pageSize = 20;
// 排序
private List<OrderItem> orderList;
// 数据权限
private String dataScope;
public class OrderItem{
private String column;
private boolean asc;
public String getColumn() {
return column;
}
public void setColumn(String column) {
this.column = column;
}
public boolean isAsc() {
return asc;
}
public void setAsc(boolean asc) {
this.asc = asc;
}
}
public String getKeyword() {
return keyword;
}
public void setKeyword(String keyword) {
this.keyword = keyword;
}
public Integer getPageNum() {
return pageNum;
}
public void setPageNum(Integer pageNum) {
this.pageNum = pageNum;
}
public Integer getPageSize() {
return pageSize;
}
public void setPageSize(Integer pageSize) {
this.pageSize = pageSize;
}
public List<OrderItem> getOrderList() {
return orderList;
}
public void setOrderList(List<OrderItem> orderList) {
this.orderList = orderList;
}
public String getDataScope() {
return dataScope;
}
public void setDataScope(String dataScope) {
this.dataScope = dataScope;
}
}

@ -1,96 +0,0 @@
package com.jiuyv.agile.data.dto.request;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
/**
* Model
*/
public class DbSchema implements Serializable {
private static final long serialVersionUID=1L;
/**
*
*/
@NotBlank(message = "主机不能为空")
private String host;
/**
*
*/
@NotNull(message = "端口不能为空")
private Integer port;
/**
*
*/
@NotBlank(message = "用户名不能为空")
private String username;
/**
*
*/
@NotBlank(message = "密码不能为空")
private String password;
/**
*
*/
private String dbName;
/**
*
*/
private String sid;
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public Integer getPort() {
return port;
}
public void setPort(Integer port) {
this.port = port;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getDbName() {
return dbName;
}
public void setDbName(String dbName) {
this.dbName = dbName;
}
public String getSid() {
return sid;
}
public void setSid(String sid) {
this.sid = sid;
}
}

@ -1,97 +0,0 @@
package com.jiuyv.agile.data.dto.request;
import javax.validation.Valid;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
import java.util.List;
/**
* Model
*/
public class ExecuteConfig implements Serializable {
private static final long serialVersionUID=1L;
/**
*
*/
@NotBlank(message = "数据源不能为空")
private Long sourceId;
/**
*
*/
@NotNull(message = "配置方式不能为空")
private String configType;
/**
*
*/
private Long tableId;
/**
*
*/
private String tableName;
/**
*
*/
@Valid
private List<FieldParam> fieldParams;
/**
* SQL
*/
private String sqlText;
public Long getSourceId() {
return sourceId;
}
public void setSourceId(Long sourceId) {
this.sourceId = sourceId;
}
public String getConfigType() {
return configType;
}
public void setConfigType(String configType) {
this.configType = configType;
}
public Long getTableId() {
return tableId;
}
public void setTableId(Long tableId) {
this.tableId = tableId;
}
public String getTableName() {
return tableName;
}
public void setTableName(String tableName) {
this.tableName = tableName;
}
public List<FieldParam> getFieldParams() {
return fieldParams;
}
public void setFieldParams(List<FieldParam> fieldParams) {
this.fieldParams = fieldParams;
}
public String getSqlText() {
return sqlText;
}
public void setSqlText(String sqlText) {
this.sqlText = sqlText;
}
}

@ -1,167 +0,0 @@
package com.jiuyv.agile.data.dto.request;
import java.io.Serializable;
/**
* Model
*/
public class FieldParam implements Serializable {
private static final long serialVersionUID=1L;
/**
*
*/
private String columnName;
/**
*
*/
private String dataType;
/**
*
*/
private Integer dataLength;
/**
*
*/
private Integer dataPrecision;
/**
*
*/
private Integer dataScale;
/**
*
*/
private String columnKey;
/**
*
*/
private String columnNullable;
/**
*
*/
private Integer columnPosition;
/**
*
*/
private String dataDefault;
/**
*
*/
private String columnComment;
/**
*
*/
private String reqable;
/**
*
*/
private String resable;
public String getColumnName() {
return columnName;
}
public void setColumnName(String columnName) {
this.columnName = columnName;
}
public String getDataType() {
return dataType;
}
public void setDataType(String dataType) {
this.dataType = dataType;
}
public Integer getDataLength() {
return dataLength;
}
public void setDataLength(Integer dataLength) {
this.dataLength = dataLength;
}
public Integer getDataPrecision() {
return dataPrecision;
}
public void setDataPrecision(Integer dataPrecision) {
this.dataPrecision = dataPrecision;
}
public Integer getDataScale() {
return dataScale;
}
public void setDataScale(Integer dataScale) {
this.dataScale = dataScale;
}
public String getColumnKey() {
return columnKey;
}
public void setColumnKey(String columnKey) {
this.columnKey = columnKey;
}
public String getColumnNullable() {
return columnNullable;
}
public void setColumnNullable(String columnNullable) {
this.columnNullable = columnNullable;
}
public Integer getColumnPosition() {
return columnPosition;
}
public void setColumnPosition(Integer columnPosition) {
this.columnPosition = columnPosition;
}
public String getDataDefault() {
return dataDefault;
}
public void setDataDefault(String dataDefault) {
this.dataDefault = dataDefault;
}
public String getColumnComment() {
return columnComment;
}
public void setColumnComment(String columnComment) {
this.columnComment = columnComment;
}
public String getReqable() {
return reqable;
}
public void setReqable(String reqable) {
this.reqable = reqable;
}
public String getResable() {
return resable;
}
public void setResable(String resable) {
this.resable = resable;
}
}

@ -1,53 +0,0 @@
package com.jiuyv.agile.data.dto.request;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
/**
* Model
*/
public class FieldRule implements Serializable {
private static final long serialVersionUID=1L;
/**
*
*/
@NotBlank(message = "字段名称不能为空")
private String fieldName;
/**
*
*/
@NotNull(message = "脱敏类型不能为空")
private String cipherType;
/**
*
*/
@NotNull(message = "规则类型不能为空")
private String cryptType;
public String getFieldName() {
return fieldName;
}
public void setFieldName(String fieldName) {
this.fieldName = fieldName;
}
public String getCipherType() {
return cipherType;
}
public void setCipherType(String cipherType) {
this.cipherType = cipherType;
}
public String getCryptType() {
return cryptType;
}
public void setCryptType(String cryptType) {
this.cryptType = cryptType;
}
}

@ -1,52 +0,0 @@
package com.jiuyv.agile.data.dto.request;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
/**
* Model
*/
public class RateLimit implements Serializable {
private static final long serialVersionUID=1L;
/**
* 0:1
*/
@NotNull(message = "是否限流不能为空")
private String enable;
/**
* 5
*/
private Integer times = 5;
/**
* 60
*/
private Integer seconds = 60;
public String getEnable() {
return enable;
}
public void setEnable(String enable) {
this.enable = enable;
}
public Integer getTimes() {
return times;
}
public void setTimes(Integer times) {
this.times = times;
}
public Integer getSeconds() {
return seconds;
}
public void setSeconds(Integer seconds) {
this.seconds = seconds;
}
}

@ -1,111 +0,0 @@
package com.jiuyv.agile.data.dto.request;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
/**
* Model
*/
public class ReqParam implements Serializable {
private static final long serialVersionUID=1L;
/**
*
*/
@NotBlank(message = "参数名称不能为空")
private String paramName;
/**
*
*/
@NotNull(message = "是否为空不能为空")
private String nullable;
/**
*
*/
@NotBlank(message = "描述不能为空")
private String paramComment;
/**
*
*/
@NotNull(message = "操作符不能为空")
private String whereType;
/**
*
*/
@NotNull(message = "参数类型不能为空")
private String paramType;
/**
*
*/
@NotBlank(message = "示例值不能为空")
private String exampleValue;
/**
*
*/
@NotBlank(message = "默认值不能为空")
private String defaultValue;
public String getParamName() {
return paramName;
}
public void setParamName(String paramName) {
this.paramName = paramName;
}
public String getNullable() {
return nullable;
}
public void setNullable(String nullable) {
this.nullable = nullable;
}
public String getParamComment() {
return paramComment;
}
public void setParamComment(String paramComment) {
this.paramComment = paramComment;
}
public String getWhereType() {
return whereType;
}
public void setWhereType(String whereType) {
this.whereType = whereType;
}
public String getParamType() {
return paramType;
}
public void setParamType(String paramType) {
this.paramType = paramType;
}
public String getExampleValue() {
return exampleValue;
}
public void setExampleValue(String exampleValue) {
this.exampleValue = exampleValue;
}
public String getDefaultValue() {
return defaultValue;
}
public void setDefaultValue(String defaultValue) {
this.defaultValue = defaultValue;
}
}

@ -1,34 +0,0 @@
package com.jiuyv.agile.data.dto.request;
import java.io.Serializable;
/**
* API
*
* @author yulei
*/
public class ReqVo implements Serializable {
/** 报文内容 */
private String body;
/** 签名 */
private String sign;
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
public String getSign() {
return sign;
}
public void setSign(String sign) {
this.sign = sign;
}
}

@ -1,82 +0,0 @@
package com.jiuyv.agile.data.dto.response;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
/**
* Model
*/
public class ResParam implements Serializable {
private static final long serialVersionUID=1L;
/**
*
*/
@NotBlank(message = "字段名称不能为空")
private String fieldName;
/**
*
*/
@NotBlank(message = "描述不能为空")
private String fieldComment;
/**
*
*/
@NotNull(message = "数据类型不能为空")
private String dataType;
/**
*
*/
@NotBlank(message = "示例值不能为空")
private String exampleValue;
/**
*
*/
private String fieldAliasName;
public String getFieldName() {
return fieldName;
}
public void setFieldName(String fieldName) {
this.fieldName = fieldName;
}
public String getFieldComment() {
return fieldComment;
}
public void setFieldComment(String fieldComment) {
this.fieldComment = fieldComment;
}
public String getDataType() {
return dataType;
}
public void setDataType(String dataType) {
this.dataType = dataType;
}
public String getExampleValue() {
return exampleValue;
}
public void setExampleValue(String exampleValue) {
this.exampleValue = exampleValue;
}
public String getFieldAliasName() {
return fieldAliasName;
}
public void setFieldAliasName(String fieldAliasName) {
this.fieldAliasName = fieldAliasName;
}
}

@ -1,55 +0,0 @@
package com.jiuyv.agile.data.dto.response;
import com.jiuyv.agile.data.web.ResultCode;
import java.io.Serializable;
/**
* API
*
* @author yulei
*/
public class RespVo implements Serializable {
/** 返回码*/
private Integer respCode;
/** 返回说明 */
private String respDesc;
public RespVo() {
}
public RespVo(Integer code, String message) {
this.respCode = code;
this.respDesc = message;
}
public static RespVo ok(){
return new RespVo(ResultCode.SUCCESS.getCode(),ResultCode.SUCCESS.getMessage());
}
public Integer getRespCode() {
return respCode;
}
public void setRespCode(Integer respCode) {
this.respCode = respCode;
}
public String getRespDesc() {
return respDesc;
}
public void setRespDesc(String respDesc) {
this.respDesc = respDesc;
}
@Override
public String toString() {
return "RespVo{" +
"respCode='" + respCode + '\'' +
", respDesc='" + respDesc + '\'' +
'}';
}
}

@ -1,20 +0,0 @@
package com.jiuyv.agile.data.web;
/**
* @ClassName : IErrorCode
* @Description : API
* @Author : sky
* @Date: 2023-06-06 16:33
*/
public interface IErrorCode {
/**
*
*/
Integer getCode();
/**
*
*/
String getMessage();
}

@ -1,107 +0,0 @@
package com.jiuyv.agile.data.web;
import com.jiuyv.agile.data.web.constant.HttpStatus;
import java.io.Serializable;
/**
*
*
* @author admin
*/
public class R<T> implements Serializable
{
private static final long serialVersionUID = 1L;
/** 成功 */
public static final int SUCCESS = HttpStatus.SUCCESS;
/** 失败 */
public static final int FAIL = HttpStatus.ERROR;
private int code;
private String msg;
private T data;
public static <T> R<T> ok()
{
return restResult(null, SUCCESS, "操作成功");
}
public static <T> R<T> ok(T data)
{
return restResult(data, SUCCESS, "操作成功");
}
public static <T> R<T> ok(T data, String msg)
{
return restResult(data, SUCCESS, msg);
}
public static <T> R<T> fail()
{
return restResult(null, FAIL, "操作失败");
}
public static <T> R<T> fail(String msg)
{
return restResult(null, FAIL, msg);
}
public static <T> R<T> fail(T data)
{
return restResult(data, FAIL, "操作失败");
}
public static <T> R<T> fail(T data, String msg)
{
return restResult(data, FAIL, msg);
}
public static <T> R<T> fail(int code, String msg)
{
return restResult(null, code, msg);
}
private static <T> R<T> restResult(T data, int code, String msg)
{
R<T> apiResult = new R<>();
apiResult.setCode(code);
apiResult.setData(data);
apiResult.setMsg(msg);
return apiResult;
}
public int getCode()
{
return code;
}
public void setCode(int code)
{
this.code = code;
}
public String getMsg()
{
return msg;
}
public void setMsg(String msg)
{
this.msg = msg;
}
public T getData()
{
return data;
}
public void setData(T data)
{
this.data = data;
}
}

@ -1,70 +0,0 @@
package com.jiuyv.agile.data.web;
/**
* API
* Created by macro on 2019/4/19.
*/
public enum ResultCode implements IErrorCode {
/** success : 成功. */
SUCCESS(200, "操作成功"),
ACCEPTED(202, "请求已经被接受"),
NO_CONTENT(204, "操作已经执行成功,但是没有返回数据"),
MOVED_PERM(301, "资源已被移除"),
SEE_OTHER(303, "重定向"),
NOT_MODIFIED(304, "资源没有被修改"),
BAD_REQUEST(400, "参数列表错误(缺少,格式不匹配)"),
UNAUTHORIZED(401, "未授权"),
FORBIDDEN(403, "访问受限,授权过期"),
NOT_FOUND(404, "资源,服务未找到"),
BAD_METHOD(405, "不允许的http方法"),
CONFLICT(409, "资源冲突,或者资源被锁"),
ERROR(500, "系统内部错误"),
NOT_IMPLEMENTED(501, "接口未实现"),
//PROCESS("process", "订单处理中,请稍后查询"),
//FAILED("failed", "操作失败"),
//VALIDATE_FAILED("input_not_valid", "输入不合法"),
//REPEAT_SUBMIT("duplicate_req_id", "请勿重复提交"),
//AUTHORIZATION_LIMIT("authorization limit", "权限限制"),
//UNAUTHORIZED("401", "暂未登录或token已经过期"),
//
//ILLEGALLY("illegally request", "不合法请求"),
///** input_not_valid : 输入不合法. */
//INPUT_NOT_VALID("input_not_valid", "输入不合法"),
///** duplicate_req_id : 重复请求. */
//DUPLICATE_REQ_ID("duplicate_req_id","重复请求"),
///** duplicate_order : 订单重复. */
//DUPLICATE_ORDER("duplicate_order","订单重复"),
//
///** product_limit : 商品限购 */
//SYS_ERROR("sys_error","系统异常"),
///** business_error : 调用返回非成功 */
//BUSINESS_ERROR("business_error","调用返回非成功"),
///** sql_lock_exception : 乐观锁异常*/
//SQL_EXCEPTION("sql_lock_exception","乐观锁异常"),
//
///** file_not_exist,请输入正确的权益号 */
//FILE_NOT_EXIST("file_not_exist","文件不存在"),
///** file_no_data,文件内容为空 */
//FILE_NO_DATA("file_no_data","文件内容为空");
;
private Integer code;
private String message;
private ResultCode(Integer code, String message) {
this.code = code;
this.message = message;
}
@Override
public Integer getCode() {
return code;
}
@Override
public String getMessage() {
return message;
}
}

@ -1,89 +0,0 @@
package com.jiuyv.agile.data.web.constant;
/**
*
*
* @author admin
*/
public class HttpStatus
{
/**
*
*/
public static final int SUCCESS = 200;
/**
*
*/
public static final int CREATED = 201;
/**
*
*/
public static final int ACCEPTED = 202;
/**
*
*/
public static final int NO_CONTENT = 204;
/**
*
*/
public static final int MOVED_PERM = 301;
/**
*
*/
public static final int SEE_OTHER = 303;
/**
*
*/
public static final int NOT_MODIFIED = 304;
/**
*
*/
public static final int BAD_REQUEST = 400;
/**
*
*/
public static final int UNAUTHORIZED = 401;
/**
* 访
*/
public static final int FORBIDDEN = 403;
/**
*
*/
public static final int NOT_FOUND = 404;
/**
* http
*/
public static final int BAD_METHOD = 405;
/**
*
*/
public static final int CONFLICT = 409;
/**
*
*/
public static final int UNSUPPORTED_TYPE = 415;
/**
*
*/
public static final int ERROR = 500;
/**
*
*/
public static final int NOT_IMPLEMENTED = 501;
}

@ -1,76 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>agile-data</artifactId>
<groupId>com.jiuyv</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>agile-data-service</artifactId>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.jiuyv</groupId>
<artifactId>agile-data-api</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional> <!-- 表示依赖不会传递 -->
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>org.hibernate.validator</groupId>
<artifactId>hibernate-validator</artifactId>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<scope>provided</scope>
</dependency>
<!--Mybatis-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
<!-- postgresql连接 -->
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
</dependency>
<dependency>
<groupId>com.zaxxer</groupId>
<artifactId>HikariCP</artifactId>
</dependency>
</dependencies>
</project>

@ -1,30 +0,0 @@
package com.jiuyv.agile.data;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableScheduling;
/**
* @author yulei
*/
@SpringBootApplication
@EnableScheduling
public class AgileDataApplication {
private static final Logger LOGGER = LoggerFactory.getLogger(AgileDataApplication.class);
public static void main(String[] args) {
SpringApplication.run(AgileDataApplication.class, args);
LOGGER.info("(♥◠‿◠)ノ゙ 模块启动成功゙ \n"+
" ___ ___ ___ \n"+
" |\\ \\ |\\ \\ / /| \n"+
" \\ \\ \\ \\ \\ \\/ / / \n"+
" __ \\ \\ \\ \\ \\ / / \n"+
" |\\ \\\\_\\ \\ \\/ / / \n"+
" \\ \\________\\ __/ / / \n"+
" \\|________| |\\___/ / \n"+
" \\|___|/ \n"
);
}
}

@ -1,211 +0,0 @@
package com.jiuyv.agile.data.common.constants;
public class DataConstant {
/**
* Oauth2
*/
public enum Security {
//请求头TOKEN名称
TOKENHEADER("gatewayToken"),
//请求头TOKEN值
TOKENVALUE("datax:gateway:123456"),
//OAUTH2请求头
AUTHORIZATION("Authorization"),
//OAUTH2令牌类型
TOKENTYPE("bearer "),
//security授权角色前缀
ROLEPREFIX("ROLE_");
Security(String val){
this.val = val;
}
private final String val;
public String getVal() {
return val;
}
}
/**
*
*/
public enum TrueOrFalse {
FALSE("0",false),
TRUE("1",true);
TrueOrFalse(String key, boolean val){
this.key = key;
this.val = val;
}
private final String key;
private final boolean val;
public String getKey() {
return key;
}
public boolean getVal() {
return val;
}
}
/**
*
*/
public enum UserAdditionalInfo {
LICENSE("license", "datax"),
USER("user", "用户"),
USERID("user_id", "用户ID"),
USERNAME("username", "用户名"),
NICKNAME("nickname", "用户昵称"),
DEPT("user_dept", "用户部门"),
ROLE("user_role", "用户角色"),
POST("user_post", "用户岗位");
UserAdditionalInfo(String key, String val){
this.key = key;
this.val = val;
}
private final String key;
private final String val;
public String getKey() {
return key;
}
public String getVal() {
return val;
}
}
/**
*
*/
public enum EnableState {
DISABLE("0","禁用"),
ENABLE("1","启用");
EnableState(String key, String val){
this.key = key;
this.val = val;
}
private final String key;
private final String val;
public String getKey() {
return key;
}
public String getVal() {
return val;
}
}
/**
*
*/
public enum AuditState{
WAIT("1","待提交"),
BACK("2", "已退回"),
AUDIT("3","审核中"),
AGREE("4","通过"),
REJECT("5","不通过"),
CANCEL("6", "已撤销");
AuditState(String key, String val){
this.key = key;
this.val = val;
}
private final String key;
private final String val;
public String getKey() {
return key;
}
public String getVal() {
return val;
}
}
/**
*
*/
public enum MenuType{
MODULE("0","模块"),
MENU("1","菜单"),
BUTTON("2","按钮");
MenuType(String key, String val){
this.key = key;
this.val = val;
}
private final String key;
private final String val;
public String getKey() {
return key;
}
public String getVal() {
return val;
}
}
/**
*
*/
public enum DataScope{
ALL("1","全部数据权限"),
CUSTOM("2","自定义数据权限"),
DEPT("3","本部门数据权限"),
DEPTANDCHILD("4","本部门及以下数据权限"),
SELF("5","仅本人数据权限");
DataScope(String key, String val){
this.key = key;
this.val = val;
}
private final String key;
private final String val;
public String getKey() {
return key;
}
public String getVal() {
return val;
}
}
/**
* Api
*/
public enum ApiState{
WAIT("1","待发布"),
RELEASE("2","已发布"),
CANCEL("3","已下线");
ApiState(String key, String val){
this.key = key;
this.val = val;
}
private final String key;
private final String val;
public String getKey() {
return key;
}
public String getVal() {
return val;
}
}
}

@ -1,33 +0,0 @@
package com.jiuyv.agile.data.config;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.jiuyv.agile.data.handler.MappingHandlerMapping;
import com.jiuyv.agile.data.handler.RequestHandler;
import com.jiuyv.agile.data.handler.RequestInterceptor;
import com.jiuyv.agile.data.service.impl.ApiMappingEngine;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
@Configuration
public class ApiMappingConfig {
@Bean
public MappingHandlerMapping mappingHandlerMapping(RequestMappingHandlerMapping requestMappingHandlerMapping,
ApiMappingEngine apiMappingEngine,
ObjectMapper objectMapper) {
MappingHandlerMapping mappingHandlerMapping = new MappingHandlerMapping();
mappingHandlerMapping.setHandler(requestHandler(apiMappingEngine, objectMapper));
mappingHandlerMapping.setRequestMappingHandlerMapping(requestMappingHandlerMapping);
return mappingHandlerMapping;
}
@Bean
public RequestHandler requestHandler(ApiMappingEngine apiMappingEngine, ObjectMapper objectMapper) {
RequestHandler handler = new RequestHandler();
handler.setApiMappingEngine(apiMappingEngine);
handler.setObjectMapper(objectMapper);
handler.setRequestInterceptor(new RequestInterceptor());
return handler;
}
}

@ -1,43 +0,0 @@
package com.jiuyv.agile.data.controller;
import com.jiuyv.agile.data.service.AgileApiService;
import com.jiuyv.agile.data.web.R;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* API
*
* @author yulei
*/
@RestController
public class AgileApiController {
@Autowired
private AgileApiService agileApiService;
/**
*
* @param id
* @return
*/
@PostMapping(value = "/dataApis/{id}/release")
public R<Object> releaseDataApi(@PathVariable Long id){
agileApiService.releaseDataApi(id);
return R.ok();
}
/**
*
* @param id
* @return
*/
@PostMapping(value = "/dataApis/{id}/cancel")
public R<Object> cancelDataApi(@PathVariable Long id){
agileApiService.cancelDataApi(id);
return R.ok();
}
}

@ -1,7 +0,0 @@
package com.jiuyv.agile.data.controller;
import com.jiuyv.agile.data.api.AgileApi;
public interface ts extends AgileApi {
}

@ -1,31 +0,0 @@
package com.jiuyv.agile.data.controller;
import com.jiuyv.agile.data.api.AgileApi;
import com.jiuyv.agile.data.service.AgileApiService;
import com.jiuyv.agile.data.web.R;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class tt implements AgileApi {
/**
*
*
* @param id
* @return
*/
@Override
public R<Object> releaseDataApi(Long id) {
return null;
}
/**
*
*
* @param id
* @return
*/
@Override
public R<Object> cancelDataApi(Long id) {
return null;
}
}

@ -1,12 +0,0 @@
package com.jiuyv.agile.data.database;
public interface DataSourceFactory {
/**
*
*
* @param property
* @return
*/
DbQuery createDbQuery(DbQueryProperty property);
}

@ -1,134 +0,0 @@
package com.jiuyv.agile.data.database;
public class DbColumn {
/**
*
*/
private String colName;
/**
*
*/
private String dataType;
/**
*
*/
private String dataLength;
/**
*
*/
private String dataPrecision;
/**
*
*/
private String dataScale;
/**
*
*/
private Boolean colKey;
/**
*
*/
private Boolean nullable;
/**
*
*/
private Integer colPosition;
/**
*
*/
private String dataDefault;
/**
*
*/
private String colComment;
public String getColName() {
return colName;
}
public void setColName(String colName) {
this.colName = colName;
}
public String getDataType() {
return dataType;
}
public void setDataType(String dataType) {
this.dataType = dataType;
}
public String getDataLength() {
return dataLength;
}
public void setDataLength(String dataLength) {
this.dataLength = dataLength;
}
public String getDataPrecision() {
return dataPrecision;
}
public void setDataPrecision(String dataPrecision) {
this.dataPrecision = dataPrecision;
}
public String getDataScale() {
return dataScale;
}
public void setDataScale(String dataScale) {
this.dataScale = dataScale;
}
public Boolean getColKey() {
return colKey;
}
public void setColKey(Boolean colKey) {
this.colKey = colKey;
}
public Boolean getNullable() {
return nullable;
}
public void setNullable(Boolean nullable) {
this.nullable = nullable;
}
public Integer getColPosition() {
return colPosition;
}
public void setColPosition(Integer colPosition) {
this.colPosition = colPosition;
}
public String getDataDefault() {
return dataDefault;
}
public void setDataDefault(String dataDefault) {
this.dataDefault = dataDefault;
}
public String getColComment() {
return colComment;
}
public void setColComment(String colComment) {
this.colComment = colComment;
}
}

@ -1,48 +0,0 @@
package com.jiuyv.agile.data.database;
import org.springframework.jdbc.core.RowMapper;
/**
*
*/
public interface DbDialect {
RowMapper<DbTable> tableMapper();
RowMapper<DbColumn> columnMapper();
/**
*
*
* @param dbName
* @param tableName
* @return
*/
String columns(String dbName, String tableName);
/**
*
*
* @param dbName
* @return
*/
String tables(String dbName);
/**
* sql
*
* @param sql
* @param offset
* @param count
* @return
*/
String buildPaginationSql(String sql, long offset, long count);
/**
* count sql
*
* @param sql
* @return
*/
String count(String sql);
}

@ -1,33 +0,0 @@
package com.jiuyv.agile.data.database;
import java.security.MessageDigest;
public class DbMD5Util {
private static final char[] HEX_CHARS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
/**
* MD5
*/
public static String encrypt(String value){
return encrypt(value.getBytes());
}
/**
* MD5
*/
public static String encrypt(byte[] value){
try {
byte[] bytes = MessageDigest.getInstance("MD5").digest(value);
char[] chars = new char[32];
for (int i = 0; i < chars.length; i = i + 2) {
byte b = bytes[i / 2];
chars[i] = HEX_CHARS[(b >>> 0x4) & 0xf];
chars[i + 1] = HEX_CHARS[b & 0xf];
}
return new String(chars);
} catch (Exception e) {
throw new RuntimeException("md5 encrypt error", e);
}
}
}

@ -1,113 +0,0 @@
package com.jiuyv.agile.data.database;
import java.sql.Connection;
import java.util.List;
import java.util.Map;
/**
*
*/
public interface DbQuery {
/**
*
*/
Connection getConnection();
/**
*
*/
boolean valid();
/**
*
*/
void close();
/**
*
* @param dbName
* @param tableName
* @return
*/
List<DbColumn> getTableColumns(String dbName, String tableName);
/**
*
*
* @param dbName
* @return
*/
List<DbTable> getTables(String dbName);
/**
*
*
* @param sql
* @return
*/
int count(String sql);
/**
*
*
* @param sql
* @return
*/
int count(String sql, Object[] args);
/**
* NamedParameterJdbcTemplate
*
* @param sql
* @return
*/
int count(String sql, Map<String, Object> params);
/**
*
*
* @param sql
* @return
*/
List<Map<String, Object>> queryList(String sql);
/**
*
*
* @param sql
* @param args
* @return
*/
List<Map<String, Object>> queryList(String sql, Object[] args);
/**
*
*
* @param sql
* @param offset
* @param size
* @return
*/
PageResult<Map<String, Object>> queryByPage(String sql, long offset, long size);
/**
*
* @param sql
* @param args
* @param offset
* @param size
* @return
*/
PageResult<Map<String, Object>> queryByPage(String sql, Object[] args, long offset, long size);
/**
* NamedParameterJdbcTemplate
* @param sql
* @param params
* @param offset
* @param size
* @return
*/
PageResult<Map<String, Object>> queryByPage(String sql, Map<String, Object> params, long offset, long size);
}

@ -1,99 +0,0 @@
package com.jiuyv.agile.data.database;
import org.springframework.util.StringUtils;
import java.io.Serializable;
//@AllArgsConstructor
public class DbQueryProperty implements Serializable {
private static final long serialVersionUID = 1L;
private String dbType;
private String host;
private String username;
private String password;
private Integer port;
private String dbName;
private String sid;
/**
*
*/
public void viald() {
if (StringUtils.isEmpty(dbType) || StringUtils.isEmpty(host) ||
StringUtils.isEmpty(username) || StringUtils.isEmpty(password) ||
StringUtils.isEmpty(port)) {
throw new RuntimeException("参数不完整");
}
if (DbType.OTHER.getDb().equals(dbType)) {
throw new RuntimeException("不支持的数据库类型");
}
}
public DbQueryProperty(String dbType, String host, String username, String password, Integer port, String dbName, String sid) {
this.dbType = dbType;
this.host = host;
this.username = username;
this.password = password;
this.port = port;
this.dbName = dbName;
this.sid = sid;
}
public String getDbType() {
return dbType;
}
public void setDbType(String dbType) {
this.dbType = dbType;
}
public String getHost() {
return host;
}
public void setHost(String host) {
this.host = host;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Integer getPort() {
return port;
}
public void setPort(Integer port) {
this.port = port;
}
public String getDbName() {
return dbName;
}
public void setDbName(String dbName) {
this.dbName = dbName;
}
public String getSid() {
return sid;
}
public void setSid(String sid) {
this.sid = sid;
}
}

@ -1,30 +0,0 @@
package com.jiuyv.agile.data.database;
public class DbTable {
/**
*
*/
private String tableName;
/**
*
*/
private String tableComment;
public String getTableName() {
return tableName;
}
public void setTableName(String tableName) {
this.tableName = tableName;
}
public String getTableComment() {
return tableComment;
}
public void setTableComment(String tableComment) {
this.tableComment = tableComment;
}
}

@ -1,87 +0,0 @@
package com.jiuyv.agile.data.database;
/**
*
*/
public enum DbType {
/**
* MYSQL
*/
MYSQL("1", "MySql数据库", "jdbc:mysql://${host}:${port}/${dbName}?serverTimezone=GMT%2B8&characterEncoding=UTF-8&useUnicode=true&useSSL=false"),
/**
* MARIADB
*/
MARIADB("2", "MariaDB数据库", "jdbc:mariadb://${host}:${port}/${dbName}"),
/**
* ORACLE
*/
ORACLE("3", "Oracle11g及以下数据库", "jdbc:oracle:thin:@${host}:${port}:${sid}"),
/**
* oracle12c new pagination
*/
ORACLE_12C("4", "Oracle12c+数据库", "jdbc:oracle:thin:@${host}:${port}:${sid}"),
/**
* POSTGRESQL
*/
POSTGRE_SQL("5", "PostgreSql数据库", "jdbc:postgresql://${host}:${port}/${dbName}"),
/**
* SQLSERVER2005
*/
SQL_SERVER2008("6", "SQLServer2008及以下数据库", "jdbc:sqlserver://${host}:${port};DatabaseName=${dbName}"),
/**
* SQLSERVER
*/
SQL_SERVER("7", "SQLServer2012+数据库", "jdbc:sqlserver://${host}:${port};DatabaseName=${dbName}"),
/**
* UNKONWN DB
*/
OTHER("8", "其他数据库", "");
/**
*
*/
private final String db;
/**
*
*/
private final String desc;
/**
* url
*/
private final String url;
public String getDb() {
return this.db;
}
public String getDesc() {
return this.desc;
}
public String getUrl() {
return this.url;
}
DbType(String db, String desc, String url) {
this.db = db;
this.desc = desc;
this.url = url;
}
/**
*
*
* @param dbType
*/
public static DbType getDbType(String dbType) {
for (DbType type : DbType.values()) {
if (type.db.equals(dbType)) {
return type;
}
}
return OTHER;
}
}

@ -1,15 +0,0 @@
package com.jiuyv.agile.data.database;
import com.jiuyv.agile.data.database.dialect.DialectRegistry;
/**
*
*/
public class DialectFactory {
private static final DialectRegistry DIALECT_REGISTRY = new DialectRegistry();
public static DbDialect getDialect(DbType dbType) {
return DIALECT_REGISTRY.getDialect(dbType);
}
}

@ -1,53 +0,0 @@
package com.jiuyv.agile.data.database;
import java.io.Serializable;
import java.util.List;
//@Accessors(chain = true)
public class PageResult<T> implements Serializable {
private static final long serialVersionUID = 1L;
private Integer pageNum;
private Integer pageSize;
private Integer total;
private List<T> data;
public PageResult(Integer total, List<T> data) {
this.total = total;
this.data = data;
}
public Integer getPageNum() {
return pageNum;
}
public void setPageNum(Integer pageNum) {
this.pageNum = pageNum;
}
public Integer getPageSize() {
return pageSize;
}
public void setPageSize(Integer pageSize) {
this.pageSize = pageSize;
}
public Integer getTotal() {
return total;
}
public void setTotal(Integer total) {
this.total = total;
}
public List<T> getData() {
return data;
}
public void setData(List<T> data) {
this.data = data;
}
}

@ -1,123 +0,0 @@
package com.jiuyv.agile.data.database.cache;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.locks.ReentrantReadWriteLock;
public class DefaultSqlCache extends LinkedHashMap<String, DefaultSqlCache.ExpireNode<Object>> implements SqlCache {
private int capacity;
private long expire;
private ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
public DefaultSqlCache(int capacity, long expire) {
super((int) Math.ceil(capacity / 0.75) + 1, 0.75f, true);
// 容量
this.capacity = capacity;
// 固定过期时间
this.expire = expire;
}
@Override
public void put(String key, Object value, long ttl) {
long expireTime = Long.MAX_VALUE;
if (ttl >= 0) {
expireTime = System.currentTimeMillis() + (ttl == 0 ? this.expire : ttl);
}
lock.writeLock().lock();
try {
// 封装成过期时间节点
put(key, new ExpireNode<>(expireTime, value));
} finally {
lock.writeLock().unlock();
}
}
@Override
public Object get(String key) {
lock.readLock().lock();
ExpireNode<Object> expireNode;
try {
expireNode = super.get(key);
} finally {
lock.readLock().unlock();
}
if (expireNode == null) {
return null;
}
// 惰性删除过期的
if (this.expire > -1L && expireNode.expire < System.currentTimeMillis()) {
try {
lock.writeLock().lock();
super.remove(key);
} finally {
lock.writeLock().unlock();
}
return null;
}
return expireNode.value;
}
@Override
public void delete(String key) {
try {
lock.writeLock().lock();
Iterator<Map.Entry<String, ExpireNode<Object>>> iterator = super.entrySet().iterator();
// 清除key的缓存
while (iterator.hasNext()) {
Map.Entry<String, ExpireNode<Object>> entry = iterator.next();
if (entry.getKey().equals(key)) {
iterator.remove();
}
}
} finally {
lock.writeLock().unlock();
}
}
@Override
protected boolean removeEldestEntry(Map.Entry<String, ExpireNode<Object>> eldest) {
if (this.expire > -1L && size() > capacity) {
clean();
}
// lru淘汰
return size() > this.capacity;
}
/**
*
*/
private void clean() {
try {
lock.writeLock().lock();
Iterator<Map.Entry<String, ExpireNode<Object>>> iterator = super.entrySet().iterator();
long now = System.currentTimeMillis();
while (iterator.hasNext()) {
Map.Entry<String, ExpireNode<Object>> next = iterator.next();
// 判断是否过期
if (next.getValue().expire < now) {
iterator.remove();
}
}
} finally {
lock.writeLock().unlock();
}
}
/**
*
*/
static class ExpireNode<V> {
long expire;
Object value;
public ExpireNode(long expire, Object value) {
this.expire = expire;
this.value = value;
}
}
}

@ -1,38 +0,0 @@
package com.jiuyv.agile.data.database.cache;
import com.jiuyv.agile.data.database.DbMD5Util;
import java.util.Arrays;
/**
* SQL
*/
public interface SqlCache {
/**
* key
*/
default String buildSqlCacheKey(String sql, Object[] args) {
return DbMD5Util.encrypt(sql + ":" + Arrays.toString(args));
}
/**
*
* @param key key
* @param value
*/
void put(String key, Object value, long ttl);
/**
*
* @param key key
* @return
*/
<T> T get(String key);
/**
*
* @param key key
*/
void delete(String key);
}

@ -1,57 +0,0 @@
package com.jiuyv.agile.data.database.datasource;
import com.jiuyv.agile.data.database.*;
import com.jiuyv.agile.data.database.query.AbstractDbQueryFactory;
import com.jiuyv.agile.data.database.query.CacheDbQueryFactoryBean;
import com.zaxxer.hikari.HikariDataSource;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.util.StringUtils;
import javax.sql.DataSource;
public abstract class AbstractDataSourceFactory implements DataSourceFactory {
@Override
public DbQuery createDbQuery(DbQueryProperty property) {
property.viald();
DbType dbType = DbType.getDbType(property.getDbType());
DataSource dataSource = createDataSource(property);
DbQuery dbQuery = createDbQuery(dataSource, dbType);
return dbQuery;
}
public DbQuery createDbQuery(DataSource dataSource, DbType dbType) {
DbDialect dbDialect = DialectFactory.getDialect(dbType);
if(dbDialect == null){
throw new RuntimeException("该数据库类型正在开发中");
}
AbstractDbQueryFactory dbQuery = new CacheDbQueryFactoryBean();
dbQuery.setDataSource(dataSource);
dbQuery.setJdbcTemplate(new JdbcTemplate(dataSource));
dbQuery.setDbDialect(dbDialect);
return dbQuery;
}
public DataSource createDataSource(DbQueryProperty property) {
HikariDataSource dataSource = new HikariDataSource();
dataSource.setJdbcUrl(trainToJdbcUrl(property));
dataSource.setUsername(property.getUsername());
dataSource.setPassword(property.getPassword());
return dataSource;
}
protected String trainToJdbcUrl(DbQueryProperty property) {
String url = DbType.getDbType(property.getDbType()).getUrl();
if (StringUtils.isEmpty(url)) {
throw new RuntimeException("无效数据库类型!");
}
url = url.replace("${host}", property.getHost());
url = url.replace("${port}", String.valueOf(property.getPort()));
if (DbType.ORACLE.getDb().equals(property.getDbType()) || DbType.ORACLE_12C.getDb().equals(property.getDbType())) {
url = url.replace("${sid}", property.getSid());
} else {
url = url.replace("${dbName}", property.getDbName());
}
return url;
}
}

@ -1,63 +0,0 @@
package com.jiuyv.agile.data.database.datasource;
import com.jiuyv.agile.data.database.DbQueryProperty;
import org.springframework.stereotype.Component;
import javax.sql.DataSource;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
@Component
public class CacheDataSourceFactoryBean extends AbstractDataSourceFactory {
/**
*
*/
private static Map<String, DataSource> dataSourceMap = new ConcurrentHashMap<>();
@Override
public DataSource createDataSource(DbQueryProperty property) {
String key = property.getHost() + ":" + property.getPort() + ":" + property.getUsername() + ":" + property.getDbName();
String s = compress(key);
DataSource dataSource = dataSourceMap.get(s);
if (null == dataSource) {
synchronized (CacheDataSourceFactoryBean.class) {
dataSource = super.createDataSource(property);
dataSourceMap.put(s, dataSource);
}
}
return dataSource;
}
// 压缩
public static String compress(String str) {
if (str == null || str.length() == 0) {
return str;
}
MessageDigest md = null;
try {
md = MessageDigest.getInstance("MD5");
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
if (md != null) {
md.update(str.getBytes());
byte[] b = md.digest();
int i;
StringBuffer buf = new StringBuffer();
for (byte value : b) {
i = value;
if (i < 0)
i += 256;
if (i < 16)
buf.append("0");
buf.append(Integer.toHexString(i));
}
str = buf.toString().substring(8, 24).toUpperCase();
}
return str;
}
}

@ -1,4 +0,0 @@
package com.jiuyv.agile.data.database.datasource;
public class DefaultDataSourceFactoryBean extends AbstractDataSourceFactory{
}

@ -1,34 +0,0 @@
package com.jiuyv.agile.data.database.dialect;
import com.jiuyv.agile.data.database.DbDialect;
/**
*
*/
public abstract class AbstractDbDialect implements DbDialect {
@Override
public String columns(String dbName, String tableName) {
return "select column_name AS COLNAME, ordinal_position AS COLPOSITION, column_default AS DATADEFAULT, is_nullable AS NULLABLE, data_type AS DATATYPE, " +
"character_maximum_length AS DATALENGTH, numeric_precision AS DATAPRECISION, numeric_scale AS DATASCALE, column_key AS COLKEY, column_comment AS COLCOMMENT " +
"from information_schema.columns where table_schema = '" + dbName + "' and table_name = '" + tableName + "' order by ordinal_position ";
}
@Override
public String tables(String dbName) {
return "SELECT table_name AS TABLENAME, table_comment AS TABLECOMMENT FROM information_schema.tables where table_schema = '" + dbName + "' ";
}
@Override
public String buildPaginationSql(String originalSql, long offset, long count) {
// 获取 分页实际条数
StringBuilder sqlBuilder = new StringBuilder(originalSql);
sqlBuilder.append(" LIMIT ").append(offset).append(" , ").append(count);
return sqlBuilder.toString();
}
@Override
public String count(String sql) {
return "SELECT COUNT(*) FROM ( " + sql + " ) TEMP";
}
}

@ -1,27 +0,0 @@
package com.jiuyv.agile.data.database.dialect;
import com.jiuyv.agile.data.database.DbDialect;
import com.jiuyv.agile.data.database.DbType;
import java.util.EnumMap;
import java.util.Map;
public class DialectRegistry {
private final Map<DbType, DbDialect> dialect_enum_map = new EnumMap<>(DbType.class);
public DialectRegistry() {
dialect_enum_map.put(DbType.MARIADB, new MariaDBDialect());
dialect_enum_map.put(DbType.MYSQL, new MySqlDialect());
dialect_enum_map.put(DbType.ORACLE_12C, new Oracle12cDialect());
dialect_enum_map.put(DbType.ORACLE, new OracleDialect());
dialect_enum_map.put(DbType.POSTGRE_SQL, new PostgreDialect());
dialect_enum_map.put(DbType.SQL_SERVER2008, new SQLServer2008Dialect());
dialect_enum_map.put(DbType.SQL_SERVER, new SQLServerDialect());
dialect_enum_map.put(DbType.OTHER, new UnknownDialect());
}
public DbDialect getDialect(DbType dbType) {
return dialect_enum_map.get(dbType);
}
}

@ -1,7 +0,0 @@
package com.jiuyv.agile.data.database.dialect;
/**
* MariaDB
*/
public class MariaDBDialect extends MySqlDialect {
}

@ -1,41 +0,0 @@
package com.jiuyv.agile.data.database.dialect;
import com.jiuyv.agile.data.database.DbColumn;
import com.jiuyv.agile.data.database.DbTable;
import org.springframework.jdbc.core.RowMapper;
import java.sql.ResultSet;
/**
* MySql
*/
public class MySqlDialect extends AbstractDbDialect {
@Override
public RowMapper<DbColumn> columnMapper() {
return (ResultSet rs, int rowNum) -> {
DbColumn entity = new DbColumn();
entity.setColName(rs.getString("COLNAME"));
entity.setDataType(rs.getString("DATATYPE"));
entity.setDataLength(rs.getString("DATALENGTH"));
entity.setDataPrecision(rs.getString("DATAPRECISION"));
entity.setDataScale(rs.getString("DATASCALE"));
entity.setColKey("PRI".equals(rs.getString("COLKEY")) ? true : false);
entity.setNullable("YES".equals(rs.getString("NULLABLE")) ? true : false);
entity.setColPosition(rs.getInt("COLPOSITION"));
entity.setDataDefault(rs.getString("DATADEFAULT"));
entity.setColComment(rs.getString("COLCOMMENT"));
return entity;
};
}
@Override
public RowMapper<DbTable> tableMapper() {
return (ResultSet rs, int rowNum) -> {
DbTable entity = new DbTable();
entity.setTableName(rs.getString("TABLENAME"));
entity.setTableComment(rs.getString("TABLECOMMENT"));
return entity;
};
}
}

@ -1,14 +0,0 @@
package com.jiuyv.agile.data.database.dialect;
/**
* ORACLE Oracle12c+
*/
public class Oracle12cDialect extends OracleDialect {
@Override
public String buildPaginationSql(String originalSql, long offset, long count) {
StringBuilder sqlBuilder = new StringBuilder(originalSql);
sqlBuilder.append(" OFFSET ").append(offset).append(" ROWS FETCH NEXT ").append(count).append(" ROWS ONLY ");
return sqlBuilder.toString();
}
}

@ -1,69 +0,0 @@
package com.jiuyv.agile.data.database.dialect;
import com.jiuyv.agile.data.database.DbColumn;
import com.jiuyv.agile.data.database.DbTable;
import org.springframework.jdbc.core.RowMapper;
import java.sql.ResultSet;
/**
* Oracle Oracle11g
*/
public class OracleDialect extends AbstractDbDialect {
@Override
public String columns(String dbName, String tableName) {
return "select columns.column_name AS colName, columns.data_type AS DATATYPE, columns.data_length AS DATALENGTH, columns.data_precision AS DATAPRECISION, " +
"columns.data_scale AS DATASCALE, columns.nullable AS NULLABLE, columns.column_id AS COLPOSITION, columns.data_default AS DATADEFAULT, comments.comments AS COLCOMMENT," +
"case when t.column_name is null then 0 else 1 end as COLKEY " +
"from sys.user_tab_columns columns LEFT JOIN sys.user_col_comments comments ON columns.table_name = comments.table_name AND columns.column_name = comments.column_name " +
"left join ( " +
"select col.column_name as column_name, con.table_name as table_name from user_constraints con, user_cons_columns col " +
"where con.constraint_name = col.constraint_name and con.constraint_type = 'P' " +
") t on t.table_name = columns.table_name and columns.column_name = t.column_name " +
"where columns.table_name = UPPER('" + tableName + "') order by columns.column_id ";
}
@Override
public String tables(String dbName) {
return "select tables.table_name AS TABLENAME, comments.comments AS TABLECOMMENT from sys.user_tables tables " +
"LEFT JOIN sys.user_tab_comments comments ON tables.table_name = comments.table_name ";
}
@Override
public String buildPaginationSql(String originalSql, long offset, long count) {
StringBuilder sqlBuilder = new StringBuilder();
sqlBuilder.append("SELECT * FROM ( SELECT TMP.*, ROWNUM ROW_ID FROM ( ");
sqlBuilder.append(originalSql).append(" ) TMP WHERE ROWNUM <=").append((offset >= 1) ? (offset + count) : count);
sqlBuilder.append(") WHERE ROW_ID > ").append(offset);
return sqlBuilder.toString();
}
@Override
public RowMapper<DbColumn> columnMapper() {
return (ResultSet rs, int rowNum) -> {
DbColumn entity = new DbColumn();
entity.setColName(rs.getString("COLNAME"));
entity.setDataType(rs.getString("DATATYPE"));
entity.setDataLength(rs.getString("DATALENGTH"));
entity.setDataPrecision(rs.getString("DATAPRECISION"));
entity.setDataScale(rs.getString("DATASCALE"));
entity.setColKey("1".equals(rs.getString("COLKEY")) ? true : false);
entity.setNullable("Y".equals(rs.getString("NULLABLE")) ? true : false);
entity.setColPosition(rs.getInt("COLPOSITION"));
entity.setDataDefault(rs.getString("DATADEFAULT"));
entity.setColComment(rs.getString("COLCOMMENT"));
return entity;
};
}
@Override
public RowMapper<DbTable> tableMapper() {
return (ResultSet rs, int rowNum) -> {
DbTable entity = new DbTable();
entity.setTableName(rs.getString("TABLENAME"));
entity.setTableComment(rs.getString("TABLECOMMENT"));
return entity;
};
}
}

@ -1,68 +0,0 @@
package com.jiuyv.agile.data.database.dialect;
import com.jiuyv.agile.data.database.DbColumn;
import com.jiuyv.agile.data.database.DbTable;
import org.springframework.jdbc.core.RowMapper;
import java.sql.ResultSet;
/**
* Postgre
*/
public class PostgreDialect extends AbstractDbDialect {
@Override
public String columns(String dbName, String tableName) {
return "select col.column_name AS COLNAME, col.ordinal_position AS COLPOSITION, col.column_default AS DATADEFAULT, col.is_nullable AS NULLABLE, col.udt_name AS DATATYPE, " +
"col.character_maximum_length AS DATALENGTH, col.numeric_precision AS DATAPRECISION, col.numeric_scale AS DATASCALE, des.description AS COLCOMMENT, " +
"case when t.colname is null then 0 else 1 end as COLKEY " +
"from information_schema.columns col left join pg_description des on col.table_name::regclass = des.objoid and col.ordinal_position = des.objsubid " +
"left join ( " +
"select pg_attribute.attname as colname from pg_constraint inner join pg_class on pg_constraint.conrelid = pg_class.oid " +
"inner join pg_attribute on pg_attribute.attrelid = pg_class.oid and pg_attribute.attnum = any(pg_constraint.conkey) " +
"where pg_class.relname = '" + tableName + "' and pg_constraint.contype = 'p' " +
") t on t.colname = col.column_name " +
"where col.table_catalog = '" + dbName + "' and col.table_schema = 'public' and col.table_name = '" + tableName + "' order by col.ordinal_position ";
}
@Override
public String tables(String dbName) {
return "select relname AS TABLENAME, cast(obj_description(relfilenode, 'pg_class') as varchar) AS TABLECOMMENT from pg_class " +
"where relname in (select tablename from pg_tables where schemaname = 'public' and position('_2' in tablename) = 0) ";
}
@Override
public String buildPaginationSql(String originalSql, long offset, long count) {
StringBuilder sqlBuilder = new StringBuilder(originalSql);
sqlBuilder.append(" LIMIT ").append(count).append(" offset ").append(offset);
return sqlBuilder.toString();
}
@Override
public RowMapper<DbColumn> columnMapper() {
return (ResultSet rs, int rowNum) -> {
DbColumn entity = new DbColumn();
entity.setColName(rs.getString("COLNAME"));
entity.setDataType(rs.getString("DATATYPE"));
entity.setDataLength(rs.getString("DATALENGTH"));
entity.setDataPrecision(rs.getString("DATAPRECISION"));
entity.setDataScale(rs.getString("DATASCALE"));
entity.setColKey("1".equals(rs.getString("COLKEY")) ? true : false);
entity.setNullable("YES".equals(rs.getString("NULLABLE")) ? true : false);
entity.setColPosition(rs.getInt("COLPOSITION"));
entity.setDataDefault(rs.getString("DATADEFAULT"));
entity.setColComment(rs.getString("COLCOMMENT"));
return entity;
};
}
@Override
public RowMapper<DbTable> tableMapper() {
return (ResultSet rs, int rowNum) -> {
DbTable entity = new DbTable();
entity.setTableName(rs.getString("TABLENAME"));
entity.setTableComment(rs.getString("TABLECOMMENT"));
return entity;
};
}
}

@ -1,102 +0,0 @@
package com.jiuyv.agile.data.database.dialect;
import com.jiuyv.agile.data.database.DbColumn;
import com.jiuyv.agile.data.database.DbTable;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.util.StringUtils;
import java.sql.ResultSet;
/**
* SQLServer 2005
*/
public class SQLServer2008Dialect extends AbstractDbDialect {
@Override
public String columns(String dbName, String tableName) {
return "select columns.name AS colName, columns.column_id AS COLPOSITION, columns.max_length AS DATALENGTH, columns.precision AS DATAPRECISION, columns.scale AS DATASCALE, " +
"columns.is_nullable AS NULLABLE, types.name AS DATATYPE, CAST(ep.value AS NVARCHAR(128)) AS COLCOMMENT, e.text AS DATADEFAULT, " +
"(select top 1 ind.is_primary_key from sys.index_columns ic left join sys.indexes ind on ic.object_id = ind.object_id and ic.index_id = ind.index_id and ind.name like 'PK_%' where ic.object_id=columns.object_id and ic.column_id=columns.column_id) AS COLKEY " +
"from sys.columns columns LEFT JOIN sys.types types ON columns.system_type_id = types.system_type_id " +
"LEFT JOIN syscomments e ON columns.default_object_id= e.id " +
"LEFT JOIN sys.extended_properties ep ON ep.major_id = columns.object_id AND ep.minor_id = columns.column_id AND ep.name = 'MS_Description' " +
"where columns.object_id = object_id('" + tableName + "') order by columns.column_id ";
}
@Override
public String tables(String dbName) {
return "select tables.name AS TABLENAME, CAST(ep.value AS NVARCHAR(128)) AS TABLECOMMENT " +
"from sys.tables tables LEFT JOIN sys.extended_properties ep ON ep.major_id = tables.object_id AND ep.minor_id = 0";
}
private static String getOrderByPart(String sql) {
String loweredString = sql.toLowerCase();
int orderByIndex = loweredString.indexOf("order by");
if (orderByIndex != -1) {
return sql.substring(orderByIndex);
} else {
return "";
}
}
@Override
public String buildPaginationSql(String originalSql, long offset, long count) {
StringBuilder pagingBuilder = new StringBuilder();
String orderby = getOrderByPart(originalSql);
String distinctStr = "";
String loweredString = originalSql.toLowerCase();
String sqlPartString = originalSql;
if (loweredString.trim().startsWith("select")) {
int index = 6;
if (loweredString.startsWith("select distinct")) {
distinctStr = "DISTINCT ";
index = 15;
}
sqlPartString = sqlPartString.substring(index);
}
pagingBuilder.append(sqlPartString);
// if no ORDER BY is specified use fake ORDER BY field to avoid errors
if (StringUtils.isEmpty(orderby)) {
orderby = "ORDER BY CURRENT_TIMESTAMP";
}
StringBuilder sql = new StringBuilder();
sql.append("WITH selectTemp AS (SELECT ").append(distinctStr).append("TOP 100 PERCENT ")
.append(" ROW_NUMBER() OVER (").append(orderby).append(") as __row_number__, ").append(pagingBuilder)
.append(") SELECT * FROM selectTemp WHERE __row_number__ BETWEEN ")
//FIX#299原因mysql中limit 10(offset,size) 是从第10开始不包含10,而这里用的BETWEEN是两边都包含所以改为offset+1
.append(offset + 1)
.append(" AND ")
.append(offset + count).append(" ORDER BY __row_number__");
return sql.toString();
}
@Override
public RowMapper<DbColumn> columnMapper() {
return (ResultSet rs, int rowNum) -> {
DbColumn entity = new DbColumn();
entity.setColName(rs.getString("COLNAME"));
entity.setDataType(rs.getString("DATATYPE"));
entity.setDataLength(rs.getString("DATALENGTH"));
entity.setDataPrecision(rs.getString("DATAPRECISION"));
entity.setDataScale(rs.getString("DATASCALE"));
entity.setColKey("1".equals(rs.getString("COLKEY")) ? true : false);
entity.setNullable("1".equals(rs.getString("NULLABLE")) ? true : false);
entity.setColPosition(rs.getInt("COLPOSITION"));
entity.setDataDefault(rs.getString("DATADEFAULT"));
entity.setColComment(rs.getString("COLCOMMENT"));
return entity;
};
}
@Override
public RowMapper<DbTable> tableMapper() {
return (ResultSet rs, int rowNum) -> {
DbTable entity = new DbTable();
entity.setTableName(rs.getString("TABLENAME"));
entity.setTableComment(rs.getString("TABLECOMMENT"));
return entity;
};
}
}

@ -1,14 +0,0 @@
package com.jiuyv.agile.data.database.dialect;
/**
* SQLServer
*/
public class SQLServerDialect extends SQLServer2008Dialect {
@Override
public String buildPaginationSql(String originalSql, long offset, long count) {
StringBuilder sqlBuilder = new StringBuilder(originalSql);
sqlBuilder.append(" OFFSET ").append(offset).append(" ROWS FETCH NEXT ").append(count).append(" ROWS ONLY ");
return sqlBuilder.toString();
}
}

@ -1,41 +0,0 @@
package com.jiuyv.agile.data.database.dialect;
import com.jiuyv.agile.data.database.DbColumn;
import com.jiuyv.agile.data.database.DbTable;
import org.springframework.jdbc.core.RowMapper;
/**
*
*/
public class UnknownDialect extends AbstractDbDialect {
@Override
public String columns(String dbName, String tableName) {
throw new RuntimeException("不支持的数据库类型");
}
@Override
public String tables(String dbName) {
throw new RuntimeException("不支持的数据库类型");
}
@Override
public String buildPaginationSql(String sql, long offset, long count) {
throw new RuntimeException("不支持的数据库类型");
}
@Override
public String count(String sql) {
throw new RuntimeException("不支持的数据库类型");
}
@Override
public RowMapper<DbColumn> columnMapper() {
throw new RuntimeException("不支持的数据库类型");
}
@Override
public RowMapper<DbTable> tableMapper() {
throw new RuntimeException("不支持的数据库类型");
}
}

@ -1,134 +0,0 @@
package com.jiuyv.agile.data.database.query;
import com.jiuyv.agile.data.database.*;
import com.zaxxer.hikari.HikariDataSource;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
public abstract class AbstractDbQueryFactory implements DbQuery {
protected DataSource dataSource;
protected JdbcTemplate jdbcTemplate;
protected DbDialect dbDialect;
@Override
public Connection getConnection() {
try {
return dataSource.getConnection();
} catch (SQLException e) {
throw new RuntimeException("获取数据库连接出错");
}
}
@Override
public boolean valid() {
Connection conn = null;
try {
conn = dataSource.getConnection();
return conn.isValid(0);
} catch (SQLException e) {
throw new RuntimeException("检测连通性出错");
} finally {
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
throw new RuntimeException("关闭数据库连接出错");
}
}
}
}
@Override
public void close() {
if (dataSource instanceof HikariDataSource) {
((HikariDataSource) dataSource).close();
} else {
throw new RuntimeException("不合法数据源类型");
}
}
@Override
public List<DbColumn> getTableColumns(String dbName, String tableName) {
String sql = dbDialect.columns(dbName, tableName);
return jdbcTemplate.query(sql, dbDialect.columnMapper());
}
@Override
public List<DbTable> getTables(String dbName) {
String sql = dbDialect.tables(dbName);
return jdbcTemplate.query(sql, dbDialect.tableMapper());
}
@Override
public int count(String sql) {
return jdbcTemplate.queryForObject(dbDialect.count(sql), Integer.class);
}
@Override
public int count(String sql, Object[] args) {
return jdbcTemplate.queryForObject(dbDialect.count(sql), args, Integer.class);
}
@Override
public int count(String sql, Map<String, Object> params) {
NamedParameterJdbcTemplate namedJdbcTemplate = new NamedParameterJdbcTemplate(jdbcTemplate);
return namedJdbcTemplate.queryForObject(dbDialect.count(sql), params, Integer.class);
}
@Override
public List<Map<String, Object>> queryList(String sql) {
return jdbcTemplate.queryForList(sql);
}
@Override
public List<Map<String, Object>> queryList(String sql, Object[] args) {
return jdbcTemplate.queryForList(sql, args);
}
@Override
public PageResult<Map<String, Object>> queryByPage(String sql, long offset, long size) {
int total = count(sql);
String pageSql = dbDialect.buildPaginationSql(sql, offset, size);
List<Map<String, Object>> records = jdbcTemplate.queryForList(pageSql);
return new PageResult<>(total, records);
}
@Override
public PageResult<Map<String, Object>> queryByPage(String sql, Object[] args, long offset, long size) {
int total = count(sql, args);
String pageSql = dbDialect.buildPaginationSql(sql, offset, size);
List<Map<String, Object>> records = jdbcTemplate.queryForList(pageSql, args);
return new PageResult<>(total, records);
}
@Override
public PageResult<Map<String, Object>> queryByPage(String sql, Map<String, Object> params, long offset, long size) {
int total = count(sql, params);
String pageSql = dbDialect.buildPaginationSql(sql, offset, size);
NamedParameterJdbcTemplate namedJdbcTemplate = new NamedParameterJdbcTemplate(jdbcTemplate);
List<Map<String, Object>> records = namedJdbcTemplate.queryForList(pageSql, params);
return new PageResult<>(total, records);
}
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
public void setDbDialect(DbDialect dbDialect) {
this.dbDialect = dbDialect;
}
}

@ -1,105 +0,0 @@
package com.jiuyv.agile.data.database.query;
import com.jiuyv.agile.data.database.DbColumn;
import com.jiuyv.agile.data.database.DbTable;
import com.jiuyv.agile.data.database.PageResult;
import com.jiuyv.agile.data.database.cache.DefaultSqlCache;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Optional;
public class CacheDbQueryFactoryBean extends AbstractDbQueryFactory {
/**
* 5
*/
private static long DEFAULT_EXPIRE = 5 * 60 * 1000;
private static DefaultSqlCache sqlCache = new DefaultSqlCache(100, DEFAULT_EXPIRE);
private <T> T putCacheValue(String key, T value, long ttl) {
sqlCache.put(key, value, ttl);
return value;
}
@Override
public List<DbColumn> getTableColumns(String dbName, String tableName) {
Object[] args = new Object[]{dbName, tableName};
Optional<Object> o = Optional.ofNullable(sqlCache.get(sqlCache.buildSqlCacheKey(super.dataSource.toString() + ":getTableColumns", args)));
return super.getTableColumns(dbName, tableName);
}
@Override
public List<DbTable> getTables(String dbName) {
Object[] args = new Object[]{dbName};
String cacheKey = sqlCache.buildSqlCacheKey(super.dataSource.toString() + ":getTables", args);
return (List<DbTable>) Optional.ofNullable(sqlCache.get(cacheKey))
.orElse(putCacheValue(cacheKey, super.getTables(dbName), DEFAULT_EXPIRE));
}
@Override
public int count(String sql) {
String cacheKey = sqlCache.buildSqlCacheKey(super.dataSource.toString() + ":" + sql, null);
return (int) Optional.ofNullable(sqlCache.get(cacheKey))
.orElse(putCacheValue(cacheKey, super.count(sql), DEFAULT_EXPIRE));
}
@Override
public int count(String sql, Object[] args) {
String cacheKey = sqlCache.buildSqlCacheKey(super.dataSource.toString() + ":" + sql, args);
return (int) Optional.ofNullable(sqlCache.get(cacheKey))
.orElse(putCacheValue(cacheKey, super.count(sql, args), DEFAULT_EXPIRE));
}
@Override
public int count(String sql, Map<String, Object> params) {
String cacheKey = sqlCache.buildSqlCacheKey(super.dataSource.toString() + ":" + sql, params.values().toArray());
return (int) Optional.ofNullable(sqlCache.get(cacheKey))
.orElse(putCacheValue(cacheKey, super.count(sql, params), DEFAULT_EXPIRE));
}
@Override
public List<Map<String, Object>> queryList(String sql) {
String cacheKey = sqlCache.buildSqlCacheKey(super.dataSource.toString() + ":" + sql, null);
return (List<Map<String, Object>>) Optional.ofNullable(sqlCache.get(cacheKey))
.orElse(putCacheValue(cacheKey, super.queryList(sql), DEFAULT_EXPIRE));
}
@Override
public List<Map<String, Object>> queryList(String sql, Object[] args) {
String cacheKey = sqlCache.buildSqlCacheKey(super.dataSource.toString() + ":" + sql, args);
return (List<Map<String, Object>>) Optional.ofNullable(sqlCache.get(cacheKey))
.orElse(putCacheValue(cacheKey, super.queryList(sql, args), DEFAULT_EXPIRE));
}
@Override
public PageResult<Map<String, Object>> queryByPage(String sql, long offset, long size) {
Object[] args = new Object[]{offset, size};
String cacheKey = sqlCache.buildSqlCacheKey(super.dataSource.toString() + ":" + sql, args);
return (PageResult<Map<String, Object>>) Optional.ofNullable(sqlCache.get(cacheKey))
.orElse(putCacheValue(cacheKey, super.queryByPage(sql, offset, size), DEFAULT_EXPIRE));
}
@Override
public PageResult<Map<String, Object>> queryByPage(String sql, Object[] args, long offset, long size) {
Object[] objects = Arrays.copyOf(args, args.length + 2);
objects[args.length] = offset;
objects[args.length + 1] = size;
String cacheKey = sqlCache.buildSqlCacheKey(super.dataSource.toString() + ":" + sql, objects);
return (PageResult<Map<String, Object>>) Optional.ofNullable(sqlCache.get(cacheKey))
.orElse(putCacheValue(cacheKey, super.queryByPage(sql, args, offset, size), DEFAULT_EXPIRE));
}
@Override
public PageResult<Map<String, Object>> queryByPage(String sql, Map<String, Object> params, long offset, long size) {
Object[] args = params.values().toArray();
Object[] objects = Arrays.copyOf(args, args.length + 2);
objects[args.length] = offset;
objects[args.length + 1] = size;
String cacheKey = sqlCache.buildSqlCacheKey(super.dataSource.toString() + ":" + sql, objects);
return (PageResult<Map<String, Object>>) Optional.ofNullable(sqlCache.get(cacheKey))
.orElse(putCacheValue(cacheKey, super.queryByPage(sql, params, offset, size), DEFAULT_EXPIRE));
}
}

@ -1,8 +0,0 @@
package com.jiuyv.agile.data.factory;
import com.jiuyv.agile.data.factory.crypto.Crypto;
public abstract class AbstractFactory {
public abstract Crypto getCrypto(String type);
}

@ -1,16 +0,0 @@
package com.jiuyv.agile.data.factory;
import com.jiuyv.agile.data.dto.enums.AlgorithmCrypto;
import com.jiuyv.agile.data.factory.crypto.AlgorithmRegistry;
import com.jiuyv.agile.data.factory.crypto.Crypto;
public class AlgorithmFactory extends AbstractFactory {
private static final AlgorithmRegistry ALGORITHM_REGISTRY = new AlgorithmRegistry();
@Override
public Crypto getCrypto(String type) {
AlgorithmCrypto crypto = AlgorithmCrypto.getAlgorithmCrypto(type);
return ALGORITHM_REGISTRY.getAlgorithm(crypto);
}
}

@ -1,17 +0,0 @@
package com.jiuyv.agile.data.factory;
import com.jiuyv.agile.data.dto.enums.CipherType;
public class FactoryProducer {
public static AbstractFactory getFactory(String type){
CipherType cipherType = CipherType.getCipherType(type);
switch (cipherType) {
case REGEX:
return new RegexFactory();
case ALGORITHM:
return new AlgorithmFactory();
}
return null;
}
}

@ -1,16 +0,0 @@
package com.jiuyv.agile.data.factory;
import com.jiuyv.agile.data.dto.enums.RegexCrypto;
import com.jiuyv.agile.data.factory.crypto.Crypto;
import com.jiuyv.agile.data.factory.crypto.RegexRegistry;
public class RegexFactory extends AbstractFactory {
private static final RegexRegistry REGEX_REGISTRY = new RegexRegistry();
@Override
public Crypto getCrypto(String type) {
RegexCrypto crypto = RegexCrypto.getRegexCrypto(type);
return REGEX_REGISTRY.getRegex(crypto);
}
}

@ -1,22 +0,0 @@
package com.jiuyv.agile.data.factory.crypto;
import org.apache.commons.lang3.StringUtils;
/**
* [] <****>
*/
public class ADDRESSCrypto implements Crypto {
@Override
public String encrypt(String content) {
if (StringUtils.isBlank(content)) {
return null;
}
return StringUtils.rightPad(StringUtils.left(content, 6), StringUtils.length(content), "*");
}
@Override
public String decrypt(String content) {
return null;
}
}

@ -1,72 +0,0 @@
package com.jiuyv.agile.data.factory.crypto;
import org.apache.commons.lang3.StringUtils;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.security.SecureRandom;
import java.util.Base64;
public class AESCrypto implements Crypto {
@Override
public String encrypt(String content) {
if (StringUtils.isBlank(content)) {
return null;
}
try {
//1.构造密钥生成器指定为AES算法,不区分大小写
KeyGenerator kGen = KeyGenerator.getInstance("AES");
//2.根据 RULES 规则初始化密钥生成器根据传入的字节数组生成一个128位的随机源
kGen.init(128, new SecureRandom(SLAT.getBytes(CHARSET_UTF8)));
//3.产生原始对称密钥
SecretKey secretKey = kGen.generateKey();
//4.获得原始对称密钥的字节数组
byte[] enCodeFormat = secretKey.getEncoded();
//5.根据字节数组生成AES密钥
SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
//6.根据指定算法AES生成密码器
Cipher cipher = Cipher.getInstance("AES");
//7.初始化密码器,第一个参数为加密(Encrypt_mode)或者解密解密(Decrypt_mode)操作第二个参数为使用的KEY
cipher.init(Cipher.ENCRYPT_MODE, key);
//8.根据密码器的初始化方式--加密:将数据加密
byte[] AES_encrypt = cipher.doFinal(content.getBytes(CHARSET_UTF8));
//9.将字符串返回
return Base64.getEncoder().encodeToString(AES_encrypt);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
@Override
public String decrypt(String content) {
if (StringUtils.isBlank(content)) {
return null;
}
try {
//1.构造密钥生成器指定为AES算法,不区分大小写
KeyGenerator kGen = KeyGenerator.getInstance("AES");
//2.根据 RULES 规则初始化密钥生成器根据传入的字节数组生成一个128位的随机源
kGen.init(128, new SecureRandom(SLAT.getBytes(CHARSET_UTF8)));
//3.产生原始对称密钥
SecretKey secretKey = kGen.generateKey();
//4.获得原始对称密钥的字节数组
byte[] enCodeFormat = secretKey.getEncoded();
//5.根据字节数组生成AES密钥
SecretKeySpec key = new SecretKeySpec(enCodeFormat, "AES");
//6.根据指定算法AES生成密码器
Cipher cipher = Cipher.getInstance("AES");
//7.初始化密码器,第一个参数为加密(Encrypt_mode)或者解密解密(Decrypt_mode)操作第二个参数为使用的KEY
cipher.init(Cipher.DECRYPT_MODE, key);// 初始化
//8.根据密码器的初始化方式--加密:将数据加密
byte[] AES_decode = cipher.doFinal(Base64.getDecoder().decode(content));
return new String(AES_decode, CHARSET_UTF8);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}

@ -1,24 +0,0 @@
package com.jiuyv.agile.data.factory.crypto;
import com.jiuyv.agile.data.dto.enums.AlgorithmCrypto;
import java.util.EnumMap;
import java.util.Map;
public class AlgorithmRegistry {
private final Map<AlgorithmCrypto, Crypto> algorithm_enum_map = new EnumMap<>(AlgorithmCrypto.class);
public AlgorithmRegistry() {
algorithm_enum_map.put(AlgorithmCrypto.BASE64, new BASE64Crypto());
algorithm_enum_map.put(AlgorithmCrypto.AES, new AESCrypto());
algorithm_enum_map.put(AlgorithmCrypto.DES, new DESCrypto());
algorithm_enum_map.put(AlgorithmCrypto.MD5, new MD5Crypto());
algorithm_enum_map.put(AlgorithmCrypto.SHA_1, new SHA1Crypto());
algorithm_enum_map.put(AlgorithmCrypto.SHA_256, new SHA256Crypto());
}
public Crypto getAlgorithm(AlgorithmCrypto crypto) {
return algorithm_enum_map.get(crypto);
}
}

@ -1,22 +0,0 @@
package com.jiuyv.agile.data.factory.crypto;
import org.apache.commons.lang3.StringUtils;
/**
* [] 1<:6222600**********1234>
*/
public class BANKCARDCrypto implements Crypto {
@Override
public String encrypt(String content) {
if (StringUtils.isBlank(content)) {
return null;
}
return StringUtils.left(content, 6).concat(StringUtils.removeStart(StringUtils.leftPad(StringUtils.right(content, 4), StringUtils.length(content), "*"), "******"));
}
@Override
public String decrypt(String content) {
return null;
}
}

@ -1,34 +0,0 @@
package com.jiuyv.agile.data.factory.crypto;
import org.apache.commons.lang3.StringUtils;
import java.util.Base64;
public class BASE64Crypto implements Crypto {
@Override
public String encrypt(String content) {
if (StringUtils.isBlank(content)) {
return null;
}
try {
byte[] encode = Base64.getEncoder().encode(content.getBytes(CHARSET_UTF8));
return new String(encode, CHARSET_UTF8);
} catch (Exception e) {
}
return null;
}
@Override
public String decrypt(String content) {
if (StringUtils.isBlank(content)) {
return null;
}
try {
byte[] decode = Base64.getDecoder().decode(content.getBytes(CHARSET_UTF8));
return new String(decode, CHARSET_UTF8);
} catch (Exception e) {
}
return null;
}
}

@ -1,22 +0,0 @@
package com.jiuyv.agile.data.factory.crypto;
import org.apache.commons.lang3.StringUtils;
/**
* [] <**>
*/
public class CHINESENAMECrypto implements Crypto {
@Override
public String encrypt(String content) {
if (StringUtils.isBlank(content)) {
return null;
}
return StringUtils.rightPad(StringUtils.left(content, 1), StringUtils.length(content), "*");
}
@Override
public String decrypt(String content) {
return null;
}
}

@ -1,22 +0,0 @@
package com.jiuyv.agile.data.factory.crypto;
import org.apache.commons.lang3.StringUtils;
/**
* [] ,1<:1234********>
*/
public class CNAPSCODECrypto implements Crypto {
@Override
public String encrypt(String content) {
if (StringUtils.isBlank(content)) {
return null;
}
return StringUtils.rightPad(StringUtils.left(content, 4), StringUtils.length(content), "*");
}
@Override
public String decrypt(String content) {
return null;
}
}

@ -1,17 +0,0 @@
package com.jiuyv.agile.data.factory.crypto;
public interface Crypto {
/**
*
*/
String CHARSET_UTF8 = "UTF-8";
/**
*
*/
String SLAT = "DATAX:20200101";
String encrypt(String content);
String decrypt(String content);
}

@ -1,54 +0,0 @@
package com.jiuyv.agile.data.factory.crypto;
import org.apache.commons.lang3.StringUtils;
import javax.crypto.Cipher;
import javax.crypto.KeyGenerator;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.security.SecureRandom;
import java.util.Base64;
public class DESCrypto implements Crypto {
@Override
public String encrypt(String content) {
if (StringUtils.isBlank(content)) {
return null;
}
try {
KeyGenerator kGen = KeyGenerator.getInstance("DES");
kGen.init(56, new SecureRandom(SLAT.getBytes(CHARSET_UTF8)));
SecretKey secretKey = kGen.generateKey();
byte[] enCodeFormat = secretKey.getEncoded();
SecretKeySpec key = new SecretKeySpec(enCodeFormat, "DES");
Cipher cipher = Cipher.getInstance("DES");
cipher.init(Cipher.ENCRYPT_MODE, key);
byte[] DES_encrypt = cipher.doFinal(content.getBytes(CHARSET_UTF8));
return Base64.getEncoder().encodeToString(DES_encrypt);
} catch (Exception e) {
}
return null;
}
@Override
public String decrypt(String content) {
if (StringUtils.isBlank(content)) {
return null;
}
try {
KeyGenerator kGen = KeyGenerator.getInstance("DES");
kGen.init(56, new SecureRandom(SLAT.getBytes(CHARSET_UTF8)));
SecretKey secretKey = kGen.generateKey();
byte[] enCodeFormat = secretKey.getEncoded();
SecretKeySpec key = new SecretKeySpec(enCodeFormat, "DES");
Cipher cipher = Cipher.getInstance("DES");
cipher.init(Cipher.DECRYPT_MODE, key);
byte[] DES_decrypt = cipher.doFinal(Base64.getDecoder().decode(content));
return new String(DES_decrypt, CHARSET_UTF8);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}

@ -1,22 +0,0 @@
package com.jiuyv.agile.data.factory.crypto;
import org.apache.commons.lang3.StringUtils;
/**
* [] <312****@qq.com>
*/
public class EMAILCrypto implements Crypto {
@Override
public String encrypt(String content) {
if (StringUtils.isBlank(content)) {
return null;
}
return content.replaceAll("(\\w{3}).*@(\\w+)", "$1****@$2");
}
@Override
public String decrypt(String content) {
return null;
}
}

@ -1,22 +0,0 @@
package com.jiuyv.agile.data.factory.crypto;
import org.apache.commons.lang3.StringUtils;
/**
* [] <****1234>
*/
public class FIXEDPHONECrypto implements Crypto {
@Override
public String encrypt(String content) {
if (StringUtils.isBlank(content)) {
return null;
}
return StringUtils.leftPad(StringUtils.right(content, 4), StringUtils.length(content), "*");
}
@Override
public String decrypt(String content) {
return null;
}
}

@ -1,22 +0,0 @@
package com.jiuyv.agile.data.factory.crypto;
import org.apache.commons.lang3.StringUtils;
/**
* [] 1815<*************5762>
*/
public class IDCARDCrypto implements Crypto {
@Override
public String encrypt(String content) {
if (StringUtils.isBlank(content)) {
return null;
}
return StringUtils.leftPad(StringUtils.right(content, 4), StringUtils.length(content), "*");
}
@Override
public String decrypt(String content) {
return null;
}
}

@ -1,32 +0,0 @@
package com.jiuyv.agile.data.factory.crypto;
import org.apache.commons.lang3.StringUtils;
import java.security.MessageDigest;
import java.util.Base64;
public class MD5Crypto implements Crypto {
@Override
public String encrypt(String content) {
if (StringUtils.isBlank(content)) {
return null;
}
MessageDigest md5 = null;
try {
md5 = MessageDigest.getInstance("MD5");
md5.update(content.getBytes(CHARSET_UTF8));
md5.update(SLAT.getBytes(CHARSET_UTF8));
} catch (Exception ignored) {
}
if (md5 != null) {
return Base64.getEncoder().encodeToString(md5.digest());
}
return null;
}
@Override
public String decrypt(String content) {
return null;
}
}

@ -1,22 +0,0 @@
package com.jiuyv.agile.data.factory.crypto;
import org.apache.commons.lang3.StringUtils;
/**
* [] <:138******1234>
*/
public class MOBILEPHONECrypto implements Crypto {
@Override
public String encrypt(String content) {
if (StringUtils.isBlank(content)) {
return null;
}
return StringUtils.left(content, 3).concat(StringUtils.removeStart(StringUtils.leftPad(StringUtils.right(content, 4), StringUtils.length(content), "*"), "***"));
}
@Override
public String decrypt(String content) {
return null;
}
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save