Compare commits

...

33 Commits
master ... dev

Author SHA1 Message Date
chao 9a59b495b4 feat() 规则级别 2024-05-12 22:41:55 +08:00
chao af247c3d7b feat() 连接池初版V1.1 2024-05-11 18:04:54 +08:00
chao 064873ecc7 feat() 连接池初版V1.1 2024-05-10 16:33:57 +08:00
chao c23040359e feat() 连接池初版V1.0 2024-05-10 14:24:50 +08:00
chao 12a0ec4ae1 refactor() 拆分数据源,规则引擎模块 三层框架 2024-05-09 09:45:17 +08:00
chao 0558149969 refactor() 拆分数据源,规则引擎模块 三层框架 2024-05-09 09:29:48 +08:00
chao dd456647dc feat() 规则维护页面,测试下拉框 2024-05-08 18:25:45 +08:00
chao c2f545cd33 feat() 规则维护页面,修改代码功能 2024-05-07 21:50:50 +08:00
chao 866b3835cb feat(): 规则维护页面,列表,添加功能 2024-05-07 21:18:36 +08:00
chao 4b62c4c7ab feat(): 引擎维护,规则维护,初始化,测试连接 2024-05-05 14:25:47 +08:00
chao 0f4b839193 feat(): 引擎维护初始化 2024-05-02 16:26:10 +08:00
chao 25da274496 feat(): 数据资产展示 2024-05-01 11:25:32 +08:00
chao 4c6a93683d feat(): 增加数据添加字典类型 2024-04-29 15:21:12 +08:00
chao 4a71865e3f feat(): 增加相关功能日志 2024-04-28 14:04:37 +08:00
chao 8fcbd510f7 feat(): 资产结构数据的数据字典 2024-04-28 08:38:31 +08:00
chao c66661c52c feat(): 资产模型基本信息 2024-04-26 15:20:04 +08:00
chao 8a897e1066 feat(): 增加异步同步 2024-04-26 10:36:04 +08:00
chao 48346981dc refactor(): 重构同步代码 2024-04-26 08:38:41 +08:00
chao 0e13e58058 style(): 增加打印日志 2024-04-25 18:24:51 +08:00
chao 3632f62a4e refactor(): 重构测试连接 2024-04-25 16:52:08 +08:00
chao 543a97c3ac refactor(): 重构测试连接 2024-04-25 15:50:22 +08:00
chao 1e1797f443 style(): 修改代码格式 2024-04-24 15:51:47 +08:00
chao d24a344ac4 feat(): 资产结构概述统计数量 2024-04-24 15:12:04 +08:00
chao e18623432a feat(): 数据同步,同步数据资产结构 2024-04-24 14:30:27 +08:00
chao a69644f0dd feat(): 整体数据资产结构概述 2024-04-23 17:31:01 +08:00
chao b89f10565f style(): 修改数据接入数据,同步数据不同步 2024-04-23 15:34:12 +08:00
chao 2101257954 fix(): 修改数据接入数据,同步数据不同步 2024-04-23 15:30:34 +08:00
chao bd68e9030f feat(): 资产结构树形结构 2024-04-22 19:04:15 +08:00
chao 9953c7c202 feat(): 数据同步 2024-04-22 20:01:18 +08:00
chao 41182d0a5d 测试连接完成,修改状态 2024-04-21 20:23:37 +08:00
chao 857423dcd9 优化 数据源,添加,修改,删除,测试连接 2024-04-21 19:34:31 +08:00
chao 1378c3f5e8 数据源,添加,修改,删除,测试连接 2024-04-21 17:01:17 +08:00
chao 03eecd791d 创建数据源模块 2024-04-20 20:04:31 +08:00
100 changed files with 5690 additions and 2 deletions

View File

@ -136,6 +136,16 @@
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>QLExpress</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -20,4 +20,9 @@ public class ServiceNameConstants {
* serviceid
*/
public static final String FILE_SERVICE = "etl-file";
/**
* serviceId
*/
public static final String DATA_SOURCE_SERVICE = "etl-data-source";
}

View File

@ -5,8 +5,7 @@ import org.springframework.cloud.openfeign.EnableFeignClients;
import java.lang.annotation.*;
/**
* feign
* basePackages
* feign basePackages
*
* @author Chao
*/

View File

@ -0,0 +1,38 @@
<?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>
<parent>
<groupId>com.etl</groupId>
<artifactId>etl-modules-data-source</artifactId>
<version>3.6.3</version>
</parent>
<artifactId>etl-modules-data-source-clinet</artifactId>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>com.etl</groupId>
<artifactId>etl-modules-data-source-remote</artifactId>
</dependency>
<!-- ETL Common DataSource -->
<dependency>
<groupId>com.etl</groupId>
<artifactId>etl-common-datasource</artifactId>
</dependency>
<!-- ETL Common DataScope -->
<dependency>
<groupId>com.etl</groupId>
<artifactId>etl-common-datascope</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,17 @@
package com.etl.data.source.clinet.config;
import org.springframework.context.annotation.Import;
import org.springframework.stereotype.Component;
/**
*
*
* @author Chao
* @ClassName: DataSourceClientConfig
* @CreateTime: 2024/5/9 9:58
*/
@Component
@Import(value = {DataSourceClientRunner.class})
public class DataSourceClientConfig {
}

View File

@ -0,0 +1,85 @@
package com.etl.data.source.clinet.config;
import com.etl.common.core.domain.Result;
import com.etl.data.source.clinet.test.DataSourceConfig;
import com.etl.data.source.clinet.test.Singleton;
import com.etl.data.source.domain.DataSource;
import com.etl.data.source.remote.DataSourceRemoteService;
import com.etl.data.type.domain.DataType;
import com.etl.data.type.remote.DataTypeRemoteService;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;
/**
*
*
* @author Chao
* @ClassName: DataSourceClientRunner
* @CreateTime: 2024/5/9 9:49
*/
@Log4j2
public class DataSourceClientRunner implements ApplicationRunner {
@Autowired
private DataSourceRemoteService dataSourceRemoteService;
@Autowired
private DataTypeRemoteService dataTypeRemoteService;
@Override
public void run(ApplicationArguments args) {
try {
Result<List<DataSource>> dataSourceResultList = dataSourceRemoteService.dataSourceList();
if (dataSourceResultList.getData() == null || dataSourceResultList.getData().isEmpty()) {
log.error("数据源列表为空");
return;
}
List<DataSource> dataSourceList = dataSourceResultList.getData();
log.info("数据源列表查询成功当前数据为{}", dataSourceList);
// 获取数据源类型列表
Result<List<DataType>> dataTypeResultList = dataTypeRemoteService.list();
if (dataTypeResultList.getData() == null || dataTypeResultList.getData().isEmpty()) {
log.error("数据源类型列表为空");
return;
}
List<DataType> dataTypeList = dataTypeResultList.getData();
log.info("数据源类型列表查询成功当前数据为{}", dataTypeList);
// 将数据源类型转换为Map ## Function.identity() 这个方法是返回一个自己
Map<Long, DataType> dataTypeMap = dataTypeList.stream()
.collect(
Collectors.toMap(
DataType::getId, Function.identity()
)
);
// 创建数据源Map
HashMap<String, javax.sql.DataSource> stringDataSourceHashMap = new HashMap<>();
// 遍历数据源列表
for (DataSource datum : dataSourceList) {
// 过滤相应的数据源类型
Optional<DataType> dataType = Optional.ofNullable(dataTypeMap.get(datum.getTypeId()));
if (dataType.isPresent()) {
javax.sql.DataSource dataSource = DataSourceConfig.dataSource(datum, dataType.get());
stringDataSourceHashMap.put(datum.getDataSourceIp() + "-" + datum.getDataSourceDatabaseName(), dataSource);
} else {
log.error("未找到数据源 ID 为 {} 的数据类型", datum.getTypeId());
}
Singleton instance = Singleton.getInstance(stringDataSourceHashMap);
Map<String, javax.sql.DataSource> map = instance.getMap();
log.info("数据源连接池初始化成功{}", map);
}
} catch (Exception e) {
log.error("初始化数据源连接池失败{}", e.getMessage());
throw new RuntimeException(e);
}
}
}

View File

@ -0,0 +1,36 @@
package com.etl.data.source.clinet.test;
import com.alibaba.druid.pool.DruidDataSource;
import com.etl.data.type.domain.DataType;
import javax.sql.DataSource;
/**
*
*
* @author Han
*/
public class DataSourceConfig {
public static DataSource dataSource(com.etl.data.source.domain.DataSource source , DataType dataType) {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setUsername(source.getDataSourceUsername());
dataSource.setPassword(source.getDataSourcePassword());
dataSource.setUrl(dataType.getJdbcPre()+source.getDataSourceIp()+":"+source.getDataSourcePort()+"/"+source.getDataSourceDatabaseName()+"?"+source.getAdditionalConfiguration());
dataSource.setDriverClassName(dataType.getDriverManager());
//初始化连接池时创建的连接数
dataSource.setInitialSize(Math.toIntExact(source.getInitialNumberOfConnections()));
//连接池最大活跃的连接数
dataSource.setMaxActive(Math.toIntExact(source.getMaximumNumberOfConnections()));
// 最大等待时间
dataSource.setMaxWait(source.getMaximumWaitingTime());
//连接池最小空闲的连接数
dataSource.setMinIdle(1);
return dataSource;
}
}

View File

@ -0,0 +1,47 @@
package com.etl.data.source.clinet.test;
import lombok.AllArgsConstructor;
import lombok.Data;
import javax.sql.DataSource;
import java.util.Map;
/**
*
*
* @author Han
*/
@Data
@AllArgsConstructor
public class Singleton {
//使用volatile修饰变量具有原子性、可见性和防止指令重排的特性。
private volatile Map<String, DataSource> map;
private volatile static Singleton singleton;
/**
* 使使volatile
*
* @param map map
* @return Singleton
*/
public static Singleton getInstance(Map<String, DataSource> map) {
//先进行实例判断,只有当不存在的时候才去创建实例。
if (singleton == null) {
//用synchronized 同步代码块
//注意此处不能用this因为this不能和static同用。
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton(map);
}
}
}
return singleton;
}
/**
* 使,
*/
private Singleton () {}
}

View File

@ -0,0 +1,27 @@
<?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>
<parent>
<groupId>com.etl</groupId>
<artifactId>etl-modules-data-source</artifactId>
<version>3.6.3</version>
</parent>
<artifactId>etl-modules-data-source-common</artifactId>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>com.etl</groupId>
<artifactId>etl-common-core</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,51 @@
package com.etl.data.dictionary.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.etl.common.core.web.domain.BaseEntity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
/**
*
* @author Chao
* @ClassName: Dictionary
* @CreateTime: 2024/4/27 9:07
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@SuperBuilder
@EqualsAndHashCode(callSuper = true)
@TableName("data_dictionary")
public class DataDictionary extends BaseEntity {
private static final long serialVersionUID = 1L;
/**
* id
*/
@TableId(value = "id", type = IdType.INPUT)
private Long id;
/**
*
* id
*/
private Long assetStructureId;
/**
*
*
*/
private String name;
/**
*
*
*/
private String type;
}

View File

@ -0,0 +1,50 @@
package com.etl.data.dictionary.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.etl.common.core.web.domain.BaseEntity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
/**
*
*
* @author Chao
* @ClassName: DataDictionaryType
* @CreateTime: 2024/4/27 9:55
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@SuperBuilder
@EqualsAndHashCode(callSuper = true)
@TableName("data_dictionary_type")
public class DataDictionaryType extends BaseEntity {
/**
* id
*/
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* id
*/
private Long dataDictionaryId;
/**
*
*/
private String label;
/**
*
*/
private String value;
}

View File

@ -0,0 +1,55 @@
package com.etl.data.dictionary.domain.resp;
import com.etl.data.dictionary.domain.DataDictionary;
import com.etl.data.dictionary.domain.DataDictionaryType;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
import java.util.List;
/**
*
*
* @author Chao
* @ClassName: DataDicitonaryResp
* @CreateTime: 2024/4/27 7:00
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@SuperBuilder
public class DataDictionaryResp {
private Long id;
/**
* id
*/
private Long assetStructureId;
/**
*
*/
private String name;
/**
*
*/
private String type;
/**
*
*/
private List<DataDictionaryType> dataDictionaryTypeList;
public static DataDictionaryResp dataDictionaryBuilder(DataDictionary dataDictionary, List<DataDictionaryType> dataDictionaryTypes) {
return DataDictionaryResp.builder()
.id(dataDictionary.getId())
.assetStructureId(dataDictionary.getAssetStructureId())
.name(dataDictionary.getName())
.type(dataDictionary.getType())
.dataDictionaryTypeList(dataDictionaryTypes)
.build();
}
}

View File

@ -0,0 +1,113 @@
package com.etl.data.source.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.etl.common.core.annotation.Excel;
import com.etl.common.core.web.domain.BaseEntity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
/**
* data_source
*
* @author Chao
* @date 2024-04-21
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@SuperBuilder
@EqualsAndHashCode(callSuper = true)
@TableName("data_source")
public class DataSource extends BaseEntity {
private static final long serialVersionUID = 1L;
/**
* id
*/
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
*
*/
@Excel(name = "数据源名称")
private String dataSourceName;
/**
*
*/
@Excel(name = "数据源系统名称")
private String dataSourceSystemName;
/**
*
*/
@Excel(name = "数据源类型")
private Long typeId;
/**
* ip
*/
@Excel(name = "数据源ip地址")
private String dataSourceIp;
/**
*
*/
@Excel(name = "端口号")
private String dataSourcePort;
/**
*
*/
@Excel(name = "连接数据库名称")
private String dataSourceDatabaseName;
/**
*
*/
private String dataSourceUsername;
/**
*
*/
private String dataSourcePassword;
/**
*
*/
private String additionalConfiguration;
/**
*
*/
@Excel(name = "状态")
private String status;
/**
*
*/
private Long initialNumberOfConnections;
/**
*
*/
private Long maximumNumberOfConnections;
/**
*
*/
private Long maximumWaitingTime;
/**
*
*/
private Long maximumWaitingTimes;
}

View File

@ -0,0 +1,147 @@
package com.etl.data.source.domain.resp;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.etl.common.core.annotation.Excel;
import com.etl.common.core.web.domain.BaseEntity;
import com.etl.data.source.domain.DataSource;
import com.etl.data.type.domain.DataType;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
/**
* data_source
*
* @author Chao
* @date 2024-04-21
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@SuperBuilder
@EqualsAndHashCode(callSuper = true)
@TableName("data_source")
public class DataSourceResp extends BaseEntity {
private static final long serialVersionUID = 1L;
/**
* id
*/
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
*
*/
@Excel(name = "数据源名称")
private String dataSourceName;
/**
*
*/
@Excel(name = "数据源系统名称")
private String dataSourceSystemName;
/**
*
*/
@Excel(name = "数据源类型")
private Long typeId;
@Excel(name = "数据源类型")
private String dataType;
/**
* ip
*/
@Excel(name = "数据源ip地址")
private String dataSourceIp;
/**
*
*/
@Excel(name = "端口号")
private String dataSourcePort;
/**
*
*/
@Excel(name = "连接数据库名称")
private String dataSourceDatabaseName;
/**
*
*/
@Excel(name = "用户名")
private String dataSourceUsername;
/**
*
*/
@Excel(name = "密码")
private String dataSourcePassword;
/**
*
*/
@Excel(name = "额外配置")
private String additionalConfiguration;
/**
*
*/
@Excel(name = "状态")
private String status;
/**
*
*/
@Excel(name = "初始化连接数量")
private Long initialNumberOfConnections;
/**
*
*/
@Excel(name = "最大连接数量")
private Long maximumNumberOfConnections;
/**
*
*/
@Excel(name = "最大等待时间")
private Long maximumWaitingTime;
/**
*
*/
@Excel(name = "最大等待次数")
private Long maximumWaitingTimes;
public static DataSourceResp dataSourceBuilder(DataSource source, DataType dataType) {
return DataSourceResp.builder()
.id(source.getId())
.dataSourceName(source.getDataSourceName())
.dataSourceSystemName(source.getDataSourceSystemName())
.typeId(source.getTypeId())
.dataType(dataType.getDataType())
.dataSourceIp(source.getDataSourceIp())
.dataSourcePort(source.getDataSourcePort())
.dataSourceDatabaseName(source.getDataSourceDatabaseName())
.dataSourceUsername(source.getDataSourceUsername())
.dataSourcePassword(source.getDataSourcePassword())
.additionalConfiguration(source.getAdditionalConfiguration())
.status(source.getStatus())
.initialNumberOfConnections(source.getInitialNumberOfConnections())
.maximumNumberOfConnections(source.getMaximumNumberOfConnections())
.maximumWaitingTime(source.getMaximumWaitingTime())
.maximumWaitingTimes(source.getMaximumWaitingTimes())
.remark(source.getRemark())
.build();
}
}

View File

@ -0,0 +1,73 @@
package com.etl.data.structure.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.etl.common.core.web.domain.BaseEntity;
import com.etl.data.source.domain.DataSource;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
/**
* asset_structure
*
* @author Chao
* @date 2024-04-22
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@SuperBuilder
@EqualsAndHashCode(callSuper = true)
@TableName("asset_structure")
public class AssetStructure extends BaseEntity {
private static final long serialVersionUID = 1L;
/**
* id
*/
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* id
*/
private Long dataSourceSystemId;
/**
*
*/
private String dataSourceName;
/**
*
*/
private String dataSourceSystemName;
/**
*
*/
private String dataSourceDatabaseName;
public static AssetStructure dataSourceSaveBuilder(Long id, DataSource dataSource) {
return AssetStructure.builder()
.dataSourceSystemId(id)
.dataSourceName(dataSource.getDataSourceName())
.dataSourceSystemName(dataSource.getDataSourceSystemName())
.dataSourceDatabaseName(dataSource.getDataSourceDatabaseName())
.build();
}
public static AssetStructure dataSourceUpdateBuilder(AssetStructure assetStructure, Long id, DataSource dataSource) {
return AssetStructure.builder()
.id(assetStructure.getId())
.dataSourceSystemId(id)
.dataSourceName(dataSource.getDataSourceName())
.dataSourceSystemName(dataSource.getDataSourceSystemName())
.dataSourceDatabaseName(dataSource.getDataSourceDatabaseName())
.build();
}
}

View File

@ -0,0 +1,58 @@
package com.etl.data.structure.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.etl.common.core.annotation.Excel;
import com.etl.common.core.web.domain.BaseEntity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
/**
* asset_structure_table
*
* @author Chao
* @date 2024-04-22
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@SuperBuilder
@EqualsAndHashCode(callSuper = true)
@TableName("asset_structure_table")
public class AssetStructureTable extends BaseEntity {
private static final long serialVersionUID = 1L;
/**
* id
*/
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* id
*/
@Excel(name = "数据资产id")
private Long assetStructureId;
/**
*
*/
@Excel(name = "数据资产表")
private String tableName;
/**
*
*/
@Excel(name = "表数据总数")
private Long tableDataCount;
/**
*
*/
@Excel(name = "表注释")
private String tableNameAnnotation;
}

View File

@ -0,0 +1,103 @@
package com.etl.data.structure.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.etl.common.core.annotation.Excel;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
/**
* asset_table_details
*
* @author Chao
* @date 2024-04-23
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@SuperBuilder
@TableName("asset_table_details")
public class AssetTableDetails {
private static final long serialVersionUID = 1L;
/**
* id
*/
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* id
*/
@Excel(name = "资产表id")
private Long assetStructureTableId;
/**
*
*/
@Excel(name = "名称")
private String name;
/**
*
*/
@Excel(name = "注释")
private String annotation;
/**
*
*/
@Excel(name = "是否主键")
private String primaryOrNot;
/**
*
*/
@Excel(name = "类型")
private String type;
/**
*
*/
@Excel(name = "映射类型")
private String mappingType;
/**
*
*/
@Excel(name = "长度")
private Long length;
/**
*
*/
@Excel(name = "小数点")
private Long decimalPoint;
/**
*
*/
@Excel(name = "是否为空")
private String nullOrNot;
/**
*
*/
@Excel(name = "默认值")
private String defaultValue;
/**
*
*/
@Excel(name = "是否字典")
private String yesNoDictionary;
/**
*
*/
@Excel(name = "映射字典")
private String mappingDictionary;
}

View File

@ -0,0 +1,41 @@
package com.etl.data.structure.domain.resp;
import com.etl.data.structure.domain.AssetStructure;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
import java.util.List;
/**
*
*
* @author Chao
* @ClassName: AssetStructureResp
* @CreateTime: 2024/4/22 7:23
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@SuperBuilder
public class AssetStructureResp {
/**
*
*/
private List<AssetStructure> assetStructureList;
/**
*
*/
private Long assetStructureTableCount;
/**
*
*/
private Long assetStructureTableDataCount;
}

View File

@ -0,0 +1,37 @@
package com.etl.data.structure.domain.resp;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
import java.util.List;
/**
*
*
* @author Chao
* @ClassName: AssetStructureTableResp
* @CreateTime: 2024/4/23 9:54
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@SuperBuilder
public class AssetStructureTableResp {
/**
*
*/
private List<TableDetailsResp> tableDetailsRespList;
/**
*
*/
private Long tableCount;
/**
*
*/
private Long tableDataCount;
}

View File

@ -0,0 +1,63 @@
package com.etl.data.structure.domain.resp;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.etl.common.core.annotation.Excel;
import com.etl.data.structure.domain.AssetTableDetails;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
import java.util.List;
/**
*
*
* @author Chao
* @ClassName: TableDetailsResp
* @CreateTime: 2024/4/26 10:41
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@SuperBuilder
public class TableDetailsResp {
private static final long serialVersionUID = 1L;
/**
* id
*/
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* id
*/
@Excel(name = "数据资产id")
private Long assetStructureId;
/**
*
*/
@Excel(name = "数据资产表")
private String tableName;
/**
*
*/
@Excel(name = "表数据总数")
private Long tableDataCount;
/**
*
*/
@Excel(name = "表注释")
private String tableNameAnnotation;
/**
*
*/
private List<AssetTableDetails> assetTableDetailsList;
}

View File

@ -0,0 +1,53 @@
package com.etl.data.type.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.etl.common.core.annotation.Excel;
import com.etl.common.core.web.domain.BaseEntity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
/**
* data_type
*
* @author Chao
* @date 2024-04-21
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
@SuperBuilder
@EqualsAndHashCode(callSuper = true)
@TableName("data_type")
public class DataType extends BaseEntity {
private static final long serialVersionUID = 1L;
/**
*
*/
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
*
*/
@Excel(name = "数据源类型")
private String dataType;
/**
*
*/
@Excel(name = "注册驱动")
private String driverManager;
/**
* jdbc
*/
@Excel(name = "jdbc前缀")
private String jdbcPre;
}

View File

@ -0,0 +1,27 @@
<?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>
<parent>
<groupId>com.etl</groupId>
<artifactId>etl-modules-data-source</artifactId>
<version>3.6.3</version>
</parent>
<artifactId>etl-modules-data-source-remote</artifactId>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>com.etl</groupId>
<artifactId>etl-modules-data-source-common</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,34 @@
package com.etl.data.source.remote;
import com.etl.common.core.constant.ServiceNameConstants;
import com.etl.common.core.domain.Result;
import com.etl.data.source.domain.DataSource;
import com.etl.data.source.remote.factory.DataSourceFactory;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import java.util.List;
/**
*
*
* @author Chao
* @ClassName: DataSourceRemoteService
* @CreateTime: 2024/5/9 3:12
*/
@FeignClient(
contextId = "DataSourceRemoteService",
value = ServiceNameConstants.DATA_SOURCE_SERVICE,
fallbackFactory = DataSourceFactory.class,
path = "/source"
)
public interface DataSourceRemoteService {
/**
*
*
* @return
*/
@PostMapping("list")
public Result<List<DataSource>> dataSourceList();
}

View File

@ -0,0 +1,23 @@
package com.etl.data.source.remote.factory;
import com.etl.common.core.domain.Result;
import com.etl.data.source.domain.DataSource;
import com.etl.data.source.remote.DataSourceRemoteService;
import org.springframework.cloud.openfeign.FallbackFactory;
import java.util.ArrayList;
/**
*
*
* @author Chao
* @ClassName: AssetStructureFactory
* @CreateTime: 2024/5/9 3:09
*/
public class DataSourceFactory implements FallbackFactory<DataSourceRemoteService> {
@Override
public DataSourceRemoteService create(Throwable cause) {
return () -> Result.success(new ArrayList<DataSource>());
}
}

View File

@ -0,0 +1,33 @@
package com.etl.data.type.remote;
import com.etl.common.core.constant.ServiceNameConstants;
import com.etl.common.core.domain.Result;
import com.etl.data.type.remote.factory.DataTypeFactory;
import com.etl.data.type.domain.DataType;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import java.util.List;
/**
*
*
* @author Chao
* @ClassName: DataTypeRemoteService
* @CreateTime: 2024/5/10 10:09
*/
@FeignClient(
contextId = "DataTypeRemoteService",
value = ServiceNameConstants.DATA_SOURCE_SERVICE,
fallbackFactory = DataTypeFactory.class,
path = "/type"
)
public interface DataTypeRemoteService {
/**
*
*
* @return
*/
@PostMapping("/list")
public Result<List<DataType>> list();
}

View File

@ -0,0 +1,23 @@
package com.etl.data.type.remote.factory;
import com.etl.common.core.domain.Result;
import com.etl.data.type.domain.DataType;
import com.etl.data.type.remote.DataTypeRemoteService;
import org.springframework.cloud.openfeign.FallbackFactory;
import java.util.ArrayList;
/**
*
*
* @author Chao
* @ClassName: DataTypeFactory aa
* @CreateTime: 2024/5/10 10:21
*/
public class DataTypeFactory implements FallbackFactory<DataTypeRemoteService> {
@Override
public DataTypeRemoteService create(Throwable cause) {
return () -> Result.error(new ArrayList<DataType>());
}
}

View File

@ -0,0 +1,3 @@
com.etl.data.source.remote.factory.DataSourceFactory
com.etl.data.type.remote.factory.DataTypeFactory

View File

@ -0,0 +1,95 @@
<?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>
<parent>
<groupId>com.etl</groupId>
<artifactId>etl-modules-data-source</artifactId>
<version>3.6.3</version>
</parent>
<artifactId>etl-modules-data-source-server</artifactId>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!-- SpringCloud Alibaba Nacos -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- SpringCloud Alibaba Nacos Config -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!-- SpringCloud Alibaba Sentinel -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<!-- SpringBoot Actuator -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- Swagger UI -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${swagger.fox.version}</version>
</dependency>
<!-- Mysql Connector -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
</dependency>
<!-- ETL Common DataSource -->
<dependency>
<groupId>com.etl</groupId>
<artifactId>etl-common-datasource</artifactId>
</dependency>
<!-- ETL Common DataScope -->
<dependency>
<groupId>com.etl</groupId>
<artifactId>etl-common-datascope</artifactId>
</dependency>
<!-- ETL Common Log -->
<dependency>
<groupId>com.etl</groupId>
<artifactId>etl-common-log</artifactId>
</dependency>
<!-- ETL Common Swagger -->
<dependency>
<groupId>com.etl</groupId>
<artifactId>etl-common-swagger</artifactId>
</dependency>
<dependency>
<groupId>com.etl</groupId>
<artifactId>etl-modules-data-source-common</artifactId>
</dependency>
<dependency>
<groupId>com.etl</groupId>
<artifactId>etl-modules-data-source-clinet</artifactId>
<version>3.6.3</version>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,24 @@
package com.etl;
import com.etl.common.security.annotation.EnableCustomConfig;
import com.etl.common.security.annotation.EnableMyFeignClients;
import com.etl.common.swagger.annotation.EnableCustomSwagger2;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;
/**
*
*
* @author Chao
*/
@EnableCustomConfig
@EnableCustomSwagger2
@EnableMyFeignClients
@SpringBootApplication
@EnableAsync
public class ETLDataSourceApplication {
public static void main (String[] args) {
SpringApplication.run(ETLDataSourceApplication.class, args);
}
}

View File

@ -0,0 +1,50 @@
package com.etl.data.dictionary.controller;
import com.etl.common.core.domain.Result;
import com.etl.common.log.annotation.Log;
import com.etl.common.log.enums.BusinessType;
import com.etl.common.security.annotation.RequiresPermissions;
import com.etl.data.dictionary.domain.DataDictionary;
import com.etl.data.dictionary.domain.resp.DataDictionaryResp;
import com.etl.data.dictionary.service.IDataDictionaryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* Controller
*
* @author Chao
* @ClassName: DataDictionaryController Controller
* @CreateTime: 2024/4/27 9:13
*/
@RestController
@RequestMapping("/dictionary")
public class DataDictionaryController {
@Autowired
private IDataDictionaryService dataDictionaryService;
/**
*
*
* @return
*/
@GetMapping("dictionaryList/{assetStructureId}")
public Result<List<DataDictionaryResp>> list(@PathVariable("assetStructureId") Long assetStructureId) {
return Result.success(dataDictionaryService.dictionaryList(assetStructureId));
}
/**
*
*/
@RequiresPermissions("data:dictionary:save")
@Log(title = "新增字典", businessType = BusinessType.INSERT)
@PostMapping("dictionarySave")
public Result save(@RequestBody DataDictionary dataDictionary) {
dataDictionaryService.save(dataDictionary);
return Result.success();
}
}

View File

@ -0,0 +1,49 @@
package com.etl.data.dictionary.controller;
import com.etl.common.core.domain.Result;
import com.etl.common.log.annotation.Log;
import com.etl.common.log.enums.BusinessType;
import com.etl.common.security.annotation.RequiresPermissions;
import com.etl.data.dictionary.domain.DataDictionaryType;
import com.etl.data.dictionary.service.IDataDictionaryTypeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
/**
* Controller
*
* @author Chao
* @ClassName: DataDictionaryTypeController Controller
* @CreateTime: 2024/4/27 9:55
*/
@RestController
@RequestMapping("/dictionaryType")
public class DataDictionaryTypeController {
@Autowired
private IDataDictionaryTypeService dataDictionaryTypeService;
/**
*
*/
@RequiresPermissions("data:dictionaryType:save")
@Log(title = "数据源信息", businessType = BusinessType.INSERT)
@PostMapping()
public Result save(@RequestBody DataDictionaryType dataDictionaryType) {
dataDictionaryTypeService.save(dataDictionaryType);
return Result.success();
}
/**
*
*/
@RequiresPermissions("data:dictionary:edit")
@Log(title = "数据源信息", businessType = BusinessType.UPDATE)
@PutMapping
public Result edit(@RequestBody DataDictionaryType dataDictionary) {
return Result.success(dataDictionaryTypeService.updateById(dataDictionary));
}
}

View File

@ -0,0 +1,14 @@
package com.etl.data.dictionary.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.etl.data.dictionary.domain.DataDictionary;
/**
* mapper
*
* @author Chao
* @ClassName: DataDictionaryMapper mapper
* @CreateTime: 2024/4/27 9:35
*/
public interface DataDictionaryMapper extends BaseMapper<DataDictionary> {
}

View File

@ -0,0 +1,14 @@
package com.etl.data.dictionary.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.etl.data.dictionary.domain.DataDictionaryType;
/**
* mapper
*
* @author Chao
* @ClassName: DataDictionaryTypeMapper mapper
* @CreateTime: 2024/4/27 3:29
*/
public interface DataDictionaryTypeMapper extends BaseMapper<DataDictionaryType> {
}

View File

@ -0,0 +1,24 @@
package com.etl.data.dictionary.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.etl.data.dictionary.domain.DataDictionary;
import com.etl.data.dictionary.domain.resp.DataDictionaryResp;
import java.util.List;
/**
* Service
*
* @author Chao
* @ClassName: IDataDictionaryService Service
* @CreateTime: 2024/4/27 9:28
*/
public interface IDataDictionaryService extends IService<DataDictionary> {
/**
*
* @param assetStructureId id
* @return
*/
List<DataDictionaryResp> dictionaryList(Long assetStructureId);
}

View File

@ -0,0 +1,14 @@
package com.etl.data.dictionary.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.etl.data.dictionary.domain.DataDictionaryType;
/**
* Service
*
* @author Chao
* @ClassName: IDataDictionaryType Service
* @CreateTime: 2024/4/27 10:07
*/
public interface IDataDictionaryTypeService extends IService<DataDictionaryType> {
}

View File

@ -0,0 +1,18 @@
package com.etl.data.dictionary.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.etl.data.dictionary.domain.DataDictionaryType;
import com.etl.data.dictionary.mapper.DataDictionaryTypeMapper;
import com.etl.data.dictionary.service.IDataDictionaryTypeService;
import org.springframework.stereotype.Service;
/**
* Service
*
* @author Chao
* @ClassName: DataDictionaryTypeServiceImpl Service
* @CreateTime: 2024/4/27 3:27
*/
@Service
public class DataDictionaryTypeServiceImpl extends ServiceImpl<DataDictionaryTypeMapper, DataDictionaryType> implements IDataDictionaryTypeService {
}

View File

@ -0,0 +1,54 @@
package com.etl.data.dictionary.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.etl.data.dictionary.domain.DataDictionary;
import com.etl.data.dictionary.domain.DataDictionaryType;
import com.etl.data.dictionary.domain.resp.DataDictionaryResp;
import com.etl.data.dictionary.mapper.DataDictionaryMapper;
import com.etl.data.dictionary.service.IDataDictionaryService;
import com.etl.data.dictionary.service.IDataDictionaryTypeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.stream.Collectors;
/**
* Service
*
* @author Chao
* @ClassName: IDataDictionaryServiceImpl Service
* @CreateTime: 2024/4/27 9:28
*/
@Service
public class IDataDictionaryServiceImpl extends ServiceImpl<DataDictionaryMapper, DataDictionary> implements IDataDictionaryService {
@Autowired
private IDataDictionaryTypeService dataDictionaryTypeService;
/**
*
*
* @param assetStructureId id
* @return
*/
@Override
public List<DataDictionaryResp> dictionaryList(Long assetStructureId) {
List<DataDictionary> dataDictionaryList = this.list(
new LambdaQueryWrapper<DataDictionary>()
.eq(DataDictionary::getAssetStructureId, assetStructureId)
);
List<DataDictionaryType> dataDictionaryTypeList = dataDictionaryTypeService.list();
return dataDictionaryList.stream().map(
dataDictionary -> {
List<DataDictionaryType> dataDictionaryTypes = dataDictionaryTypeList.stream()
.filter(
dataDictionaryType -> dataDictionaryType.getDataDictionaryId().equals(dataDictionary.getId())
).collect(Collectors.toList());
return DataDictionaryResp.dataDictionaryBuilder(dataDictionary, dataDictionaryTypes);
}
).collect(Collectors.toList());
}
}

View File

@ -0,0 +1,124 @@
package com.etl.data.source.controller;
import com.etl.common.core.domain.Result;
import com.etl.common.core.utils.poi.ExcelUtil;
import com.etl.common.core.web.controller.BaseController;
import com.etl.common.core.web.page.TableDataInfo;
import com.etl.common.log.annotation.Log;
import com.etl.common.log.enums.BusinessType;
import com.etl.common.security.annotation.RequiresPermissions;
import com.etl.data.source.domain.DataSource;
import com.etl.data.source.domain.resp.DataSourceResp;
import com.etl.data.source.service.IDataSourceService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
/**
* Controller
*
* @author Chao
* @date 2024-04-21
*/
@RestController
@RequestMapping("/source")
public class DataSourceController extends BaseController {
@Autowired
private IDataSourceService dataSourceService;
/**
*
*/
@RequiresPermissions("data:source:list")
@GetMapping("/list")
public Result<TableDataInfo<DataSourceResp>> list(DataSource dataSource) {
startPage();
List<DataSourceResp> list = dataSourceService.selectDataSourceList(dataSource);
return getDataTable(list);
}
/**
*
* @return
*/
@PostMapping("list")
public Result<List<DataSource>> dataSourceList(){
return dataSourceService.dataSourceList();
}
/**
*
*/
@RequiresPermissions("data:source:export")
@Log(title = "数据源信息", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, DataSource dataSource) {
List<DataSourceResp> list = dataSourceService.selectDataSourceList(dataSource);
ExcelUtil<DataSourceResp> util = new ExcelUtil<DataSourceResp>(DataSourceResp.class);
util.exportExcel(response, list, "数据源信息数据");
}
/**
*
*/
@RequiresPermissions("data:source:query")
@GetMapping(value = "/{id}")
public Result getInfo(@PathVariable("id") Long id) {
return success(dataSourceService.selectDataSourceById(id));
}
/**
*
*/
@RequiresPermissions("data:source:add")
@Log(title = "数据源信息", businessType = BusinessType.INSERT)
@PostMapping
public Result add(@RequestBody DataSource dataSource) {
return toAjax(dataSourceService.insertDataSource(dataSource));
}
/**
*
*/
@RequiresPermissions("data:source:edit")
@Log(title = "数据源信息", businessType = BusinessType.UPDATE)
@PutMapping
public Result edit(@RequestBody DataSource dataSource) {
return toAjax(dataSourceService.updateDataSource(dataSource));
}
/**
*
*/
@RequiresPermissions("data:source:remove")
@Log(title = "数据源信息", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public Result remove(@PathVariable Long[] ids) {
return toAjax(dataSourceService.deleteDataSourceByIds(ids));
}
/**
*
* @param id id
* @return
*/
@RequiresPermissions("data:source:testConnection")
@PostMapping(value = "testConnection/{id}")
public Result testConnection(@PathVariable("id") Long id) {
return Result.success(dataSourceService.testConnection(id));
}
/**
*
* @param id id
* @return
*/
@RequiresPermissions("data:source:assetSynchronization")
@PostMapping(value = "assetSynchronization/{id}")
public Result assetSynchronization(@PathVariable("id") Long id) {
return Result.success(dataSourceService.assetSynchronization(id));
}
}

View File

@ -0,0 +1,62 @@
package com.etl.data.source.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.etl.data.source.domain.DataSource;
import java.util.List;
/**
* Mapper
*
* @author Chao
* @date 2024-04-21
*/
public interface DataSourceMapper extends BaseMapper<DataSource> {
/**
*
*
* @param id
* @return
*/
public DataSource selectDataSourceById(Long id);
/**
*
*
* @param dataSource
* @return
*/
public List<DataSource> selectDataSourceList(DataSource dataSource);
/**
*
*
* @param dataSource
* @return
*/
public int insertDataSource(DataSource dataSource);
/**
*
*
* @param dataSource
* @return
*/
public int updateDataSource(DataSource dataSource);
/**
*
*
* @param id
* @return
*/
public int deleteDataSourceById(Long id);
/**
*
*
* @param ids
* @return
*/
public int deleteDataSourceByIds(Long[] ids);
}

View File

@ -0,0 +1,84 @@
package com.etl.data.source.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.etl.common.core.domain.Result;
import com.etl.data.source.domain.DataSource;
import com.etl.data.source.domain.resp.DataSourceResp;
import java.util.List;
/**
* Service
*
* @author Chao
* @date 2024-04-21
*/
public interface IDataSourceService extends IService<DataSource> {
/**
*
*
* @param id
* @return
*/
public DataSource selectDataSourceById(Long id);
/**
*
*
* @param dataSource
* @return
*/
public List<DataSourceResp> selectDataSourceList(DataSource dataSource);
/**
*
*
* @param dataSource
* @return
*/
public int insertDataSource(DataSource dataSource);
/**
*
*
* @param dataSource
* @return
*/
public int updateDataSource(DataSource dataSource);
/**
*
*
* @param ids
* @return
*/
public int deleteDataSourceByIds(Long[] ids);
/**
*
*
* @param id
* @return
*/
public int deleteDataSourceById(Long id);
/**
*
* @param id id
*/
boolean testConnection(Long id);
/**
*
* @param id id
* @return
*/
boolean assetSynchronization(Long id);
/**
*
* @return
*/
Result<List<DataSource>> dataSourceList();
}

View File

@ -0,0 +1,659 @@
package com.etl.data.source.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.etl.common.core.domain.Result;
import com.etl.common.core.utils.DateUtils;
import com.etl.data.source.domain.DataSource;
import com.etl.data.source.domain.resp.DataSourceResp;
import com.etl.data.source.mapper.DataSourceMapper;
import com.etl.data.source.service.IDataSourceService;
import com.etl.data.structure.domain.AssetStructure;
import com.etl.data.structure.domain.AssetStructureTable;
import com.etl.data.structure.domain.AssetTableDetails;
import com.etl.data.structure.service.IAssetStructureService;
import com.etl.data.structure.service.IAssetStructureTableService;
import com.etl.data.structure.service.IAssetTableDetailsService;
import com.etl.data.type.domain.DataType;
import com.etl.data.type.service.IDataTypeService;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import redis.clients.jedis.Jedis;
import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* Service
*
* @author Chao
* @date 2024-04-21
*/
@Service
@Log4j2
public class DataSourceServiceImpl extends ServiceImpl<DataSourceMapper, DataSource> implements IDataSourceService {
@Autowired
private DataSourceMapper dataSourceMapper;
@Autowired
private IDataTypeService dataTypeService;
@Autowired
private IAssetStructureService assetStructureService;
@Autowired
private IAssetStructureTableService assetStructureTableService;
@Autowired
private IAssetTableDetailsService assetTableDetailsService;
/**
*
*
* @param id
* @return
*/
@Override
public DataSource selectDataSourceById(Long id) {
log.info("查询数据源信息");
return dataSourceMapper.selectDataSourceById(id);
}
/**
*
*
* @param dataSource
* @return
*/
@Override
public List<DataSourceResp> selectDataSourceList(DataSource dataSource) {
log.info("查询数据源信息列表");
List<DataSource> dataSources = dataSourceMapper.selectDataSourceList(dataSource);
log.info("查询数据源连接类型");
List<DataType> dataTypeList = dataTypeService.list();
List<DataSourceResp> dataSourceResps = new ArrayList<>();
log.info("过滤当前数据源连接数据类型");
dataSources.stream()
.flatMap(source ->
dataTypeList.stream()
.filter(dataType -> dataType.getId().equals(source.getTypeId()))
.map(dataType -> DataSourceResp.dataSourceBuilder(source, dataType))
).forEach(dataSourceResps::add);
log.info("返回查询出的数据源信息+数据源类型信息");
return dataSourceResps;
}
/**
*
*
* @param dataSource
* @return
*/
@Override
public int insertDataSource(DataSource dataSource) {
dataSource.setCreateTime(DateUtils.getNowDate());
log.info("新增数据源信息");
return dataSourceMapper.insertDataSource(dataSource);
}
/**
*
*
* @param dataSource
* @return
*/
@Override
public int updateDataSource(DataSource dataSource) {
dataSource.setUpdateTime(DateUtils.getNowDate());
log.info("修改数据源信息");
return dataSourceMapper.updateDataSource(dataSource);
}
/**
*
*
* @param ids
* @return
*/
@Override
public int deleteDataSourceByIds(Long[] ids) {
log.info("批量删除数据源信息");
return dataSourceMapper.deleteDataSourceByIds(ids);
}
/**
*
*
* @param id
* @return
*/
@Override
public int deleteDataSourceById(Long id) {
log.info("删除数据源信息");
return dataSourceMapper.deleteDataSourceById(id);
}
/**
*
*
* @param id id
*/
@Override
public boolean testConnection(Long id) {
log.info("根据数据源id获取数据源信息");
DataSource dataSource = this.getOne(
new LambdaQueryWrapper<DataSource>()
.eq(DataSource::getId, id)
);
log.info("根据查询出的数据源类型id获取数据源类型");
DataType dataType = dataTypeService.getOne(
new LambdaQueryWrapper<DataType>()
.eq(DataType::getId, dataSource.getTypeId())
);
boolean flag = false;
log.info("判断数据源驱动和jdbc前缀是否为空");
if (dataType.getDriverManager() != null && dataType.getJdbcPre() != null) {
log.info("调用测试连接方法");
flag = testDatasource(dataSource, dataType);
} else {
log.info("调用redis测试连接方法");
// 调用redis测试是否连接方法
flag = this.redisConnection(dataSource);
}
if (flag) {
log.info("连接成功,更新数据源状态为S");
this.update(new UpdateWrapper<DataSource>().set("status", "S").eq("id", id));
} else {
log.info("连接失败,更新数据源状态为E");
this.update(new UpdateWrapper<DataSource>().set("status", "E").eq("id", id));
}
return flag;
}
/**
*
*
* @param id id
* @return
*/
@Override
@Transactional
public boolean assetSynchronization(Long id) {
log.info("根据数据源id查询出当前数据源信息");
DataSource dataSource = this.getOne(
new LambdaQueryWrapper<DataSource>()
.eq(DataSource::getId, id)
);
// 查询是否存在当前数据源
log.info("查询是否存在当前数据源");
AssetStructure assetStructure = assetStructureService.getOne(
new LambdaQueryWrapper<AssetStructure>()
.eq(AssetStructure::getDataSourceSystemId, id)
);
// 判断是否连接成功
if (this.testConnection(id)) {
log.info("连接成功,正在同步数据...");
// 如果不存在就给他添加资产结构表
if (assetStructure == null) {
log.info("当前数据为新数据,正在同步");
// 构建实体
AssetStructure entity = AssetStructure.dataSourceSaveBuilder(id, dataSource);
// 保存数据源信息
assetStructureService.save(entity);
log.info("数据源信息已同步");
DataType dataType = dataTypeService.selectDataTypeById(dataSource.getTypeId());
Map<String, Object> jdbcSyncMap = this.jdbcSync(entity, dataSource, dataType);
if (jdbcSyncMap != null) {
List<AssetStructureTable> assetStructureTableList = (List<AssetStructureTable>) jdbcSyncMap.get("assetStructureTableList");
Connection connection = (Connection) jdbcSyncMap.get("Connection");
assetTableDetailsSync(assetStructureTableList, connection);
return true;
}
} else { // 如果他存在就给他修改
log.info("当前数据源已被修改,正在重新同步...");
AssetStructure entity = AssetStructure.dataSourceUpdateBuilder(assetStructure, id, dataSource);
// 修改资产结构
assetStructureService.update(
entity, new LambdaUpdateWrapper<AssetStructure>()
.eq(AssetStructure::getId, entity.getId())
);
log.info("已将修改过的数据源信息同步");
// 获取原来的数据
log.info("备份原有数据");
List<AssetStructureTable> assetStructureTables = assetStructureTableService.list(
new LambdaQueryWrapper<AssetStructureTable>()
.eq(AssetStructureTable::getAssetStructureId, entity.getId())
);
// 删除资产结构表信息
log.info("删除原有数据");
assetStructureTableService.remove(
new LambdaQueryWrapper<AssetStructureTable>()
.eq(AssetStructureTable::getAssetStructureId, entity.getId())
);
DataType dataType = dataTypeService.selectDataTypeById(dataSource.getTypeId());
// 获取数据
Map<String, Object> jdbcSyncMap = this.jdbcSync(entity, dataSource, dataType);
if (jdbcSyncMap != null) {
List<AssetStructureTable> assetStructureTableList = (List<AssetStructureTable>) jdbcSyncMap.get("assetStructureTableList");
Connection connection = (Connection) jdbcSyncMap.get("Connection");
List<Long> collect = assetStructureTables.stream().map(
assetStructureTable -> assetStructureTable.getId()
).collect(Collectors.toList());
for (Long assetStructureTableId : collect) {
assetTableDetailsService.remove(
new LambdaQueryWrapper<AssetTableDetails>()
.eq(AssetTableDetails::getAssetStructureTableId, assetStructureTableId)
);
}
log.info("已删除原数据,正在准备同步新数据");
assetTableDetailsSync(assetStructureTableList, connection);
}
}
} else {
log.info("连接失败,同步数据失败");
// 如果连接失败并存在就给他删除
if (assetStructure != null) {
// 删除
assetStructureService.removeById(assetStructure.getId());
}
return false;
}
return true;
}
/**
*
* @return
*/
@Override
public Result<List<DataSource>> dataSourceList() {
return Result.success(
this.list(
new LambdaQueryWrapper<DataSource>()
.eq(DataSource::getStatus, "S")
)
);
}
/**
*
*
* @param driveClass
* @param url
* @param username
* @param password
* @return
*/
public static boolean testDatasource(String driveClass, String url, String username, String password) {
try {
Class.forName(driveClass);
DriverManager.getConnection(url, username, password);
return true;
} catch (Exception e) {
return false;
}
}
/**
*
*
* @param dataSource
* @param dataType
* @return
*/
public boolean testDatasource(DataSource dataSource, DataType dataType) {
if ("mysql".equals(dataType.getDataType())) {
log.info("MySQL测试连接");
Map<String, String> mysqlEdConnection = this.mysqlConnection(dataSource, dataType);
return testDatasource(mysqlEdConnection.get("driveClass"), mysqlEdConnection.get("jdbcUrl"), dataSource.getDataSourceUsername(), dataSource.getDataSourcePassword());
}
if ("oracle".equals(dataType.getDataType())) {
log.info("Oracle测试连接");
Map<String, String> mysqlEdConnection = this.oracleConnection(dataSource, dataType);
return testDatasource(mysqlEdConnection.get("driveClass"), mysqlEdConnection.get("jdbcUrl"), dataSource.getDataSourceUsername(), dataSource.getDataSourcePassword());
}
if ("sqlserver".equals(dataType.getDataType())) {
log.info("SQLServer测试连接");
Map<String, String> mysqlEdConnection = this.sqlserverConnection(dataSource, dataType);
return testDatasource(mysqlEdConnection.get("driveClass"), mysqlEdConnection.get("jdbcUrl"), dataSource.getDataSourceUsername(), dataSource.getDataSourcePassword());
}
return false;
}
/**
* mysql
*
* @param dataSource
* @param dataType
* @return
*/
public Map<String, String> mysqlConnection(DataSource dataSource, DataType dataType) {
String driveClass = dataType.getDriverManager();
String jdbcUrl = dataType.getJdbcPre() + dataSource.getDataSourceIp() + ":" + dataSource.getDataSourcePort() + "/" + dataSource.getDataSourceDatabaseName() + "?" + dataSource.getAdditionalConfiguration();
return new HashMap<String, String>() {{
put("driveClass", driveClass);
put("jdbcUrl", jdbcUrl);
}};
}
/**
* oracle
*
* @param dataSource
* @param dataType
* @return
*/
public Map<String, String> oracleConnection(DataSource dataSource, DataType dataType) {
String driveClass = dataType.getDriverManager();
String jdbcUrl = dataType.getJdbcPre() + dataSource.getDataSourceIp() + ":" + dataSource.getDataSourcePort() + ":" + dataSource.getDataSourceDatabaseName();
return new HashMap<String, String>() {{
put("driveClass", driveClass);
put("jdbcUrl", jdbcUrl);
}};
}
/**
* sqlserver
*
* @param dataSource
* @param dataType
* @return
*/
public HashMap<String, String> sqlserverConnection(DataSource dataSource, DataType dataType) {
String driveClass = dataType.getDriverManager();
String jdbcUrl = dataType.getJdbcPre() + dataSource.getDataSourceIp() + ":" + dataSource.getDataSourcePort() + ";databaseName=" + dataSource.getDataSourceDatabaseName();
return new HashMap<String, String>() {{
put("driveClass", driveClass);
put("jdbcUrl", jdbcUrl);
}};
}
/**
* redis
*
* @param dataSource
* @return
*/
public boolean redisConnection(DataSource dataSource) {
try {
//连接指定的redis
Jedis jedis = new Jedis(dataSource.getDataSourceIp(), Integer.valueOf(dataSource.getDataSourcePort()));
//如果有密码则需要下面这一行
if (dataSource.getDataSourcePassword() != null && !dataSource.getDataSourcePassword().equals("")) {
jedis.auth(dataSource.getDataSourcePassword());
}
//查看服务是否运行,运行正常的话返回一个PONG否则返回一个连接错误
jedis.ping();
return true;
} catch (Exception e) {
log.info("redis连接失败{}", e.getMessage());
return false;
}
}
/**
*
*
* @param assetStructure
* @param dataSource
* @param dataType
*/
@Async
public Map<String, Object> jdbcSync(AssetStructure assetStructure, DataSource dataSource, DataType dataType) {
if (dataType.getDriverManager() != null && dataType.getJdbcPre() != null) {
if ("mysql".equals(dataType.getDataType())) {
log.info("当前数据正在同步");
Map<String, String> stringStringMap = mysqlConnection(dataSource, dataType);
String driveClass = stringStringMap.get("driveClass");
String jdbcUrl = stringStringMap.get("jdbcUrl");
// 统计当前库所有表 初始数组
List<AssetStructureTable> assetStructureTableList = new ArrayList<>();
Connection conn = null;
Statement st = null;
ResultSet rs = null;
// 查询表
String tableSql = "select * from information_schema.tables where TABLE_SCHEMA = " + "'" + dataSource.getDataSourceDatabaseName() + "'";
try {
// 加载数据库驱动
Class.forName(driveClass);
// 连接数据库
conn = DriverManager.getConnection(jdbcUrl, dataSource.getDataSourceUsername(), dataSource.getDataSourcePassword());
st = conn.createStatement();
rs = st.executeQuery(tableSql);
while (rs.next()) {
// 获取表名
String tableName = rs.getString("TABLE_NAME");
// 表注释
String tableNameAnnotation = rs.getString("TABLE_COMMENT");
// 添加数据
// 表数据数量
assetStructureTableList.add(
AssetStructureTable.builder()
.assetStructureId(assetStructure.getId())
.tableName(tableName)
.tableNameAnnotation(tableNameAnnotation)
.build()
);
}
log.info("正在同步当前所有表总体数据数量");
Statement finalSt = st;
assetStructureTableList.stream().forEach(assetStructureTable -> {
String tableDataCountSQL = "select count(*) as countNum from " + assetStructureTable.getTableName();
try {
ResultSet rs2 = finalSt.executeQuery(tableDataCountSQL);
while (rs2.next()) {
assetStructureTable.setTableDataCount(rs2.getLong("countNum"));
}
rs2.close();
} catch (SQLException e) {
log.info("mysql查询表数据总数失败");
}
});
// 批量插入
assetStructureTableService.saveBatch(assetStructureTableList);
log.info("同步所有当前库所有表完成");
Connection finalConn = conn;
return new HashMap<String, Object>() {{
put("assetStructureTableList", assetStructureTableList);
put("Connection", finalConn);
}};
} catch (ClassNotFoundException e) {
log.info("mysql驱动加载失败");
throw new RuntimeException(e);
} catch (SQLException e) {
log.info("mysql连接失败");
throw new RuntimeException(e);
} finally {
try {
if (st != null) {
st.close();
}
if (rs != null) {
rs.close();
}
} catch (SQLException e) {
log.info("无法关闭 JDBC 资源");
}
}
}
if ("oracle".equals(dataType.getDataType())) {
log.info("oracle正在同步数据");
}
if ("sqlserver".equals(dataType.getDataType())) {
log.info("sqlserver正在同步数据");
}
} else {
// redis
//连接指定的redis
Jedis jedis = new Jedis(dataSource.getDataSourceIp(), Integer.valueOf(dataSource.getDataSourcePort()));
//如果有密码则需要下面这一行
if (dataSource.getDataSourcePassword() != null && !dataSource.getDataSourcePassword().equals("")) {
jedis.auth(dataSource.getDataSourcePassword());
}
//查看服务是否运行,运行正常的话返回一个PONG否则返回一个连接错误
try {
jedis.ping();
log.info("redis连接成功");
} catch (Exception e) {
log.info("redis连接失败");
}
}
return null;
}
/**
*
*
* @param assetStructureTableList
* @param conn
*/
@Async
public void assetTableDetailsSync(List<AssetStructureTable> assetStructureTableList, Connection conn) {
List<AssetTableDetails> assetTableDetails = new ArrayList<>();
try {
log.info("正在同步表详细信息");
assetStructureTableList.forEach(assetStructureTable -> {
try {
DatabaseMetaData metaData = conn.getMetaData();
ResultSet rs = getColumns(metaData, conn, assetStructureTable);
while (rs.next()) {
AssetTableDetails details = processRow(rs, metaData, conn, assetStructureTable);
assetTableDetails.add(details);
}
rs.close();
log.info("同步表详细信息完成");
} catch (Exception e) {
log.info("同步表的表详细信息时出错");
}
});
assetTableDetailsService.saveBatch(assetTableDetails);
log.info("同步所有表详细信息完成");
} catch (Exception e) {
log.info("处理数据库连接时出错");
}
}
/**
*
*
* @param metaData
* @param conn
* @param assetStructureTable
* @return
* @throws SQLException
*/
@Async
public ResultSet getColumns(DatabaseMetaData metaData, Connection conn, AssetStructureTable assetStructureTable) throws SQLException {
return metaData.getColumns(null, null, assetStructureTable.getTableName(), null);
}
/**
*
*
* @param metaData
* @param conn
* @param assetStructureTable
* @return
* @throws SQLException
* @throws ClassNotFoundException
* @throws IllegalAccessException
* @throws InstantiationException
*/
@Async
public AssetTableDetails processRow(ResultSet rs, DatabaseMetaData metaData, Connection conn, AssetStructureTable assetStructureTable) throws SQLException, ClassNotFoundException, IllegalAccessException, InstantiationException {
String columnName = rs.getString("COLUMN_NAME");
String remarks = rs.getString("REMARKS");
boolean isPrimaryKey = isColumnPrimaryKey(metaData, assetStructureTable.getTableName(), columnName);
String dataDetailsSQL = "select * from " + assetStructureTable.getTableName() + " where 1=2";
String typeName = rs.getString("TYPE_NAME");
String mappingType = getMappingType(conn, dataDetailsSQL, columnName);
int columnSize = rs.getInt("COLUMN_SIZE");
int decimalDigits = rs.getInt("DECIMAL_DIGITS");
boolean isNullable = (rs.getInt("NULLABLE") == DatabaseMetaData.columnNullable);
String defaultValue = rs.getString("COLUMN_DEF");
boolean finalIsPrimaryKey = isPrimaryKey;
String finalMappingType = mappingType;
return AssetTableDetails.builder()
.assetStructureTableId(assetStructureTable.getId())
.name(columnName)
.annotation(remarks)
.primaryOrNot(finalIsPrimaryKey ? "Y" : "N")
.type(typeName)
.mappingType(finalMappingType)
.length((long) columnSize)
.decimalPoint((long) decimalDigits)
.nullOrNot(isNullable ? "Y" : "N")
.defaultValue(defaultValue)
.yesNoDictionary(null)
.build();
}
/**
*
*
* @param metaData
* @param tableName
* @param columnName
* @return
* @throws SQLException
*/
@Async
public boolean isColumnPrimaryKey(DatabaseMetaData metaData, String tableName, String columnName) throws SQLException {
try (ResultSet rs = metaData.getPrimaryKeys(null, null, tableName)) {
while (rs.next()) {
String primaryKeyColumnName = rs.getString("COLUMN_NAME");
if (columnName.equals(primaryKeyColumnName)) {
return true;
}
}
return false;
}
}
/**
*
*
* @param conn
* @param dataDetailsSQL
* @param columnName
* @return
* @throws SQLException
* @throws ClassNotFoundException
* @throws IllegalAccessException
* @throws InstantiationException
*/
@Async
public String getMappingType(Connection conn, String dataDetailsSQL, String columnName) throws SQLException, ClassNotFoundException, IllegalAccessException, InstantiationException {
try (
PreparedStatement st = conn.prepareStatement(dataDetailsSQL);
ResultSet rs = st.executeQuery()) {
ResultSetMetaData rsmd = rs.getMetaData();
for (int i = 0; i < rsmd.getColumnCount(); i++) {
if (columnName.equals(rsmd.getColumnName(i + 1))) {
int lastDotIndex = rsmd.getColumnClassName(i + 1).lastIndexOf('.');
return rsmd.getColumnClassName(i + 1).substring(lastDotIndex + 1);
}
}
}
return null;
}
}

View File

@ -0,0 +1,36 @@
package com.etl.data.structure.controller;
import com.etl.common.core.domain.Result;
import com.etl.common.security.annotation.RequiresPermissions;
import com.etl.data.structure.domain.resp.AssetStructureResp;
import com.etl.data.structure.service.IAssetStructureService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* Controller
*
* @author Chao
* @ClassName: AssetStructureController Controller
* @CreateTime: 2024/4/22 10:09
*/
@RestController
@RequestMapping("/structure")
public class AssetStructureController {
@Autowired
private IAssetStructureService assetStructureService;
/**
*
*/
@RequiresPermissions("data:structure:list")
@PostMapping("/list")
public Result<AssetStructureResp> list() {
return Result.success(assetStructureService.selectAssetSouructureList());
}
}

View File

@ -0,0 +1,38 @@
package com.etl.data.structure.controller;
import com.etl.common.core.domain.Result;
import com.etl.common.security.annotation.RequiresPermissions;
import com.etl.data.structure.domain.resp.AssetStructureTableResp;
import com.etl.data.structure.service.IAssetStructureTableService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* Controller
*
* @author Chao
* @ClassName: AssetStructureTableController Controller
* @CreateTime: 2024/4/22 7:28
*/
@RestController
@RequestMapping("/structureTable")
public class AssetStructureTableController {
@Autowired
private IAssetStructureTableService assetStructureTableService;
/**
*
* @param assetStructureId
* @return
*/
@RequiresPermissions("data:structureTable:list")
@PostMapping("list/{assetStructureId}")
public Result<AssetStructureTableResp> list(@PathVariable("assetStructureId") Long assetStructureId) {
return Result.success(assetStructureTableService.selectAssetSouructureTableList(assetStructureId));
}
}

View File

@ -0,0 +1,67 @@
package com.etl.data.structure.controller;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.etl.common.core.domain.Result;
import com.etl.common.log.annotation.Log;
import com.etl.common.log.enums.BusinessType;
import com.etl.common.security.annotation.RequiresPermissions;
import com.etl.data.structure.domain.AssetTableDetails;
import com.etl.data.structure.service.IAssetTableDetailsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.Map;
import static com.etl.common.core.domain.Result.success;
/**
* Controller
*
* @author Chao
* @ClassName: AssetTableDetailsController Controller
* @CreateTime: 2024/4/29 2:25
*/
@RestController
@RequestMapping("/details")
public class AssetTableDetailsController {
@Autowired
private IAssetTableDetailsService assetTableDetailsService;
/**
*
*/
@RequiresPermissions("data:details:query")
@GetMapping(value = "/{assetStructureTableId}")
public Result findByAssetStructureTableIdList(@PathVariable("assetStructureTableId") Long assetStructureTableId) {
return success(assetTableDetailsService.list(
new LambdaQueryWrapper<AssetTableDetails>()
.eq(AssetTableDetails::getAssetStructureTableId, assetStructureTableId))
);
}
/**
*
*/
@RequiresPermissions("data:details:edit")
@Log(title = "修改数据源详情信息", businessType = BusinessType.UPDATE)
@PutMapping
public Result edit(@RequestBody AssetTableDetails assetTableDetails) {
return success(
assetTableDetailsService.updateAssetTableDetails(assetTableDetails)
);
}
/**
* value
*/
@RequiresPermissions("data:details:tableDetailsValue")
@PostMapping(value = "tableDetailsValue/{tableId}")
public Result<Map<String, Object>> getTableDetailsValueList(@PathVariable("tableId") Long tableId) {
Map<String, Object> hashObjectMap = assetTableDetailsService.getTableDetailsValueList(tableId);
System.out.println(hashObjectMap);
return success(hashObjectMap);
}
}

View File

@ -0,0 +1,14 @@
package com.etl.data.structure.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.etl.data.structure.domain.AssetStructure;
/**
* Mapper
*
* @author Chao
* @ClassName: AssetStructureMapper Mapper
* @CreateTime: 2024/4/22 2:12
*/
public interface AssetStructureMapper extends BaseMapper<AssetStructure> {
}

View File

@ -0,0 +1,14 @@
package com.etl.data.structure.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.etl.data.structure.domain.AssetStructureTable;
/**
* Mapper
*
* @author Chao
* @ClassName: AssetStructureTableMapper Mapper
* @CreateTime: 2024/4/22 5:23
*/
public interface AssetStructureTableMapper extends BaseMapper<AssetStructureTable> {
}

View File

@ -0,0 +1,15 @@
package com.etl.data.structure.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.etl.data.structure.domain.AssetTableDetails;
/**
* Mapper
*
* @author Chao
* @ClassName: AssetTableDetailsMapper Mapper
* @CreateTime: 2024/4/23 7:46
*/
public interface AssetTableDetailsMapper extends BaseMapper<AssetTableDetails> {
}

View File

@ -0,0 +1,22 @@
package com.etl.data.structure.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.etl.data.structure.domain.AssetStructure;
import com.etl.data.structure.domain.resp.AssetStructureResp;
/**
* Service
*
* @author Chao
* @ClassName: IAssetStructureService Service
* @CreateTime: 2024/4/22 2:08
*/
public interface IAssetStructureService extends IService<AssetStructure> {
/**
*
*
* @return
*/
AssetStructureResp selectAssetSouructureList();
}

View File

@ -0,0 +1,22 @@
package com.etl.data.structure.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.etl.data.structure.domain.AssetStructureTable;
import com.etl.data.structure.domain.resp.AssetStructureTableResp;
/**
* Service
*
* @author Chao
* @ClassName: IAssetStructureTableService Service
* @CreateTime: 2024/4/22 5:21
*/
public interface IAssetStructureTableService extends IService<AssetStructureTable> {
/**
*
* @param assetStructureId id
* @return
*/
AssetStructureTableResp selectAssetSouructureTableList(Long assetStructureId );
}

View File

@ -0,0 +1,40 @@
package com.etl.data.structure.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.etl.data.structure.domain.AssetTableDetails;
import java.util.List;
import java.util.Map;
/**
* Service
*
* @author Chao
* @ClassName: IAssetTableDetailsService Service
* @CreateTime: 2024/4/23 7:38
*/
public interface IAssetTableDetailsService extends IService<AssetTableDetails> {
/**
*
*
* @return
*/
public List<AssetTableDetails> selectAssetTableDetailsList();
/**
*
*
* @param assetTableDetails
* @return
*/
boolean updateAssetTableDetails(AssetTableDetails assetTableDetails);
/**
* value
*
* @param tableId
* @return
*/
Map<String, Object> getTableDetailsValueList(Long tableId);
}

View File

@ -0,0 +1,59 @@
package com.etl.data.structure.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.etl.data.structure.domain.AssetStructure;
import com.etl.data.structure.domain.AssetStructureTable;
import com.etl.data.structure.domain.resp.AssetStructureResp;
import com.etl.data.structure.mapper.AssetStructureMapper;
import com.etl.data.structure.service.IAssetStructureService;
import com.etl.data.structure.service.IAssetStructureTableService;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* Service
*
* @author Chao
* @ClassName: AssetStructureServiceImpl Service
* @CreateTime: 2024/4/22 2:10
*/
@Service
@Log4j2
public class AssetStructureServiceImpl extends ServiceImpl<AssetStructureMapper, AssetStructure> implements IAssetStructureService {
@Autowired
private IAssetStructureTableService assetStructureTableService;
/**
*
*
* @return
*/
@Override
public AssetStructureResp selectAssetSouructureList() {
// 创建一个列表
log.info("查询数据资产列表");
List<AssetStructure> assetStructureList = this.list();
log.info("查询数据资产表列表");
List<AssetStructureTable> assetStructureTableList = assetStructureTableService.list();
// 统计数据
long assetStructureTableCount = assetStructureTableList.size();
// 统计数据总数
long assetStructureTableDataCount;
assetStructureTableDataCount = assetStructureTableList.stream().mapToLong(AssetStructureTable::getTableDataCount).sum();
return AssetStructureResp.builder()
.assetStructureList(assetStructureList)
.assetStructureTableCount(assetStructureTableCount)
.assetStructureTableDataCount(assetStructureTableDataCount)
.build();
}
}

View File

@ -0,0 +1,89 @@
package com.etl.data.structure.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.etl.data.structure.domain.AssetStructureTable;
import com.etl.data.structure.domain.AssetTableDetails;
import com.etl.data.structure.domain.resp.AssetStructureTableResp;
import com.etl.data.structure.domain.resp.TableDetailsResp;
import com.etl.data.structure.mapper.AssetStructureTableMapper;
import com.etl.data.structure.service.IAssetStructureTableService;
import com.etl.data.structure.service.IAssetTableDetailsService;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.stream.Collectors;
/**
* Service
*
* @author Chao
* @ClassName: AssetStructureTableServiceImpl Service
* @CreateTime: 2024/4/22 5:22
*/
@Service
@Log4j2
public class AssetStructureTableServiceImpl extends ServiceImpl<AssetStructureTableMapper, AssetStructureTable> implements IAssetStructureTableService {
@Autowired
private IAssetTableDetailsService assetTableDetailsService;
/**
*
*
* @param assetStructureId id
* @return
*/
@Override
public AssetStructureTableResp selectAssetSouructureTableList(Long assetStructureId) {
// 检查assetStructureId是否为null
if (assetStructureId == null) {
log.info("数据资产id不能为空");
throw new IllegalArgumentException("数据资产id不能为空");
}
log.info("查询该数据资产表");
List<AssetStructureTable> assetStructureTableList = this.list(
new LambdaQueryWrapper<AssetStructureTable>()
.eq(AssetStructureTable::getAssetStructureId, assetStructureId)
);
// 如果assetStructureTableList为空则返回空的AssetStructureTableResp对象
if (assetStructureTableList.isEmpty()){
log.info("该数据资产表为空");
return AssetStructureTableResp.builder().build();
}
// 获取所有AssetTableDetails
List<AssetTableDetails> assetTableDetails = assetTableDetailsService.selectAssetTableDetailsList();
// 遍历assetStructureTableList获取每个AssetStructureTable的AssetTableDetails
log.info("开始过滤并获取每一个表的数据结构");
List<TableDetailsResp> assetTableDetailsList = assetStructureTableList.stream()
.map(assetStructureTable -> {
List<AssetTableDetails> matchingDetails = assetTableDetails.stream()
.filter(tableDetails -> assetStructureTable.getId().equals(tableDetails.getAssetStructureTableId()))
.collect(Collectors.toList());
return TableDetailsResp.builder()
.id(assetStructureTable.getId())
.assetStructureId(assetStructureTable.getAssetStructureId())
.tableName(assetStructureTable.getTableName())
.tableDataCount(assetStructureTable.getTableDataCount())
.tableNameAnnotation(assetStructureTable.getTableNameAnnotation())
.assetTableDetailsList(matchingDetails)
.build();
}).collect(Collectors.toList());
// 统计数据表总数
log.info("统计数据表总数");
long tableCount = assetStructureTableList.size();
log.info("统计数据表数据总数");
long tableDataCount = assetStructureTableList.stream().mapToLong(AssetStructureTable::getTableDataCount).sum();
log.info("------------------------------分隔符------------------------------------");
return AssetStructureTableResp.builder()
.tableDetailsRespList(assetTableDetailsList)
.tableCount(tableCount)
.tableDataCount(tableDataCount)
.build();
}
}

View File

@ -0,0 +1,175 @@
package com.etl.data.structure.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.etl.data.source.domain.DataSource;
import com.etl.data.source.service.IDataSourceService;
import com.etl.data.structure.domain.AssetStructure;
import com.etl.data.structure.domain.AssetStructureTable;
import com.etl.data.structure.domain.AssetTableDetails;
import com.etl.data.structure.mapper.AssetTableDetailsMapper;
import com.etl.data.structure.service.IAssetStructureService;
import com.etl.data.structure.service.IAssetStructureTableService;
import com.etl.data.structure.service.IAssetTableDetailsService;
import com.etl.data.type.domain.DataType;
import com.etl.data.type.service.IDataTypeService;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import java.sql.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* Service
*
* @author Chao
* @ClassName: AssetTableDetailsServiceImpl
* @CreateTime: 2024/4/23 7:45
*/
@Service
@Log4j2
public class AssetTableDetailsServiceImpl extends ServiceImpl<AssetTableDetailsMapper, AssetTableDetails> implements IAssetTableDetailsService {
@Autowired
private IAssetStructureTableService assetStructureTableService;
@Autowired
private IAssetStructureService assetStructureService;
@Lazy
@Autowired
private IDataSourceService dataSourceService;
@Autowired
private IDataTypeService dataTypeService;
/**
*
*
* @return
*/
@Override
public List<AssetTableDetails> selectAssetTableDetailsList() {
log.info("获取所有数据详情列表");
return this.list();
}
@Override
public boolean updateAssetTableDetails(AssetTableDetails assetTableDetails) {
if ("Y".equals(assetTableDetails.getYesNoDictionary())) {
return this.update(
new LambdaUpdateWrapper<AssetTableDetails>()
.eq(AssetTableDetails::getId, assetTableDetails.getId())
.set(AssetTableDetails::getYesNoDictionary, assetTableDetails.getYesNoDictionary())
.set(AssetTableDetails::getMappingDictionary, assetTableDetails.getMappingDictionary())
);
} else {
return this.update(
new LambdaUpdateWrapper<AssetTableDetails>()
.eq(AssetTableDetails::getId, assetTableDetails.getId())
.set(AssetTableDetails::getYesNoDictionary, assetTableDetails.getYesNoDictionary())
.set(AssetTableDetails::getYesNoDictionary, "")
);
}
}
/**
* value
*
* @param tableId id
* @return value
*/
@Override
public Map<String, Object> getTableDetailsValueList(Long tableId) {
List<AssetTableDetails> assetTableDetailsList = this.list(
new LambdaQueryWrapper<AssetTableDetails>()
.eq(AssetTableDetails::getAssetStructureTableId, tableId)
);
Map<String, Object> stringObjectHashMap = new HashMap<>();
// 获取所有字段的名字
List<String> strings = assetTableDetailsList.stream().map(AssetTableDetails::getName).toList();
//获取表名
AssetStructureTable structureTable = assetStructureTableService.getOne(
new LambdaQueryWrapper<AssetStructureTable>()
.eq(AssetStructureTable::getId, tableId)
);
// 获取数据源
AssetStructure assetStructure = assetStructureService.getOne(
new LambdaQueryWrapper<AssetStructure>()
.eq(AssetStructure::getId, structureTable.getAssetStructureId())
);
// 获取数据信息
DataSource dataSource = dataSourceService.getOne(
new LambdaQueryWrapper<DataSource>()
.eq(DataSource::getId, assetStructure.getDataSourceSystemId())
);
DataType dataType = dataTypeService.getOne(
new LambdaQueryWrapper<DataType>()
.eq(DataType::getId, dataSource.getTypeId())
);
String driveClass = dataType.getDriverManager();
String jdbcUrl = dataType.getJdbcPre() + dataSource.getDataSourceIp() + ":" + dataSource.getDataSourcePort() + "/" + dataSource.getDataSourceDatabaseName() + "?" + dataSource.getAdditionalConfiguration();
if ("mysql".equals(dataType.getDataType())) {
log.info("MySQL");
Connection conn = null;
Statement st = null;
ResultSet rs = null;
String tableDetails = "";
for (AssetTableDetails assetTableDetails : assetTableDetailsList) {
tableDetails += assetTableDetails.getName() + ",";
}
// 去掉最后一个逗号
tableDetails = tableDetails.substring(0, tableDetails.length() - 1);
String sql = "select " + tableDetails + " from " + structureTable.getTableName();
try {
Class.forName(driveClass);
conn = DriverManager.getConnection(jdbcUrl, dataSource.getDataSourceUsername(), dataSource.getDataSourcePassword());
st = conn.createStatement();
rs = st.executeQuery(sql);
while (rs.next()) {
for (String s : strings) {
String s1 = rs.getString(s);
stringObjectHashMap.put(s,s1);
}
}
System.out.println("----------------------------------分割线----------------------------------------");
} catch (Exception e) {
log.info("连接失败");
}finally {
try {
if (conn != null) {
conn.close();
}
if (st != null) {
st.close();
}
if (rs != null) {
rs.close();
}
} catch (SQLException e) {
log.info("关闭资源失败");
throw new RuntimeException(e);
}
}
}
if ("oracle".equals(dataType.getDataType())) {
log.info("Oracle");
}
if ("sqlserver".equals(dataType.getDataType())) {
log.info("SQLServer");
}
return stringObjectHashMap;
}
}

View File

@ -0,0 +1,96 @@
package com.etl.data.type.controller;
import com.etl.common.core.domain.Result;
import com.etl.common.core.utils.poi.ExcelUtil;
import com.etl.common.core.web.controller.BaseController;
import com.etl.common.core.web.page.TableDataInfo;
import com.etl.common.log.annotation.Log;
import com.etl.common.log.enums.BusinessType;
import com.etl.common.security.annotation.RequiresPermissions;
import com.etl.data.type.domain.DataType;
import com.etl.data.type.service.IDataTypeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
/**
* Controller
*
* @author Chao
* @date 2024-04-21
*/
@RestController
@RequestMapping("/type")
public class DataTypeController extends BaseController {
@Autowired
private IDataTypeService dataTypeService;
/**
*
*/
@RequiresPermissions("data:type:list")
@GetMapping("/list")
public Result<TableDataInfo<DataType>> list(DataType dataType) {
startPage();
List<DataType> list = dataTypeService.selectDataTypeList(dataType);
return getDataTable(list);
}
@PostMapping("/list")
public Result<List<DataType>> list() {
return Result.success(dataTypeService.list());
}
/**
*
*/
@RequiresPermissions("data:type:export")
@Log(title = "数据源类型", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, DataType dataType) {
List<DataType> list = dataTypeService.selectDataTypeList(dataType);
ExcelUtil<DataType> util = new ExcelUtil<DataType>(DataType.class);
util.exportExcel(response, list, "数据源类型数据");
}
/**
*
*/
@RequiresPermissions("data:type:query")
@GetMapping(value = "/{id}")
public Result getInfo(@PathVariable("id") Long id) {
return success(dataTypeService.selectDataTypeById(id));
}
/**
*
*/
@RequiresPermissions("data:type:add")
@Log(title = "数据源类型", businessType = BusinessType.INSERT)
@PostMapping
public Result add(@RequestBody DataType dataType) {
return toAjax(dataTypeService.insertDataType(dataType));
}
/**
*
*/
@RequiresPermissions("data:type:edit")
@Log(title = "数据源类型", businessType = BusinessType.UPDATE)
@PutMapping
public Result edit(@RequestBody DataType dataType) {
return toAjax(dataTypeService.updateDataType(dataType));
}
/**
*
*/
@RequiresPermissions("data:type:remove")
@Log(title = "数据源类型", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public Result remove(@PathVariable Long[] ids) {
return toAjax(dataTypeService.deleteDataTypeByIds(ids));
}
}

View File

@ -0,0 +1,62 @@
package com.etl.data.type.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.etl.data.type.domain.DataType;
import java.util.List;
/**
* Mapper
*
* @author Chao
* @date 2024-04-21
*/
public interface DataTypeMapper extends BaseMapper<DataType> {
/**
*
*
* @param id
* @return
*/
public DataType selectDataTypeById(Long id);
/**
*
*
* @param dataType
* @return
*/
public List<DataType> selectDataTypeList(DataType dataType);
/**
*
*
* @param dataType
* @return
*/
public int insertDataType(DataType dataType);
/**
*
*
* @param dataType
* @return
*/
public int updateDataType(DataType dataType);
/**
*
*
* @param id
* @return
*/
public int deleteDataTypeById(Long id);
/**
*
*
* @param ids
* @return
*/
public int deleteDataTypeByIds(Long[] ids);
}

View File

@ -0,0 +1,62 @@
package com.etl.data.type.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.etl.data.type.domain.DataType;
import java.util.List;
/**
* Service
*
* @author Chao
* @date 2024-04-21
*/
public interface IDataTypeService extends IService<DataType> {
/**
*
*
* @param id
* @return
*/
public DataType selectDataTypeById(Long id);
/**
*
*
* @param dataType
* @return
*/
public List<DataType> selectDataTypeList(DataType dataType);
/**
*
*
* @param dataType
* @return
*/
public int insertDataType(DataType dataType);
/**
*
*
* @param dataType
* @return
*/
public int updateDataType(DataType dataType);
/**
*
*
* @param ids
* @return
*/
public int deleteDataTypeByIds(Long[] ids);
/**
*
*
* @param id
* @return
*/
public int deleteDataTypeById(Long id);
}

View File

@ -0,0 +1,112 @@
package com.etl.data.type.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.etl.common.core.utils.DateUtils;
import com.etl.data.type.domain.DataType;
import com.etl.data.type.mapper.DataTypeMapper;
import com.etl.data.type.service.IDataTypeService;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* Service
*
* @author Chao
* @date 2024-04-21
*/
@Service
@Log4j2
public class DataTypeServiceImpl extends ServiceImpl<DataTypeMapper, DataType> implements IDataTypeService {
@Autowired
private DataTypeMapper dataTypeMapper;
/**
*
*
* @param id
* @return
*/
@Override
public DataType selectDataTypeById(Long id) {
log.info("查询数据源类型");
return dataTypeMapper.selectDataTypeById(id);
}
/**
*
*
* @param dataType
* @return
*/
@Override
public List<DataType> selectDataTypeList(DataType dataType) {
log.info("获取所有数据源类型列表");
return dataTypeMapper.selectDataTypeList(dataType);
}
/**
*
*
* @param dataType
* @return
*/
@Override
public int insertDataType(DataType dataType) {
dataType.setCreateTime(DateUtils.getNowDate());
dataType.setDataType(lowerCase(dataType.getDataType()));
log.info("新增数据源类型");
return dataTypeMapper.insertDataType(dataType);
}
/**
*
*
* @param dataType
* @return
*/
@Override
public int updateDataType(DataType dataType) {
dataType.setUpdateTime(DateUtils.getNowDate());
dataType.setDataType(lowerCase(dataType.getDataType()));
log.info("新增数据源类型");
return dataTypeMapper.updateDataType(dataType);
}
/**
*
*
* @param ids
* @return
*/
@Override
public int deleteDataTypeByIds(Long[] ids) {
log.info("批量删除数据源类型");
return dataTypeMapper.deleteDataTypeByIds(ids);
}
/**
*
*
* @param id
* @return
*/
@Override
public int deleteDataTypeById(Long id) {
log.info("删除数据源类型");
return dataTypeMapper.deleteDataTypeById(id);
}
/**
*
* @param str
* @return
*/
public static String lowerCase(String str){
log.info("添加修改数据源类型时将所有的大写转换成小写并清除中间所有的空格");
return str.toLowerCase().replaceAll(" ","");
}
}

View File

@ -0,0 +1,2 @@
Spring Boot Version: ${spring-boot.version}
Spring Application Name: ${spring.application.name}

View File

@ -0,0 +1,35 @@
# Tomcat
server:
port: 9302
# Spring
spring:
application:
# 应用名称
name: etl-data-source
profiles:
# 环境配置
active: dev
cloud:
nacos:
discovery:
# 服务注册地址
server-addr: 192.168.23.133:8848
# 命名空间
namespace: etl
config:
# 配置中心地址
server-addr: 192.168.23.133:8848
# 命名空间
namespace: etl
# 配置文件格式
file-extension: yml
# 共享配置
shared-configs:
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
# 主启动类 允许循环依赖
main:
allow-circular-references: true
logging:
level:
com.etl.system.mapper: DEBUG

View File

@ -0,0 +1,74 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
<!-- 日志存放路径 -->
<property name="log.path" value="logs/etl-system"/>
<!-- 日志输出格式 -->
<property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n"/>
<!-- 控制台输出 -->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
</appender>
<!-- 系统日志输出 -->
<appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/info.log</file>
<!-- 循环政策:基于时间创建日志文件 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志文件名格式 -->
<fileNamePattern>${log.path}/info.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 日志最大的历史 60天 -->
<maxHistory>60</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- 过滤的级别 -->
<level>INFO</level>
<!-- 匹配时的操作:接收(记录) -->
<onMatch>ACCEPT</onMatch>
<!-- 不匹配时的操作:拒绝(不记录) -->
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/error.log</file>
<!-- 循环政策:基于时间创建日志文件 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志文件名格式 -->
<fileNamePattern>${log.path}/error.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 日志最大的历史 60天 -->
<maxHistory>60</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- 过滤的级别 -->
<level>ERROR</level>
<!-- 匹配时的操作:接收(记录) -->
<onMatch>ACCEPT</onMatch>
<!-- 不匹配时的操作:拒绝(不记录) -->
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 系统模块日志级别控制 -->
<logger name="com.etl" level="info"/>
<!-- Spring日志级别控制 -->
<logger name="org.springframework" level="warn"/>
<root level="info">
<appender-ref ref="console"/>
</root>
<!--系统操作日志-->
<root level="info">
<appender-ref ref="file_info"/>
<appender-ref ref="file_error"/>
</root>
</configuration>

View File

@ -0,0 +1,130 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.etl.data.source.mapper.DataSourceMapper">
<resultMap type="com.etl.data.source.domain.DataSource" id="DataSourceResult">
<result property="id" column="id" />
<result property="dataSourceName" column="data_source_name" />
<result property="dataSourceSystemName" column="data_source_system_name" />
<result property="typeId" column="type_id" />
<result property="dataSourceIp" column="data_source_ip" />
<result property="dataSourcePort" column="data_source_port" />
<result property="dataSourceDatabaseName" column="data_source_database_name" />
<result property="dataSourceUsername" column="data_source_username" />
<result property="dataSourcePassword" column="data_source_password" />
<result property="additionalConfiguration" column="additional_configuration" />
<result property="status" column="status" />
<result property="remark" column="remark" />
<result property="initialNumberOfConnections" column="initial_number_of_connections" />
<result property="maximumNumberOfConnections" column="maximum_number_of_connections" />
<result property="maximumWaitingTime" column="maximum_waiting_time" />
<result property="maximumWaitingTimes" column="maximum_waiting_times" />
<result property="createBy" column="create_by" />
<result property="createTime" column="create_time" />
<result property="updateBy" column="update_by" />
<result property="updateTime" column="update_time" />
</resultMap>
<sql id="selectDataSourceVo">
select id, data_source_name, data_source_system_name, type_id, data_source_ip, data_source_port, data_source_database_name, data_source_username, data_source_password, additional_configuration, status, remark, initial_number_of_connections, maximum_number_of_connections, maximum_waiting_time, maximum_waiting_times, create_by, create_time, update_by, update_time from data_source
</sql>
<select id="selectDataSourceList" parameterType="com.etl.data.source.domain.DataSource" resultMap="DataSourceResult">
<include refid="selectDataSourceVo"/>
<where>
<if test="typeId != null and typeId != ''"> and type_id = #{typeId}</if>
<if test="dataSourceName != null and dataSourceName != ''"> and data_source_name like concat('%', #{dataSourceName}, '%')</if>
<if test="dataSourceSystemName != null and dataSourceSystemName != ''"> and data_source_system_name like concat('%', #{dataSourceSystemName}, '%')</if>
</where>
</select>
<select id="selectDataSourceById" parameterType="Long" resultMap="DataSourceResult">
<include refid="selectDataSourceVo"/>
where id = #{id}
</select>
<insert id="insertDataSource" parameterType="com.etl.data.source.domain.DataSource" useGeneratedKeys="true" keyProperty="id">
insert into data_source
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="dataSourceName != null">data_source_name,</if>
<if test="dataSourceSystemName != null">data_source_system_name,</if>
<if test="typeId != null">type_id,</if>
<if test="dataSourceIp != null">data_source_ip,</if>
<if test="dataSourcePort != null">data_source_port,</if>
<if test="dataSourceDatabaseName != null">data_source_database_name,</if>
<if test="dataSourceUsername != null">data_source_username,</if>
<if test="dataSourcePassword != null">data_source_password,</if>
<if test="additionalConfiguration != null">additional_configuration,</if>
<if test="status != null">status,</if>
<if test="remark != null">remark,</if>
<if test="initialNumberOfConnections != null">initial_number_of_connections,</if>
<if test="maximumNumberOfConnections != null">maximum_number_of_connections,</if>
<if test="maximumWaitingTime != null">maximum_waiting_time,</if>
<if test="maximumWaitingTimes != null">maximum_waiting_times,</if>
<if test="createBy != null">create_by,</if>
<if test="createTime != null">create_time,</if>
<if test="updateBy != null">update_by,</if>
<if test="updateTime != null">update_time,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="dataSourceName != null">#{dataSourceName},</if>
<if test="dataSourceSystemName != null">#{dataSourceSystemName},</if>
<if test="typeId != null">#{typeId},</if>
<if test="dataSourceIp != null">#{dataSourceIp},</if>
<if test="dataSourcePort != null">#{dataSourcePort},</if>
<if test="dataSourceDatabaseName != null">#{dataSourceDatabaseName},</if>
<if test="dataSourceUsername != null">#{dataSourceUsername},</if>
<if test="dataSourcePassword != null">#{dataSourcePassword},</if>
<if test="additionalConfiguration != null">#{additionalConfiguration},</if>
<if test="status != null">#{status},</if>
<if test="remark != null">#{remark},</if>
<if test="initialNumberOfConnections != null">#{initialNumberOfConnections},</if>
<if test="maximumNumberOfConnections != null">#{maximumNumberOfConnections},</if>
<if test="maximumWaitingTime != null">#{maximumWaitingTime},</if>
<if test="maximumWaitingTimes != null">#{maximumWaitingTimes},</if>
<if test="createBy != null">#{createBy},</if>
<if test="createTime != null">#{createTime},</if>
<if test="updateBy != null">#{updateBy},</if>
<if test="updateTime != null">#{updateTime},</if>
</trim>
</insert>
<update id="updateDataSource" parameterType="com.etl.data.source.domain.DataSource">
update data_source
<trim prefix="SET" suffixOverrides=",">
<if test="dataSourceName != null">data_source_name = #{dataSourceName},</if>
<if test="dataSourceSystemName != null">data_source_system_name = #{dataSourceSystemName},</if>
<if test="typeId != null">type_id = #{typeId},</if>
<if test="dataSourceIp != null">data_source_ip = #{dataSourceIp},</if>
<if test="dataSourcePort != null">data_source_port = #{dataSourcePort},</if>
<if test="dataSourceDatabaseName != null">data_source_database_name = #{dataSourceDatabaseName},</if>
<if test="dataSourceUsername != null">data_source_username = #{dataSourceUsername},</if>
<if test="dataSourcePassword != null">data_source_password = #{dataSourcePassword},</if>
<if test="additionalConfiguration != null">additional_configuration = #{additionalConfiguration},</if>
<if test="status != null">status = #{status},</if>
<if test="remark != null">remark = #{remark},</if>
<if test="initialNumberOfConnections != null">initial_number_of_connections = #{initialNumberOfConnections},</if>
<if test="maximumNumberOfConnections != null">maximum_number_of_connections = #{maximumNumberOfConnections},</if>
<if test="maximumWaitingTime != null">maximum_waiting_time = #{maximumWaitingTime},</if>
<if test="maximumWaitingTimes != null">maximum_waiting_times = #{maximumWaitingTimes},</if>
<if test="createBy != null">create_by = #{createBy},</if>
<if test="createTime != null">create_time = #{createTime},</if>
<if test="updateBy != null">update_by = #{updateBy},</if>
<if test="updateTime != null">update_time = #{updateTime},</if>
</trim>
where id = #{id}
</update>
<delete id="deleteDataSourceById" parameterType="Long">
delete from data_source where id = #{id}
</delete>
<delete id="deleteDataSourceByIds" parameterType="String">
delete from data_source where id in
<foreach item="id" collection="array" open="(" separator="," close=")">
#{id}
</foreach>
</delete>
</mapper>

View File

@ -0,0 +1,84 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.etl.data.type.mapper.DataTypeMapper">
<resultMap type="com.etl.data.type.domain.DataType" id="DataTypeResult">
<result property="id" column="id" />
<result property="dataType" column="data_type" />
<result property="driverManager" column="driver_manager" />
<result property="jdbcPre" column="jdbc_pre" />
<result property="remark" column="remark" />
<result property="createBy" column="create_by" />
<result property="createTime" column="create_time" />
<result property="updateBy" column="update_by" />
<result property="updateTime" column="update_time" />
</resultMap>
<sql id="selectDataTypeVo">
select id, data_type, driver_manager, jdbc_pre, remark, create_by, create_time, update_by, update_time from data_type
</sql>
<select id="selectDataTypeList" parameterType="com.etl.data.type.domain.DataType" resultMap="DataTypeResult">
<include refid="selectDataTypeVo"/>
<where>
<if test="dataType != null and dataType != ''"> and data_type like concat('%', #{dataType}, '%')</if>
</where>
</select>
<select id="selectDataTypeById" parameterType="Long" resultMap="DataTypeResult">
<include refid="selectDataTypeVo"/>
where id = #{id}
</select>
<insert id="insertDataType" parameterType="com.etl.data.type.domain.DataType" useGeneratedKeys="true" keyProperty="id">
insert into data_type
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="dataType != null">data_type,</if>
<if test="driverManager != null">driver_manager,</if>
<if test="jdbcPre != null">jdbc_pre,</if>
<if test="remark != null">remark,</if>
<if test="createBy != null">create_by,</if>
<if test="createTime != null">create_time,</if>
<if test="updateBy != null">update_by,</if>
<if test="updateTime != null">update_time,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="dataType != null">#{dataType},</if>
<if test="driverManager != null">#{driverManager},</if>
<if test="jdbcPre != null">#{jdbcPre},</if>
<if test="remark != null">#{remark},</if>
<if test="createBy != null">#{createBy},</if>
<if test="createTime != null">#{createTime},</if>
<if test="updateBy != null">#{updateBy},</if>
<if test="updateTime != null">#{updateTime},</if>
</trim>
</insert>
<update id="updateDataType" parameterType="com.etl.data.type.domain.DataType">
update data_type
<trim prefix="SET" suffixOverrides=",">
<if test="dataType != null">data_type = #{dataType},</if>
<if test="driverManager != null">driver_manager = #{driverManager},</if>
<if test="jdbcPre != null">jdbc_pre = #{jdbcPre},</if>
<if test="remark != null">remark = #{remark},</if>
<if test="createBy != null">create_by = #{createBy},</if>
<if test="createTime != null">create_time = #{createTime},</if>
<if test="updateBy != null">update_by = #{updateBy},</if>
<if test="updateTime != null">update_time = #{updateTime},</if>
</trim>
where id = #{id}
</update>
<delete id="deleteDataTypeById" parameterType="Long">
delete from data_type where id = #{id}
</delete>
<delete id="deleteDataTypeByIds" parameterType="String">
delete from data_type where id in
<foreach item="id" collection="array" open="(" separator="," close=")">
#{id}
</foreach>
</delete>
</mapper>

View File

@ -0,0 +1,30 @@
<?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>
<parent>
<groupId>com.etl</groupId>
<artifactId>etl-modules</artifactId>
<version>3.6.3</version>
</parent>
<artifactId>etl-modules-data-source</artifactId>
<packaging>pom</packaging>
<modules>
<module>etl-modules-data-source-common</module>
<module>etl-modules-data-source-remote</module>
<module>etl-modules-data-source-server</module>
<module>etl-modules-data-source-clinet</module>
</modules>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<description>
etl-modules-data-source 数据源模块
</description>
</project>

View File

@ -0,0 +1,26 @@
<?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>
<parent>
<groupId>com.etl</groupId>
<artifactId>etl-modules-rule-engine</artifactId>
<version>3.6.3</version>
</parent>
<artifactId>etl-modules-rule-engine-common</artifactId>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>com.etl</groupId>
<artifactId>etl-common-core</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,82 @@
package com.etl.rule.engine.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.etl.common.core.annotation.Excel;
import com.etl.common.core.web.domain.BaseEntity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
/**
* engine_rule
*
* @author Chao
* @date 2024-05-02
*/
@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
@TableName("engine_rule")
public class EngineRule extends BaseEntity {
private static final long serialVersionUID = 1L;
/**
* ID
*/
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
*
*/
@Excel(name = "规则名称")
private String name;
/**
* (1- 2-)
*/
@Excel(name = "规则类型(1-规则模板 2-自定义模板)")
private String type;
/**
* (1- 2- 3-)
*/
@Excel(name = "规则作用域(1-数据字段 2-数据集 3-记录)")
private Long scope;
/**
*
*/
@Excel(name = "引擎编码")
private String encoding;
/**
* (Y- N-)
*/
@Excel(name = "是否激活(Y-激活 N-未激活)")
private String activatedOrNot;
/**
* (Y- N-)
*/
@Excel(name = "规则状态(Y-正常 N-停用)")
private String status;
/**
*
*/
@Excel(name = "描述")
private String description;
/**
*
*/
@Excel(name = "编辑代码文本")
private String codeText;
}

View File

@ -0,0 +1,88 @@
package com.etl.rule.engine.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.etl.common.core.annotation.Excel;
import com.etl.common.core.web.domain.BaseEntity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
/**
* engine_rule_version
*
* @author Chao
* @date 2024-05-07
*/
@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
@TableName("engine_rule_version")
public class EngineRuleVersion extends BaseEntity {
private static final long serialVersionUID = 1L;
/**
* ID
*/
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
* id
*/
@Excel(name = "规则id")
private Long engineRuleId;
/**
*
*/
@Excel(name = "版本类")
private String versionClass;
/**
*
*/
@Excel(name = "版本名")
private String versionName;
/**
*
*/
@Excel(name = "版本编码")
private String versionCode;
/**
* ( 1- 2- 3- 4-)
*/
@Excel(name = "状态( 1- 初始化 2- 待发布 3-已发布 4-其他)")
private Long versionType;
/**
* (Y - N- )
*/
@Excel(name = "是否激活(Y - 激活 N- 未激活)")
private String activatedOrNot;
/**
* (Y - N - D - )
*/
@Excel(name = "是否测试(Y - 测试通过 N - 通过不了 D - 待测试)")
private String yesNoTest;
/**
*
*/
@Excel(name = "引擎编码")
private String codeText;
/**
*
*/
@Excel(name = "描述")
private String description;
}

View File

@ -0,0 +1,92 @@
package com.etl.rule.engine.domain.resp;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.etl.rule.engine.domain.EngineRule;
import com.etl.rule.engine.domain.EngineRuleVersion;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
import java.util.List;
/**
*
*
* @author Chao
* @ClassName: EngineRuleAndEngineRuleVersionResp
* @CreateTime: 2024/5/7 8:17
*/
@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
public class EngineRuleAndEngineRuleVersionResp {
/**
* ID
*/
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
*
*/
private String name;
/**
* (1- 2-)
*/
private String type;
/**
* (1- 2- 3-)
*/
private Long scope;
/**
*
*/
private String encoding;
/**
* (Y- N-)
*/
private String activatedOrNot;
/**
* (Y- N-)
*/
private String status;
/**
*
*/
private String description;
/**
*
*/
private String codeText;
/**
*
*/
private List<EngineRuleVersion> engineRuleVersionList;
public static EngineRuleAndEngineRuleVersionResp engineRuleAndEngineRuleVersionBuild(EngineRule engineRule, List<EngineRuleVersion> ruleVersionList) {
return EngineRuleAndEngineRuleVersionResp.builder()
.id(engineRule.getId())
.name(engineRule.getName())
.type(engineRule.getType())
.scope(engineRule.getScope())
.encoding(engineRule.getEncoding())
.activatedOrNot(engineRule.getActivatedOrNot())
.status(engineRule.getStatus())
.description(engineRule.getDescription())
.codeText(engineRule.getCodeText())
.engineRuleVersionList(ruleVersionList)
.build();
}
}

View File

@ -0,0 +1,48 @@
package com.etl.rule.version.domain;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import com.etl.common.core.annotation.Excel;
import com.etl.common.core.web.domain.BaseEntity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
import lombok.experimental.SuperBuilder;
/**
*
*
* @author Chao
* @ClassName: VersionCode
* @CreateTime: 2024/5/12 8:29
*/
@Data
@SuperBuilder
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(callSuper = true)
@TableName("version_code")
public class VersionCode extends BaseEntity {
private static final long serialVersionUID = 1L;
/**
* ID
*/
@TableId(value = "id", type = IdType.AUTO)
private Long id;
/**
*
*/
@Excel(name = "名称")
private String name;
/**
*
*/
@Excel(name = "代码")
private String code;
}

View File

@ -0,0 +1,26 @@
<?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>
<parent>
<groupId>com.etl</groupId>
<artifactId>etl-modules-rule-engine</artifactId>
<version>3.6.3</version>
</parent>
<artifactId>etl-modules-rule-engine-remote</artifactId>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>com.etl</groupId>
<artifactId>etl-modules-rule-engine-common</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,88 @@
<?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>
<parent>
<groupId>com.etl</groupId>
<artifactId>etl-modules-rule-engine</artifactId>
<version>3.6.3</version>
</parent>
<artifactId>etl-modules-rule-engine-server</artifactId>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!-- SpringCloud Alibaba Nacos -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<!-- SpringCloud Alibaba Nacos Config -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
<!-- SpringCloud Alibaba Sentinel -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-sentinel</artifactId>
</dependency>
<!-- SpringBoot Actuator -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<!-- Swagger UI -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>${swagger.fox.version}</version>
</dependency>
<!-- Mysql Connector -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
</dependency>
<!-- ETL Common DataSource -->
<dependency>
<groupId>com.etl</groupId>
<artifactId>etl-common-datasource</artifactId>
</dependency>
<!-- ETL Common DataScope -->
<dependency>
<groupId>com.etl</groupId>
<artifactId>etl-common-datascope</artifactId>
</dependency>
<!-- ETL Common Log -->
<dependency>
<groupId>com.etl</groupId>
<artifactId>etl-common-log</artifactId>
</dependency>
<!-- ETL Common Swagger -->
<dependency>
<groupId>com.etl</groupId>
<artifactId>etl-common-swagger</artifactId>
</dependency>
<dependency>
<groupId>com.etl</groupId>
<artifactId>etl-modules-rule-engine-common</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,24 @@
package com.etl.rule;
import com.etl.common.security.annotation.EnableCustomConfig;
import com.etl.common.security.annotation.EnableMyFeignClients;
import com.etl.common.swagger.annotation.EnableCustomSwagger2;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;
/**
*
*
* @author Chao
*/
@EnableCustomConfig
@EnableCustomSwagger2
@EnableMyFeignClients
@SpringBootApplication
@EnableAsync
public class ETLRuleEngineApplication {
public static void main (String[] args) {
SpringApplication.run(ETLRuleEngineApplication.class, args);
}
}

View File

@ -0,0 +1,12 @@
package com.etl.rule.engine.action;
/**
*
*
* @author Chao
* @ClassName: ActionDiscard
* @CreateTime: 2024/5/9 10:01
*/
public class ActionDiscard {
}

View File

@ -0,0 +1,14 @@
package com.etl.rule.engine.classLoading;
/**
*
*
* @author Chao
* @ClassName: CustomClassLoader
* @CreateTime: 2024/5/4 2:10
*/
public class CustomClassLoader extends ClassLoader {
public Class<?> defineClassFromBytes(String name, byte[] data) {
return defineClass(name, data, 0, data.length);
}
}

View File

@ -0,0 +1,146 @@
package com.etl.rule.engine.controller;
import com.etl.common.core.domain.Result;
import com.etl.common.core.utils.poi.ExcelUtil;
import com.etl.common.core.web.controller.BaseController;
import com.etl.common.core.web.page.TableDataInfo;
import com.etl.common.log.annotation.Log;
import com.etl.common.log.enums.BusinessType;
import com.etl.common.security.annotation.RequiresPermissions;
import com.etl.rule.engine.domain.EngineRule;
import com.etl.rule.engine.domain.resp.EngineRuleAndEngineRuleVersionResp;
import com.etl.rule.engine.service.IEngineRuleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
/**
* Controller
*
* @author Chao
* @date 2024-05-02
*/
@RestController
@RequestMapping("/engine")
public class EngineRuleController extends BaseController {
@Autowired
private IEngineRuleService engineRuleService;
/**
*
*/
@RequiresPermissions("rule:engine:list")
@GetMapping("/list")
public Result<TableDataInfo<EngineRule>> list(EngineRule engineRule) {
startPage();
List<EngineRule> list = engineRuleService.selectEngineRuleList(engineRule);
return getDataTable(list);
}
/**
*
*/
@RequiresPermissions("rule:engine:export")
@Log(title = "引擎维护", businessType = BusinessType.EXPORT)
@PostMapping("/export")
public void export(HttpServletResponse response, EngineRule engineRule) {
List<EngineRule> list = engineRuleService.selectEngineRuleList(engineRule);
ExcelUtil<EngineRule> util = new ExcelUtil<EngineRule>(EngineRule.class);
util.exportExcel(response, list, "引擎维护数据");
}
/**
*
*/
@RequiresPermissions("rule:engine:query")
@GetMapping(value = "/{id}")
public Result getInfo(@PathVariable("id") Long id) {
return success(engineRuleService.selectEngineRuleById(id));
}
/**
*
*/
@RequiresPermissions("rule:engine:add")
@Log(title = "引擎维护", businessType = BusinessType.INSERT)
@PostMapping
public Result add(@RequestBody EngineRule engineRule) {
return toAjax(engineRuleService.insertEngineRule(engineRule));
}
/**
*
*/
@RequiresPermissions("rule:engine:edit")
@Log(title = "引擎维护", businessType = BusinessType.UPDATE)
@PutMapping
public Result edit(@RequestBody EngineRule engineRule) {
return toAjax(engineRuleService.updateEngineRule(engineRule));
}
/**
*
*/
@RequiresPermissions("rule:engine:remove")
@Log(title = "引擎维护", businessType = BusinessType.DELETE)
@DeleteMapping("/{ids}")
public Result remove(@PathVariable Long[] ids) {
return toAjax(engineRuleService.deleteEngineRuleByIds(ids));
}
/**
*
*/
@RequiresPermissions("rule:engine:editActivatedOrNot")
@Log(title = "引擎维护", businessType = BusinessType.UPDATE)
@PutMapping("/editActivatedOrNot")
public Result editActivatedOrNot(@RequestBody EngineRule engineRule) {
return success(engineRuleService.editEngineRuleActivatedOrNot(engineRule));
}
/**
*
*/
@RequiresPermissions("rule:engine:editStatus")
@Log(title = "引擎维护", businessType = BusinessType.UPDATE)
@PutMapping("/editStatus")
public Result editStatus(@RequestBody EngineRule engineRule) {
return toAjax(engineRuleService.editStatus(engineRule));
}
/**
*
*/
@RequiresPermissions("rule:engine:queryEngineAndEngineVersion")
@GetMapping(value = "queryEngineAndEngineVersion/{id}")
public Result<EngineRuleAndEngineRuleVersionResp> queryEngineAndEngineVersion(@PathVariable("id") Long id) {
return Result.success(engineRuleService.queryEngineAndEngineVersion(id));
}
/**
*
* @param engineRule
* @return
*/
@PostMapping("initializeRuleEngine")
public Result initializeRuleEngine(@RequestBody EngineRule engineRule) {
return engineRuleService.initializeRuleMaintenance(engineRule);
}
/**
*
* @param encoding
* @return
*/
@GetMapping(value = "/testMethod/{encoding}")
public Result testMethod(@PathVariable("encoding") String encoding) {
return engineRuleService.testMethod(encoding);
}
}

View File

@ -0,0 +1,47 @@
package com.etl.rule.engine.controller;
import com.etl.common.core.domain.Result;
import com.etl.common.log.annotation.Log;
import com.etl.common.log.enums.BusinessType;
import com.etl.common.security.annotation.RequiresPermissions;
import com.etl.rule.engine.domain.EngineRuleVersion;
import com.etl.rule.engine.service.IEngineRuleVersionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
/**
* Controller
*
* @author Chao
* @ClassName: EngineRuleVersionController Controller
* @CreateTime: 2024/5/7 6:46
*/
@RestController
@RequestMapping("/engineVersion")
public class EngineRuleVersionController {
@Autowired
private IEngineRuleVersionService engineRuleVersionService;
/**
*
*/
@RequiresPermissions("rule:engineVersion:add")
@Log(title = "引擎维护版本", businessType = BusinessType.INSERT)
@PostMapping
public Result add(@RequestBody EngineRuleVersion engineRuleVersion) {
return Result.success(engineRuleVersionService.saveEngineRuleVersion(engineRuleVersion));
}
/**
*
*/
@RequiresPermissions("rule:engineVersion:edit")
@Log(title = "引擎维护版本", businessType = BusinessType.UPDATE)
@PutMapping
public Result editStatus(@RequestBody EngineRuleVersion engineRuleVersion) {
return Result.success(engineRuleVersionService.updateEngineVersion(engineRuleVersion));
}
}

View File

@ -0,0 +1,62 @@
package com.etl.rule.engine.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.etl.rule.engine.domain.EngineRule;
import java.util.List;
/**
* Mapper
*
* @author Chao
* @date 2024-05-02
*/
public interface EngineRuleMapper extends BaseMapper<EngineRule> {
/**
*
*
* @param id
* @return
*/
public EngineRule selectEngineRuleById(Long id);
/**
*
*
* @param engineRule
* @return
*/
public List<EngineRule> selectEngineRuleList(EngineRule engineRule);
/**
*
*
* @param engineRule
* @return
*/
public int insertEngineRule(EngineRule engineRule);
/**
*
*
* @param engineRule
* @return
*/
public int updateEngineRule(EngineRule engineRule);
/**
*
*
* @param id
* @return
*/
public int deleteEngineRuleById(Long id);
/**
*
*
* @param ids
* @return
*/
public int deleteEngineRuleByIds(Long[] ids);
}

View File

@ -0,0 +1,15 @@
package com.etl.rule.engine.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.etl.rule.engine.domain.EngineRuleVersion;
/**
* Mapper
*
* @author Chao
* @ClassName: EngineRuleVersionMapper Mapper
* @CreateTime: 2024/5/7 6:44
*/
public interface EngineRuleVersionMapper extends BaseMapper<EngineRuleVersion> {
}

View File

@ -0,0 +1,15 @@
package com.etl.rule.engine.scope;
/**
* @Author: Chao
* @Description:
* @Version: 1.0
*/
public class DataModelContext {
private final DataSetContext dataSetContext;
public DataModelContext (DataSetContext dataSetContext) {
this.dataSetContext = dataSetContext;
}
}

View File

@ -0,0 +1,15 @@
package com.etl.rule.engine.scope;
/**
* @Author: Chao
* @Description:
* @Version: 1.0
*/
public class DataSetContext {
private final RecordContext recordContext;
public DataSetContext (RecordContext recordContext) {
this.recordContext = recordContext;
}
}

View File

@ -0,0 +1,15 @@
package com.etl.rule.engine.scope;
/**
* @Author: Chao
* @Description: /
* @Version: 1.0
*/
public class RecordContext {
private final TaskContext taskContext;
public RecordContext (TaskContext taskContext) {
this.taskContext = taskContext;
}
}

View File

@ -0,0 +1,13 @@
package com.etl.rule.engine.scope;
/**
* @Author: Chao
* @Description:
* @Version: 1.0
*/
public class TaskContext {
public static TaskContext build(){
return new TaskContext();
}
}

View File

@ -0,0 +1,92 @@
package com.etl.rule.engine.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.etl.common.core.domain.Result;
import com.etl.rule.engine.domain.EngineRule;
import com.etl.rule.engine.domain.resp.EngineRuleAndEngineRuleVersionResp;
import java.util.List;
/**
* Service
*
* @author Chao
* @date 2024-05-02
*/
public interface IEngineRuleService extends IService<EngineRule> {
/**
*
*
* @param id
* @return
*/
public EngineRule selectEngineRuleById(Long id);
/**
*
*
* @param engineRule
* @return
*/
public List<EngineRule> selectEngineRuleList(EngineRule engineRule);
/**
*
*
* @param engineRule
* @return
*/
public int insertEngineRule(EngineRule engineRule);
/**
*
*
* @param engineRule
* @return
*/
public int updateEngineRule(EngineRule engineRule);
/**
*
*
* @param ids
* @return
*/
public int deleteEngineRuleByIds(Long[] ids);
/**
*
*
* @param id
* @return
*/
public int deleteEngineRuleById(Long id);
Result initializeRuleMaintenance(EngineRule engineRule);
Result testMethod(String code);
/**
*
*
* @param engineRule
* @return
*/
boolean editEngineRuleActivatedOrNot(EngineRule engineRule);
/**
*
*
* @param engineRule
* @return
*/
boolean editStatus(EngineRule engineRule);
/**
*
* @param id
* @return
*/
EngineRuleAndEngineRuleVersionResp queryEngineAndEngineVersion(Long id);
}

View File

@ -0,0 +1,29 @@
package com.etl.rule.engine.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.etl.rule.engine.domain.EngineRuleVersion;
/**
* Service
*
* @author Chao
* @ClassName: IEngineRuleVersionService Service
* @CreateTime: 2024/5/7 6:42
*/
public interface IEngineRuleVersionService extends IService<EngineRuleVersion> {
/**
*
*
* @param engineRuleVersion
* @return
*/
boolean saveEngineRuleVersion(EngineRuleVersion engineRuleVersion);
/**
*
*
* @param engineRuleVersion
* @return
*/
boolean updateEngineVersion(EngineRuleVersion engineRuleVersion);
}

View File

@ -0,0 +1,288 @@
package com.etl.rule.engine.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.etl.common.core.domain.Result;
import com.etl.common.core.utils.DateUtils;
import com.etl.rule.engine.domain.EngineRule;
import com.etl.rule.engine.domain.EngineRuleVersion;
import com.etl.rule.engine.domain.resp.EngineRuleAndEngineRuleVersionResp;
import com.etl.rule.engine.mapper.EngineRuleMapper;
import com.etl.rule.engine.service.IEngineRuleService;
import com.etl.rule.engine.service.IEngineRuleVersionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import javax.tools.JavaCompiler;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
/**
* Service
*
* @author Chao
* @date 2024-05-02
*/
@Service
public class EngineRuleServiceImpl extends ServiceImpl<EngineRuleMapper, EngineRule> implements IEngineRuleService {
@Autowired
private EngineRuleMapper engineRuleMapper;
@Autowired
private IEngineRuleVersionService engineRuleVersionService;
/**
*
*
* @param id
* @return
*/
@Override
public EngineRule selectEngineRuleById(Long id) {
return engineRuleMapper.selectEngineRuleById(id);
}
/**
*
*
* @param engineRule
* @return
*/
@Override
public List<EngineRule> selectEngineRuleList(EngineRule engineRule) {
return engineRuleMapper.selectEngineRuleList(engineRule);
}
/**
*
*
* @param engineRule
* @return
*/
@Override
public int insertEngineRule(EngineRule engineRule) {
engineRule.setCreateTime(DateUtils.getNowDate());
String className = "Rule" + Character.toUpperCase(engineRule.getEncoding().charAt(0)) + engineRule.getEncoding().substring(1) + "Class";
engineRule.setCodeText("package com.etl.data.rule.domain;\n\n\n" +
"public class " + className + "{\n" +
"}");
return engineRuleMapper.insertEngineRule(engineRule);
}
/**
*
*
* @param engineRule
* @return
*/
@Override
public int updateEngineRule(EngineRule engineRule) {
engineRule.setUpdateTime(DateUtils.getNowDate());
return engineRuleMapper.updateEngineRule(engineRule);
}
/**
*
*
* @param ids
* @return
*/
@Override
public int deleteEngineRuleByIds(Long[] ids) {
return engineRuleMapper.deleteEngineRuleByIds(ids);
}
/**
*
*
* @param id
* @return
*/
@Override
public int deleteEngineRuleById(Long id) {
return engineRuleMapper.deleteEngineRuleById(id);
}
@Override
public Result initializeRuleMaintenance(EngineRule engineRule) {
try {
String className = "Rule" + Character.toUpperCase(engineRule.getEncoding().charAt(0)) + engineRule.getEncoding().substring(1) + "Class";
String javaPath = "D:\\Java\\etl\\dataProcess\\ETL-Cloud\\etl-modules\\etl-modules-data-source\\etl-modules-data-source-common\\src\\main\\java\\com\\etl\\data\\rule\\domain\\";
String classPath = "D:\\Java\\etl\\dataProcess\\ETL-Cloud\\etl-modules\\etl-modules-data-source\\etl-modules-data-source-common\\target\\classes";
String fileName = javaPath + className + ".java";
File file = new File(fileName);
File parentFile = file.getParentFile();
if (!parentFile.exists()) {
parentFile.mkdirs();
}
if (file.exists()) {
file.delete();
}
file.createNewFile();
FileWriter fileWriter = new FileWriter(file);
fileWriter.write(engineRule.getCodeText());
fileWriter.flush();
fileWriter.close();
JavaCompiler javaCompiler = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager fileManager = javaCompiler.getStandardFileManager(null, null, null);
Iterable fileObjects = fileManager.getJavaFileObjects(fileName);
List<String> options = Arrays.asList("-d", classPath);
JavaCompiler.CompilationTask cTask = javaCompiler.getTask(null, fileManager, null, options, null, fileObjects);
Boolean call = cTask.call();
fileManager.close();
if (call) {
return Result.success(null, "初始化成功");
}
} catch (IOException e) {
log.error(e.getMessage());
Result.error("初始化失败");
}
return Result.error(null, "初始化失败");
}
@Override
public Result testMethod(String encoding) {
String className = "Rule" + Character.toUpperCase(encoding.charAt(0)) + encoding.substring(1) + "Class";
String classPath = "etl-modules/etl-modules-data-source/etl-modules-data-source-common/target/classes/com/etl/data/rule/domain";
// String classPath = "D:\\Java\\etl\\dataProcess\\ETL-Cloud\\etl-modules\\etl-modules-data-source\\etl-modules-data-source-common\\target\\classes\\" + className.replace(".", "\\") + ".class";
try {
// 将路径转换为URL
URL classUrl = Paths.get(classPath).toUri().toURL();
// 创建一个只包含我们自定义路径的URLClassLoader
URLClassLoader classLoader = new URLClassLoader(new URL[]{classUrl});
// 使用自定义的ClassLoader加载类
Class<?> clazz = Class.forName("com.etl.data.rule.domain." + className, true, classLoader); // 替换YourClassName为你的类名
Object testInstance = clazz.newInstance(); // 或者使用getDeclaredConstructor().newInstance();
// byte[] classData = Files.readAllBytes(Paths.get(classPath));
// CustomClassLoader customClassLoader = new CustomClassLoader();
// Class<?> aClass = customClassLoader.defineClassFromBytes(className, classData);
// Object o = aClass.newInstance();
// Method[] methods = clazz.getMethods();
Method method = clazz.getMethod("main", String[].class);
method.invoke(null, new Object[]{null});
// 遍历所有方法,寻找第一个无参方法并执行
// for (Method method : methods) {
// if (method.getParameterTypes().length == 0) { // 检查方法是否有参数
// System.out.println("调用无参方法: " + method.getName());
// method.invoke(testInstance); // 调用找到的无参方法
// break; // 如果只需要调用第一个无参方法,则可以跳出循环
// }
// }
// customClassLoader = null;
} catch (Exception e) {
log.error(e.getMessage());
return Result.error("测试失败");
}
return Result.success(null, "测试成功");
}
/**
*
*
* @param engineRule
* @return
*/
@Override
public boolean editEngineRuleActivatedOrNot(EngineRule engineRule) {
String activateOrNot = null;
if ("Y".equals(engineRule.getStatus())) {
if ("Y".equals(engineRule.getActivatedOrNot())) {
activateOrNot = "N";
} else if ("N".equals(engineRule.getActivatedOrNot())) {
activateOrNot = "Y";
}
return this.update(
new LambdaUpdateWrapper<EngineRule>()
.eq(EngineRule::getId, engineRule.getId())
.set(EngineRule::getActivatedOrNot, activateOrNot)
);
}
return false;
}
/**
*
*
* @param engineRule
* @return
*/
@Override
public boolean editStatus(EngineRule engineRule) {
String status = null;
if ("Y".equals(engineRule.getStatus())) {
status = "N";
} else if ("N".equals(engineRule.getStatus())) {
status = "Y";
}
return this.update(
new LambdaUpdateWrapper<EngineRule>()
.eq(EngineRule::getId, engineRule.getId())
.set(EngineRule::getStatus, status)
);
}
/**
*
*
* @param id
* @return
*/
@Override
public EngineRuleAndEngineRuleVersionResp queryEngineAndEngineVersion(Long id) {
// 引擎维护
EngineRule engineRule = this.getOne(
new LambdaQueryWrapper<EngineRule>()
.eq(EngineRule::getId, id)
);
List<EngineRuleVersion> engineRuleVersionList = engineRuleVersionService.list();
List<EngineRuleVersion> ruleVersionList = engineRuleVersionList.stream()
.filter(
engineRuleVersion -> engineRuleVersion.getEngineRuleId().equals(engineRule.getId())
).collect(Collectors.toList());
return EngineRuleAndEngineRuleVersionResp.engineRuleAndEngineRuleVersionBuild(engineRule, ruleVersionList);
}
public String getTypeCodeText(EngineRule engineRule) {
String className = Character.toUpperCase(engineRule.getEncoding().charAt(0)) + engineRule.getEncoding().substring(1);
switch (engineRule.getType()) {
case "data-set":
className = className + "DataSetContext";
return "package com.etl.data.rule.domain;\n" +
"\n" +
"public class " + className + " {\n" +
"\n" +
" private final RecordContext recordContext;\n" +
"\n" +
" public DataSetContext (RecordContext recordContext) {\n" +
" this.recordContext = recordContext;\n" +
" }\n" +
"}\n";
case "data-record":
return "记录";
default:
return "数据字段";
}
}
}

View File

@ -0,0 +1,47 @@
package com.etl.rule.engine.service.impl;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.etl.rule.engine.domain.EngineRuleVersion;
import com.etl.rule.engine.mapper.EngineRuleVersionMapper;
import com.etl.rule.engine.service.IEngineRuleVersionService;
import org.springframework.stereotype.Service;
/**
* Service
*
* @author Chao
* @ClassName: EngineRuleVersionServiceImpl Service
* @CreateTime: 2024/5/7 6:43
*/
@Service
public class EngineRuleVersionServiceImpl extends ServiceImpl<EngineRuleVersionMapper, EngineRuleVersion> implements IEngineRuleVersionService {
/**
*
*
* @param engineRuleVersion
* @return
*/
@Override
public boolean saveEngineRuleVersion(EngineRuleVersion engineRuleVersion) {
engineRuleVersion.setYesNoTest("D");
return this.save(engineRuleVersion);
}
/**
*
*
* @param engineRuleVersion
* @return
*/
@Override
public boolean updateEngineVersion(EngineRuleVersion engineRuleVersion) {
return this.update(
new LambdaUpdateWrapper<EngineRuleVersion>()
.eq(EngineRuleVersion::getId, engineRuleVersion.getId())
.set(EngineRuleVersion::getCodeText, engineRuleVersion.getCodeText())
.set(EngineRuleVersion::getVersionType, 2)
);
}
}

View File

@ -0,0 +1,63 @@
package com.etl.rule.engine.utils;
import javax.tools.JavaCompiler;
import javax.tools.JavaFileObject;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
import java.io.File;
import java.io.FileWriter;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.List;
public class DynamicCompilation {
/**
* Java Compiler API
* Java
*
* @param args 使
* @throws Exception I/O
*/
public static void main(String[] args) throws Exception {
// 1. 初始化Java编译器实例利用ToolProvider获取系统默认的Java编译器。
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
// 2. 获取标准的文件管理器,用于处理源文件、类文件等。
StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
try {
// 3. 创建一个临时的Java源文件"HelloWorld.java",并向其中写入简单的打印"Hello World!"代码。
File sourceFile = new File("HelloWorld.java");
FileWriter writer = new FileWriter(sourceFile);
writer.write("public class HelloWorld { public static void main(String[] args) { System.out.println(\"Hello World!\"); } }");
writer.close();
// 4. 准备编译任务,指定源文件并配置编译选项(本例中未设置额外选项)。
Iterable<? extends JavaFileObject> compilationUnits = fileManager.getJavaFileObjectsFromFiles(List.of(sourceFile));
JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager, null, null, null, compilationUnits);
// 5. 执行编译任务并检查是否成功。
boolean success = task.call();
// 6. 若编译成功,则动态加载并执行新生成的类。
if (success) {
// 动态创建类加载器,指向当前目录以查找新编译的类。
URLClassLoader classLoader = new URLClassLoader(new URL[]{new File(".").toURI().toURL()});
// 加载名为"HelloWorld"的类。
Class<?> clazz = classLoader.loadClass("HelloWorld");
// 获取该类的main方法并执行它。
Method method = clazz.getMethod("main", String[].class);
// 传递null作为main方法的args参数。
method.invoke(null, (Object) null);
}
} finally {
// 注意实际应用中应考虑在此处关闭fileManager等资源但为简化示例此处省略。
}
}
}

View File

@ -0,0 +1,64 @@
package com.etl.rule.engine.utils;
import javax.tools.*;
import java.io.File;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Collections;
/**
* @author Han
*/
public class DynamicCompilationExample {
/**
* Java
* Javamain
*
* @param args 使
* @throws Exception
*/
public static void main(String[] args) throws Exception {
// 获取系统Java编译器实例
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
// 创建诊断信息收集器,用于收集编译过程中的错误和警告
DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<>();
// 获取标准Java文件管理器实例 获取一个标准的文件管理器用于处理源文件、类文件等。这里它使用了之前创建的诊断收集器并且没有指定特定的字符集或locale
StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnostics, null, null);
// 定义要编译的Java代码字符串
String code = "public class HelloWorld {\n" +
" public static void main(String[] args) {\n" +
" System.out.println(\"Hello, world!\");\n" +
" }\n" +
"}";
// 将代码字符串转换为Java源文件对象
JavaFileObject source = new JavaSourceFromString("HelloWorld", code);
// 创建编译任务并执行
Iterable<? extends JavaFileObject> compilationUnits = Collections.singletonList(source);
JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager, diagnostics, null, null, compilationUnits);
boolean success = task.call();
// 关闭文件管理器
fileManager.close();
// 处理编译结果
if (success) {
System.out.println("编译成功。");
// 使用反射加载并执行编译后的类
URLClassLoader classLoader = new URLClassLoader(new URL[]{new File(".").toURI().toURL()});
Class<?> clazz = classLoader.loadClass("HelloWorld");
Method method = clazz.getMethod("main", String[].class);
method.invoke(null, new Object[]{null});
} else {
System.out.println("编译失败.");
// 输出诊断信息,如编译错误或警告
for (Diagnostic<? extends JavaFileObject> diagnostic : diagnostics.getDiagnostics()) {
System.out.println(diagnostic.getMessage(null));
}
}
}
}

View File

@ -0,0 +1,29 @@
package com.etl.rule.engine.utils;
import javax.tools.SimpleJavaFileObject;
import java.net.URI;
/**
* JavaJava
* @author Han
*/
public class JavaSourceFromString extends SimpleJavaFileObject {
final String code;
/**
* 使Java
*
* @param className
* @param code
*/
JavaSourceFromString(String className, String code) {
super(URI.create("string:///" + className.replace('.', '/') + Kind.SOURCE.extension), Kind.SOURCE);
this.code = code;
}
@Override
public CharSequence getCharContent(boolean ignoreEncodingErrors) {
return code;
}
}

View File

@ -0,0 +1,52 @@
package com.etl.rule.version.controller;
import com.etl.common.core.domain.Result;
import com.etl.common.core.web.controller.BaseController;
import com.etl.common.security.annotation.RequiresPermissions;
import com.etl.rule.version.service.IVersionCodeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
/**
*
*
* @author Chao
* @ClassName: VersionCode
* @CreateTime: 2024/5/12 8:33
*/
@RestController
@RequestMapping("/versionCode")
public class VersionCodeController extends BaseController {
@Autowired
private IVersionCodeService versionCodeService;
/**
*
*
* @return versionCode
*/
@RequiresPermissions("rule:versionCode:list")
@PostMapping("/list")
public Result list() {
return success(versionCodeService.versionCodeList());
}
/**
* id
*
* @param id
* @return versionCod
*/
@RequiresPermissions("rule:versionCode:getVersionCode")
@GetMapping("getVersionCode/{id}")
public Result getVersionCode(@PathVariable("id") Long id) {
return success(versionCodeService.getVersionCode(id));
}
@RequiresPermissions("rule:versionCode:add")
@PostMapping("/add")
public Result add(@RequestBody)
}

View File

@ -0,0 +1,15 @@
package com.etl.rule.version.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.etl.rule.version.domain.VersionCode;
/**
* mapper
*
* @author Chao
* @ClassName: VersionCodeMapper mapper
* @CreateTime: 2024/5/12 8:39
*/
public interface VersionCodeMapper extends BaseMapper<VersionCode> {
}

View File

@ -0,0 +1,30 @@
package com.etl.rule.version.service;
import com.baomidou.mybatisplus.extension.service.IService;
import com.etl.rule.version.domain.VersionCode;
import java.util.List;
/**
* Service
*
* @author Chao
* @ClassName: IVersionCodeService Service
* @CreateTime: 2024/5/12 8:37
*/
public interface IVersionCodeService extends IService<VersionCode> {
/**
*
*
* @return List<VersionCode>
*/
List<VersionCode> versionCodeList();
/**
* idversionCode
*
* @param id id
* @return VersionCode
*/
VersionCode getVersionCode(Long id);
}

View File

@ -0,0 +1,45 @@
package com.etl.rule.version.service.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.etl.rule.version.domain.VersionCode;
import com.etl.rule.version.mapper.VersionCodeMapper;
import com.etl.rule.version.service.IVersionCodeService;
import org.springframework.stereotype.Service;
import java.util.List;
/**
* Service
*
* @author Chao
* @ClassName: VersionCodeService Service
* @CreateTime: 2024/5/12 8:38
*/
@Service
public class VersionCodeServiceImpl extends ServiceImpl<VersionCodeMapper, VersionCode> implements IVersionCodeService {
/**
*
*
* @return List<VersionCode>
*/
@Override
public List<VersionCode> versionCodeList() {
return this.list();
}
/**
* idVersionCode
*
* @param id id
* @return VersionCode
*/
@Override
public VersionCode getVersionCode(Long id) {
return this.getOne(
new LambdaQueryWrapper<VersionCode>()
.eq(VersionCode::getId, id)
);
}
}

View File

@ -0,0 +1,2 @@
Spring Boot Version: ${spring-boot.version}
Spring Application Name: ${spring.application.name}

View File

@ -0,0 +1,35 @@
# Tomcat
server:
port: 9303
# Spring
spring:
application:
# 应用名称
name: etl-rule-engine
profiles:
# 环境配置
active: dev
cloud:
nacos:
discovery:
# 服务注册地址
server-addr: 192.168.23.133:8848
# 命名空间
namespace: etl
config:
# 配置中心地址
server-addr: 192.168.23.133:8848
# 命名空间
namespace: etl
# 配置文件格式
file-extension: yml
# 共享配置
shared-configs:
- application-${spring.profiles.active}.${spring.cloud.nacos.config.file-extension}
# 主启动类 允许循环依赖
main:
allow-circular-references: true
logging:
level:
com.etl.system.mapper: DEBUG

View File

@ -0,0 +1,74 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
<!-- 日志存放路径 -->
<property name="log.path" value="logs/etl-system"/>
<!-- 日志输出格式 -->
<property name="log.pattern" value="%d{HH:mm:ss.SSS} [%thread] %-5level %logger{20} - [%method,%line] - %msg%n"/>
<!-- 控制台输出 -->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
</appender>
<!-- 系统日志输出 -->
<appender name="file_info" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/info.log</file>
<!-- 循环政策:基于时间创建日志文件 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志文件名格式 -->
<fileNamePattern>${log.path}/info.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 日志最大的历史 60天 -->
<maxHistory>60</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- 过滤的级别 -->
<level>INFO</level>
<!-- 匹配时的操作:接收(记录) -->
<onMatch>ACCEPT</onMatch>
<!-- 不匹配时的操作:拒绝(不记录) -->
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<appender name="file_error" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}/error.log</file>
<!-- 循环政策:基于时间创建日志文件 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 日志文件名格式 -->
<fileNamePattern>${log.path}/error.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 日志最大的历史 60天 -->
<maxHistory>60</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${log.pattern}</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- 过滤的级别 -->
<level>ERROR</level>
<!-- 匹配时的操作:接收(记录) -->
<onMatch>ACCEPT</onMatch>
<!-- 不匹配时的操作:拒绝(不记录) -->
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 系统模块日志级别控制 -->
<logger name="com.etl" level="info"/>
<!-- Spring日志级别控制 -->
<logger name="org.springframework" level="warn"/>
<root level="info">
<appender-ref ref="console"/>
</root>
<!--系统操作日志-->
<root level="info">
<appender-ref ref="file_info"/>
<appender-ref ref="file_error"/>
</root>
</configuration>

View File

@ -0,0 +1,108 @@
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.etl.rule.engine.mapper.EngineRuleMapper">
<resultMap type="com.etl.rule.engine.domain.EngineRule" id="EngineRuleResult">
<result property="id" column="id" />
<result property="name" column="name" />
<result property="type" column="type" />
<result property="scope" column="scope" />
<result property="encoding" column="encoding" />
<result property="activatedOrNot" column="activated_or_not" />
<result property="status" column="status" />
<result property="description" column="description" />
<result property="remark" column="remark" />
<result property="codeText" column="code_text" />
<result property="createBy" column="create_by" />
<result property="createTime" column="create_time" />
<result property="updateBy" column="update_by" />
<result property="updateTime" column="update_time" />
</resultMap>
<sql id="selectEngineRuleVo">
select id, name, type, scope, encoding, activated_or_not, status, description, remark, code_text, create_by, create_time, update_by, update_time from engine_rule
</sql>
<select id="selectEngineRuleList" parameterType="com.etl.rule.engine.domain.EngineRule" resultMap="EngineRuleResult">
<include refid="selectEngineRuleVo"/>
<where>
<if test="name != null and name != ''"> and name like concat('%', #{name}, '%')</if>
<if test="type != null and type != ''"> and type = #{type}</if>
<if test="scope != null "> and scope = #{scope}</if>
<if test="activatedOrNot != null and activatedOrNot != ''"> and activated_or_not = #{activatedOrNot}</if>
<if test="status != null "> and status = #{status}</if>
</where>
</select>
<select id="selectEngineRuleById" parameterType="Long" resultMap="EngineRuleResult">
<include refid="selectEngineRuleVo"/>
where id = #{id}
</select>
<insert id="insertEngineRule" parameterType="com.etl.rule.engine.domain.EngineRule" useGeneratedKeys="true" keyProperty="id">
insert into engine_rule
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="name != null">name,</if>
<if test="type != null">type,</if>
<if test="scope != null">scope,</if>
<if test="encoding != null">encoding,</if>
<if test="activatedOrNot != null">activated_or_not,</if>
<if test="status != null">status,</if>
<if test="description != null">description,</if>
<if test="codeText != null">code_text,</if>
<if test="remark != null">remark,</if>
<if test="createBy != null">create_by,</if>
<if test="createTime != null">create_time,</if>
<if test="updateBy != null">update_by,</if>
<if test="updateTime != null">update_time,</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides=",">
<if test="name != null">#{name},</if>
<if test="type != null">#{type},</if>
<if test="scope != null">#{scope},</if>
<if test="encoding != null">#{encoding},</if>
<if test="activatedOrNot != null">#{activatedOrNot},</if>
<if test="status != null">#{status},</if>
<if test="description != null">#{description},</if>
<if test="codeText != null">#{codeText},</if>
<if test="remark != null">#{remark},</if>
<if test="createBy != null">#{createBy},</if>
<if test="createTime != null">#{createTime},</if>
<if test="updateBy != null">#{updateBy},</if>
<if test="updateTime != null">#{updateTime},</if>
</trim>
</insert>
<update id="updateEngineRule" parameterType="com.etl.rule.engine.domain.EngineRule">
update engine_rule
<trim prefix="SET" suffixOverrides=",">
<if test="name != null">name = #{name},</if>
<if test="type != null">type = #{type},</if>
<if test="scope != null">scope = #{scope},</if>
<if test="encoding != null">encoding = #{encoding},</if>
<if test="activatedOrNot != null">activated_or_not = #{activatedOrNot},</if>
<if test="status != null">status = #{status},</if>
<if test="description != null">description = #{description},</if>
<if test="codeText != null">code_text = #{codeText},</if>
<if test="remark != null">remark = #{remark},</if>
<if test="createBy != null">create_by = #{createBy},</if>
<if test="createTime != null">create_time = #{createTime},</if>
<if test="updateBy != null">update_by = #{updateBy},</if>
<if test="updateTime != null">update_time = #{updateTime},</if>
</trim>
where id = #{id}
</update>
<delete id="deleteEngineRuleById" parameterType="Long">
delete from engine_rule where id = #{id}
</delete>
<delete id="deleteEngineRuleByIds" parameterType="String">
delete from engine_rule where id in
<foreach item="id" collection="array" open="(" separator="," close=")">
#{id}
</foreach>
</delete>
</mapper>

View File

@ -0,0 +1,29 @@
<?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>
<parent>
<groupId>com.etl</groupId>
<artifactId>etl-modules</artifactId>
<version>3.6.3</version>
</parent>
<artifactId>etl-modules-rule-engine</artifactId>
<packaging>pom</packaging>
<modules>
<module>etl-modules-rule-engine-common</module>
<module>etl-modules-rule-engine-remote</module>
<module>etl-modules-rule-engine-server</module>
</modules>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<description>
etl-modules-rule-engine 规则引擎模块
</description>
</project>

View File

@ -13,6 +13,8 @@
<module>etl-modules-gen</module>
<module>etl-modules-job</module>
<module>etl-modules-file</module>
<module>etl-modules-data-source</module>
<module>etl-modules-rule-engine</module>
</modules>
<artifactId>etl-modules</artifactId>

42
pom.xml
View File

@ -34,6 +34,8 @@
<jjwt.version>0.9.1</jjwt.version>
<minio.version>8.2.2</minio.version>
<poi.version>4.1.2</poi.version>
<jedis.version>2.9.0</jedis.version>
<QLExpress.version>3.2.3</QLExpress.version>
<transmittable-thread-local.version>2.14.3</transmittable-thread-local.version>
</properties>
@ -206,6 +208,46 @@
<version>${etl.version}</version>
</dependency>
<!-- 数据源模块 公共依赖-->
<dependency>
<groupId>com.etl</groupId>
<artifactId>etl-modules-data-source-common</artifactId>
<version>${etl.version}</version>
</dependency>
<!-- 数据源模块 远程依赖-->
<dependency>
<groupId>com.etl</groupId>
<artifactId>etl-modules-data-source-remote</artifactId>
<version>${etl.version}</version>
</dependency>
<!-- 规则引擎模块 公共依赖-->
<dependency>
<groupId>com.etl</groupId>
<artifactId>etl-modules-rule-engine-common</artifactId>
<version>${etl.version}</version>
</dependency>
<!-- 规则引擎模块 远程依赖-->
<dependency>
<groupId>com.etl</groupId>
<artifactId>etl-modules-rule-engine-remote</artifactId>
<version>${etl.version}</version>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>${jedis.version}</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>QLExpress</artifactId>
<version>${QLExpress.version}</version>
</dependency>
</dependencies>
</dependencyManagement>