mirror of
https://github.com/CodePhiliaX/Chat2DB.git
synced 2025-08-02 13:34:07 +08:00
navicat链接导入
This commit is contained in:
@ -0,0 +1,65 @@
|
||||
package ai.chat2db.server.web.api.controller.ncx;
|
||||
|
||||
import ai.chat2db.server.tools.base.wrapper.result.DataResult;
|
||||
import ai.chat2db.server.tools.common.util.ConfigUtils;
|
||||
import ai.chat2db.server.web.api.aspect.ConnectionInfoAspect;
|
||||
import ai.chat2db.server.web.api.controller.ncx.service.ConverterService;
|
||||
import ai.chat2db.server.web.api.controller.ncx.vo.UploadVO;
|
||||
import lombok.SneakyThrows;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
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.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* ConverterController
|
||||
*
|
||||
* @author lzy
|
||||
**/
|
||||
@RequestMapping("/api/converter")
|
||||
@RestController
|
||||
@Slf4j
|
||||
public class ConverterController {
|
||||
|
||||
@Autowired
|
||||
private ConverterService converterService;
|
||||
|
||||
@SneakyThrows
|
||||
@PostMapping("/ncx/upload")
|
||||
public DataResult<UploadVO> uploadFile(@RequestParam("file") MultipartFile file) {
|
||||
// 验证文件后缀
|
||||
String fileExtension = getFileExtension(Objects.requireNonNull(file.getOriginalFilename()));
|
||||
if (!isAllowedExtension(fileExtension)) {
|
||||
return DataResult.error("1", "上传的文件必须是ncx文件!");
|
||||
}
|
||||
File temp = new File(ConfigUtils.CONFIG_BASE_PATH + File.separator + "temp.tmp");
|
||||
file.transferTo(temp);
|
||||
return DataResult.of(converterService.uploadFile(temp));
|
||||
}
|
||||
|
||||
private String getFileExtension(String fileName) {
|
||||
int dotIndex = fileName.lastIndexOf(".");
|
||||
if (dotIndex > 0) {
|
||||
return fileName.substring(dotIndex + 1).toLowerCase();
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isAllowedExtension(String extension) {
|
||||
// 只允许上传的文件后缀
|
||||
String[] allowedExtensions = {"ncx"};
|
||||
for (String ext : allowedExtensions) {
|
||||
if (ext.equalsIgnoreCase(extension)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
package ai.chat2db.server.web.api.controller.ncx.cipher;
|
||||
|
||||
import java.util.Formatter;
|
||||
|
||||
/**
|
||||
* CommonCipher 公共加/解密
|
||||
*
|
||||
* @author lzy
|
||||
*/
|
||||
public abstract class CommonCipher {
|
||||
|
||||
public String encryptString(String plaintext) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String decryptString(String ciphertext) {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String printHexBinary(byte[] data) {
|
||||
StringBuilder hexBuilder = new StringBuilder();
|
||||
Formatter formatter = new Formatter(hexBuilder);
|
||||
for (byte b : data) {
|
||||
formatter.format("%02x", b);
|
||||
}
|
||||
return hexBuilder.toString();
|
||||
}
|
||||
|
||||
public static byte[] parseHexBinary(String data) {
|
||||
return hexStringToByteArray(data);
|
||||
}
|
||||
|
||||
public static byte[] hexStringToByteArray(String hex) {
|
||||
if (hex.length() % 2 != 0) {
|
||||
throw new IllegalArgumentException("Hex string length must be even");
|
||||
}
|
||||
byte[] bytes = new byte[hex.length() / 2];
|
||||
for (int i = 0; i < hex.length(); i += 2) {
|
||||
String byteString = hex.substring(i, i + 2);
|
||||
bytes[i / 2] = (byte) Integer.parseInt(byteString, 16);
|
||||
}
|
||||
return bytes;
|
||||
}
|
||||
}
|
@ -0,0 +1,177 @@
|
||||
package ai.chat2db.server.web.api.controller.ncx.cipher;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.MessageDigest;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Navicat11及以下密码加密解密
|
||||
*
|
||||
* @author lzy
|
||||
*/
|
||||
public class Navicat11Cipher extends CommonCipher {
|
||||
public static final String DefaultUserKey = "3DC5CA39";
|
||||
private static byte[] IV;
|
||||
|
||||
private static SecretKeySpec key;
|
||||
private static Cipher encryptor;
|
||||
private static Cipher decrypt;
|
||||
|
||||
private static void initKey() {
|
||||
try {
|
||||
MessageDigest sha1 = MessageDigest.getInstance("SHA1");
|
||||
byte[] userKey_data = Navicat11Cipher.DefaultUserKey.getBytes(StandardCharsets.UTF_8);
|
||||
sha1.update(userKey_data, 0, userKey_data.length);
|
||||
key = new SecretKeySpec(sha1.digest(), "Blowfish");
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static void initCipherEncrypt() {
|
||||
try {
|
||||
// Must use NoPadding
|
||||
encryptor = Cipher.getInstance("Blowfish/ECB/NoPadding");
|
||||
encryptor.init(Cipher.ENCRYPT_MODE, key);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static void initCipherDecrypt() {
|
||||
try {
|
||||
// Must use NoPadding
|
||||
decrypt = Cipher.getInstance("Blowfish/ECB/NoPadding");
|
||||
decrypt.init(Cipher.DECRYPT_MODE, key);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private static void initIV() {
|
||||
try {
|
||||
byte[] initVec = parseHexBinary("FFFFFFFFFFFFFFFF");
|
||||
IV = encryptor.doFinal(initVec);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void xorBytes(byte[] a, byte[] b) {
|
||||
for (int i = 0; i < a.length; i++) {
|
||||
int aVal = a[i] & 0xff; // convert byte to integer
|
||||
int bVal = b[i] & 0xff;
|
||||
a[i] = (byte) (aVal ^ bVal); // xor aVal and bVal and typecast to byte
|
||||
}
|
||||
}
|
||||
|
||||
private void xorBytes(byte[] a, byte[] b, int l) {
|
||||
for (int i = 0; i < l; i++) {
|
||||
int aVal = a[i] & 0xff; // convert byte to integer
|
||||
int bVal = b[i] & 0xff;
|
||||
a[i] = (byte) (aVal ^ bVal); // xor aVal and bVal and typecast to byte
|
||||
}
|
||||
}
|
||||
|
||||
static {
|
||||
initKey();
|
||||
initCipherEncrypt();
|
||||
initCipherDecrypt();
|
||||
initIV();
|
||||
}
|
||||
|
||||
private byte[] Encrypt(byte[] inData) {
|
||||
try {
|
||||
byte[] CV = Arrays.copyOf(IV, IV.length);
|
||||
byte[] ret = new byte[inData.length];
|
||||
|
||||
int blocks_len = inData.length / 8;
|
||||
int left_len = inData.length % 8;
|
||||
|
||||
for (int i = 0; i < blocks_len; i++) {
|
||||
byte[] temp = Arrays.copyOfRange(inData, i * 8, (i * 8) + 8);
|
||||
|
||||
xorBytes(temp, CV);
|
||||
temp = encryptor.doFinal(temp);
|
||||
xorBytes(CV, temp);
|
||||
|
||||
System.arraycopy(temp, 0, ret, i * 8, 8);
|
||||
}
|
||||
|
||||
if (left_len != 0) {
|
||||
CV = encryptor.doFinal(CV);
|
||||
byte[] temp = Arrays.copyOfRange(inData, blocks_len * 8, (blocks_len * 8) + left_len);
|
||||
xorBytes(temp, CV, left_len);
|
||||
System.arraycopy(temp, 0, ret, blocks_len * 8, temp.length);
|
||||
}
|
||||
|
||||
return ret;
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String encryptString(String inputString) {
|
||||
try {
|
||||
byte[] inData = inputString.getBytes(StandardCharsets.UTF_8);
|
||||
byte[] outData = Encrypt(inData);
|
||||
return printHexBinary(outData);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private byte[] Decrypt(byte[] inData) {
|
||||
try {
|
||||
byte[] cv = Arrays.copyOf(IV, IV.length);
|
||||
byte[] ret = new byte[inData.length];
|
||||
|
||||
int blocks_len = inData.length / 8;
|
||||
int left_len = inData.length % 8;
|
||||
|
||||
for (int i = 0; i < blocks_len; i++) {
|
||||
byte[] temp = Arrays.copyOfRange(inData, i * 8, (i * 8) + 8);
|
||||
|
||||
temp = decrypt.doFinal(temp);
|
||||
xorBytes(temp, cv);
|
||||
System.arraycopy(temp, 0, ret, i * 8, 8);
|
||||
for (int j = 0; j < cv.length; j++) {
|
||||
cv[j] = (byte) (cv[j] ^ inData[i * 8 + j]);
|
||||
}
|
||||
}
|
||||
|
||||
if (left_len != 0) {
|
||||
cv = encryptor.doFinal(cv);
|
||||
byte[] temp = Arrays.copyOfRange(inData, blocks_len * 8, (blocks_len * 8) + left_len);
|
||||
|
||||
xorBytes(temp, cv, left_len);
|
||||
for (int j = 0; j < temp.length; j++) {
|
||||
ret[blocks_len * 8 + j] = temp[j];
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String decryptString(String hexString) {
|
||||
if (StringUtils.isEmpty(hexString)) {
|
||||
return "";
|
||||
}
|
||||
try {
|
||||
byte[] inData = parseHexBinary(hexString);
|
||||
byte[] outData = Decrypt(inData);
|
||||
return new String(outData, StandardCharsets.UTF_8);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
package ai.chat2db.server.web.api.controller.ncx.cipher;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
|
||||
/**
|
||||
* Navicat12及以上密码加密解密
|
||||
*
|
||||
* @author lzy
|
||||
*/
|
||||
public class Navicat12Cipher extends CommonCipher {
|
||||
private static final SecretKeySpec AES_KEY;
|
||||
private static final IvParameterSpec AES_IV;
|
||||
|
||||
static {
|
||||
AES_KEY = new SecretKeySpec("libcckeylibcckey".getBytes(StandardCharsets.UTF_8), "AES");
|
||||
AES_IV = new IvParameterSpec("libcciv libcciv ".getBytes(StandardCharsets.UTF_8));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String encryptString(String plaintext) {
|
||||
try {
|
||||
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
|
||||
cipher.init(Cipher.ENCRYPT_MODE, AES_KEY, AES_IV);
|
||||
byte[] ret = cipher.doFinal(plaintext.getBytes(StandardCharsets.UTF_8));
|
||||
return printHexBinary(ret);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String decryptString(String ciphertext) {
|
||||
if (StringUtils.isEmpty(ciphertext)) {
|
||||
return "";
|
||||
}
|
||||
try {
|
||||
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
|
||||
cipher.init(Cipher.DECRYPT_MODE, AES_KEY, AES_IV);
|
||||
byte[] ret = cipher.doFinal(parseHexBinary(ciphertext));
|
||||
return new String(ret, StandardCharsets.UTF_8);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,87 @@
|
||||
package ai.chat2db.server.web.api.controller.ncx.enums;
|
||||
|
||||
import lombok.Getter;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
/**
|
||||
* DataBaseType
|
||||
*
|
||||
* @author lzy
|
||||
**/
|
||||
@Getter
|
||||
public enum DataBaseType {
|
||||
/**
|
||||
* MYSQL
|
||||
*/
|
||||
MYSQL("jdbc:mysql://%s:%s"),
|
||||
/**
|
||||
* ORACLE
|
||||
*/
|
||||
ORACLE("jdbc:oracle:thin:@%s:%s:XE"),
|
||||
/**
|
||||
* SQL_SERVER
|
||||
*/
|
||||
SQLSERVER("jdbc:sqlserver://%s:%s"),
|
||||
/**
|
||||
* SQL_SERVER
|
||||
*/
|
||||
SQLITE("jdbc:sqlite:%s"),
|
||||
/**
|
||||
* POSTGRESQL
|
||||
**/
|
||||
POSTGRESQL("jdbc:postgresql://%s:%s"),
|
||||
/**
|
||||
* DB2
|
||||
**/
|
||||
DB2("jdbc:db2://%s:%s"),
|
||||
/**
|
||||
* Mariadb
|
||||
**/
|
||||
Mariadb("jdbc:mariadb://%s:%s"),
|
||||
/**
|
||||
* DM
|
||||
**/
|
||||
DM("jdbc:dm://%s:%s"),
|
||||
/**
|
||||
* KINGBASE8
|
||||
**/
|
||||
KINGBASE8("jdbc:kingbase8://%s:%s"),
|
||||
/**
|
||||
* Presto
|
||||
**/
|
||||
Presto("jdbc:presto://%s:%s"),
|
||||
/**
|
||||
* OceanBase
|
||||
**/
|
||||
OceanBase("jdbc:oceanbase://%s:%s"),
|
||||
/**
|
||||
* Hive
|
||||
**/
|
||||
Hive("jdbc:hive2://%s:%s"),
|
||||
/**
|
||||
* ClickHouse
|
||||
**/
|
||||
ClickHouse("jdbc:clickhouse://%s:%s");
|
||||
|
||||
private String urlString;
|
||||
|
||||
DataBaseType(String urlString) {
|
||||
this.urlString = urlString;
|
||||
}
|
||||
|
||||
public void setUrlString(String urlString) {
|
||||
this.urlString = urlString;
|
||||
}
|
||||
|
||||
public static DataBaseType matchType(String value) {
|
||||
if (StringUtils.isNotEmpty(value)) {
|
||||
for (DataBaseType dataBase : DataBaseType.values()) {
|
||||
if (dataBase.name().equals(value.toUpperCase())) {
|
||||
return dataBase;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
package ai.chat2db.server.web.api.controller.ncx.enums;
|
||||
|
||||
/**
|
||||
* navicat版本枚举(版本区分navicat加密算法)
|
||||
*
|
||||
* @author lzy
|
||||
*/
|
||||
public enum VersionEnum {
|
||||
/**
|
||||
* navicat11
|
||||
*/
|
||||
native11,
|
||||
/**
|
||||
* navicat12+
|
||||
*/
|
||||
navicat12more
|
||||
}
|
@ -0,0 +1,45 @@
|
||||
package ai.chat2db.server.web.api.controller.ncx.factory;
|
||||
|
||||
import ai.chat2db.server.web.api.controller.ncx.cipher.CommonCipher;
|
||||
import ai.chat2db.server.web.api.controller.ncx.cipher.Navicat11Cipher;
|
||||
import ai.chat2db.server.web.api.controller.ncx.cipher.Navicat12Cipher;
|
||||
import ai.chat2db.server.web.api.controller.ncx.enums.VersionEnum;
|
||||
import lombok.SneakyThrows;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
/**
|
||||
* CipherFactory
|
||||
*
|
||||
* @author lzy
|
||||
**/
|
||||
@Service
|
||||
public class CipherFactory {
|
||||
/**
|
||||
* NavicatCipher缓存池
|
||||
*/
|
||||
private static final Map<String, CommonCipher> REPORT_POOL = new ConcurrentHashMap<>(0);
|
||||
|
||||
static {
|
||||
REPORT_POOL.put(VersionEnum.native11.name(), new Navicat11Cipher());
|
||||
REPORT_POOL.put(VersionEnum.navicat12more.name(), new Navicat12Cipher());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取对应加/解密方法
|
||||
*
|
||||
* @param type 类型
|
||||
* @return ITokenGranter
|
||||
*/
|
||||
@SneakyThrows
|
||||
public static CommonCipher get(String type) {
|
||||
CommonCipher cipher = REPORT_POOL.get(type);
|
||||
if (cipher == null) {
|
||||
throw new ClassNotFoundException("no CommonCipher was found");
|
||||
} else {
|
||||
return cipher;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package ai.chat2db.server.web.api.controller.ncx.service;
|
||||
|
||||
import ai.chat2db.server.web.api.controller.ncx.vo.UploadVO;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* ConverterService
|
||||
*
|
||||
* @author lzy
|
||||
**/
|
||||
public interface ConverterService {
|
||||
|
||||
UploadVO uploadFile(File file);
|
||||
}
|
@ -0,0 +1,156 @@
|
||||
package ai.chat2db.server.web.api.controller.ncx.service.impl;
|
||||
|
||||
import ai.chat2db.server.domain.core.util.DesUtil;
|
||||
import ai.chat2db.server.domain.repository.entity.DataSourceDO;
|
||||
import ai.chat2db.server.domain.repository.mapper.DataSourceMapper;
|
||||
import ai.chat2db.server.web.api.controller.ncx.cipher.CommonCipher;
|
||||
import ai.chat2db.server.web.api.controller.ncx.enums.DataBaseType;
|
||||
import ai.chat2db.server.web.api.controller.ncx.enums.VersionEnum;
|
||||
import ai.chat2db.server.web.api.controller.ncx.factory.CipherFactory;
|
||||
import ai.chat2db.server.web.api.controller.ncx.service.ConverterService;
|
||||
import ai.chat2db.server.web.api.controller.ncx.vo.UploadVO;
|
||||
import ai.chat2db.spi.model.SSHInfo;
|
||||
import com.alibaba.excel.util.FileUtils;
|
||||
import com.alibaba.fastjson2.JSON;
|
||||
import lombok.SneakyThrows;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.NamedNodeMap;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import java.io.File;
|
||||
import java.time.LocalDateTime;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* ConverterServiceImpl
|
||||
*
|
||||
* @author lzy
|
||||
**/
|
||||
@Service
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
public class ConverterServiceImpl implements ConverterService {
|
||||
|
||||
private static final double NAVICAT11 = 1.1D;
|
||||
|
||||
private static CommonCipher cipher;
|
||||
|
||||
@Autowired
|
||||
private DataSourceMapper dataSourceMapper;
|
||||
|
||||
@Override
|
||||
public UploadVO uploadFile(File file) {
|
||||
|
||||
UploadVO vo = new UploadVO();
|
||||
try {
|
||||
// List<Map <连接名,Map<属性名,值>>> 要导入的连接
|
||||
List<Map<String, Map<String, String>>> configMap = new ArrayList<>();
|
||||
//1、创建一个DocumentBuilderFactory的对象
|
||||
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
|
||||
//2、创建一个DocumentBuilder的对象
|
||||
//创建DocumentBuilder对象
|
||||
DocumentBuilder db = dbf.newDocumentBuilder();
|
||||
//3、通过DocumentBuilder对象的parser方法加载xml文件到当前项目下
|
||||
Document document = db.parse(file);
|
||||
//获取所有Connections节点的集合
|
||||
NodeList connectList = document.getElementsByTagName("Connection");
|
||||
|
||||
NodeList nodeList = document.getElementsByTagName("Connections");
|
||||
//选中第一个节点
|
||||
NamedNodeMap verMap = nodeList.item(0).getAttributes();
|
||||
double version = Double.parseDouble((verMap.getNamedItem("Ver").getNodeValue()));
|
||||
if (version <= NAVICAT11) {
|
||||
cipher = CipherFactory.get(VersionEnum.native11.name());
|
||||
} else {
|
||||
cipher = CipherFactory.get(VersionEnum.navicat12more.name());
|
||||
}
|
||||
//配置map
|
||||
Map<String, Map<String, String>> connectionMap = new HashMap<>();
|
||||
//遍历每一个Connections节点
|
||||
for (int i = 0; i < connectList.getLength(); i++) {
|
||||
//通过 item(i)方法 获取一个Connection节点,nodeList的索引值从0开始
|
||||
Node connect = connectList.item(i);
|
||||
//获取Connection节点的所有属性集合
|
||||
NamedNodeMap attrs = connect.getAttributes();
|
||||
//遍历Connection的属性
|
||||
Map<String, String> map = new HashMap<>(0);
|
||||
for (int j = 0; j < attrs.getLength(); j++) {
|
||||
//通过item(index)方法获取connect节点的某一个属性
|
||||
Node attr = attrs.item(j);
|
||||
map.put(attr.getNodeName(), attr.getNodeValue());
|
||||
}
|
||||
connectionMap.put(map.get("ConnectionName") + map.get("ConnType"), map);
|
||||
}
|
||||
configMap.add(connectionMap);
|
||||
// 将获取到navicat导入的链接,写入chat2db的h2数据库
|
||||
insertDBConfig(configMap);
|
||||
//删除临时文件
|
||||
FileUtils.delete(file);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
return vo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 写入到数据库
|
||||
*
|
||||
* @param list 读取ncx文件的数据
|
||||
*/
|
||||
@SneakyThrows
|
||||
public void insertDBConfig(List<Map<String, Map<String, String>>> list) {
|
||||
for (Map<String, Map<String, String>> map : list) {
|
||||
for (Map.Entry<String, Map<String, String>> valueMap : map.entrySet()) {
|
||||
Map<String, String> resultMap = valueMap.getValue();
|
||||
// 解密密码
|
||||
String password = cipher.decryptString(resultMap.getOrDefault("Password", ""));
|
||||
DataSourceDO dataSourceDO = new DataSourceDO();
|
||||
LocalDateTime dateTime = LocalDateTime.now();
|
||||
dataSourceDO.setGmtCreate(dateTime);
|
||||
dataSourceDO.setGmtModified(dateTime);
|
||||
dataSourceDO.setAlias(resultMap.get("ConnectionName"));
|
||||
dataSourceDO.setHost(resultMap.get("Host"));
|
||||
dataSourceDO.setPort(resultMap.get("Port"));
|
||||
dataSourceDO.setUserName(resultMap.get("UserName"));
|
||||
dataSourceDO.setType(resultMap.get("ConnType"));
|
||||
// mysql的版本还无法区分
|
||||
dataSourceDO.setUrl(String.format(Objects.requireNonNull(DataBaseType.matchType(dataSourceDO.getType())).getUrlString(), dataSourceDO.getHost(), dataSourceDO.getPort()));
|
||||
//password 为解密出来的密文,再使用chat2db的加密
|
||||
DesUtil desUtil = new DesUtil(DesUtil.DES_KEY);
|
||||
String encryptStr = desUtil.encrypt(password, "CBC");
|
||||
dataSourceDO.setPassword(encryptStr);
|
||||
SSHInfo sshInfo = new SSHInfo();
|
||||
if ("false".equals(resultMap.get("SSH"))) {
|
||||
sshInfo.setUse(false);
|
||||
} else {
|
||||
sshInfo.setUse(true);
|
||||
sshInfo.setHostName(resultMap.get("SSH_Host"));
|
||||
sshInfo.setPort(resultMap.get("SSH_Port"));
|
||||
sshInfo.setUserName(resultMap.get("SSH_UserName"));
|
||||
// 目前chat2DB只支持 password 和 Private key
|
||||
boolean passwordType = "password".equalsIgnoreCase(resultMap.get("SSH_AuthenMethod"));
|
||||
sshInfo.setAuthenticationType(passwordType ? "password" : "Private key");
|
||||
if (passwordType) {
|
||||
// 解密密码
|
||||
String ssh_password = cipher.decryptString(resultMap.getOrDefault("SSH_Password", ""));
|
||||
sshInfo.setPassword(ssh_password);
|
||||
} else {
|
||||
sshInfo.setKeyFile(resultMap.get("SSH_PrivateKey"));
|
||||
sshInfo.setPassphrase(resultMap.get("SSH_Passphrase"));
|
||||
}
|
||||
}
|
||||
dataSourceDO.setSsh(JSON.toJSONString(sshInfo));
|
||||
dataSourceMapper.insert(dataSourceDO);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package ai.chat2db.server.web.api.controller.ncx.vo;
|
||||
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Data;
|
||||
import lombok.NoArgsConstructor;
|
||||
import lombok.experimental.SuperBuilder;
|
||||
|
||||
/**
|
||||
* UploadVO
|
||||
*
|
||||
* @author lzy
|
||||
**/
|
||||
@Data
|
||||
@SuperBuilder
|
||||
@NoArgsConstructor
|
||||
@AllArgsConstructor
|
||||
public class UploadVO {
|
||||
private String result;
|
||||
}
|
Reference in New Issue
Block a user