mirror of
				https://github.com/vran-dev/databasir.git
				synced 2025-11-04 16:26:10 +08:00 
			
		
		
		
	feat: add test connection api (#4)
This commit is contained in:
		@@ -55,4 +55,10 @@ public class ProjectController {
 | 
				
			|||||||
                                                      ProjectListCondition condition) {
 | 
					                                                      ProjectListCondition condition) {
 | 
				
			||||||
        return JsonData.ok(projectService.list(page, condition));
 | 
					        return JsonData.ok(projectService.list(page, condition));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @PostMapping(Routes.GroupProject.TEST_CONNECTION)
 | 
				
			||||||
 | 
					    public JsonData<Void> testConnection(@RequestBody @Valid ProjectTestConnectionRequest request) {
 | 
				
			||||||
 | 
					        projectService.testConnection(request);
 | 
				
			||||||
 | 
					        return JsonData.ok();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -57,6 +57,8 @@ public interface Routes {
 | 
				
			|||||||
        String UPDATE = BASE + "/groups/{groupId}/projects";
 | 
					        String UPDATE = BASE + "/groups/{groupId}/projects";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        String DELETE = BASE + "/groups/{groupId}/projects/{projectId}";
 | 
					        String DELETE = BASE + "/groups/{groupId}/projects/{projectId}";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        String TEST_CONNECTION = BASE + "/projects/test_connection";
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    interface Document {
 | 
					    interface Document {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,5 @@
 | 
				
			|||||||
server.port=8080
 | 
					server.port=8080
 | 
				
			||||||
logging.level.org.jooq=DEBUG
 | 
					logging.level.org.jooq=INFO
 | 
				
			||||||
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
 | 
					spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
 | 
				
			||||||
spring.datasource.username=root
 | 
					spring.datasource.username=root
 | 
				
			||||||
spring.datasource.password=123456
 | 
					spring.datasource.password=123456
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -46,4 +46,11 @@ public class DatabasirException extends RuntimeException {
 | 
				
			|||||||
        this.errCode = errorCodeMessage.getErrCode();
 | 
					        this.errCode = errorCodeMessage.getErrCode();
 | 
				
			||||||
        this.errMessage = errorCodeMessage.getErrMessage();
 | 
					        this.errMessage = errorCodeMessage.getErrMessage();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public DatabasirException(DatabasirErrors errorCodeMessage, String overrideMessage, Throwable cause) {
 | 
				
			||||||
 | 
					        super(overrideMessage, cause);
 | 
				
			||||||
 | 
					        this.errorCodeMessage = errorCodeMessage;
 | 
				
			||||||
 | 
					        this.errCode = errorCodeMessage.getErrCode();
 | 
				
			||||||
 | 
					        this.errMessage = overrideMessage;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -35,4 +35,8 @@ public enum DomainErrors implements DatabasirErrors {
 | 
				
			|||||||
    public DatabasirException exception(Throwable origin) {
 | 
					    public DatabasirException exception(Throwable origin) {
 | 
				
			||||||
        return new DatabasirException(this, origin);
 | 
					        return new DatabasirException(this, origin);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public DatabasirException exception(String message, Throwable origin) {
 | 
				
			||||||
 | 
					        return new DatabasirException(this, message, origin);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -0,0 +1,29 @@
 | 
				
			|||||||
 | 
					package com.databasir.core.domain.project.data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import lombok.Data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import javax.validation.constraints.NotBlank;
 | 
				
			||||||
 | 
					import java.util.ArrayList;
 | 
				
			||||||
 | 
					import java.util.List;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@Data
 | 
				
			||||||
 | 
					public class ProjectTestConnectionRequest {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private Integer projectId;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @NotBlank
 | 
				
			||||||
 | 
					    private String username;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private String password;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @NotBlank
 | 
				
			||||||
 | 
					    private String url;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @NotBlank
 | 
				
			||||||
 | 
					    private String databaseName;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @NotBlank
 | 
				
			||||||
 | 
					    private String databaseType;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private List<DataSourcePropertyValue> properties = new ArrayList<>();
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -6,6 +6,7 @@ import com.databasir.core.domain.project.converter.DataSourcePojoConverter;
 | 
				
			|||||||
import com.databasir.core.domain.project.converter.ProjectPojoConverter;
 | 
					import com.databasir.core.domain.project.converter.ProjectPojoConverter;
 | 
				
			||||||
import com.databasir.core.domain.project.converter.ProjectResponseConverter;
 | 
					import com.databasir.core.domain.project.converter.ProjectResponseConverter;
 | 
				
			||||||
import com.databasir.core.domain.project.data.*;
 | 
					import com.databasir.core.domain.project.data.*;
 | 
				
			||||||
 | 
					import com.databasir.core.infrastructure.connection.DatabaseConnectionService;
 | 
				
			||||||
import com.databasir.dao.impl.*;
 | 
					import com.databasir.dao.impl.*;
 | 
				
			||||||
import com.databasir.dao.tables.pojos.*;
 | 
					import com.databasir.dao.tables.pojos.*;
 | 
				
			||||||
import lombok.RequiredArgsConstructor;
 | 
					import lombok.RequiredArgsConstructor;
 | 
				
			||||||
@@ -19,6 +20,7 @@ import org.springframework.util.StringUtils;
 | 
				
			|||||||
import java.util.List;
 | 
					import java.util.List;
 | 
				
			||||||
import java.util.Map;
 | 
					import java.util.Map;
 | 
				
			||||||
import java.util.Optional;
 | 
					import java.util.Optional;
 | 
				
			||||||
 | 
					import java.util.Properties;
 | 
				
			||||||
import java.util.function.Function;
 | 
					import java.util.function.Function;
 | 
				
			||||||
import java.util.stream.Collectors;
 | 
					import java.util.stream.Collectors;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -42,6 +44,8 @@ public class ProjectService {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    private final ProjectResponseConverter projectResponseConverter;
 | 
					    private final ProjectResponseConverter projectResponseConverter;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private final DatabaseConnectionService databaseConnectionService;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    public ProjectDetailResponse getOne(Integer id) {
 | 
					    public ProjectDetailResponse getOne(Integer id) {
 | 
				
			||||||
        return projectDao.selectOptionalById(id)
 | 
					        return projectDao.selectOptionalById(id)
 | 
				
			||||||
                .map(schemaSource -> {
 | 
					                .map(schemaSource -> {
 | 
				
			||||||
@@ -142,4 +146,25 @@ public class ProjectService {
 | 
				
			|||||||
        });
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public void testConnection(ProjectTestConnectionRequest request) {
 | 
				
			||||||
 | 
					        String password;
 | 
				
			||||||
 | 
					        if (request.getProjectId() != null && !StringUtils.hasText(request.getPassword())) {
 | 
				
			||||||
 | 
					            DataSourcePojo dataSource = dataSourceDao.selectByProjectId(request.getProjectId());
 | 
				
			||||||
 | 
					            SysKeyPojo sysKey = sysKeyDao.selectTopOne();
 | 
				
			||||||
 | 
					            password = Aes.decryptFromBase64Data(dataSource.getPassword(), sysKey.getAesKey());
 | 
				
			||||||
 | 
					        } else if (StringUtils.hasText(request.getPassword())) {
 | 
				
			||||||
 | 
					            password = request.getPassword();
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            throw DomainErrors.PASSWORD_MUST_NOT_BE_BLANK.exception();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        Properties properties = new Properties();
 | 
				
			||||||
 | 
					        request.getProperties().forEach(prop -> properties.put(prop.getKey(), prop.getValue()));
 | 
				
			||||||
 | 
					        databaseConnectionService.testConnection(request.getUsername(),
 | 
				
			||||||
 | 
					                password,
 | 
				
			||||||
 | 
					                request.getUrl(),
 | 
				
			||||||
 | 
					                request.getDatabaseName(),
 | 
				
			||||||
 | 
					                request.getDatabaseType(),
 | 
				
			||||||
 | 
					                properties);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,7 @@
 | 
				
			|||||||
package com.databasir.core.infrastructure.connection;
 | 
					package com.databasir.core.infrastructure.connection;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.sql.Connection;
 | 
					import java.sql.Connection;
 | 
				
			||||||
 | 
					import java.sql.SQLException;
 | 
				
			||||||
import java.util.Properties;
 | 
					import java.util.Properties;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
public interface DatabaseConnectionFactory {
 | 
					public interface DatabaseConnectionFactory {
 | 
				
			||||||
@@ -11,5 +12,5 @@ public interface DatabaseConnectionFactory {
 | 
				
			|||||||
                             String password,
 | 
					                             String password,
 | 
				
			||||||
                             String url,
 | 
					                             String url,
 | 
				
			||||||
                             String schema,
 | 
					                             String schema,
 | 
				
			||||||
                             Properties properties);
 | 
					                             Properties properties) throws SQLException;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,6 +10,7 @@ import lombok.RequiredArgsConstructor;
 | 
				
			|||||||
import org.springframework.stereotype.Component;
 | 
					import org.springframework.stereotype.Component;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.sql.Connection;
 | 
					import java.sql.Connection;
 | 
				
			||||||
 | 
					import java.sql.SQLException;
 | 
				
			||||||
import java.util.List;
 | 
					import java.util.List;
 | 
				
			||||||
import java.util.Properties;
 | 
					import java.util.Properties;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -30,10 +31,31 @@ public class DatabaseConnectionService {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        Properties info = new Properties();
 | 
					        Properties info = new Properties();
 | 
				
			||||||
        dataSourceProperties.forEach(prop -> info.put(prop.getKey(), prop.getValue()));
 | 
					        dataSourceProperties.forEach(prop -> info.put(prop.getKey(), prop.getValue()));
 | 
				
			||||||
        return factories.stream()
 | 
					        try {
 | 
				
			||||||
                .filter(factory -> factory.support(dataSource.getDatabaseType()))
 | 
					            return factories.stream()
 | 
				
			||||||
                .findFirst()
 | 
					                    .filter(factory -> factory.support(dataSource.getDatabaseType()))
 | 
				
			||||||
                .orElseThrow(DomainErrors.NOT_SUPPORT_DATABASE_TYPE::exception)
 | 
					                    .findFirst()
 | 
				
			||||||
                .getConnection(username, password, url, dataSource.getDatabaseName(), info);
 | 
					                    .orElseThrow(DomainErrors.NOT_SUPPORT_DATABASE_TYPE::exception)
 | 
				
			||||||
 | 
					                    .getConnection(username, password, url, dataSource.getDatabaseName(), info);
 | 
				
			||||||
 | 
					        } catch (SQLException e) {
 | 
				
			||||||
 | 
					            throw DomainErrors.CONNECT_DATABASE_FAILED.exception(e.getMessage(), e);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public void testConnection(String username,
 | 
				
			||||||
 | 
					                               String password,
 | 
				
			||||||
 | 
					                               String url,
 | 
				
			||||||
 | 
					                               String databaseName,
 | 
				
			||||||
 | 
					                               String databaseType,
 | 
				
			||||||
 | 
					                               Properties properties) {
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					            factories.stream()
 | 
				
			||||||
 | 
					                    .filter(factory -> factory.support(databaseType))
 | 
				
			||||||
 | 
					                    .findFirst()
 | 
				
			||||||
 | 
					                    .orElseThrow(DomainErrors.NOT_SUPPORT_DATABASE_TYPE::exception)
 | 
				
			||||||
 | 
					                    .getConnection(username, password, url, databaseName, properties);
 | 
				
			||||||
 | 
					        } catch (SQLException e) {
 | 
				
			||||||
 | 
					            throw DomainErrors.CONNECT_DATABASE_FAILED.exception(e.getMessage(), e);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,5 @@
 | 
				
			|||||||
package com.databasir.core.infrastructure.connection;
 | 
					package com.databasir.core.infrastructure.connection;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import com.databasir.core.domain.DomainErrors;
 | 
					 | 
				
			||||||
import org.springframework.stereotype.Component;
 | 
					import org.springframework.stereotype.Component;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.sql.Connection;
 | 
					import java.sql.Connection;
 | 
				
			||||||
@@ -17,7 +16,11 @@ public class MysqlDatabaseConnectionFactory implements DatabaseConnectionFactory
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public Connection getConnection(String username, String password, String url, String schema, Properties properties) {
 | 
					    public Connection getConnection(String username,
 | 
				
			||||||
 | 
					                                    String password,
 | 
				
			||||||
 | 
					                                    String url,
 | 
				
			||||||
 | 
					                                    String schema,
 | 
				
			||||||
 | 
					                                    Properties properties) throws SQLException {
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
            Class.forName("com.mysql.cj.jdbc.Driver");
 | 
					            Class.forName("com.mysql.cj.jdbc.Driver");
 | 
				
			||||||
        } catch (ClassNotFoundException e) {
 | 
					        } catch (ClassNotFoundException e) {
 | 
				
			||||||
@@ -29,11 +32,7 @@ public class MysqlDatabaseConnectionFactory implements DatabaseConnectionFactory
 | 
				
			|||||||
        info.put("password", password);
 | 
					        info.put("password", password);
 | 
				
			||||||
        info.putAll(properties);
 | 
					        info.putAll(properties);
 | 
				
			||||||
        String jdbcUrl = "jdbc:mysql://" + url + "/" + schema;
 | 
					        String jdbcUrl = "jdbc:mysql://" + url + "/" + schema;
 | 
				
			||||||
        try {
 | 
					        return DriverManager.getConnection(jdbcUrl, info);
 | 
				
			||||||
            return DriverManager.getConnection(jdbcUrl, info);
 | 
					 | 
				
			||||||
        } catch (SQLException e) {
 | 
					 | 
				
			||||||
            throw DomainErrors.CONNECT_DATABASE_FAILED.exception(e);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,7 +1,6 @@
 | 
				
			|||||||
package com.databasir.core.infrastructure.connection;
 | 
					package com.databasir.core.infrastructure.connection;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import com.databasir.core.domain.DomainErrors;
 | 
					 | 
				
			||||||
import org.springframework.stereotype.Component;
 | 
					import org.springframework.stereotype.Component;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import java.sql.Connection;
 | 
					import java.sql.Connection;
 | 
				
			||||||
@@ -18,7 +17,11 @@ public class PostgresqlDatabaseConnectionFactory implements DatabaseConnectionFa
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
    public Connection getConnection(String username, String password, String url, String schema, Properties properties) {
 | 
					    public Connection getConnection(String username,
 | 
				
			||||||
 | 
					                                    String password,
 | 
				
			||||||
 | 
					                                    String url,
 | 
				
			||||||
 | 
					                                    String schema,
 | 
				
			||||||
 | 
					                                    Properties properties) throws SQLException {
 | 
				
			||||||
        try {
 | 
					        try {
 | 
				
			||||||
            Class.forName("org.postgresql.Driver");
 | 
					            Class.forName("org.postgresql.Driver");
 | 
				
			||||||
        } catch (ClassNotFoundException e) {
 | 
					        } catch (ClassNotFoundException e) {
 | 
				
			||||||
@@ -30,10 +33,6 @@ public class PostgresqlDatabaseConnectionFactory implements DatabaseConnectionFa
 | 
				
			|||||||
        info.put("password", password);
 | 
					        info.put("password", password);
 | 
				
			||||||
        info.putAll(properties);
 | 
					        info.putAll(properties);
 | 
				
			||||||
        String jdbcUrl = "jdbc:postgresql://" + url + "/" + schema;
 | 
					        String jdbcUrl = "jdbc:postgresql://" + url + "/" + schema;
 | 
				
			||||||
        try {
 | 
					        return DriverManager.getConnection(jdbcUrl, info);
 | 
				
			||||||
            return DriverManager.getConnection(jdbcUrl, info);
 | 
					 | 
				
			||||||
        } catch (SQLException e) {
 | 
					 | 
				
			||||||
            throw DomainErrors.CONNECT_DATABASE_FAILED.exception(e);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user