forked from github/dataease
feat: 支持数据源驱动管理
This commit is contained in:
parent
1c0c09acc7
commit
ad01a695b4
@ -0,0 +1,91 @@
|
||||
package io.dataease.controller.datasource;
|
||||
|
||||
|
||||
import io.dataease.dto.DriverDTO;
|
||||
import io.dataease.plugins.common.base.domain.DeDriver;
|
||||
import io.dataease.plugins.common.base.domain.DeDriverDetails;
|
||||
import io.dataease.service.datasource.DriverService;
|
||||
import io.swagger.annotations.ApiImplicitParam;
|
||||
import io.swagger.annotations.ApiImplicitParams;
|
||||
import io.swagger.annotations.ApiOperation;
|
||||
import org.apache.shiro.authz.annotation.RequiresPermissions;
|
||||
import org.springframework.security.core.parameters.P;
|
||||
import org.springframework.web.bind.annotation.*;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
import springfox.documentation.annotations.ApiIgnore;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@ApiIgnore
|
||||
@RequestMapping("driver")
|
||||
@RestController
|
||||
public class DriverMgmController {
|
||||
|
||||
@Resource
|
||||
private DriverService driverService;
|
||||
|
||||
@RequiresPermissions("datasource:read")
|
||||
@ApiOperation("驱动列表")
|
||||
@PostMapping("/list")
|
||||
public List<DriverDTO> listDeDriver() throws Exception{
|
||||
return driverService.list();
|
||||
}
|
||||
|
||||
@RequiresPermissions("datasource:read")
|
||||
@ApiOperation("删除驱动")
|
||||
@PostMapping("/delete/{id}")
|
||||
public void delete(@PathVariable String id) throws Exception{
|
||||
driverService.delete(id);
|
||||
}
|
||||
|
||||
@RequiresPermissions("datasource:read")
|
||||
@ApiOperation("驱动列表")
|
||||
@GetMapping("/list/{type}")
|
||||
public List<DriverDTO> listDeDriver(@PathVariable String type) throws Exception{
|
||||
return listDeDriver().stream().filter(driverDTO -> driverDTO.getType().equalsIgnoreCase(type)).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
@RequiresPermissions("datasource:read")
|
||||
@ApiOperation("添加驱动")
|
||||
@PostMapping("/save")
|
||||
public DeDriver save(@RequestBody DeDriver deDriver) throws Exception{
|
||||
return driverService.save(deDriver);
|
||||
}
|
||||
|
||||
@RequiresPermissions("datasource:read")
|
||||
@ApiOperation("更新驱动")
|
||||
@PostMapping("/update")
|
||||
public DeDriver update(@RequestBody DeDriver deDriver) throws Exception{
|
||||
return driverService.update(deDriver);
|
||||
}
|
||||
|
||||
@RequiresPermissions("datasource:read")
|
||||
@ApiOperation("驱动文件列表")
|
||||
@GetMapping("/listDriverDetails/{id}")
|
||||
public List<DeDriverDetails> listDriverDetails(@PathVariable String id) throws Exception{
|
||||
return driverService.listDriverDetails(id);
|
||||
}
|
||||
|
||||
@RequiresPermissions("datasource:read")
|
||||
@ApiOperation("删除驱动文件")
|
||||
@PostMapping("/deleteDriverFile/{id}")
|
||||
public void deleteDriverFile(@PathVariable String id) throws Exception{
|
||||
driverService.deleteDriverFile(id);
|
||||
}
|
||||
|
||||
@RequiresPermissions("datasource:read")
|
||||
@ApiOperation("驱动文件上传")
|
||||
@PostMapping("file/upload")
|
||||
@ApiImplicitParams({
|
||||
@ApiImplicitParam(name = "file", value = "文件", required = true, dataType = "MultipartFile"),
|
||||
@ApiImplicitParam(name = "id", value = "驱动D", required = true, dataType = "String")
|
||||
})
|
||||
public void excelUpload(@RequestParam("file") MultipartFile file, @RequestParam("id") String id) throws Exception {
|
||||
driverService.saveJar(file, id);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
9
backend/src/main/java/io/dataease/dto/DriverDTO.java
Normal file
9
backend/src/main/java/io/dataease/dto/DriverDTO.java
Normal file
@ -0,0 +1,9 @@
|
||||
package io.dataease.dto;
|
||||
|
||||
import io.dataease.plugins.common.base.domain.DeDriver;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class DriverDTO extends DeDriver {
|
||||
private String typeDesc;
|
||||
}
|
@ -1,6 +1,5 @@
|
||||
package io.dataease.provider;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import io.dataease.plugins.common.constants.DatasourceTypes;
|
||||
import io.dataease.plugins.common.dto.datasource.DataSourceType;
|
||||
import io.dataease.plugins.config.SpringContextUtil;
|
||||
@ -25,7 +24,7 @@ public class ProviderFactory implements ApplicationContextAware {
|
||||
for(final DatasourceTypes d: DatasourceTypes.values()) {
|
||||
final ConfigurableListableBeanFactory beanFactory = ((ConfigurableApplicationContext) context).getBeanFactory();
|
||||
if(d.isDatasource()){
|
||||
DataSourceType dataSourceType = new DataSourceType(d.getType(), d.getName(), false, d.getExtraParams(), d.getCalculationMode());
|
||||
DataSourceType dataSourceType = new DataSourceType(d.getType(), d.getName(), false, d.getExtraParams(), d.getCalculationMode(), d.isJdbc());
|
||||
if(dataSourceType.getType().equalsIgnoreCase("oracle")){
|
||||
dataSourceType.setCharset(d.getCharset());
|
||||
}
|
||||
|
@ -6,16 +6,20 @@ import com.google.gson.Gson;
|
||||
import io.dataease.dto.datasource.*;
|
||||
import io.dataease.exception.DataEaseException;
|
||||
import io.dataease.i18n.Translator;
|
||||
import io.dataease.plugins.common.base.domain.DeDriver;
|
||||
import io.dataease.plugins.common.base.mapper.DeDriverMapper;
|
||||
import io.dataease.plugins.common.constants.DatasourceTypes;
|
||||
import io.dataease.plugins.common.dto.datasource.TableField;
|
||||
import io.dataease.plugins.common.request.datasource.DatasourceRequest;
|
||||
import io.dataease.plugins.datasource.entity.JdbcConfiguration;
|
||||
import io.dataease.plugins.datasource.provider.DefaultJdbcProvider;
|
||||
import io.dataease.plugins.datasource.provider.ExtendedJdbcClassLoader;
|
||||
import io.dataease.plugins.datasource.query.QueryProvider;
|
||||
import io.dataease.provider.ProviderFactory;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.beans.PropertyVetoException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.sql.*;
|
||||
@ -25,6 +29,8 @@ import java.util.*;
|
||||
public class JdbcProvider extends DefaultJdbcProvider {
|
||||
|
||||
|
||||
@Resource
|
||||
private DeDriverMapper deDriverMapper;
|
||||
@Override
|
||||
public boolean isUseDatasourcePool(){
|
||||
return true;
|
||||
@ -294,10 +300,12 @@ public class JdbcProvider extends DefaultJdbcProvider {
|
||||
public Connection getConnection(DatasourceRequest datasourceRequest) throws Exception {
|
||||
String username = null;
|
||||
String password = null;
|
||||
String driver = null;
|
||||
String defaultDriver = null;
|
||||
String jdbcurl = null;
|
||||
String customDriver = null;
|
||||
DatasourceTypes datasourceType = DatasourceTypes.valueOf(datasourceRequest.getDatasource().getType());
|
||||
Properties props = new Properties();
|
||||
DeDriver deDriver = null;
|
||||
switch (datasourceType) {
|
||||
case mysql:
|
||||
case mariadb:
|
||||
@ -309,21 +317,24 @@ public class JdbcProvider extends DefaultJdbcProvider {
|
||||
MysqlConfiguration mysqlConfiguration = new Gson().fromJson(datasourceRequest.getDatasource().getConfiguration(), MysqlConfiguration.class);
|
||||
username = mysqlConfiguration.getUsername();
|
||||
password = mysqlConfiguration.getPassword();
|
||||
driver = "com.mysql.jdbc.Driver";
|
||||
defaultDriver = "com.mysql.jdbc.Driver";
|
||||
jdbcurl = mysqlConfiguration.getJdbc();
|
||||
customDriver = mysqlConfiguration.getCustomDriver();
|
||||
break;
|
||||
case sqlServer:
|
||||
SqlServerConfiguration sqlServerConfiguration = new Gson().fromJson(datasourceRequest.getDatasource().getConfiguration(), SqlServerConfiguration.class);
|
||||
username = sqlServerConfiguration.getUsername();
|
||||
password = sqlServerConfiguration.getPassword();
|
||||
driver = sqlServerConfiguration.getDriver();
|
||||
defaultDriver = sqlServerConfiguration.getDriver();
|
||||
customDriver = sqlServerConfiguration.getCustomDriver();
|
||||
jdbcurl = sqlServerConfiguration.getJdbc();
|
||||
break;
|
||||
case oracle:
|
||||
OracleConfiguration oracleConfiguration = new Gson().fromJson(datasourceRequest.getDatasource().getConfiguration(), OracleConfiguration.class);
|
||||
username = oracleConfiguration.getUsername();
|
||||
password = oracleConfiguration.getPassword();
|
||||
driver = oracleConfiguration.getDriver();
|
||||
defaultDriver = oracleConfiguration.getDriver();
|
||||
customDriver = oracleConfiguration.getCustomDriver();
|
||||
jdbcurl = oracleConfiguration.getJdbc();
|
||||
props.put("oracle.net.CONNECT_TIMEOUT", "5000");
|
||||
break;
|
||||
@ -331,56 +342,84 @@ public class JdbcProvider extends DefaultJdbcProvider {
|
||||
PgConfiguration pgConfiguration = new Gson().fromJson(datasourceRequest.getDatasource().getConfiguration(), PgConfiguration.class);
|
||||
username = pgConfiguration.getUsername();
|
||||
password = pgConfiguration.getPassword();
|
||||
driver = pgConfiguration.getDriver();
|
||||
defaultDriver = pgConfiguration.getDriver();
|
||||
customDriver = pgConfiguration.getCustomDriver();
|
||||
jdbcurl = pgConfiguration.getJdbc();
|
||||
break;
|
||||
case ck:
|
||||
CHConfiguration chConfiguration = new Gson().fromJson(datasourceRequest.getDatasource().getConfiguration(), CHConfiguration.class);
|
||||
username = chConfiguration.getUsername();
|
||||
password = chConfiguration.getPassword();
|
||||
driver = chConfiguration.getDriver();
|
||||
defaultDriver = chConfiguration.getDriver();
|
||||
customDriver = chConfiguration.getCustomDriver();
|
||||
jdbcurl = chConfiguration.getJdbc();
|
||||
break;
|
||||
case mongo:
|
||||
MongodbConfiguration mongodbConfiguration = new Gson().fromJson(datasourceRequest.getDatasource().getConfiguration(), MongodbConfiguration.class);
|
||||
username = mongodbConfiguration.getUsername();
|
||||
password = mongodbConfiguration.getPassword();
|
||||
driver = mongodbConfiguration.getDriver();
|
||||
defaultDriver = mongodbConfiguration.getDriver();
|
||||
customDriver = mongodbConfiguration.getCustomDriver();
|
||||
jdbcurl = mongodbConfiguration.getJdbc(datasourceRequest.getDatasource().getId());
|
||||
break;
|
||||
case redshift:
|
||||
RedshiftConfigration redshiftConfigration = new Gson().fromJson(datasourceRequest.getDatasource().getConfiguration(), RedshiftConfigration.class);
|
||||
username = redshiftConfigration.getUsername();
|
||||
password = redshiftConfigration.getPassword();
|
||||
driver = redshiftConfigration.getDriver();
|
||||
defaultDriver = redshiftConfigration.getDriver();
|
||||
customDriver = redshiftConfigration.getCustomDriver();
|
||||
jdbcurl = redshiftConfigration.getJdbc();
|
||||
break;
|
||||
case hive:
|
||||
HiveConfiguration hiveConfiguration = new Gson().fromJson(datasourceRequest.getDatasource().getConfiguration(), HiveConfiguration.class);
|
||||
username = hiveConfiguration.getUsername();
|
||||
password = hiveConfiguration.getPassword();
|
||||
driver = hiveConfiguration.getDriver();
|
||||
defaultDriver = hiveConfiguration.getDriver();
|
||||
customDriver = hiveConfiguration.getCustomDriver();
|
||||
jdbcurl = hiveConfiguration.getJdbc();
|
||||
|
||||
if(StringUtils.isNotEmpty(hiveConfiguration.getAuthMethod()) && hiveConfiguration.getAuthMethod().equalsIgnoreCase("kerberos")){
|
||||
System.setProperty("java.security.krb5.conf", "/opt/dataease/conf/krb5.conf");
|
||||
ExtendedJdbcClassLoader classLoader;
|
||||
if(isDefaultClassLoader(customDriver)){
|
||||
classLoader = extendedJdbcClassLoader;
|
||||
}else {
|
||||
deDriver = deDriverMapper.selectByPrimaryKey(customDriver);
|
||||
classLoader = getCustomJdbcClassLoader(deDriver);
|
||||
}
|
||||
Class<?> ConfigurationClass = classLoader.loadClass("org.apache.hadoop.conf.Configuration");
|
||||
Method set = ConfigurationClass.getMethod("set",String.class, String.class) ;
|
||||
Object obj = ConfigurationClass.newInstance();
|
||||
set.invoke(obj, "hadoop.security.authentication", "Kerberos");
|
||||
|
||||
Class<?> UserGroupInformationClass = classLoader.loadClass("org.apache.hadoop.security.UserGroupInformation");
|
||||
Method setConfiguration = UserGroupInformationClass.getMethod("setConfiguration",ConfigurationClass) ;
|
||||
Method loginUserFromKeytab = UserGroupInformationClass.getMethod("loginUserFromKeytab",String.class, String.class) ;
|
||||
setConfiguration.invoke(null, obj);
|
||||
loginUserFromKeytab.invoke(null, hiveConfiguration.getUsername(), "/opt/dataease/conf/" + hiveConfiguration.getPassword());
|
||||
}else {
|
||||
username = hiveConfiguration.getUsername();
|
||||
password = hiveConfiguration.getPassword();
|
||||
}
|
||||
break;
|
||||
case impala:
|
||||
ImpalaConfiguration impalaConfiguration = new Gson().fromJson(datasourceRequest.getDatasource().getConfiguration(), ImpalaConfiguration.class);
|
||||
username = impalaConfiguration.getUsername();
|
||||
password = impalaConfiguration.getPassword();
|
||||
driver = impalaConfiguration.getDriver();
|
||||
defaultDriver = impalaConfiguration.getDriver();
|
||||
customDriver = impalaConfiguration.getCustomDriver();
|
||||
jdbcurl = impalaConfiguration.getJdbc();
|
||||
break;
|
||||
case db2:
|
||||
Db2Configuration db2Configuration = new Gson().fromJson(datasourceRequest.getDatasource().getConfiguration(), Db2Configuration.class);
|
||||
username = db2Configuration.getUsername();
|
||||
password = db2Configuration.getPassword();
|
||||
driver = db2Configuration.getDriver();
|
||||
defaultDriver = db2Configuration.getDriver();
|
||||
customDriver = db2Configuration.getCustomDriver();
|
||||
jdbcurl = db2Configuration.getJdbc();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
Driver driverClass = (Driver) extendedJdbcClassLoader.loadClass(driver).newInstance();
|
||||
if (StringUtils.isNotBlank(username)) {
|
||||
props.setProperty("user", username);
|
||||
if (StringUtils.isNotBlank(password)) {
|
||||
@ -388,12 +427,34 @@ public class JdbcProvider extends DefaultJdbcProvider {
|
||||
}
|
||||
}
|
||||
|
||||
Connection conn = driverClass.connect(jdbcurl, props);
|
||||
Connection conn;
|
||||
String driverClassName ;
|
||||
ExtendedJdbcClassLoader jdbcClassLoader;
|
||||
if(isDefaultClassLoader(customDriver)){
|
||||
driverClassName = defaultDriver;
|
||||
jdbcClassLoader = extendedJdbcClassLoader;
|
||||
}else {
|
||||
driverClassName = deDriver.getDriverClass();
|
||||
jdbcClassLoader = getCustomJdbcClassLoader(deDriver);
|
||||
}
|
||||
|
||||
Driver driverClass = (Driver) jdbcClassLoader.loadClass(driverClassName).newInstance();
|
||||
ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
|
||||
try {
|
||||
Thread.currentThread().setContextClassLoader(jdbcClassLoader);
|
||||
conn= driverClass.connect(jdbcurl, props);
|
||||
}catch (Exception e){
|
||||
e.printStackTrace();
|
||||
throw e;
|
||||
}finally {
|
||||
Thread.currentThread().setContextClassLoader(classLoader);
|
||||
}
|
||||
return conn;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public JdbcConfiguration setCredential(DatasourceRequest datasourceRequest, DruidDataSource dataSource) throws PropertyVetoException {
|
||||
public JdbcConfiguration setCredential(DatasourceRequest datasourceRequest, DruidDataSource dataSource) throws Exception{
|
||||
DatasourceTypes datasourceType = DatasourceTypes.valueOf(datasourceRequest.getDatasource().getType());
|
||||
JdbcConfiguration jdbcConfiguration = new JdbcConfiguration();
|
||||
switch (datasourceType) {
|
||||
@ -474,7 +535,15 @@ public class JdbcProvider extends DefaultJdbcProvider {
|
||||
}
|
||||
|
||||
dataSource.setUsername(jdbcConfiguration.getUsername());
|
||||
dataSource.setDriverClassLoader(extendedJdbcClassLoader);
|
||||
|
||||
ExtendedJdbcClassLoader classLoader;
|
||||
if(isDefaultClassLoader(jdbcConfiguration.getCustomDriver())){
|
||||
classLoader = extendedJdbcClassLoader;
|
||||
}else {
|
||||
DeDriver deDriver = deDriverMapper.selectByPrimaryKey(jdbcConfiguration.getCustomDriver());
|
||||
classLoader = getCustomJdbcClassLoader(deDriver);
|
||||
}
|
||||
dataSource.setDriverClassLoader(classLoader);
|
||||
dataSource.setPassword(jdbcConfiguration.getPassword());
|
||||
|
||||
return jdbcConfiguration;
|
||||
|
@ -2270,7 +2270,7 @@ public class DataSetTableService {
|
||||
record.setSyncStatus(JobStatus.Error.name());
|
||||
example.clear();
|
||||
example.createCriteria().andSyncStatusEqualTo(JobStatus.Underway.name())
|
||||
.andIdIn(datasetTableTasks.stream().map(DatasetTableTask::getTableId).collect(Collectors.toList()));
|
||||
.andIdIn(jobStoppeddDatasetTables.stream().map(DatasetTable::getId).collect(Collectors.toList()));
|
||||
datasetTableMapper.updateByExampleSelective(record, example);
|
||||
|
||||
//TaskLog
|
||||
|
@ -27,11 +27,13 @@ import io.dataease.i18n.Translator;
|
||||
import io.dataease.plugins.common.base.domain.*;
|
||||
import io.dataease.plugins.common.base.mapper.DatasetTableMapper;
|
||||
import io.dataease.plugins.common.base.mapper.DatasourceMapper;
|
||||
import io.dataease.plugins.common.constants.DatasourceCalculationMode;
|
||||
import io.dataease.plugins.common.constants.DatasourceTypes;
|
||||
import io.dataease.plugins.common.dto.datasource.DataSourceType;
|
||||
import io.dataease.plugins.common.dto.datasource.TableDesc;
|
||||
import io.dataease.plugins.common.request.datasource.DatasourceRequest;
|
||||
import io.dataease.plugins.config.SpringContextUtil;
|
||||
import io.dataease.plugins.datasource.entity.JdbcConfiguration;
|
||||
import io.dataease.plugins.datasource.provider.Provider;
|
||||
import io.dataease.provider.ProviderFactory;
|
||||
import io.dataease.provider.datasource.ApiProvider;
|
||||
@ -41,10 +43,8 @@ import io.dataease.service.sys.SysAuthService;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.apache.commons.lang3.ObjectUtils;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.data.redis.core.RedisTemplate;
|
||||
import org.springframework.data.redis.core.StringRedisTemplate;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
|
||||
@ -131,6 +131,13 @@ public class DatasourceService {
|
||||
datasourceDTO.setCalculationMode(dataSourceType.getCalculationMode());
|
||||
}
|
||||
});
|
||||
if(!datasourceDTO.getType().equalsIgnoreCase(DatasourceTypes.api.toString())){
|
||||
JdbcConfiguration configuration = new Gson().fromJson(datasourceDTO.getConfiguration(), JdbcConfiguration.class);
|
||||
if(StringUtils.isNotEmpty(configuration.getCustomDriver()) && !configuration.getCustomDriver().equalsIgnoreCase("default")){
|
||||
datasourceDTO.setCalculationMode(DatasourceCalculationMode.DIRECT);
|
||||
}
|
||||
}
|
||||
|
||||
if(datasourceDTO.getType().equalsIgnoreCase(DatasourceTypes.mysql.toString())){
|
||||
datasourceDTO.setConfiguration(JSONObject.toJSONString(new Gson().fromJson(datasourceDTO.getConfiguration(), MysqlConfiguration.class)) );
|
||||
}
|
||||
|
@ -0,0 +1,175 @@
|
||||
package io.dataease.service.datasource;
|
||||
|
||||
import io.dataease.commons.utils.BeanUtils;
|
||||
import io.dataease.commons.utils.DeFileUtils;
|
||||
import io.dataease.dto.DriverDTO;
|
||||
import io.dataease.plugins.common.base.domain.DeDriver;
|
||||
import io.dataease.plugins.common.base.domain.DeDriverDetails;
|
||||
import io.dataease.plugins.common.base.domain.DeDriverDetailsExample;
|
||||
import io.dataease.plugins.common.base.mapper.DeDriverDetailsMapper;
|
||||
import io.dataease.plugins.common.base.mapper.DeDriverMapper;
|
||||
import io.dataease.plugins.datasource.provider.ExtendedJdbcClassLoader;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
import org.springframework.web.multipart.MultipartFile;
|
||||
|
||||
import javax.annotation.Resource;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Enumeration;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarFile;
|
||||
|
||||
@Transactional(rollbackFor = Exception.class)
|
||||
@Service
|
||||
public class DriverService {
|
||||
|
||||
private static String DRIVER_PATH = "/opt/dataease/drivers/custom/";
|
||||
@Resource
|
||||
private DeDriverMapper deDriverMapper;
|
||||
@Resource
|
||||
private DeDriverDetailsMapper deDriverDetailsMapper;
|
||||
@Resource
|
||||
private DatasourceService datasourceService;
|
||||
|
||||
|
||||
public List<DriverDTO> list() throws Exception {
|
||||
List<DriverDTO> driverDTOS = new ArrayList<>();
|
||||
deDriverMapper.selectByExample(null).forEach(deDriver -> {
|
||||
DriverDTO driverDTO = new DriverDTO();
|
||||
BeanUtils.copyBean(driverDTO, deDriver);
|
||||
datasourceService.types().forEach(dataSourceType -> {
|
||||
if (dataSourceType.getType().equalsIgnoreCase(deDriver.getType())) {
|
||||
driverDTO.setTypeDesc(dataSourceType.getName());
|
||||
}
|
||||
|
||||
});
|
||||
driverDTOS.add(driverDTO);
|
||||
});
|
||||
return driverDTOS;
|
||||
}
|
||||
|
||||
public void delete(String driverId) {
|
||||
deDriverMapper.deleteByPrimaryKey(driverId);
|
||||
|
||||
DeDriverDetailsExample example = new DeDriverDetailsExample();
|
||||
example.createCriteria().andDeDriverIdEqualTo(driverId);
|
||||
deDriverDetailsMapper.deleteByExample(example);
|
||||
DeFileUtils.deleteFile(DRIVER_PATH + driverId + "/");
|
||||
}
|
||||
|
||||
public DeDriver save(DeDriver deDriver) {
|
||||
deDriver.setCreateTime(System.currentTimeMillis());
|
||||
deDriver.setId(UUID.randomUUID().toString());
|
||||
deDriverMapper.insert(deDriver);
|
||||
return deDriver;
|
||||
}
|
||||
|
||||
public DeDriver update(DeDriver deDriver) {
|
||||
deDriverMapper.updateByPrimaryKey(deDriver);
|
||||
return deDriver;
|
||||
}
|
||||
|
||||
|
||||
public List<DeDriverDetails> listDriverDetails(String driverId) {
|
||||
DeDriverDetailsExample example = new DeDriverDetailsExample();
|
||||
example.createCriteria().andDeDriverIdEqualTo(driverId);
|
||||
return deDriverDetailsMapper.selectByExampleWithBLOBs(example);
|
||||
}
|
||||
|
||||
public void deleteDriverFile(String driverFileId) {
|
||||
DeDriverDetails deDriverDetails = deDriverDetailsMapper.selectByPrimaryKey(driverFileId);
|
||||
DeFileUtils.deleteFile(DRIVER_PATH + deDriverDetails.getDeDriverId() + "/" + deDriverDetails.getFileName());
|
||||
deDriverDetailsMapper.deleteByPrimaryKey(driverFileId);
|
||||
}
|
||||
|
||||
public void saveJar(MultipartFile file, String driverId) throws Exception {
|
||||
String filename = file.getOriginalFilename();
|
||||
String dirPath = DRIVER_PATH + driverId + "/";
|
||||
String filePath = dirPath + filename;
|
||||
|
||||
saveFile(file, dirPath, filePath);
|
||||
List<String> jdbcList = new ArrayList<>();
|
||||
String version = "";
|
||||
// ExtendedJdbcClassLoader extendedJdbcClassLoader = new ExtendedJdbcClassLoader(new URL[]{new File(filePath).toURI().toURL()}, null);
|
||||
// for (String className : getClassNameFrom(filePath)) {
|
||||
// if (isChildClass(className, java.sql.Driver.class, extendedJdbcClassLoader)) {
|
||||
// jdbcList.add(className);
|
||||
// version = classVersion(extendedJdbcClassLoader, className);
|
||||
// }
|
||||
// }
|
||||
|
||||
DeDriverDetails deDriverDetails = new DeDriverDetails();
|
||||
deDriverDetails.setId(UUID.randomUUID().toString());
|
||||
deDriverDetails.setDeDriverId(driverId);
|
||||
deDriverDetails.setVersion(version);
|
||||
deDriverDetails.setFileName(filename);
|
||||
deDriverDetails.setDriverClass(String.join(",", jdbcList));
|
||||
deDriverDetailsMapper.insert(deDriverDetails);
|
||||
}
|
||||
|
||||
private List<String> getClassNameFrom(String jarName) {
|
||||
List<String> fileList = new ArrayList<String>();
|
||||
try {
|
||||
JarFile jarFile = new JarFile(new File(jarName));
|
||||
Enumeration<JarEntry> en = jarFile.entries(); // 枚举获得JAR文件内的实体,即相对路径
|
||||
while (en.hasMoreElements()) {
|
||||
String name1 = en.nextElement().getName();
|
||||
if (!name1.endsWith(".class")) {//不是class文件
|
||||
continue;
|
||||
}
|
||||
String name2 = name1.substring(0, name1.lastIndexOf(".class"));
|
||||
String name3 = name2.replaceAll("/", ".");
|
||||
fileList.add(name3);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return fileList;
|
||||
}
|
||||
|
||||
public boolean isChildClass(String className, Class parentClazz, ExtendedJdbcClassLoader extendedJdbcClassLoader) {
|
||||
if (className == null) return false;
|
||||
|
||||
Class clazz = null;
|
||||
try {
|
||||
clazz = extendedJdbcClassLoader.loadClass(className);
|
||||
if (Modifier.isAbstract(clazz.getModifiers())) {//抽象类忽略
|
||||
return false;
|
||||
}
|
||||
if (Modifier.isInterface(clazz.getModifiers())) {//接口忽略
|
||||
return false;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
}
|
||||
return parentClazz.isAssignableFrom(clazz);
|
||||
}
|
||||
|
||||
private String classVersion(ExtendedJdbcClassLoader extendedJdbcClassLoader, String className) throws Exception {
|
||||
Class clazz = extendedJdbcClassLoader.loadClass(className);
|
||||
return clazz.getPackage().getImplementationVersion();
|
||||
}
|
||||
|
||||
private String saveFile(MultipartFile file, String dirPath, String filePath) throws Exception {
|
||||
File p = new File(dirPath);
|
||||
if (!p.exists()) {
|
||||
p.mkdirs();
|
||||
}
|
||||
File f = new File(filePath);
|
||||
FileOutputStream fileOutputStream = new FileOutputStream(f);
|
||||
fileOutputStream.write(file.getBytes());
|
||||
fileOutputStream.flush();
|
||||
fileOutputStream.close();
|
||||
return filePath;
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -1,2 +1,23 @@
|
||||
ALTER TABLE `panel_group`
|
||||
ADD COLUMN `status` varchar(255) NULL DEFAULT 'publish' COMMENT '1.publish--发布 2.unpublished--未发布' AFTER `mobile_layout`;
|
||||
|
||||
|
||||
CREATE TABLE `de_driver` (
|
||||
`id` varchar(50) NOT NULL COMMENT '主键',
|
||||
`name` varchar(50) NOT NULL COMMENT '用户ID',
|
||||
`create_time` bigint(13) NOT NULL COMMENT '创健时间',
|
||||
`type` varchar(255) DEFAULT NULL COMMENT '数据源类型',
|
||||
`driver_class` varchar(255) DEFAULT NULL COMMENT '驱动类',
|
||||
`desc` varchar(255) DEFAULT NULL COMMENT '描述',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='驱动';
|
||||
|
||||
|
||||
CREATE TABLE `de_driver_details` (
|
||||
`id` varchar(50) NOT NULL COMMENT '主键',
|
||||
`de_driver_id` varchar(50) NOT NULL COMMENT '驱动主键',
|
||||
`file_name` varchar(255) DEFAULT NULL COMMENT '名称',
|
||||
`version` varchar(255) DEFAULT NULL COMMENT '版本',
|
||||
`driver_class` longtext DEFAULT NULL COMMENT '驱动类',
|
||||
PRIMARY KEY (`id`) USING BTREE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='驱动详情';
|
@ -15,6 +15,13 @@ export function listDatasource() {
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
export function listDrivers() {
|
||||
return request({
|
||||
url: '/driver/list',
|
||||
loading: true,
|
||||
method: 'post'
|
||||
})
|
||||
}
|
||||
export function listDatasourceType() {
|
||||
return request({
|
||||
url: '/datasource/types',
|
||||
@ -29,6 +36,13 @@ export function listDatasourceByType(type) {
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
export function listDriverByType(type) {
|
||||
return request({
|
||||
url: '/driver/list/' + type,
|
||||
loading: true,
|
||||
method: 'get'
|
||||
})
|
||||
}
|
||||
export function addDs(data) {
|
||||
return request({
|
||||
url: 'datasource/add/',
|
||||
@ -90,4 +104,45 @@ export function checkApiDatasource(data){
|
||||
})
|
||||
}
|
||||
|
||||
export function addDriver(data) {
|
||||
return request({
|
||||
url: '/driver/save',
|
||||
method: 'post',
|
||||
loading: true,
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export function listDriverDetails(id) {
|
||||
return request({
|
||||
url: '/driver/listDriverDetails/' + id,
|
||||
method: 'get',
|
||||
loading: true
|
||||
})
|
||||
}
|
||||
|
||||
export function deleteDriverFile(id) {
|
||||
return request({
|
||||
url: '/driver/deleteDriverFile/' + id,
|
||||
method: 'post',
|
||||
loading: true
|
||||
})
|
||||
}
|
||||
|
||||
export function delDriver(id) {
|
||||
return request({
|
||||
url: 'driver/delete/' + id,
|
||||
loading: true,
|
||||
method: 'post'
|
||||
})
|
||||
}
|
||||
export function updateDriver(data) {
|
||||
return request({
|
||||
url: 'driver/update/',
|
||||
loading: true,
|
||||
method: 'post',
|
||||
data
|
||||
})
|
||||
}
|
||||
|
||||
export default { dsGrid, addDs, editDs, delDs, validateDs, listDatasource, getSchema }
|
||||
|
@ -1328,7 +1328,22 @@ export default {
|
||||
sql_ds_union_error: 'Direct connect SQL dataset can not be union',
|
||||
api_data: 'API dataset'
|
||||
},
|
||||
driver:{
|
||||
driver: 'Driver',
|
||||
please_choose_driver: 'Please choose driver',
|
||||
mgm: 'Driver',
|
||||
add: 'ADD Driver',
|
||||
modify: 'Modify',
|
||||
show_info: 'Driver info',
|
||||
file_name: 'File name',
|
||||
version: 'version'
|
||||
},
|
||||
datasource: {
|
||||
auth_method: 'Auth method',
|
||||
passwd: 'UserName Password',
|
||||
kerbers_info: 'Please make sure krb5 Conf, KeyTab key, added to path: /opt/dataease/conf',
|
||||
client_principal: 'Client Principal',
|
||||
keytab_Key_path: 'Keytab Key Path',
|
||||
datasource: 'Data Source',
|
||||
please_select_left: 'Please select the data source from the left',
|
||||
show_info: 'Data Source Info',
|
||||
|
@ -1328,7 +1328,22 @@ export default {
|
||||
sql_ds_union_error: '直連模式下SQL數據集,不支持關聯',
|
||||
api_data: 'API 數據集'
|
||||
},
|
||||
driver:{
|
||||
driver: '驅動',
|
||||
please_choose_driver: '青選擇驅動',
|
||||
mgm: '驅動管理',
|
||||
add: '添加驅動',
|
||||
modify: '修改',
|
||||
show_info: '驅動信息',
|
||||
file_name: '文件名',
|
||||
version: '版本'
|
||||
},
|
||||
datasource: {
|
||||
auth_method: '認證方式',
|
||||
passwd: '用户名密码',
|
||||
kerbers_info: '请确保 krb5.Conf、Keytab Key,已经添加到路径:/opt/dataease/conf',
|
||||
client_principal: 'Client Principal',
|
||||
keytab_Key_path: 'Keytab Key Path',
|
||||
datasource: '數據源',
|
||||
please_select_left: '請從左側選擇數據源',
|
||||
show_info: '數據源信息',
|
||||
|
@ -1330,7 +1330,22 @@ export default {
|
||||
sql_ds_union_error: '直连模式下SQL数据集,不支持关联',
|
||||
api_data: 'API 数据集'
|
||||
},
|
||||
driver:{
|
||||
driver: '驱动',
|
||||
please_choose_driver: '请选择驱动',
|
||||
mgm: '驱动管理',
|
||||
add: '添加驱动',
|
||||
modify: '修改',
|
||||
show_info: '驱动信息',
|
||||
file_name: '文件名',
|
||||
version: '版本'
|
||||
},
|
||||
datasource: {
|
||||
auth_method: '认证方式',
|
||||
passwd: '用户名密码',
|
||||
kerbers_info: '请确保 krb5.Conf、Keytab Key,已经添加到路径:/opt/dataease/conf',
|
||||
client_principal: 'Client Principal',
|
||||
keytab_Key_path: 'Keytab Key Path',
|
||||
datasource: '数据源',
|
||||
please_select_left: '请从左侧选择数据源',
|
||||
show_info: '数据源信息',
|
||||
|
294
frontend/src/views/system/datasource/DriverForm.vue
Normal file
294
frontend/src/views/system/datasource/DriverForm.vue
Normal file
@ -0,0 +1,294 @@
|
||||
<template>
|
||||
<layout-content>
|
||||
<template v-slot:header>
|
||||
<el-icon name="back" class="back-button" @click.native="backToList"/>
|
||||
{{
|
||||
params && params.id && params.showModel && params.showModel === 'show' && !canEdit ? $t('driver.show_info') : $t('driver.modify')
|
||||
}}
|
||||
<el-button v-if="canEdit" size="mini" style="float: right;"type="primary" @click="save">{{ $t('commons.save') }}
|
||||
</el-button>
|
||||
<el-button v-else size="mini" style="float: right;" type="primary" @click="changeEdit">{{ $t('commons.edit') }}
|
||||
</el-button>
|
||||
|
||||
|
||||
</template>
|
||||
<div>
|
||||
|
||||
<el-form
|
||||
ref="driverForm"
|
||||
:model="driverForm"
|
||||
:rules="rule"
|
||||
size="small"
|
||||
:disabled="params && params.id && params.showModel && params.showModel === 'show' && !canEdit"
|
||||
label-width="180px"
|
||||
label-position="right"
|
||||
>
|
||||
<el-form-item :label="$t('commons.name')" prop="name">
|
||||
<el-input v-model="driverForm.name" autocomplete="off"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('commons.description')" prop="desc">
|
||||
<el-input v-model="driverForm.desc" autocomplete="off"/>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('datasource.type')" prop="type">
|
||||
<el-select
|
||||
v-model="driverForm.type"
|
||||
:placeholder="$t('datasource.please_choose_type')"
|
||||
class="select-width"
|
||||
disabled
|
||||
filterable
|
||||
>
|
||||
<el-option
|
||||
v-for="item in dsTypes"
|
||||
:key="item.type"
|
||||
:label="item.name"
|
||||
:value="item.type"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<!-- <el-form-item :label="$t('driver.driver')" >-->
|
||||
<!-- <el-select-->
|
||||
<!-- v-model="driverForm.driverClass"-->
|
||||
<!-- :placeholder="$t('driver.please_choose_driver')"-->
|
||||
<!-- class="select-width"-->
|
||||
<!-- filterable-->
|
||||
<!-- >-->
|
||||
<!-- <el-option-->
|
||||
<!-- v-for="item in driverClassList"-->
|
||||
<!-- :key="item"-->
|
||||
<!-- :label="item"-->
|
||||
<!-- :value="item"-->
|
||||
<!-- />-->
|
||||
<!-- </el-select>-->
|
||||
<!-- </el-form-item>-->
|
||||
|
||||
<el-form-item :label="$t('driver.driver')" >
|
||||
<el-input v-model="driverForm.driverClass" autocomplete="off"/>
|
||||
</el-form-item>
|
||||
|
||||
|
||||
</el-form>
|
||||
|
||||
<el-upload
|
||||
:action="baseUrl+'driver/file/upload'"
|
||||
:multiple="true"
|
||||
:show-file-list="false"
|
||||
:file-list="fileList"
|
||||
:data="params"
|
||||
accept=".jar"
|
||||
:before-upload="beforeUpload"
|
||||
:on-success="uploadSuccess"
|
||||
:on-error="uploadFail"
|
||||
name="file"
|
||||
:headers="headers"
|
||||
style="float: right;"
|
||||
>
|
||||
<el-button size="mini" type="primary" style="float: right;" :disabled="uploading">
|
||||
<span v-if="!uploading" style="font-size: 12px;">{{ $t('dataset.upload_file') }}</span>
|
||||
<span v-if="uploading" style="font-size: 12px;"><i class="el-icon-loading" /> {{ $t('dataset.uploading') }}</span>
|
||||
</el-button>
|
||||
</el-upload>
|
||||
<fu-table :data="driverFiles">
|
||||
<el-table-column prop="fileName" :label="$t('driver.file_name')"/>
|
||||
<el-table-column prop="version" :label="$t('driver.version')"/>
|
||||
<fu-table-operations :buttons="buttons" :label="$t('commons.operating')" fix/>
|
||||
</fu-table>
|
||||
|
||||
</div>
|
||||
</layout-content>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LayoutContent from '@/components/business/LayoutContent'
|
||||
import i18n from '@/lang/index'
|
||||
import ApiHttpRequestForm from '@/views/system/datasource/ApiHttpRequestForm'
|
||||
import DsConfiguration from "@/views/system/datasource/DsConfiguration";
|
||||
import PluginCom from '@/views/system/plugin/PluginCom'
|
||||
import {deleteDriverFile, listDriverDetails, updateDriver} from "@/api/system/datasource";
|
||||
import {delUser} from "@/api/system/user";
|
||||
import {$alert} from "@/utils/message";
|
||||
import store from "@/store";
|
||||
import {getToken} from "@/utils/auth";
|
||||
|
||||
const token = getToken()
|
||||
|
||||
export default {
|
||||
name: 'DriverForm',
|
||||
components: {
|
||||
DsConfiguration,
|
||||
LayoutContent,
|
||||
ApiHttpRequestForm,
|
||||
PluginCom
|
||||
},
|
||||
props: {
|
||||
params: {
|
||||
type: Object,
|
||||
default: null
|
||||
},
|
||||
tData: {
|
||||
type: Array,
|
||||
default: null
|
||||
},
|
||||
dsTypes: {
|
||||
type: Array,
|
||||
default: null
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
disabled: false,
|
||||
driverForm: {
|
||||
id:'',
|
||||
name: '',
|
||||
desc: '',
|
||||
type: '',
|
||||
driverClass: ''
|
||||
},
|
||||
datasourceType: {},
|
||||
driverClassList: [],
|
||||
rule: {
|
||||
name: [{required: true, message: i18n.t('datasource.input_name'), trigger: 'blur'},
|
||||
{min: 2, max: 50, message: i18n.t('datasource.input_limit_2_25', [2, 25]), trigger: 'blur'}],
|
||||
desc: [{required: true, message: i18n.t('datasource.input_name'), trigger: 'blur'},
|
||||
{min: 2, max: 200, message: i18n.t('datasource.input_limit_2_25', [2, 25]), trigger: 'blur'}],
|
||||
type: [{required: true, message: i18n.t('datasource.please_choose_type'), trigger: 'blur'}]
|
||||
},
|
||||
canEdit: false,
|
||||
driverFiles: [],
|
||||
btnDisabled: false,
|
||||
buttons: [
|
||||
{
|
||||
label: this.$t('commons.delete'), icon: 'el-icon-delete', type: 'danger', click: this.deleteDriverFile,
|
||||
disabled: this.btnDisabled
|
||||
}
|
||||
],
|
||||
uploading: false,
|
||||
baseUrl: process.env.VUE_APP_BASE_API,
|
||||
headers: { Authorization: token, 'Accept-Language': i18n.locale.replace('_', '-') },
|
||||
fileList: []
|
||||
}
|
||||
},
|
||||
|
||||
created() {
|
||||
const row = this.params
|
||||
this.driverForm = JSON.parse(JSON.stringify(row))
|
||||
this.disabled = this.params && this.params.id && this.params.showModel && this.params.showModel === 'show' && !this.canEdit
|
||||
this.listDriverDetails()
|
||||
},
|
||||
mounted() {
|
||||
},
|
||||
|
||||
|
||||
methods: {
|
||||
beforeUpload(file) {
|
||||
this.uploading = true
|
||||
},
|
||||
uploadSuccess(response, file, fileList) {
|
||||
this.uploading = false
|
||||
this.listDriverDetails()
|
||||
},
|
||||
uploadFail(response, file, fileList) {
|
||||
let myError = response.toString()
|
||||
myError = myError.replace('Error: ', '')
|
||||
if(myError.indexOf('AuthenticationException') >= 0){
|
||||
const message = i18n.t('login.tokenError')
|
||||
$alert(message, () => {
|
||||
store.dispatch('user/logout').then(() => {
|
||||
location.reload()
|
||||
})
|
||||
}, {
|
||||
confirmButtonText: i18n.t('login.re_login'),
|
||||
showClose: false
|
||||
})
|
||||
return
|
||||
}
|
||||
const errorMessage = JSON.parse(myError).message
|
||||
this.uploading = false
|
||||
this.$message({
|
||||
type: 'error',
|
||||
message: errorMessage,
|
||||
showClose: true
|
||||
})
|
||||
},
|
||||
deleteDriverFile(row){
|
||||
deleteDriverFile(row.id).then(res => {
|
||||
this.$success(this.$t('commons.delete_success'))
|
||||
this.listDriverDetails()
|
||||
})
|
||||
},
|
||||
listDriverDetails(){
|
||||
listDriverDetails(this.driverForm.id).then(res => {
|
||||
this.driverFiles = res.data
|
||||
this.driverClassList = []
|
||||
this.driverFiles.forEach(driverFile => {
|
||||
this.driverClassList = this.driverClassList.concat(driverFile.driverClass.split(','))
|
||||
})
|
||||
})
|
||||
},
|
||||
changeEdit() {
|
||||
this.canEdit = true
|
||||
this.formType = 'modify'
|
||||
this.disabled = this.params && this.params.id && this.params.showModel && this.params.showModel === 'show' && !this.canEdit
|
||||
},
|
||||
save(){
|
||||
updateDriver(this.driverForm).then(res => {
|
||||
this.$success(i18n.t('commons.success'))
|
||||
this.canEdit = false
|
||||
})
|
||||
},
|
||||
reset() {
|
||||
this.$refs.dsForm.resetFields()
|
||||
},
|
||||
backToList() {
|
||||
this.$emit('switch-component', {})
|
||||
},
|
||||
refreshType(form) {
|
||||
this.$emit('refresh-type', DsForm)
|
||||
},
|
||||
handleClick(tab, event) {}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
<style scoped>
|
||||
.el-input {
|
||||
width: 300px;
|
||||
}
|
||||
|
||||
.el-select {
|
||||
width: 300px;
|
||||
}
|
||||
|
||||
.ms-http-input {
|
||||
width: 500px;
|
||||
margin-top: 5px;
|
||||
}
|
||||
|
||||
.tip {
|
||||
padding: 3px 5px;
|
||||
font-size: 16px;
|
||||
border-radius: 0;
|
||||
border-left: 4px solid #409EFF;
|
||||
margin: 5px 5px 10px 5px;
|
||||
}
|
||||
|
||||
.el-select >>> input {
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
.el-select >>> .el-input__suffix {
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.dialog-css >>> .el-dialog__header {
|
||||
padding: 10px 20px 0px;
|
||||
}
|
||||
|
||||
.dialog-css >>> .el-dialog__body {
|
||||
padding: 10px 20px 10px;
|
||||
}
|
||||
|
||||
.dialog-footer >>> .el-dialog__footer {
|
||||
padding: 10px 10px 10px;
|
||||
}
|
||||
|
||||
</style>
|
@ -3,13 +3,13 @@
|
||||
<el-row>
|
||||
<el-col>
|
||||
<el-form
|
||||
ref="DsConfig"
|
||||
:model="form"
|
||||
:rules="rule"
|
||||
size="small"
|
||||
:disabled="disabled"
|
||||
label-width="180px"
|
||||
label-position="right"
|
||||
ref="DsConfig"
|
||||
:model="form"
|
||||
:rules="rule"
|
||||
size="small"
|
||||
:disabled="disabled"
|
||||
label-width="180px"
|
||||
label-position="right"
|
||||
>
|
||||
<el-form-item v-if="form.type == 'api'" :label="$t('datasource.data_table')">
|
||||
<el-col>
|
||||
@ -77,7 +77,8 @@
|
||||
</div>
|
||||
|
||||
<el-form-item :label="$t('datasource.data_path')" prop="dataPath">
|
||||
<el-input :placeholder="$t('datasource.data_path_desc')" v-model="apiItem.dataPath" autocomplete="off"/>
|
||||
<el-input :placeholder="$t('datasource.data_path_desc')" v-model="apiItem.dataPath"
|
||||
autocomplete="off"/>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-row>
|
||||
@ -103,7 +104,10 @@
|
||||
</el-tabs>
|
||||
</el-row>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button @click="next" :disabled="disabledNext" v-show="active === 1">{{ $t('fu.steps.next') }}</el-button>
|
||||
<el-button @click="next" :disabled="disabledNext" v-show="active === 1">{{
|
||||
$t('fu.steps.next')
|
||||
}}
|
||||
</el-button>
|
||||
<el-button @click="before" v-show="active === 2">{{ $t('fu.steps.prev') }}</el-button>
|
||||
<el-button @click="saveItem" v-show="active === 2">{{ $t('commons.save') }}</el-button>
|
||||
</div>
|
||||
@ -125,20 +129,55 @@
|
||||
<el-input v-model="form.configuration.dataBase" autocomplete="off"/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item v-if="form.type=='oracle' && form.type !== 'api'" :label="$t('datasource.oracle_connection_type')"
|
||||
<el-form-item v-if="form.type=='oracle' && form.type !== 'api'"
|
||||
:label="$t('datasource.oracle_connection_type')"
|
||||
prop="configuration.connectionType">
|
||||
<el-radio v-model="form.configuration.connectionType" label="sid">{{ $t('datasource.oracle_sid') }}</el-radio>
|
||||
<el-radio v-model="form.configuration.connectionType" label="sid">{{
|
||||
$t('datasource.oracle_sid')
|
||||
}}
|
||||
</el-radio>
|
||||
<el-radio v-model="form.configuration.connectionType" label="serviceName">
|
||||
{{ $t('datasource.oracle_service_name') }}
|
||||
</el-radio>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item v-if="form.type !== 'es' && form.type !== 'api'"
|
||||
<el-form-item v-if="form.type=='hive' " :label="$t('datasource.auth_method')">
|
||||
<el-select
|
||||
v-model="form.configuration.authMethod"
|
||||
class="select-width"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in authMethodList"
|
||||
:key="item.id"
|
||||
:label="item.label"
|
||||
:value="item.id"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item v-if="form.type === 'hive' && form.configuration.authMethod === 'kerberos'"
|
||||
:label="$t('datasource.client_principal')">
|
||||
<el-input v-model="form.configuration.username" autocomplete="off"/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item v-if="form.type === 'hive' && form.configuration.authMethod === 'kerberos'"
|
||||
:label="$t('datasource.keytab_Key_path')">
|
||||
<el-input v-model="form.configuration.password" autocomplete="off" show-password/>
|
||||
<p>
|
||||
{{$t('datasource.kerbers_info')}}
|
||||
</p>
|
||||
</el-form-item>
|
||||
|
||||
<span v-if="form.type === 'hive' && form.configuration.authMethod === 'kerberos'">
|
||||
|
||||
</span>
|
||||
|
||||
<el-form-item v-if="form.type !== 'es' && form.type !== 'api' && form.configuration.authMethod !== 'kerberos'"
|
||||
:label="$t('datasource.user_name')">
|
||||
<el-input v-model="form.configuration.username" autocomplete="off"/>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item v-if="form.type !== 'es' && form.type !== 'api'"
|
||||
<el-form-item v-if="form.type !== 'es' && form.type !== 'api' && form.configuration.authMethod !== 'kerberos'"
|
||||
:label="$t('datasource.password')">
|
||||
<el-input v-model="form.configuration.password" autocomplete="off" show-password/>
|
||||
</el-form-item>
|
||||
@ -164,21 +203,26 @@
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item
|
||||
v-if="form.type=='oracle' || form.type=='sqlServer' || form.type=='pg' || form.type=='redshift' || form.type=='db2'">
|
||||
<el-button icon="el-icon-plus" size="mini" @click="getSchema()">{{ $t('datasource.get_schema') }}</el-button>
|
||||
v-if="form.type=='oracle' || form.type=='sqlServer' || form.type=='pg' || form.type=='redshift' || form.type=='db2'">
|
||||
<el-button icon="el-icon-plus" size="mini" @click="getSchema()">{{
|
||||
$t('datasource.get_schema')
|
||||
}}
|
||||
</el-button>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item
|
||||
v-if="form.type=='oracle' || form.type=='sqlServer' || form.type=='pg' || form.type=='redshift' || form.type=='db2'"
|
||||
:label="$t('datasource.schema')">
|
||||
<el-select v-model="form.configuration.schema" filterable :placeholder="$t('datasource.please_choose_schema')"
|
||||
v-if="form.type=='oracle' || form.type=='sqlServer' || form.type=='pg' || form.type=='redshift' || form.type=='db2'"
|
||||
:label="$t('datasource.schema')">
|
||||
<el-select v-model="form.configuration.schema" filterable
|
||||
:placeholder="$t('datasource.please_choose_schema')"
|
||||
class="select-width">
|
||||
<el-option v-for="item in schemas" :key="item" :label="item" :value="item"/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item v-if="form.type=='oracle'" :label="$t('datasource.charset')">
|
||||
<el-select v-model="form.configuration.charset" filterable :placeholder="$t('datasource.please_choose_charset')"
|
||||
<el-select v-model="form.configuration.charset" filterable
|
||||
:placeholder="$t('datasource.please_choose_charset')"
|
||||
class="select-width">
|
||||
<el-option v-for="item in datasourceType.charset" :key="item" :label="item" :value="item"/>
|
||||
</el-select>
|
||||
@ -208,7 +252,6 @@
|
||||
<script>
|
||||
|
||||
|
||||
|
||||
import i18n from "@/lang";
|
||||
import {checkApiDatasource, getSchema} from "@/api/system/datasource";
|
||||
import ApiHttpRequestForm from '@/views/system/datasource/ApiHttpRequestForm'
|
||||
@ -367,15 +410,20 @@ export default {
|
||||
{label: this.$t('dataset.location'), value: 5}
|
||||
],
|
||||
height: 500,
|
||||
disabledNext: false
|
||||
disabledNext: false,
|
||||
authMethodList: [
|
||||
{
|
||||
id: 'passwd',
|
||||
label: i18n.t('datasource.passwd')
|
||||
}, {
|
||||
id: 'kerberos',
|
||||
label: 'Kerberos'
|
||||
}]
|
||||
}
|
||||
},
|
||||
created() {
|
||||
|
||||
},
|
||||
watch: {
|
||||
|
||||
},
|
||||
watch: {},
|
||||
methods: {
|
||||
getSchema() {
|
||||
this.$refs.DsConfig.validate(valid => {
|
||||
|
@ -41,6 +41,23 @@
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<el-form-item v-if="datasourceType.isJdbc" :label="$t('driver.driver')">
|
||||
<el-select
|
||||
v-model="form.configuration.customDriver"
|
||||
:placeholder="$t('driver.please_choose_driver')"
|
||||
class="select-width"
|
||||
filterable
|
||||
>
|
||||
<el-option
|
||||
v-for="item in driverList"
|
||||
:key="item.id"
|
||||
:label="item.name"
|
||||
:value="item.id"
|
||||
:disabled="!item.driverClass"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
|
||||
<ds-configuration ref="dsConfig" v-if="!datasourceType.isPlugin" :datasource-type='datasourceType' :form="form" :disabled="params && params.id && params.showModel && params.showModel === 'show' && !canEdit"></ds-configuration>
|
||||
<plugin-com ref="pluginDsConfig" v-if="datasourceType.isPlugin" :component-name="datasourceType.type" :obj="{form, disabled }" />
|
||||
|
||||
@ -70,7 +87,15 @@
|
||||
|
||||
<script>
|
||||
import LayoutContent from '@/components/business/LayoutContent'
|
||||
import {addDs, editDs, getSchema, validateDs, validateDsById, checkApiDatasource} from '@/api/system/datasource'
|
||||
import {
|
||||
addDs,
|
||||
editDs,
|
||||
getSchema,
|
||||
validateDs,
|
||||
validateDsById,
|
||||
checkApiDatasource,
|
||||
listDriverByType
|
||||
} from '@/api/system/datasource'
|
||||
import {$confirm} from '@/utils/message'
|
||||
import i18n from '@/lang/index'
|
||||
import ApiHttpRequestForm from '@/views/system/datasource/ApiHttpRequestForm'
|
||||
@ -227,7 +252,8 @@ export default {
|
||||
{label: this.$t('dataset.location'), value: 5}
|
||||
],
|
||||
height: 500,
|
||||
disabledNext: false
|
||||
disabledNext: false,
|
||||
driverList: []
|
||||
}
|
||||
},
|
||||
|
||||
@ -235,7 +261,7 @@ export default {
|
||||
if (this.params && this.params.id) {
|
||||
const row = this.params
|
||||
this.edit(row)
|
||||
this.changeType()
|
||||
this.changeType(true)
|
||||
} else {
|
||||
this.create()
|
||||
if (this.params && this.params.type) {
|
||||
@ -492,13 +518,19 @@ export default {
|
||||
}
|
||||
})
|
||||
},
|
||||
changeType() {
|
||||
changeType(init) {
|
||||
for (let i = 0; i < this.dsTypes.length; i++) {
|
||||
if (this.dsTypes[i].type === this.form.type) {
|
||||
if(this.form.type !== 'api'){
|
||||
if(this.form.type !== 'api' && !init){
|
||||
this.form.configuration.extraParams = this.dsTypes[i].extraParams
|
||||
}
|
||||
this.datasourceType = this.dsTypes[i]
|
||||
if(this.datasourceType.isJdbc){
|
||||
listDriverByType(this.datasourceType.type).then(res => {
|
||||
this.driverList = res.data
|
||||
this.driverList.push({id: 'default', name: 'Default', driverClass:'Default'})
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
@ -22,7 +22,8 @@ import DeMainContainer from '@/components/dataease/DeMainContainer'
|
||||
import DeContainer from '@/components/dataease/DeContainer'
|
||||
import DeAsideContainer from '@/components/dataease/DeAsideContainer'
|
||||
import DsTree from './DsTree'
|
||||
import DsForm from './form'
|
||||
import DsForm from './DsForm'
|
||||
import DriverForm from "./DriverForm";
|
||||
import DataHome from './DataHome'
|
||||
|
||||
export default {
|
||||
@ -56,6 +57,12 @@ export default {
|
||||
this.tData = tData
|
||||
this.dsTypes = dsTypes
|
||||
break
|
||||
case 'DriverForm':
|
||||
this.component = DriverForm
|
||||
this.param = componentParam
|
||||
this.tData = tData
|
||||
this.dsTypes = dsTypes
|
||||
break
|
||||
default:
|
||||
this.component = DataHome
|
||||
this.param = null
|
||||
|
@ -1,15 +1,15 @@
|
||||
<template xmlns:el-col="http://www.w3.org/1999/html">
|
||||
<el-col class="tree-style">
|
||||
<el-col>
|
||||
<el-row class="title-css">
|
||||
<span class="title-text">
|
||||
{{ $t('commons.datasource') }}
|
||||
</span>
|
||||
<el-button icon="el-icon-plus" type="text" size="mini" style="float: right;"
|
||||
@click="addFolder"/>
|
||||
|
||||
<el-row >
|
||||
<el-tabs v-model="showView" @tab-click="changeTab" type="card">
|
||||
<el-tab-pane v-for="(item, index) in editableTabs" :key="item.name" :label="item.title" :name="item.name">
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
</el-row>
|
||||
<el-row>
|
||||
<el-button icon="el-icon-plus" type="text" size="mini" style="float: left;" @click="addFolder"/>
|
||||
</el-row>
|
||||
<el-divider/>
|
||||
<el-row>
|
||||
<el-form>
|
||||
<el-form-item class="form-item">
|
||||
@ -99,11 +99,55 @@
|
||||
</el-tree>
|
||||
</div>
|
||||
</el-col>
|
||||
|
||||
<el-dialog v-dialogDrag :title="dialogTitle" :visible="editDriver" :show-close="false" width="50%" append-to-body>
|
||||
<el-form ref="driverForm" :model="driverForm" label-position="right" label-width="100px" :rules="rule">
|
||||
<el-form-item :label="$t('commons.name')" prop="name">
|
||||
<el-input v-model="driverForm.name" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('commons.description')" prop="desc">
|
||||
<el-input v-model="driverForm.desc" />
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('datasource.type')" prop="type">
|
||||
<el-select
|
||||
v-model="driverForm.type"
|
||||
:placeholder="$t('datasource.please_choose_type')"
|
||||
class="select-width"
|
||||
:disabled="disabledModifyType"
|
||||
filterable
|
||||
>
|
||||
<el-option
|
||||
v-for="item in dsTypes"
|
||||
:key="item.type"
|
||||
:label="item.name"
|
||||
:value="item.type"
|
||||
/>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
<div slot="footer" class="dialog-footer">
|
||||
<el-button size="mini" @click="close()">{{ $t('commons.cancel') }}</el-button>
|
||||
<el-button type="primary" size="mini" @click="saveDriver(driverForm)">{{ $t('commons.save') }}
|
||||
</el-button>
|
||||
</div>
|
||||
</el-dialog>
|
||||
|
||||
|
||||
</el-col>
|
||||
</el-col>
|
||||
</template>
|
||||
<script>
|
||||
import {listDatasource, listDatasourceByType, delDs, listDatasourceType} from '@/api/system/datasource'
|
||||
import {
|
||||
listDatasource,
|
||||
listDatasourceByType,
|
||||
listDriverByType,
|
||||
delDs,
|
||||
listDatasourceType,
|
||||
listDrivers,
|
||||
addDriver, delDriver
|
||||
} from '@/api/system/datasource'
|
||||
import { mapGetters } from 'vuex'
|
||||
import i18n from "@/lang";
|
||||
|
||||
export default {
|
||||
name: 'DsTree',
|
||||
@ -119,7 +163,27 @@ export default {
|
||||
tData: [],
|
||||
dsTypes: [],
|
||||
showSearchInput: false,
|
||||
key: ''
|
||||
key: '',
|
||||
showView: 'Datasource',
|
||||
dialogTitle: '',
|
||||
editDriver: false,
|
||||
driverForm: {
|
||||
name: '',
|
||||
desc: '',
|
||||
type: ''
|
||||
},
|
||||
disabledModifyType: false,
|
||||
rule: {
|
||||
name: [{required: true, message: i18n.t('datasource.input_name'), trigger: 'blur'},
|
||||
{min: 2, max: 50, message: i18n.t('datasource.input_limit_2_25', [2, 25]), trigger: 'blur'}],
|
||||
desc: [{required: true, message: i18n.t('datasource.input_name'), trigger: 'blur'},
|
||||
{min: 2, max: 200, message: i18n.t('datasource.input_limit_2_25', [2, 25]), trigger: 'blur'}],
|
||||
type: [{required: true, message: i18n.t('datasource.please_choose_type'), trigger: 'blur'}]
|
||||
},
|
||||
editableTabs: [{
|
||||
title: i18n.t('commons.datasource'),
|
||||
name: 'Datasource'
|
||||
}]
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
@ -127,14 +191,22 @@ export default {
|
||||
this.$refs.myDsTree.filter(val)
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
...mapGetters([
|
||||
'user'
|
||||
])
|
||||
},
|
||||
created() {
|
||||
this.queryTreeDatas()
|
||||
this.datasourceTypes()
|
||||
if(this.user.isAdmin){
|
||||
this.editableTabs.push({
|
||||
title: i18n.t('driver.mgm'),
|
||||
name: 'Driver'
|
||||
})
|
||||
}
|
||||
|
||||
},
|
||||
// mounted() {
|
||||
// this.queryTreeDatas()
|
||||
// this.datasourceTypes()
|
||||
// },
|
||||
methods: {
|
||||
filterNode(value, data) {
|
||||
if (!value) return true
|
||||
@ -148,9 +220,16 @@ export default {
|
||||
this.showSearchInput = false
|
||||
},
|
||||
queryTreeDatas() {
|
||||
listDatasource().then(res => {
|
||||
this.tData = this.buildTree(res.data)
|
||||
})
|
||||
if(this.showView === 'Datasource'){
|
||||
listDatasource().then(res => {
|
||||
this.tData = this.buildTree(res.data)
|
||||
})
|
||||
}
|
||||
if(this.showView === 'Driver'){
|
||||
listDrivers().then(res => {
|
||||
this.tData = this.buildTree(res.data)
|
||||
})
|
||||
}
|
||||
},
|
||||
datasourceTypes() {
|
||||
listDatasourceType().then(res => {
|
||||
@ -158,8 +237,9 @@ export default {
|
||||
})
|
||||
},
|
||||
refreshType(datasource) {
|
||||
const method = this.showView === 'Datasource' ? listDatasourceByType : listDriverByType
|
||||
let typeData = []
|
||||
listDatasourceByType(datasource.type).then(res => {
|
||||
method(datasource.type).then(res => {
|
||||
typeData = this.buildTree(res.data)
|
||||
if (typeData.length === 0) {
|
||||
let index = this.tData.findIndex(item => {
|
||||
@ -209,10 +289,30 @@ export default {
|
||||
},
|
||||
|
||||
addFolder() {
|
||||
this.switchMain('DsForm', {}, this.tData, this.dsTypes)
|
||||
if(this.showView === 'Driver'){
|
||||
this.dialogTitle = this.$t('driver.driver')
|
||||
this.editDriver = true
|
||||
// this.switchMain('DriverForm', {}, this.tData, this.dsTypes)
|
||||
}else {
|
||||
this.switchMain('DsForm', {}, this.tData, this.dsTypes)
|
||||
}
|
||||
},
|
||||
|
||||
changeTab() {
|
||||
this.expandedArray = []
|
||||
this.tData = []
|
||||
this.queryTreeDatas()
|
||||
},
|
||||
|
||||
addFolderWithType(data) {
|
||||
this.switchMain('DsForm', {type: data.id}, this.tData, this.dsTypes)
|
||||
if(this.showView === 'Driver'){
|
||||
this.driverForm.type = data.id
|
||||
this.dialogTitle = this.$t('driver.driver')
|
||||
this.editDriver = false
|
||||
this.switchMain('DriverForm', {}, this.tData, this.dsTypes)
|
||||
}else {
|
||||
this.switchMain('DsForm', {type: data.id}, this.tData, this.dsTypes)
|
||||
}
|
||||
},
|
||||
nodeClick(node, data) {
|
||||
if (node.type === 'folder') return
|
||||
@ -240,7 +340,12 @@ export default {
|
||||
},
|
||||
showInfo(row) {
|
||||
const param = {...row.data, ...{showModel: 'show'}}
|
||||
this.switchMain('DsForm', param, this.tData, this.dsTypes)
|
||||
if(this.showView === 'Datasource'){
|
||||
this.switchMain('DsForm', param, this.tData, this.dsTypes)
|
||||
}else {
|
||||
this.switchMain('DriverForm', param, this.tData, this.dsTypes)
|
||||
}
|
||||
|
||||
},
|
||||
_handleDelete(datasource) {
|
||||
this.$confirm(this.$t('datasource.delete_warning'), '', {
|
||||
@ -248,7 +353,8 @@ export default {
|
||||
cancelButtonText: this.$t('commons.cancel'),
|
||||
type: 'warning'
|
||||
}).then(() => {
|
||||
delDs(datasource.id).then(res => {
|
||||
const method = this.showView === 'Datasource' ? delDs : delDriver
|
||||
method(datasource.id).then(res => {
|
||||
if(res.success){
|
||||
this.$success(this.$t('commons.delete_success'))
|
||||
this.switchMain('DataHome', {}, this.tData, this.dsTypes)
|
||||
@ -289,7 +395,33 @@ export default {
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
},
|
||||
close() {
|
||||
this.$refs['driverForm'].resetFields()
|
||||
this.editDriver = false
|
||||
this.driverForm = {
|
||||
name: '',
|
||||
desc: '',
|
||||
type: ''
|
||||
}
|
||||
},
|
||||
saveDriver(driverForm) {
|
||||
this.$refs['driverForm'].validate((valid) => {
|
||||
if (valid) {
|
||||
addDriver(driverForm).then(res => {
|
||||
this.$message({
|
||||
message: this.$t('dataset.save_success'),
|
||||
type: 'success',
|
||||
showClose: true
|
||||
})
|
||||
this.refreshType(driverForm)
|
||||
this.close()
|
||||
})
|
||||
} else {
|
||||
return false
|
||||
}
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
@ -8,7 +8,6 @@
|
||||
@search="search"
|
||||
>
|
||||
<template #toolbar>
|
||||
|
||||
<el-upload
|
||||
:action="baseUrl+'api/plugin/upload'"
|
||||
:multiple="false"
|
||||
|
Loading…
Reference in New Issue
Block a user