mirror of
https://github.com/dbeaver/cloudbeaver.git
synced 2026-09-24 16:04:36 +08:00
dbeaver/pro#6656 create web connection info objects in a session project (#3751)
* dbeaver/pro#6656 create web connection info objects in a session project * dbeaver/pro#6656 fix data source connection test --------- Co-authored-by: mr-anton-t <42037741+mr-anton-t@users.noreply.github.com>
This commit is contained in:
+109
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2024 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.cloudbeaver;
|
||||
|
||||
import io.cloudbeaver.model.WebConnectionConfig;
|
||||
import io.cloudbeaver.model.app.WebAppConfiguration;
|
||||
import io.cloudbeaver.utils.ServletAppUtils;
|
||||
import io.cloudbeaver.utils.WebDataSourceUtils;
|
||||
import org.jkiss.code.NotNull;
|
||||
import org.jkiss.dbeaver.Log;
|
||||
import org.jkiss.dbeaver.model.app.DBPDataSourceRegistry;
|
||||
import org.jkiss.dbeaver.model.connection.DBPConnectionConfiguration;
|
||||
import org.jkiss.dbeaver.model.connection.DBPDriver;
|
||||
import org.jkiss.dbeaver.registry.DataSourceDescriptor;
|
||||
import org.jkiss.utils.CommonUtils;
|
||||
|
||||
public class WebConnectionConfigInputHandler<T extends WebConnectionConfig, C extends DataSourceDescriptor> {
|
||||
private static final Log log = Log.getLog(WebConnectionConfigInputHandler.class);
|
||||
protected final T input;
|
||||
protected final DBPDataSourceRegistry registry;
|
||||
|
||||
public WebConnectionConfigInputHandler(@NotNull DBPDataSourceRegistry registry, T configInput) {
|
||||
this.registry = registry;
|
||||
this.input = configInput;
|
||||
}
|
||||
|
||||
public C createDataSourceContainer() throws DBWebException {
|
||||
String driverId = input.getDriverId();
|
||||
if (CommonUtils.isEmpty(driverId)) {
|
||||
throw new DBWebException("Driver must be specified");
|
||||
}
|
||||
DBPDriver driver = WebDataSourceUtils.getDriverById(driverId);
|
||||
|
||||
C newDataSource = createDataSourceContainerFromInput(driver);
|
||||
|
||||
if (ServletAppUtils.getServletApplication().getAppConfiguration() instanceof WebAppConfiguration webAppConfiguration) {
|
||||
newDataSource.setNavigatorSettings(webAppConfiguration.getDefaultNavigatorSettings());
|
||||
}
|
||||
|
||||
WebDataSourceUtils.saveAuthProperties(
|
||||
newDataSource,
|
||||
newDataSource.getConnectionConfiguration(),
|
||||
input.getCredentials(),
|
||||
input.isSaveCredentials(),
|
||||
input.isSharedCredentials()
|
||||
);
|
||||
return newDataSource;
|
||||
}
|
||||
|
||||
public void updateDataSource(@NotNull C dataSource) throws DBWebException {
|
||||
dataSource.setId(dataSource.getId());
|
||||
if (!CommonUtils.isEmpty(input.getName())) {
|
||||
dataSource.setName(input.getName());
|
||||
}
|
||||
|
||||
if (input.getDescription() != null) {
|
||||
dataSource.setDescription(input.getDescription());
|
||||
}
|
||||
|
||||
dataSource.setFolder(input.getFolder() != null ? registry.getFolder(input.getFolder()) : null);
|
||||
if (input.isDefaultAutoCommit() != null) {
|
||||
dataSource.setDefaultAutoCommit(input.isDefaultAutoCommit());
|
||||
}
|
||||
WebDataSourceUtils.setConnectionConfiguration(
|
||||
dataSource.getDriver(),
|
||||
dataSource.getConnectionConfiguration(),
|
||||
input
|
||||
);
|
||||
WebDataSourceUtils.saveAuthProperties(
|
||||
dataSource,
|
||||
dataSource.getConnectionConfiguration(),
|
||||
input.getCredentials(),
|
||||
input.isSaveCredentials(),
|
||||
input.isSharedCredentials()
|
||||
);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected C createDataSourceContainerFromInput(@NotNull DBPDriver driver) {
|
||||
DBPConnectionConfiguration dsConfig = new DBPConnectionConfiguration();
|
||||
WebDataSourceUtils.setConnectionConfiguration(driver, dsConfig, input);
|
||||
C newDataSource = registry.createDataSource(driver, dsConfig);
|
||||
|
||||
newDataSource.setSavePassword(true);
|
||||
newDataSource.setName(CommonUtils.notNull(input.getName(), "NewConnection"));
|
||||
newDataSource.setDescription(input.getDescription());
|
||||
newDataSource.setConnectionReadOnly(input.isReadOnly());
|
||||
if (input.getFolder() != null) {
|
||||
newDataSource.setFolder(registry.getFolder(input.getFolder()));
|
||||
}
|
||||
return newDataSource;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -16,11 +16,13 @@
|
||||
*/
|
||||
package io.cloudbeaver;
|
||||
|
||||
import io.cloudbeaver.model.WebConnectionConfig;
|
||||
import io.cloudbeaver.model.WebConnectionInfo;
|
||||
import io.cloudbeaver.model.session.WebSession;
|
||||
import io.cloudbeaver.utils.WebDataSourceUtils;
|
||||
import org.jkiss.code.NotNull;
|
||||
import org.jkiss.code.Nullable;
|
||||
import org.jkiss.dbeaver.DBException;
|
||||
import org.jkiss.dbeaver.Log;
|
||||
import org.jkiss.dbeaver.model.DBPDataSourceContainer;
|
||||
import org.jkiss.dbeaver.model.app.DBPDataSourceRegistry;
|
||||
@@ -33,6 +35,7 @@ import org.jkiss.dbeaver.model.websocket.event.datasource.WSDataSourceProperty;
|
||||
import org.jkiss.dbeaver.registry.DataSourceDescriptor;
|
||||
import org.jkiss.dbeaver.registry.DataSourceRegistry;
|
||||
import org.jkiss.dbeaver.runtime.jobs.DisconnectJob;
|
||||
import org.jkiss.utils.CommonUtils;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.ArrayList;
|
||||
@@ -159,7 +162,7 @@ public class WebSessionProjectImpl extends WebProjectImpl {
|
||||
*/
|
||||
@NotNull
|
||||
public synchronized WebConnectionInfo addConnection(@NotNull DBPDataSourceContainer dataSourceContainer) {
|
||||
WebConnectionInfo connection = new WebConnectionInfo(webSession, dataSourceContainer);
|
||||
WebConnectionInfo connection = createConnectionInfo(dataSourceContainer);
|
||||
synchronized (connections) {
|
||||
connections.put(dataSourceContainer.getId(), connection);
|
||||
}
|
||||
@@ -237,4 +240,110 @@ public class WebSessionProjectImpl extends WebProjectImpl {
|
||||
}
|
||||
return sendDataSourceUpdatedEvent;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public WebConnectionInfo createConnectionInfo(@NotNull DBPDataSourceContainer dataSourceDescriptor) {
|
||||
return new WebConnectionInfo(webSession, dataSourceDescriptor);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public WebConnectionInfo createConnection(@NotNull Map<String, Object> configMap) throws DBWebException {
|
||||
if (CommonUtils.isEmpty(configMap)) {
|
||||
throw new DBWebException("Connection configuration parameters are missing");
|
||||
}
|
||||
DBPDataSourceContainer newDataSource = getDataSourceContainerFromInput(configMap);
|
||||
return addDataSourceToProject(newDataSource);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public WebConnectionInfo addDataSourceToProject(@NotNull DBPDataSourceContainer newDataSource) throws DBWebException {
|
||||
DBPDataSourceRegistry registry = getDataSourceRegistry();
|
||||
try {
|
||||
registry.addDataSource(newDataSource);
|
||||
registry.checkForErrors();
|
||||
} catch (DBException e) {
|
||||
registry.removeDataSource(newDataSource);
|
||||
throw new DBWebException("Failed to create connection", e);
|
||||
}
|
||||
|
||||
WebConnectionInfo connectionInfo = addConnection(newDataSource);
|
||||
webSession.addInfoMessage("New connection was created - " + WebDataSourceUtils.getConnectionContainerInfo(
|
||||
newDataSource));
|
||||
log.info(String.format(
|
||||
"New connection was created: [info=%s, user=%s]",
|
||||
WebDataSourceUtils.getConnectionContainerInfo(newDataSource),
|
||||
webSession.getUserId()
|
||||
));
|
||||
return connectionInfo;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public WebConnectionInfo updateConnection(@Nullable Map<String, Object> configMap) throws DBWebException {
|
||||
WebConnectionConfig config = getConnectionConfigInput(configMap);
|
||||
WebConnectionInfo connectionInfo = getWebConnectionInfo(config.getConnectionId());
|
||||
DataSourceDescriptor dataSource = (DataSourceDescriptor) connectionInfo.getDataSourceContainer();
|
||||
webSession.addInfoMessage("Update connection - " + WebDataSourceUtils.getConnectionContainerInfo(dataSource));
|
||||
|
||||
DBPDataSourceRegistry registry = getDataSourceRegistry();
|
||||
getInputConfigHandler(configMap).updateDataSource(dataSource);
|
||||
connectionInfo.setCredentialsSavedInSession(null);
|
||||
try {
|
||||
registry.updateDataSource(dataSource);
|
||||
registry.checkForErrors();
|
||||
} catch (DBException e) {
|
||||
throw new DBWebException("Failed to update connection", e);
|
||||
}
|
||||
return connectionInfo;
|
||||
}
|
||||
|
||||
public boolean deleteConnection(@NotNull String connectionId) throws DBWebException {
|
||||
WebConnectionInfo connectionInfo = getWebConnectionInfo(connectionId);
|
||||
webSession.addInfoMessage("Delete connection - " +
|
||||
WebDataSourceUtils.getConnectionContainerInfo(connectionInfo.getDataSourceContainer()));
|
||||
closeAndDeleteConnection(connectionInfo);
|
||||
|
||||
log.info(String.format(
|
||||
"Connection deleted: [info=%s, userId=%s]",
|
||||
WebDataSourceUtils.getConnectionContainerInfo(connectionInfo.getDataSourceContainer()),
|
||||
webSession.getUserId()
|
||||
));
|
||||
return true;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private WebConnectionInfo closeAndDeleteConnection(@NotNull WebConnectionInfo connectionInfo) throws DBWebException {
|
||||
DBPDataSourceContainer dataSourceContainer = connectionInfo.getDataSourceContainer();
|
||||
boolean disconnected = WebDataSourceUtils.disconnectDataSource(webSession, dataSourceContainer);
|
||||
DBPDataSourceRegistry registry = getDataSourceRegistry();
|
||||
registry.removeDataSource(dataSourceContainer);
|
||||
try {
|
||||
registry.checkForErrors();
|
||||
} catch (DBException e) {
|
||||
try {
|
||||
registry.addDataSource(dataSourceContainer);
|
||||
} catch (DBException ex) {
|
||||
log.error("Error re-adding after delete attempt", e);
|
||||
}
|
||||
throw new DBWebException("Failed to delete connection", e);
|
||||
}
|
||||
removeConnection(dataSourceContainer);
|
||||
return connectionInfo;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public DataSourceDescriptor getDataSourceContainerFromInput(@NotNull Map<String, Object> configMap) throws DBWebException {
|
||||
return getInputConfigHandler(configMap).createDataSourceContainer();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public WebConnectionConfig getConnectionConfigInput(@Nullable Map<String, Object> configMap) {
|
||||
return new WebConnectionConfig(configMap == null ? Map.of() : configMap);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
protected WebConnectionConfigInputHandler getInputConfigHandler(@NotNull Map<String, Object> configMap) {
|
||||
return new WebConnectionConfigInputHandler<>(getDataSourceRegistry(), getConnectionConfigInput(configMap));
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
+40
-47
@@ -16,11 +16,11 @@
|
||||
*/
|
||||
package io.cloudbeaver.model;
|
||||
|
||||
import org.jkiss.code.NotNull;
|
||||
import org.jkiss.code.Nullable;
|
||||
import org.jkiss.dbeaver.model.connection.DBPDriverConfigurationType;
|
||||
import org.jkiss.dbeaver.model.data.json.JSONUtils;
|
||||
import org.jkiss.dbeaver.model.meta.Property;
|
||||
import org.jkiss.utils.CommonUtils;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -58,7 +58,6 @@ public class WebConnectionConfig {
|
||||
private Map<String, Object> mainPropertyValues;
|
||||
private Map<String, Object> expertSettingsValues;
|
||||
private Map<String, Object> providerProperties;
|
||||
private Map<String, Object> externalParameters;
|
||||
private List<WebNetworkHandlerConfigInput> networkHandlersConfig;
|
||||
private DBPDriverConfigurationType configurationType;
|
||||
private String selectedSecretId;
|
||||
@@ -69,54 +68,52 @@ public class WebConnectionConfig {
|
||||
public WebConnectionConfig() {
|
||||
}
|
||||
|
||||
public WebConnectionConfig(Map<String, Object> params) {
|
||||
if (!CommonUtils.isEmpty(params)) {
|
||||
connectionId = JSONUtils.getString(params, "connectionId");
|
||||
driverId = JSONUtils.getString(params, "driverId");
|
||||
public WebConnectionConfig(@NotNull Map<String, Object> params) {
|
||||
connectionId = JSONUtils.getString(params, "connectionId");
|
||||
driverId = JSONUtils.getString(params, "driverId");
|
||||
|
||||
host = JSONUtils.getString(params, "host");
|
||||
port = JSONUtils.getString(params, "port");
|
||||
serverName = JSONUtils.getString(params, "serverName");
|
||||
databaseName = JSONUtils.getString(params, "databaseName");
|
||||
url = JSONUtils.getString(params, "url");
|
||||
host = JSONUtils.getString(params, "host");
|
||||
port = JSONUtils.getString(params, "port");
|
||||
serverName = JSONUtils.getString(params, "serverName");
|
||||
databaseName = JSONUtils.getString(params, "databaseName");
|
||||
url = JSONUtils.getString(params, "url");
|
||||
|
||||
name = JSONUtils.getString(params, "name");
|
||||
description = JSONUtils.getString(params, "description");
|
||||
folder = JSONUtils.getString(params, "folder");
|
||||
name = JSONUtils.getString(params, "name");
|
||||
description = JSONUtils.getString(params, "description");
|
||||
folder = JSONUtils.getString(params, "folder");
|
||||
|
||||
properties = JSONUtils.getObjectOrNull(params, "properties");
|
||||
userName = JSONUtils.getString(params, "userName");
|
||||
userPassword = JSONUtils.getString(params, "userPassword");
|
||||
selectedSecretId = JSONUtils.getString(params, "selectedSecretId");
|
||||
properties = JSONUtils.getObjectOrNull(params, "properties");
|
||||
userName = JSONUtils.getString(params, "userName");
|
||||
userPassword = JSONUtils.getString(params, "userPassword");
|
||||
selectedSecretId = JSONUtils.getString(params, "selectedSecretId");
|
||||
|
||||
authModelId = JSONUtils.getString(params, "authModelId");
|
||||
credentials = JSONUtils.getObjectOrNull(params, "credentials");
|
||||
saveCredentials = JSONUtils.getBoolean(params, "saveCredentials");
|
||||
sharedCredentials = JSONUtils.getBoolean(params, "sharedCredentials");
|
||||
authModelId = JSONUtils.getString(params, "authModelId");
|
||||
credentials = JSONUtils.getObjectOrNull(params, "credentials");
|
||||
saveCredentials = JSONUtils.getBoolean(params, "saveCredentials");
|
||||
sharedCredentials = JSONUtils.getBoolean(params, "sharedCredentials");
|
||||
|
||||
mainPropertyValues = JSONUtils.getObjectOrNull(params, "mainPropertyValues");
|
||||
providerProperties = JSONUtils.getObjectOrNull(params, "providerProperties");
|
||||
mainPropertyValues = JSONUtils.getObjectOrNull(params, "mainPropertyValues");
|
||||
providerProperties = JSONUtils.getObjectOrNull(params, "providerProperties");
|
||||
expertSettingsValues = JSONUtils.getObjectOrNull(params, "expertSettingsValues");
|
||||
keepAliveInterval = JSONUtils.getInteger(
|
||||
expertSettingsValues != null ? expertSettingsValues : params, WebExpertSettingsProperties.PROP_KEEP_ALIVE_INTERVAL, -1);
|
||||
readOnly = JSONUtils.getBoolean(
|
||||
expertSettingsValues != null ? expertSettingsValues : params, WebExpertSettingsProperties.PROP_READ_ONLY);
|
||||
defaultAutoCommit = JSONUtils.getBoolean(
|
||||
expertSettingsValues != null ? expertSettingsValues : params, WebExpertSettingsProperties.PROP_AUTO_COMMIT, true);
|
||||
defaultCatalogName = JSONUtils.getString(
|
||||
expertSettingsValues != null ? expertSettingsValues : params, WebExpertSettingsProperties.PROP_DEFAULT_CATALOG);
|
||||
defaultSchemaName = JSONUtils.getString(
|
||||
expertSettingsValues != null ? expertSettingsValues : params,
|
||||
WebExpertSettingsProperties.PROP_DEFAULT_SCHEMA
|
||||
);
|
||||
|
||||
expertSettingsValues = JSONUtils.getObjectOrNull(params, "expertSettingsValues");
|
||||
keepAliveInterval = JSONUtils.getInteger(
|
||||
expertSettingsValues != null ? expertSettingsValues : params, WebExpertSettingsProperties.PROP_KEEP_ALIVE_INTERVAL, -1);
|
||||
readOnly = JSONUtils.getBoolean(
|
||||
expertSettingsValues != null ? expertSettingsValues : params, WebExpertSettingsProperties.PROP_READ_ONLY);
|
||||
defaultAutoCommit = JSONUtils.getBoolean(
|
||||
expertSettingsValues != null ? expertSettingsValues : params, WebExpertSettingsProperties.PROP_AUTO_COMMIT, true);
|
||||
defaultCatalogName = JSONUtils.getString(
|
||||
expertSettingsValues != null ? expertSettingsValues : params, WebExpertSettingsProperties.PROP_DEFAULT_CATALOG);
|
||||
defaultSchemaName = JSONUtils.getString(
|
||||
expertSettingsValues != null ? expertSettingsValues : params, WebExpertSettingsProperties.PROP_DEFAULT_SCHEMA);
|
||||
String configType = JSONUtils.getString(params, "configurationType");
|
||||
configurationType = configType == null ? null : DBPDriverConfigurationType.valueOf(configType);
|
||||
|
||||
String configType = JSONUtils.getString(params, "configurationType");
|
||||
configurationType = configType == null ? null : DBPDriverConfigurationType.valueOf(configType);
|
||||
externalParameters = JSONUtils.getObjectOrNull(params, "externalParameters");
|
||||
|
||||
networkHandlersConfig = new ArrayList<>();
|
||||
for (Map<String, Object> nhc : JSONUtils.getObjectList(params, "networkHandlersConfig")) {
|
||||
networkHandlersConfig.add(new WebNetworkHandlerConfigInput(nhc));
|
||||
}
|
||||
networkHandlersConfig = new ArrayList<>();
|
||||
for (Map<String, Object> nhc : JSONUtils.getObjectList(params, "networkHandlersConfig")) {
|
||||
networkHandlersConfig.add(new WebNetworkHandlerConfigInput(nhc));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -262,8 +259,4 @@ public class WebConnectionConfig {
|
||||
public String getDefaultSchemaName() {
|
||||
return defaultSchemaName;
|
||||
}
|
||||
|
||||
public Map<String, Object> getExternalParameters() {
|
||||
return externalParameters;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
*/
|
||||
package io.cloudbeaver.model;
|
||||
|
||||
import io.cloudbeaver.DBWebException;
|
||||
import io.cloudbeaver.WebProjectImpl;
|
||||
import io.cloudbeaver.model.app.BaseWebAppConfiguration;
|
||||
import io.cloudbeaver.model.session.WebSession;
|
||||
@@ -319,6 +320,10 @@ public class WebConnectionInfo {
|
||||
!dataSourceContainer.getDriver().isAnonymousAccess();
|
||||
}
|
||||
|
||||
public void validateConnection() throws DBWebException {
|
||||
|
||||
}
|
||||
|
||||
// we don't show non-secured properties in FE when connecting to DB without saved credentials
|
||||
private boolean isAuthPropertiesEmpty() {
|
||||
return Arrays.stream(getAuthProperties()).allMatch(f -> f.hasFeature(DBConstants.PROP_FEATURE_NON_SECURED));
|
||||
|
||||
+185
-3
@@ -23,6 +23,7 @@ import com.google.gson.Strictness;
|
||||
import io.cloudbeaver.DBWConstants;
|
||||
import io.cloudbeaver.DBWebException;
|
||||
import io.cloudbeaver.WebSessionProjectImpl;
|
||||
import io.cloudbeaver.model.WebConnectionConfig;
|
||||
import io.cloudbeaver.model.WebConnectionInfo;
|
||||
import io.cloudbeaver.model.WebNetworkHandlerConfigInput;
|
||||
import io.cloudbeaver.model.session.WebSession;
|
||||
@@ -30,21 +31,25 @@ import org.jkiss.code.NotNull;
|
||||
import org.jkiss.code.Nullable;
|
||||
import org.jkiss.dbeaver.DBException;
|
||||
import org.jkiss.dbeaver.Log;
|
||||
import org.jkiss.dbeaver.model.DBConstants;
|
||||
import org.jkiss.dbeaver.model.DBPDataSourceContainer;
|
||||
import org.jkiss.dbeaver.model.access.DBAAuthCredentials;
|
||||
import org.jkiss.dbeaver.model.access.DBAAuthCredentialsWithComplexProperties;
|
||||
import org.jkiss.dbeaver.model.app.DBPDataSourceRegistry;
|
||||
import org.jkiss.dbeaver.model.app.DBPProject;
|
||||
import org.jkiss.dbeaver.model.connection.DBPConnectionConfiguration;
|
||||
import org.jkiss.dbeaver.model.connection.DBPDataSourceProviderDescriptor;
|
||||
import org.jkiss.dbeaver.model.connection.DBPDriver;
|
||||
import org.jkiss.dbeaver.model.impl.auth.AuthModelDatabaseNativeCredentials;
|
||||
import org.jkiss.dbeaver.model.net.DBWHandlerConfiguration;
|
||||
import org.jkiss.dbeaver.model.net.ssh.SSHConstants;
|
||||
import org.jkiss.dbeaver.model.websocket.event.datasource.WSDataSourceDisconnectEvent;
|
||||
import org.jkiss.dbeaver.registry.network.NetworkHandlerDescriptor;
|
||||
import org.jkiss.dbeaver.registry.network.NetworkHandlerRegistry;
|
||||
import org.jkiss.dbeaver.runtime.DBWorkbench;
|
||||
import org.jkiss.utils.CommonUtils;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.*;
|
||||
|
||||
public class WebDataSourceUtils {
|
||||
|
||||
@@ -219,4 +224,181 @@ public class WebDataSourceUtils {
|
||||
}
|
||||
credGson.fromJson(credGson.toJsonTree(properties), credentials.getClass());
|
||||
}
|
||||
|
||||
public static void saveAuthProperties(
|
||||
@NotNull DBPDataSourceContainer dataSourceContainer,
|
||||
@NotNull DBPConnectionConfiguration configuration,
|
||||
@Nullable Map<String, Object> authProperties,
|
||||
boolean saveCredentials,
|
||||
boolean sharedCredentials
|
||||
) {
|
||||
saveAuthProperties(dataSourceContainer, configuration, authProperties, saveCredentials, sharedCredentials, false);
|
||||
}
|
||||
|
||||
public static void saveAuthProperties(
|
||||
@NotNull DBPDataSourceContainer dataSourceContainer,
|
||||
@NotNull DBPConnectionConfiguration configuration,
|
||||
@Nullable Map<String, Object> authProperties,
|
||||
boolean saveCredentials,
|
||||
boolean sharedCredentials,
|
||||
boolean isTest
|
||||
) {
|
||||
dataSourceContainer.setSavePassword(saveCredentials);
|
||||
dataSourceContainer.setSharedCredentials(sharedCredentials);
|
||||
if (!saveCredentials) {
|
||||
// Reset credentials
|
||||
if (authProperties == null) {
|
||||
authProperties = new LinkedHashMap<>();
|
||||
}
|
||||
authProperties.replace(AuthModelDatabaseNativeCredentials.PROP_USER_PASSWORD, null);
|
||||
dataSourceContainer.resetPassword();
|
||||
} else {
|
||||
if (authProperties == null) {
|
||||
// No changes
|
||||
return;
|
||||
}
|
||||
}
|
||||
{
|
||||
// Read save credentials
|
||||
DBAAuthCredentials credentials = configuration.getAuthModel().loadCredentials(dataSourceContainer, configuration);
|
||||
|
||||
if (isTest) {
|
||||
var currentAuthProps = new HashMap<String, String>();
|
||||
for (Map.Entry<String, Object> stringObjectEntry : authProperties.entrySet()) {
|
||||
var value = stringObjectEntry.getValue() == null ? null : stringObjectEntry.getValue().toString();
|
||||
currentAuthProps.put(stringObjectEntry.getKey(), value);
|
||||
}
|
||||
configuration.setAuthProperties(currentAuthProps);
|
||||
}
|
||||
if (!authProperties.isEmpty()) {
|
||||
updateCredentialsFromProperties(credentials, authProperties);
|
||||
}
|
||||
|
||||
configuration.getAuthModel().saveCredentials(dataSourceContainer, configuration, credentials);
|
||||
}
|
||||
}
|
||||
|
||||
public static void setConnectionConfiguration(
|
||||
@NotNull DBPDriver driver,
|
||||
@NotNull DBPConnectionConfiguration dsConfig,
|
||||
@NotNull WebConnectionConfig config
|
||||
) {
|
||||
setMainProperties(dsConfig, config);
|
||||
if (config.getProperties() != null) {
|
||||
Map<String, String> newProps = new LinkedHashMap<>();
|
||||
for (Map.Entry<String, Object> pe : config.getProperties().entrySet()) {
|
||||
newProps.put(pe.getKey(), CommonUtils.toString(pe.getValue()));
|
||||
}
|
||||
dsConfig.setProperties(newProps);
|
||||
}
|
||||
if (config.getUserName() != null) {
|
||||
dsConfig.setUserName(config.getUserName());
|
||||
}
|
||||
if (config.getUserPassword() != null) {
|
||||
dsConfig.setUserPassword(config.getUserPassword());
|
||||
}
|
||||
if (config.getAuthModelId() != null) {
|
||||
dsConfig.setAuthModelId(config.getAuthModelId());
|
||||
}
|
||||
if (config.getKeepAliveInterval() >= 0) {
|
||||
dsConfig.setKeepAliveInterval(config.getKeepAliveInterval());
|
||||
}
|
||||
if (config.isDefaultAutoCommit() != null) {
|
||||
dsConfig.getBootstrap().setDefaultAutoCommit(config.isDefaultAutoCommit());
|
||||
}
|
||||
dsConfig.getBootstrap().setDefaultCatalogName(config.getDefaultCatalogName());
|
||||
dsConfig.getBootstrap().setDefaultSchemaName(config.getDefaultSchemaName());
|
||||
// Save provider props
|
||||
if (config.getProviderProperties() != null) {
|
||||
dsConfig.setProviderProperties(new LinkedHashMap<>());
|
||||
for (Map.Entry<String, Object> e : config.getProviderProperties().entrySet()) {
|
||||
dsConfig.setProviderProperty(e.getKey(), CommonUtils.toString(e.getValue()));
|
||||
}
|
||||
}
|
||||
if (config.getConfigurationType() != null) {
|
||||
dsConfig.setConfigurationType(config.getConfigurationType());
|
||||
}
|
||||
if (CommonUtils.isEmpty(config.getUrl())) {
|
||||
dsConfig.setUrl(driver.getConnectionURL(dsConfig));
|
||||
}
|
||||
// Save network handlers
|
||||
if (config.getNetworkHandlersConfig() != null) {
|
||||
for (WebNetworkHandlerConfigInput nhc : config.getNetworkHandlersConfig()) {
|
||||
DBWHandlerConfiguration handlerConfig = dsConfig.getHandler(nhc.getId());
|
||||
if (handlerConfig == null) {
|
||||
NetworkHandlerDescriptor handlerDescriptor = NetworkHandlerRegistry.getInstance().getDescriptor(nhc.getId());
|
||||
if (handlerDescriptor == null) {
|
||||
log.warn("Can't find network handler '" + nhc.getId() + "'");
|
||||
continue;
|
||||
} else {
|
||||
handlerConfig = new DBWHandlerConfiguration(handlerDescriptor, null);
|
||||
WebDataSourceUtils.updateHandlerConfig(handlerConfig, nhc);
|
||||
}
|
||||
} else {
|
||||
WebDataSourceUtils.updateHandlerConfig(handlerConfig, nhc);
|
||||
}
|
||||
dsConfig.updateHandler(handlerConfig);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void setMainProperties(@NotNull DBPConnectionConfiguration dsConfig, @NotNull WebConnectionConfig config) {
|
||||
if (CommonUtils.isNotEmpty(config.getUrl())) {
|
||||
dsConfig.setUrl(config.getUrl());
|
||||
return;
|
||||
}
|
||||
if (config.getMainPropertyValues() != null) {
|
||||
for (Map.Entry<String, Object> e : config.getMainPropertyValues().entrySet()) {
|
||||
if (e.getValue() == null) {
|
||||
continue;
|
||||
}
|
||||
switch (e.getKey()) {
|
||||
case DBConstants.PROP_HOST -> dsConfig.setHostName(CommonUtils.toString(e.getValue()));
|
||||
case DBConstants.PROP_PORT -> dsConfig.setHostPort(CommonUtils.toString(e.getValue()));
|
||||
case DBConstants.PROP_DATABASE -> dsConfig.setDatabaseName(CommonUtils.toString(e.getValue()));
|
||||
case DBConstants.PROP_SERVER -> dsConfig.setServerName(CommonUtils.toString(e.getValue()));
|
||||
default -> throw new IllegalStateException("Unexpected value: " + e.getKey());
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (config.getHost() != null) {
|
||||
dsConfig.setHostName(config.getHost());
|
||||
}
|
||||
if (config.getPort() != null) {
|
||||
dsConfig.setHostPort(config.getPort());
|
||||
}
|
||||
if (config.getDatabaseName() != null) {
|
||||
dsConfig.setDatabaseName(config.getDatabaseName());
|
||||
}
|
||||
if (config.getServerName() != null) {
|
||||
dsConfig.setServerName(config.getServerName());
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static DBPDriver getDriverById(String id) throws DBWebException {
|
||||
int divPos = id.indexOf(':');
|
||||
if (divPos < 0) {
|
||||
throw new DBWebException("Bad driver id [" + id + "]");
|
||||
}
|
||||
String dsId = id.substring(0, divPos);
|
||||
String driverId = id.substring(divPos + 1);
|
||||
DBPDataSourceProviderDescriptor dsProvider = DBWorkbench.getPlatform().getDataSourceProviderRegistry().getDataSourceProvider(dsId);
|
||||
if (dsProvider == null) {
|
||||
throw new DBWebException("Data source provider '" + dsId + "' not found");
|
||||
}
|
||||
DBPDriver driver = dsProvider.getDriver(driverId);
|
||||
if (driver == null) {
|
||||
throw new DBWebException("Driver '" + driverId + "' not found in provider '" + dsId + "'");
|
||||
}
|
||||
return driver;
|
||||
}
|
||||
|
||||
public static String getConnectionContainerInfo(@Nullable DBPDataSourceContainer container) {
|
||||
if (container == null) {
|
||||
return null;
|
||||
}
|
||||
return container.getName() + " [" + container.getId() + "]";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,8 +30,6 @@ import io.cloudbeaver.registry.WebDriverRegistry;
|
||||
import io.cloudbeaver.registry.WebFeatureRegistry;
|
||||
import io.cloudbeaver.registry.WebServiceRegistry;
|
||||
import io.cloudbeaver.server.jetty.CBJettyServer;
|
||||
import io.cloudbeaver.service.ConnectionController;
|
||||
import io.cloudbeaver.service.ConnectionControllerCE;
|
||||
import io.cloudbeaver.service.DBWServiceInitializer;
|
||||
import io.cloudbeaver.service.DBWServiceServerConfigurator;
|
||||
import io.cloudbeaver.service.session.CBSessionManager;
|
||||
@@ -785,11 +783,6 @@ public abstract class CBApplication<T extends CBServerConfig>
|
||||
return new CBWebServerConfig(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ConnectionController getConnectionController() {
|
||||
return new ConnectionControllerCE();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public ServletSystemInformationCollector<?> getSystemInformationCollector() {
|
||||
|
||||
@@ -18,10 +18,7 @@ package io.cloudbeaver;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import io.cloudbeaver.model.WebConnectionConfig;
|
||||
import io.cloudbeaver.model.WebNetworkHandlerConfigInput;
|
||||
import io.cloudbeaver.model.WebPropertyInfo;
|
||||
import io.cloudbeaver.model.app.ServletApplication;
|
||||
import io.cloudbeaver.model.app.WebAppConfiguration;
|
||||
import io.cloudbeaver.model.rm.DBNResourceManagerResource;
|
||||
import io.cloudbeaver.model.session.WebActionParameters;
|
||||
@@ -30,7 +27,6 @@ import io.cloudbeaver.model.utils.ConfigurationUtils;
|
||||
import io.cloudbeaver.registry.WebAuthProviderDescriptor;
|
||||
import io.cloudbeaver.registry.WebAuthProviderRegistry;
|
||||
import io.cloudbeaver.server.WebAppUtils;
|
||||
import io.cloudbeaver.server.WebApplication;
|
||||
import io.cloudbeaver.service.navigator.WebPropertyFilter;
|
||||
import io.cloudbeaver.utils.ServletAppUtils;
|
||||
import io.cloudbeaver.utils.WebCommonUtils;
|
||||
@@ -39,25 +35,14 @@ import org.jkiss.code.NotNull;
|
||||
import org.jkiss.code.Nullable;
|
||||
import org.jkiss.dbeaver.DBException;
|
||||
import org.jkiss.dbeaver.Log;
|
||||
import org.jkiss.dbeaver.model.DBConstants;
|
||||
import org.jkiss.dbeaver.model.DBPDataSourceContainer;
|
||||
import org.jkiss.dbeaver.model.access.DBAAuthCredentials;
|
||||
import org.jkiss.dbeaver.model.app.DBPDataSourceRegistry;
|
||||
import org.jkiss.dbeaver.model.app.DBPProject;
|
||||
import org.jkiss.dbeaver.model.connection.DBPConnectionConfiguration;
|
||||
import org.jkiss.dbeaver.model.connection.DBPDriver;
|
||||
import org.jkiss.dbeaver.model.impl.auth.AuthModelDatabaseNativeCredentials;
|
||||
import org.jkiss.dbeaver.model.navigator.*;
|
||||
import org.jkiss.dbeaver.model.net.DBWHandlerConfiguration;
|
||||
import org.jkiss.dbeaver.model.preferences.DBPPropertyDescriptor;
|
||||
import org.jkiss.dbeaver.model.rm.RMProjectType;
|
||||
import org.jkiss.dbeaver.registry.DataSourceDescriptor;
|
||||
import org.jkiss.dbeaver.registry.DataSourceNavigatorSettings;
|
||||
import org.jkiss.dbeaver.registry.DataSourceProviderDescriptor;
|
||||
import org.jkiss.dbeaver.registry.DataSourceProviderRegistry;
|
||||
import org.jkiss.dbeaver.registry.driver.DriverDescriptor;
|
||||
import org.jkiss.dbeaver.registry.network.NetworkHandlerDescriptor;
|
||||
import org.jkiss.dbeaver.registry.network.NetworkHandlerRegistry;
|
||||
import org.jkiss.dbeaver.runtime.properties.PropertyCollector;
|
||||
import org.jkiss.utils.CommonUtils;
|
||||
|
||||
@@ -74,25 +59,6 @@ public class WebServiceUtils extends WebCommonUtils {
|
||||
|
||||
private static final Gson gson = new GsonBuilder().create();
|
||||
|
||||
@NotNull
|
||||
public static DBPDriver getDriverById(String id) throws DBWebException {
|
||||
int divPos = id.indexOf(':');
|
||||
if (divPos < 0) {
|
||||
throw new DBWebException("Bad driver id [" + id + "]");
|
||||
}
|
||||
String dsId = id.substring(0, divPos);
|
||||
String driverId = id.substring(divPos + 1);
|
||||
DataSourceProviderDescriptor dsProvider = DataSourceProviderRegistry.getInstance().getDataSourceProvider(dsId);
|
||||
if (dsProvider == null) {
|
||||
throw new DBWebException("Data source provider '" + dsId + "' not found");
|
||||
}
|
||||
DriverDescriptor driver = dsProvider.getDriver(driverId);
|
||||
if (driver == null) {
|
||||
throw new DBWebException("Driver '" + driverId + "' not found in provider '" + dsId + "'");
|
||||
}
|
||||
return driver;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static DBPDataSourceRegistry getGlobalDataSourceRegistry() throws DBWebException {
|
||||
return WebDataSourceUtils.getGlobalDataSourceRegistry();
|
||||
@@ -102,198 +68,6 @@ public class WebServiceUtils extends WebCommonUtils {
|
||||
return WebServiceUtils.class.getClassLoader().getResourceAsStream(path);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static DBPDataSourceContainer createConnectionFromConfig(WebConnectionConfig config, DBPDataSourceRegistry registry) throws DBWebException {
|
||||
DBPDataSourceContainer newDataSource;
|
||||
if (!CommonUtils.isEmpty(config.getDriverId())) {
|
||||
String driverId = config.getDriverId();
|
||||
if (CommonUtils.isEmpty(driverId)) {
|
||||
throw new DBWebException("Driver not specified");
|
||||
}
|
||||
DBPDriver driver = getDriverById(driverId);
|
||||
|
||||
DBPConnectionConfiguration dsConfig = new DBPConnectionConfiguration();
|
||||
|
||||
setConnectionConfiguration(driver, dsConfig, config);
|
||||
|
||||
newDataSource = registry.createDataSource(driver, dsConfig);
|
||||
} else {
|
||||
throw new DBWebException("Template connection or driver must be specified");
|
||||
}
|
||||
|
||||
newDataSource.setSavePassword(true);
|
||||
newDataSource.setName(config.getName());
|
||||
newDataSource.setDescription(config.getDescription());
|
||||
newDataSource.setConnectionReadOnly(config.isReadOnly());
|
||||
if (config.getFolder() != null) {
|
||||
newDataSource.setFolder(registry.getFolder(config.getFolder()));
|
||||
}
|
||||
|
||||
ServletApplication app = ServletAppUtils.getServletApplication();
|
||||
if (app instanceof WebApplication webApplication) {
|
||||
((DataSourceDescriptor) newDataSource).setNavigatorSettings(
|
||||
webApplication.getAppConfiguration().getDefaultNavigatorSettings());
|
||||
}
|
||||
|
||||
saveAuthProperties(
|
||||
newDataSource,
|
||||
newDataSource.getConnectionConfiguration(),
|
||||
config.getCredentials(),
|
||||
config.isSaveCredentials(),
|
||||
config.isSharedCredentials()
|
||||
);
|
||||
|
||||
|
||||
return newDataSource;
|
||||
}
|
||||
|
||||
public static void setConnectionConfiguration(DBPDriver driver, DBPConnectionConfiguration dsConfig, WebConnectionConfig config) {
|
||||
setMainProperties(dsConfig, config);
|
||||
if (config.getProperties() != null) {
|
||||
Map<String, String> newProps = new LinkedHashMap<>();
|
||||
for (Map.Entry<String, Object> pe : config.getProperties().entrySet()) {
|
||||
newProps.put(pe.getKey(), CommonUtils.toString(pe.getValue()));
|
||||
}
|
||||
dsConfig.setProperties(newProps);
|
||||
}
|
||||
if (config.getUserName() != null) {
|
||||
dsConfig.setUserName(config.getUserName());
|
||||
}
|
||||
if (config.getUserPassword() != null) {
|
||||
dsConfig.setUserPassword(config.getUserPassword());
|
||||
}
|
||||
if (config.getAuthModelId() != null) {
|
||||
dsConfig.setAuthModelId(config.getAuthModelId());
|
||||
}
|
||||
if (config.getKeepAliveInterval() >= 0) {
|
||||
dsConfig.setKeepAliveInterval(config.getKeepAliveInterval());
|
||||
}
|
||||
if (config.isDefaultAutoCommit() != null) {
|
||||
dsConfig.getBootstrap().setDefaultAutoCommit(config.isDefaultAutoCommit());
|
||||
}
|
||||
dsConfig.getBootstrap().setDefaultCatalogName(config.getDefaultCatalogName());
|
||||
dsConfig.getBootstrap().setDefaultSchemaName(config.getDefaultSchemaName());
|
||||
// Save provider props
|
||||
if (config.getProviderProperties() != null) {
|
||||
dsConfig.setProviderProperties(new LinkedHashMap<>());
|
||||
for (Map.Entry<String, Object> e : config.getProviderProperties().entrySet()) {
|
||||
dsConfig.setProviderProperty(e.getKey(), CommonUtils.toString(e.getValue()));
|
||||
}
|
||||
}
|
||||
if (config.getConfigurationType() != null) {
|
||||
dsConfig.setConfigurationType(config.getConfigurationType());
|
||||
}
|
||||
if (CommonUtils.isEmpty(config.getUrl())) {
|
||||
dsConfig.setUrl(driver.getConnectionURL(dsConfig));
|
||||
}
|
||||
// Save network handlers
|
||||
if (config.getNetworkHandlersConfig() != null) {
|
||||
for (WebNetworkHandlerConfigInput nhc : config.getNetworkHandlersConfig()) {
|
||||
DBWHandlerConfiguration handlerConfig = dsConfig.getHandler(nhc.getId());
|
||||
if (handlerConfig == null) {
|
||||
NetworkHandlerDescriptor handlerDescriptor = NetworkHandlerRegistry.getInstance().getDescriptor(nhc.getId());
|
||||
if (handlerDescriptor == null) {
|
||||
log.warn("Can't find network handler '" + nhc.getId() + "'");
|
||||
continue;
|
||||
} else {
|
||||
handlerConfig = new DBWHandlerConfiguration(handlerDescriptor, null);
|
||||
WebDataSourceUtils.updateHandlerConfig(handlerConfig, nhc);
|
||||
}
|
||||
} else {
|
||||
WebDataSourceUtils.updateHandlerConfig(handlerConfig, nhc);
|
||||
}
|
||||
dsConfig.updateHandler(handlerConfig);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void setMainProperties(DBPConnectionConfiguration dsConfig, WebConnectionConfig config) {
|
||||
if (CommonUtils.isNotEmpty(config.getUrl())) {
|
||||
dsConfig.setUrl(config.getUrl());
|
||||
return;
|
||||
}
|
||||
if (config.getMainPropertyValues() != null) {
|
||||
for (Map.Entry<String, Object> e : config.getMainPropertyValues().entrySet()) {
|
||||
if (e.getValue() == null) {
|
||||
continue;
|
||||
}
|
||||
switch (e.getKey()) {
|
||||
case DBConstants.PROP_HOST -> dsConfig.setHostName(CommonUtils.toString(e.getValue()));
|
||||
case DBConstants.PROP_PORT -> dsConfig.setHostPort(CommonUtils.toString(e.getValue()));
|
||||
case DBConstants.PROP_DATABASE -> dsConfig.setDatabaseName(CommonUtils.toString(e.getValue()));
|
||||
case DBConstants.PROP_SERVER -> dsConfig.setServerName(CommonUtils.toString(e.getValue()));
|
||||
default -> throw new IllegalStateException("Unexpected value: " + e.getKey());
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (config.getHost() != null) {
|
||||
dsConfig.setHostName(config.getHost());
|
||||
}
|
||||
if (config.getPort() != null) {
|
||||
dsConfig.setHostPort(config.getPort());
|
||||
}
|
||||
if (config.getDatabaseName() != null) {
|
||||
dsConfig.setDatabaseName(config.getDatabaseName());
|
||||
}
|
||||
if (config.getServerName() != null) {
|
||||
dsConfig.setServerName(config.getServerName());
|
||||
}
|
||||
}
|
||||
|
||||
public static void saveAuthProperties(
|
||||
@NotNull DBPDataSourceContainer dataSourceContainer,
|
||||
@NotNull DBPConnectionConfiguration configuration,
|
||||
@Nullable Map<String, Object> authProperties,
|
||||
boolean saveCredentials,
|
||||
boolean sharedCredentials
|
||||
) {
|
||||
saveAuthProperties(dataSourceContainer, configuration, authProperties, saveCredentials, sharedCredentials, false);
|
||||
}
|
||||
|
||||
public static void saveAuthProperties(
|
||||
@NotNull DBPDataSourceContainer dataSourceContainer,
|
||||
@NotNull DBPConnectionConfiguration configuration,
|
||||
@Nullable Map<String, Object> authProperties,
|
||||
boolean saveCredentials,
|
||||
boolean sharedCredentials,
|
||||
boolean isTest
|
||||
) {
|
||||
dataSourceContainer.setSavePassword(saveCredentials);
|
||||
dataSourceContainer.setSharedCredentials(sharedCredentials);
|
||||
if (!saveCredentials) {
|
||||
// Reset credentials
|
||||
if (authProperties == null) {
|
||||
authProperties = new LinkedHashMap<>();
|
||||
}
|
||||
authProperties.replace(AuthModelDatabaseNativeCredentials.PROP_USER_PASSWORD, null);
|
||||
dataSourceContainer.resetPassword();
|
||||
} else {
|
||||
if (authProperties == null) {
|
||||
// No changes
|
||||
return;
|
||||
}
|
||||
}
|
||||
{
|
||||
// Read save credentials
|
||||
DBAAuthCredentials credentials = configuration.getAuthModel().loadCredentials(dataSourceContainer, configuration);
|
||||
|
||||
if (isTest) {
|
||||
var currentAuthProps = new HashMap<String, String>();
|
||||
for (Map.Entry<String, Object> stringObjectEntry : authProperties.entrySet()) {
|
||||
var value = stringObjectEntry.getValue() == null ? null : stringObjectEntry.getValue().toString();
|
||||
currentAuthProps.put(stringObjectEntry.getKey(), value);
|
||||
}
|
||||
configuration.setAuthProperties(currentAuthProps);
|
||||
}
|
||||
if (!authProperties.isEmpty()) {
|
||||
WebDataSourceUtils.updateCredentialsFromProperties(credentials, authProperties);
|
||||
}
|
||||
|
||||
configuration.getAuthModel().saveCredentials(dataSourceContainer, configuration, credentials);
|
||||
}
|
||||
}
|
||||
|
||||
public static DBNBrowseSettings parseNavigatorSettings(Map<String, Object> settingsMap) {
|
||||
return gson.fromJson(
|
||||
gson.toJsonTree(settingsMap), DataSourceNavigatorSettings.class);
|
||||
@@ -310,13 +84,6 @@ public class WebServiceUtils extends WebCommonUtils {
|
||||
WebActionParameters.saveToSession(webSession, actionParameters);
|
||||
}
|
||||
|
||||
public static String getConnectionContainerInfo(DBPDataSourceContainer container) {
|
||||
if (container == null) {
|
||||
return null;
|
||||
}
|
||||
return container.getName() + " [" + container.getId() + "]";
|
||||
}
|
||||
|
||||
public static void refreshDatabases(WebSession session, String projectId) throws DBWebException {
|
||||
DBNProject projectNode = session.getNavigatorModelOrThrow().getRoot().getProjectNode(session.getProjectById(projectId));
|
||||
if (projectNode != null) {
|
||||
|
||||
@@ -21,7 +21,6 @@ import io.cloudbeaver.model.app.ServletApplication;
|
||||
import io.cloudbeaver.model.app.WebAppConfiguration;
|
||||
import io.cloudbeaver.model.app.WebServerConfiguration;
|
||||
import io.cloudbeaver.registry.WebDriverRegistry;
|
||||
import io.cloudbeaver.service.ConnectionController;
|
||||
import org.jkiss.code.NotNull;
|
||||
|
||||
import java.net.InetAddress;
|
||||
@@ -53,6 +52,4 @@ public interface WebApplication extends ServletApplication {
|
||||
|
||||
WebServerConfig getWebServerConfig();
|
||||
|
||||
ConnectionController getConnectionController();
|
||||
|
||||
}
|
||||
|
||||
-99
@@ -1,99 +0,0 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2025 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.cloudbeaver.service;
|
||||
|
||||
import io.cloudbeaver.DBWebException;
|
||||
import io.cloudbeaver.WebObjectId;
|
||||
import io.cloudbeaver.model.WebConnectionConfig;
|
||||
import io.cloudbeaver.model.WebConnectionInfo;
|
||||
import io.cloudbeaver.model.WebNetworkHandlerConfigInput;
|
||||
import io.cloudbeaver.model.session.WebSession;
|
||||
import org.jkiss.code.NotNull;
|
||||
import org.jkiss.code.Nullable;
|
||||
import org.jkiss.dbeaver.model.DBPDataSourceContainer;
|
||||
import org.jkiss.dbeaver.model.app.DBPDataSourceRegistry;
|
||||
import org.jkiss.dbeaver.registry.DataSourceDescriptor;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
public interface ConnectionController {
|
||||
|
||||
DBPDataSourceContainer createDataSourceContainer(
|
||||
@NotNull WebSession webSession,
|
||||
@Nullable @WebObjectId String projectId,
|
||||
@NotNull WebConnectionConfig connectionConfig
|
||||
) throws DBWebException;
|
||||
|
||||
WebConnectionInfo createConnection(
|
||||
@NotNull WebSession webSession,
|
||||
@Nullable String projectId,
|
||||
DBPDataSourceRegistry sessionRegistry,
|
||||
DBPDataSourceContainer newDataSource
|
||||
) throws DBWebException;
|
||||
|
||||
DBPDataSourceContainer getDatasourceConnection(
|
||||
@NotNull WebSession webSession,
|
||||
@Nullable @WebObjectId String projectId,
|
||||
@NotNull WebConnectionConfig connectionConfig) throws DBWebException;
|
||||
|
||||
WebConnectionInfo updateConnection(
|
||||
@NotNull WebSession webSession,
|
||||
@Nullable String projectId,
|
||||
@NotNull WebConnectionConfig config,
|
||||
DBPDataSourceContainer dataSource,
|
||||
DBPDataSourceRegistry sessionRegistry
|
||||
) throws DBWebException;
|
||||
|
||||
boolean deleteConnection(
|
||||
@NotNull WebSession webSession,
|
||||
@Nullable @WebObjectId String projectId,
|
||||
@NotNull String connectionId) throws DBWebException;
|
||||
|
||||
DataSourceDescriptor prepareTestConnection(
|
||||
@NotNull WebSession webSession,
|
||||
@Nullable String projectId,
|
||||
@NotNull WebConnectionConfig connectionConfig) throws DBWebException;
|
||||
|
||||
WebConnectionInfo testConnection(
|
||||
@NotNull WebSession webSession,
|
||||
@Nullable String projectId,
|
||||
@NotNull WebConnectionConfig connectionConfig,
|
||||
DataSourceDescriptor dataSource
|
||||
) throws DBWebException;
|
||||
|
||||
WebConnectionInfo getConnectionState(
|
||||
@NotNull WebSession webSession,
|
||||
@Nullable String projectId,
|
||||
@NotNull String connectionId
|
||||
) throws DBWebException;
|
||||
|
||||
WebConnectionInfo initConnection(
|
||||
@NotNull WebSession webSession,
|
||||
@Nullable String projectId,
|
||||
@NotNull String connectionId,
|
||||
@NotNull Map<String, Object> authProperties,
|
||||
@Nullable List<WebNetworkHandlerConfigInput> networkCredentials,
|
||||
boolean saveCredentials,
|
||||
boolean sharedCredentials,
|
||||
@Nullable String selectedSecretId
|
||||
) throws DBWebException;
|
||||
|
||||
void validateConnection(DBPDataSourceContainer dataSourceContainer) throws DBWebException;
|
||||
|
||||
}
|
||||
-496
@@ -1,496 +0,0 @@
|
||||
/*
|
||||
* DBeaver - Universal Database Manager
|
||||
* Copyright (C) 2010-2025 DBeaver Corp and others
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
package io.cloudbeaver.service;
|
||||
|
||||
import io.cloudbeaver.*;
|
||||
import io.cloudbeaver.model.WebConnectionConfig;
|
||||
import io.cloudbeaver.model.WebConnectionInfo;
|
||||
import io.cloudbeaver.model.WebNetworkHandlerConfigInput;
|
||||
import io.cloudbeaver.model.session.WebSession;
|
||||
import io.cloudbeaver.utils.ServletAppUtils;
|
||||
import io.cloudbeaver.utils.WebDataSourceUtils;
|
||||
import org.jkiss.code.NotNull;
|
||||
import org.jkiss.code.Nullable;
|
||||
import org.jkiss.dbeaver.DBException;
|
||||
import org.jkiss.dbeaver.Log;
|
||||
import org.jkiss.dbeaver.model.DBPDataSourceContainer;
|
||||
import org.jkiss.dbeaver.model.app.DBPDataSourceRegistry;
|
||||
import org.jkiss.dbeaver.model.exec.DBCConnectException;
|
||||
import org.jkiss.dbeaver.model.net.DBWHandlerConfiguration;
|
||||
import org.jkiss.dbeaver.model.net.DBWHandlerType;
|
||||
import org.jkiss.dbeaver.model.rm.RMProjectType;
|
||||
import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
|
||||
import org.jkiss.dbeaver.model.secret.DBSSecretController;
|
||||
import org.jkiss.dbeaver.model.secret.DBSSecretValue;
|
||||
import org.jkiss.dbeaver.registry.DataSourceDescriptor;
|
||||
import org.jkiss.dbeaver.runtime.DBWorkbench;
|
||||
import org.jkiss.dbeaver.runtime.jobs.ConnectionTestJob;
|
||||
import org.jkiss.dbeaver.utils.RuntimeUtils;
|
||||
import org.jkiss.utils.CommonUtils;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class ConnectionControllerCE implements ConnectionController {
|
||||
|
||||
private static final Log log = Log.getLog(ConnectionController.class);
|
||||
|
||||
|
||||
@Override
|
||||
public DBPDataSourceContainer createDataSourceContainer(
|
||||
@NotNull WebSession webSession,
|
||||
@Nullable String projectId,
|
||||
@NotNull WebConnectionConfig connectionConfig
|
||||
) throws DBWebException {
|
||||
WebSessionProjectImpl project = getProjectById(webSession, projectId);
|
||||
var rmProject = project.getRMProject();
|
||||
if (rmProject.getType() == RMProjectType.USER
|
||||
&& !webSession.hasPermission(DBWConstants.PERMISSION_ADMIN)
|
||||
&& !ServletAppUtils.getServletApplication().getAppConfiguration().isSupportsCustomConnections()
|
||||
) {
|
||||
throw new DBWebException("New connection create is restricted by server configuration");
|
||||
}
|
||||
webSession.addInfoMessage("Create new connection");
|
||||
DBPDataSourceRegistry sessionRegistry = project.getDataSourceRegistry();
|
||||
|
||||
DBPDataSourceContainer newDataSource = WebServiceUtils.createConnectionFromConfig(connectionConfig,
|
||||
sessionRegistry);
|
||||
if (CommonUtils.isEmpty(newDataSource.getName())) {
|
||||
newDataSource.setName(CommonUtils.notNull(connectionConfig.getName(), "NewConnection"));
|
||||
}
|
||||
return newDataSource;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public WebConnectionInfo createConnection(
|
||||
@NotNull WebSession webSession,
|
||||
@Nullable String projectId,
|
||||
DBPDataSourceRegistry sessionRegistry,
|
||||
DBPDataSourceContainer newDataSource
|
||||
) throws DBWebException {
|
||||
WebSessionProjectImpl project = getProjectById(webSession, projectId);
|
||||
try {
|
||||
sessionRegistry.addDataSource(newDataSource);
|
||||
|
||||
sessionRegistry.checkForErrors();
|
||||
} catch (DBException e) {
|
||||
sessionRegistry.removeDataSource(newDataSource);
|
||||
throw new DBWebException("Failed to create connection", e);
|
||||
}
|
||||
|
||||
WebConnectionInfo connectionInfo = project.addConnection(newDataSource);
|
||||
webSession.addInfoMessage("New connection was created - " + WebServiceUtils.getConnectionContainerInfo(
|
||||
newDataSource));
|
||||
log.info(String.format(
|
||||
"New connection was created: [info=%s, user=%s]",
|
||||
WebServiceUtils.getConnectionContainerInfo(newDataSource),
|
||||
webSession.getUserId()
|
||||
));
|
||||
return connectionInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DBPDataSourceContainer getDatasourceConnection(
|
||||
@NotNull WebSession webSession,
|
||||
@Nullable String projectId,
|
||||
@NotNull WebConnectionConfig config
|
||||
) throws DBWebException {
|
||||
// Do not check for custom connection option. Already created connections can be edited.
|
||||
// Also template connections can be edited
|
||||
// if (!CBApplication.getInstance().getAppConfiguration().isSupportsCustomConnections()) {
|
||||
// throw new DBWebException("Connection edit is restricted by server configuration");
|
||||
// }
|
||||
|
||||
WebConnectionInfo connectionInfo = WebDataSourceUtils.getWebConnectionInfo(webSession, projectId, config.getConnectionId());
|
||||
DBPDataSourceContainer dataSource = connectionInfo.getDataSourceContainer();
|
||||
webSession.addInfoMessage("Update connection - " + WebServiceUtils.getConnectionContainerInfo(dataSource));
|
||||
getOldDataSource(dataSource);
|
||||
if (!CommonUtils.isEmpty(config.getName())) {
|
||||
dataSource.setName(config.getName());
|
||||
}
|
||||
|
||||
if (config.getDescription() != null) {
|
||||
dataSource.setDescription(config.getDescription());
|
||||
}
|
||||
|
||||
WebSessionProjectImpl project = getProjectById(webSession, projectId);
|
||||
DBPDataSourceRegistry sessionRegistry = project.getDataSourceRegistry();
|
||||
dataSource.setFolder(config.getFolder() != null ? sessionRegistry.getFolder(config.getFolder()) : null);
|
||||
if (config.isDefaultAutoCommit() != null) {
|
||||
dataSource.setDefaultAutoCommit(config.isDefaultAutoCommit());
|
||||
}
|
||||
dataSource.setConnectionReadOnly(config.isReadOnly());
|
||||
WebServiceUtils.setConnectionConfiguration(dataSource.getDriver(),
|
||||
dataSource.getConnectionConfiguration(),
|
||||
config);
|
||||
|
||||
// we should check that the config has changed but not check for password changes
|
||||
dataSource.setSharedCredentials(config.isSharedCredentials());
|
||||
dataSource.setSavePassword(config.isSaveCredentials());
|
||||
boolean sharedCredentials = isSharedCredentials(dataSource);
|
||||
if (sharedCredentials) {
|
||||
//we must notify about the shared password change
|
||||
WebServiceUtils.saveAuthProperties(
|
||||
dataSource,
|
||||
dataSource.getConnectionConfiguration(),
|
||||
config.getCredentials(),
|
||||
config.isSaveCredentials(),
|
||||
config.isSharedCredentials()
|
||||
);
|
||||
}
|
||||
connectionInfo.setCredentialsSavedInSession(null);
|
||||
// same here
|
||||
return dataSource;
|
||||
}
|
||||
|
||||
private static boolean isSharedCredentials(DBPDataSourceContainer dataSource) {
|
||||
return dataSource.isSharedCredentials() || !dataSource.getProject()
|
||||
.isUseSecretStorage() && dataSource.isSavePassword();
|
||||
}
|
||||
|
||||
private static DataSourceDescriptor getOldDataSource(DBPDataSourceContainer dataSource) {
|
||||
DataSourceDescriptor oldDataSource;
|
||||
oldDataSource = dataSource.getRegistry().createDataSource(dataSource);
|
||||
oldDataSource.setId(dataSource.getId());
|
||||
return oldDataSource;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WebConnectionInfo updateConnection(
|
||||
@NotNull WebSession webSession,
|
||||
@Nullable String projectId,
|
||||
@NotNull WebConnectionConfig config,
|
||||
DBPDataSourceContainer dataSource,
|
||||
DBPDataSourceRegistry sessionRegistry
|
||||
) throws DBWebException {
|
||||
WebConnectionInfo connectionInfo = WebDataSourceUtils.getWebConnectionInfo(webSession, projectId, config.getConnectionId());
|
||||
if (!isSharedCredentials(dataSource)) {
|
||||
// secret controller is responsible for notification, password changes applied after checks
|
||||
WebServiceUtils.saveAuthProperties(
|
||||
dataSource,
|
||||
dataSource.getConnectionConfiguration(),
|
||||
config.getCredentials(),
|
||||
config.isSaveCredentials(),
|
||||
config.isSharedCredentials()
|
||||
);
|
||||
}
|
||||
try {
|
||||
sessionRegistry.updateDataSource(dataSource);
|
||||
sessionRegistry.checkForErrors();
|
||||
} catch (DBException e) {
|
||||
throw new DBWebException("Failed to update connection", e);
|
||||
}
|
||||
log.info(String.format(
|
||||
"Connection updated: [info=%s, userId=%s]",
|
||||
WebServiceUtils.getConnectionContainerInfo(dataSource),
|
||||
webSession.getUser()
|
||||
));
|
||||
return connectionInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean deleteConnection(
|
||||
@NotNull WebSession webSession, @Nullable String projectId, @NotNull String connectionId
|
||||
) throws DBWebException {
|
||||
WebConnectionInfo connectionInfo = WebDataSourceUtils.getWebConnectionInfo(webSession, projectId, connectionId);
|
||||
if (connectionInfo.getDataSourceContainer().getProject() != getProjectById(webSession, projectId)) {
|
||||
throw new DBWebException("Global connection '" + connectionInfo.getName() + "' configuration cannot be deleted");
|
||||
}
|
||||
webSession.addInfoMessage("Delete connection - " +
|
||||
WebServiceUtils.getConnectionContainerInfo(connectionInfo.getDataSourceContainer()));
|
||||
closeAndDeleteConnection(webSession, projectId, connectionId, true);
|
||||
|
||||
log.info(String.format(
|
||||
"Connection deleted: [info=%s, userId=%s]",
|
||||
WebServiceUtils.getConnectionContainerInfo(connectionInfo.getDataSourceContainer()),
|
||||
webSession.getUserId()
|
||||
));
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public DataSourceDescriptor prepareTestConnection(
|
||||
@NotNull WebSession webSession,
|
||||
@Nullable String projectId,
|
||||
@NotNull WebConnectionConfig connectionConfig
|
||||
) throws DBWebException {
|
||||
String connectionId = connectionConfig.getConnectionId();
|
||||
|
||||
connectionConfig.setSaveCredentials(true); // It is used in createConnectionFromConfig
|
||||
|
||||
DataSourceDescriptor dataSource = (DataSourceDescriptor) WebDataSourceUtils.getLocalOrGlobalDataSource(
|
||||
webSession, projectId, connectionId);
|
||||
|
||||
validateConnection(dataSource);
|
||||
|
||||
WebProjectImpl project = getProjectById(webSession, projectId);
|
||||
DBPDataSourceRegistry sessionRegistry = project.getDataSourceRegistry();
|
||||
DataSourceDescriptor testDataSource;
|
||||
if (dataSource != null) {
|
||||
try {
|
||||
// Check that creds are saved to trigger secrets resolve
|
||||
dataSource.isCredentialsSaved();
|
||||
} catch (DBException e) {
|
||||
throw new DBWebException("Can't determine whether datasource credentials are saved", e);
|
||||
}
|
||||
|
||||
testDataSource = (DataSourceDescriptor) dataSource.createCopy(dataSource.getRegistry());
|
||||
WebServiceUtils.setConnectionConfiguration(
|
||||
testDataSource.getDriver(),
|
||||
testDataSource.getConnectionConfiguration(),
|
||||
connectionConfig
|
||||
);
|
||||
if (connectionConfig.getSelectedSecretId() != null) {
|
||||
try {
|
||||
dataSource.listSharedCredentials()
|
||||
.stream()
|
||||
.filter(secret -> connectionConfig.getSelectedSecretId().equals(secret.getSubjectId()))
|
||||
.findFirst()
|
||||
.ifPresent(testDataSource::setSelectedSharedCredentials);
|
||||
|
||||
} catch (DBException e) {
|
||||
throw new DBWebException("Failed to load secret value: " + connectionConfig.getSelectedSecretId());
|
||||
}
|
||||
}
|
||||
WebServiceUtils.saveAuthProperties(
|
||||
testDataSource,
|
||||
testDataSource.getConnectionConfiguration(),
|
||||
connectionConfig.getCredentials(),
|
||||
true,
|
||||
false,
|
||||
true
|
||||
);
|
||||
} else {
|
||||
testDataSource = (DataSourceDescriptor) WebServiceUtils.createConnectionFromConfig(connectionConfig,
|
||||
sessionRegistry);
|
||||
}
|
||||
return testDataSource;
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public WebConnectionInfo testConnection(
|
||||
@NotNull WebSession webSession,
|
||||
@Nullable String projectId,
|
||||
@NotNull WebConnectionConfig connectionConfig,
|
||||
DataSourceDescriptor testDataSource
|
||||
) throws DBWebException {
|
||||
validateDriverLibrariesPresence(testDataSource);
|
||||
webSession.provideAuthParameters(webSession.getProgressMonitor(),
|
||||
testDataSource,
|
||||
testDataSource.getConnectionConfiguration());
|
||||
testDataSource.setSavePassword(true); // We need for test to avoid password callback
|
||||
if (DataSourceDescriptor.class.isAssignableFrom(testDataSource.getClass())) {
|
||||
testDataSource.setAccessCheckRequired(!webSession.hasPermission(DBWConstants.PERMISSION_ADMIN));
|
||||
}
|
||||
try {
|
||||
ConnectionTestJob ct = new ConnectionTestJob(testDataSource, param -> {
|
||||
});
|
||||
ct.run(webSession.getProgressMonitor());
|
||||
if (ct.getConnectError() != null) {
|
||||
if (ct.getConnectError() instanceof DBCConnectException error) {
|
||||
Throwable rootCause = CommonUtils.getRootCause(error);
|
||||
if (rootCause instanceof ClassNotFoundException) {
|
||||
throwDriverNotFoundException(testDataSource);
|
||||
}
|
||||
}
|
||||
throw new DBWebException("Connection failed", ct.getConnectError());
|
||||
}
|
||||
WebConnectionInfo connectionInfo = new WebConnectionInfo(webSession, testDataSource);
|
||||
connectionInfo.setConnectError(ct.getConnectError());
|
||||
connectionInfo.setServerVersion(ct.getServerVersion());
|
||||
connectionInfo.setClientVersion(ct.getClientVersion());
|
||||
connectionInfo.setConnectTime(RuntimeUtils.formatExecutionTime(ct.getConnectTime()));
|
||||
return connectionInfo;
|
||||
} catch (DBException e) {
|
||||
throw new DBWebException("Error connecting to database", e);
|
||||
}
|
||||
}
|
||||
|
||||
private WebSessionProjectImpl getProjectById(WebSession webSession, String projectId) throws DBWebException {
|
||||
WebSessionProjectImpl project = webSession.getProjectById(projectId);
|
||||
if (project == null) {
|
||||
throw new DBWebException("Project '" + projectId + "' not found");
|
||||
}
|
||||
return project;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private WebConnectionInfo closeAndDeleteConnection(
|
||||
@NotNull WebSession webSession,
|
||||
@NotNull String projectId,
|
||||
@NotNull String connectionId,
|
||||
boolean forceDelete
|
||||
) throws DBWebException {
|
||||
WebSessionProjectImpl project = getProjectById(webSession, projectId);
|
||||
WebConnectionInfo connectionInfo = project.getWebConnectionInfo(connectionId);
|
||||
|
||||
DBPDataSourceContainer dataSourceContainer = connectionInfo.getDataSourceContainer();
|
||||
boolean disconnected = WebDataSourceUtils.disconnectDataSource(webSession, dataSourceContainer);
|
||||
if (forceDelete) {
|
||||
DBPDataSourceRegistry registry = project.getDataSourceRegistry();
|
||||
registry.removeDataSource(dataSourceContainer);
|
||||
try {
|
||||
registry.checkForErrors();
|
||||
} catch (DBException e) {
|
||||
try {
|
||||
registry.addDataSource(dataSourceContainer);
|
||||
} catch (DBException ex) {
|
||||
log.error("Error re-adding after delete attempt", e);
|
||||
}
|
||||
throw new DBWebException("Failed to delete connection", e);
|
||||
}
|
||||
project.removeConnection(dataSourceContainer);
|
||||
} else {
|
||||
// Just reset saved credentials
|
||||
connectionInfo.clearCache();
|
||||
}
|
||||
|
||||
return connectionInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WebConnectionInfo getConnectionState(
|
||||
@NotNull WebSession webSession,
|
||||
@Nullable String projectId,
|
||||
@NotNull String connectionId
|
||||
) throws DBWebException {
|
||||
return WebDataSourceUtils.getWebConnectionInfo(webSession, projectId, connectionId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WebConnectionInfo initConnection(@NotNull WebSession webSession, @Nullable String projectId, @NotNull String connectionId, @NotNull Map<String, Object> authProperties, @Nullable List<WebNetworkHandlerConfigInput> networkCredentials, boolean saveCredentials, boolean sharedCredentials, @Nullable String selectedSecretId) throws DBWebException {
|
||||
WebConnectionInfo connectionInfo = WebDataSourceUtils.getWebConnectionInfo(webSession, projectId, connectionId);
|
||||
connectionInfo.setSavedCredentials(authProperties, networkCredentials);
|
||||
|
||||
var dataSourceContainer = connectionInfo.getDataSourceContainer();;
|
||||
validateConnection(dataSourceContainer);
|
||||
if (dataSourceContainer.isConnected()) {
|
||||
throw new DBWebException("Datasource '" + dataSourceContainer.getName() + "' is already connected");
|
||||
}
|
||||
if (dataSourceContainer.isSharedCredentials() && selectedSecretId != null) {
|
||||
List<DBSSecretValue> allSecrets;
|
||||
try {
|
||||
allSecrets = dataSourceContainer.listSharedCredentials();
|
||||
} catch (DBException e) {
|
||||
throw new DBWebException("Error loading connection secret", e);
|
||||
}
|
||||
DBSSecretValue selectedSecret =
|
||||
allSecrets.stream()
|
||||
.filter(secret -> selectedSecretId.equals(secret.getUniqueId()))
|
||||
.findFirst().orElse(null);
|
||||
if (selectedSecret == null) {
|
||||
throw new DBWebException("Secret not found:" + selectedSecretId);
|
||||
}
|
||||
dataSourceContainer.setSelectedSharedCredentials(selectedSecret);
|
||||
}
|
||||
|
||||
boolean oldSavePassword = dataSourceContainer.isSavePassword();
|
||||
DBRProgressMonitor monitor = webSession.getProgressMonitor();
|
||||
validateDriverLibrariesPresence(dataSourceContainer);
|
||||
try {
|
||||
boolean connect = dataSourceContainer.connect(monitor, true, false);
|
||||
} catch (Exception e) {
|
||||
if (e instanceof DBCConnectException) {
|
||||
Throwable rootCause = CommonUtils.getRootCause(e);
|
||||
if (rootCause instanceof ClassNotFoundException) {
|
||||
throwDriverNotFoundException(dataSourceContainer);
|
||||
}
|
||||
}
|
||||
throw new DBWebException("Error connecting to database", e);
|
||||
} finally {
|
||||
dataSourceContainer.setSavePassword(oldSavePassword);
|
||||
connectionInfo.clearCache();
|
||||
}
|
||||
// Mark all specified network configs as saved
|
||||
boolean[] saveConfig = new boolean[1];
|
||||
|
||||
if (networkCredentials != null) {
|
||||
networkCredentials.forEach(c -> {
|
||||
if (CommonUtils.toBoolean(c.isSavePassword())) {
|
||||
DBWHandlerConfiguration handlerCfg = dataSourceContainer.getConnectionConfiguration()
|
||||
.getHandler(c.getId());
|
||||
if (handlerCfg != null &&
|
||||
// check username param only for ssh config
|
||||
!(CommonUtils.isEmpty(c.getUserName()) && CommonUtils.equalObjects(handlerCfg.getType(),
|
||||
DBWHandlerType.TUNNEL))
|
||||
) {
|
||||
WebDataSourceUtils.updateHandlerCredentials(handlerCfg, c);
|
||||
handlerCfg.setSavePassword(true);
|
||||
saveConfig[0] = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
if (saveCredentials) {
|
||||
// Save all passed credentials in the datasource container
|
||||
WebServiceUtils.saveAuthProperties(
|
||||
dataSourceContainer,
|
||||
dataSourceContainer.getConnectionConfiguration(),
|
||||
authProperties,
|
||||
true,
|
||||
sharedCredentials
|
||||
);
|
||||
|
||||
var project = dataSourceContainer.getProject();
|
||||
if (project.isUseSecretStorage()) {
|
||||
try {
|
||||
dataSourceContainer.persistSecrets(
|
||||
DBSSecretController.getProjectSecretController(dataSourceContainer.getProject())
|
||||
);
|
||||
} catch (DBException e) {
|
||||
throw new DBWebException("Failed to save credentials", e);
|
||||
}
|
||||
}
|
||||
|
||||
WebDataSourceUtils.saveCredentialsInDataSource(connectionInfo,
|
||||
dataSourceContainer,
|
||||
dataSourceContainer.getConnectionConfiguration());
|
||||
saveConfig[0] = true;
|
||||
}
|
||||
if (WebServiceUtils.isGlobalProject(dataSourceContainer.getProject())) {
|
||||
// Do not flush config for global project (only admin can do it - CB-2415)
|
||||
if (saveCredentials) {
|
||||
connectionInfo.setCredentialsSavedInSession(true);
|
||||
}
|
||||
saveConfig[0] = false;
|
||||
}
|
||||
if (saveConfig[0]) {
|
||||
dataSourceContainer.persistConfiguration();
|
||||
}
|
||||
|
||||
return connectionInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void validateConnection(DBPDataSourceContainer dataSourceContainer) throws DBWebException {
|
||||
}
|
||||
|
||||
|
||||
private void validateDriverLibrariesPresence(@NotNull DBPDataSourceContainer container) throws DBWebException {
|
||||
if (!DBWorkbench.isDistributed() && container.getDriver().getDriverLoader(container).needsExternalDependencies()) {
|
||||
throwDriverNotFoundException(container);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String throwDriverNotFoundException(@NotNull DBPDataSourceContainer container) throws DBWebException {
|
||||
throw new DBWebException("Driver files for %s are not found. Please ask the administrator to download it."
|
||||
.formatted(container.getDriver().getName()));
|
||||
}
|
||||
}
|
||||
+11
-5
@@ -130,31 +130,37 @@ public interface DBWServiceCore extends DBWService {
|
||||
WebConnectionInfo createConnection(
|
||||
@NotNull WebSession webSession,
|
||||
@Nullable @WebObjectId String projectId,
|
||||
@NotNull WebConnectionConfig connectionConfig
|
||||
@NotNull Map<String, Object> connectionConfig
|
||||
) throws DBWebException;
|
||||
|
||||
@WebProjectAction(requireProjectPermissions = {RMConstants.PERMISSION_PROJECT_DATASOURCES_EDIT})
|
||||
WebConnectionInfo updateConnection(
|
||||
@NotNull WebSession webSession,
|
||||
@Nullable @WebObjectId String projectId,
|
||||
@NotNull WebConnectionConfig connectionConfig) throws DBWebException;
|
||||
@NotNull Map<String, Object> connectionConfig
|
||||
) throws DBWebException;
|
||||
|
||||
@WebProjectAction(requireProjectPermissions = {RMConstants.PERMISSION_PROJECT_DATASOURCES_EDIT})
|
||||
boolean deleteConnection(
|
||||
@NotNull WebSession webSession,
|
||||
@Nullable @WebObjectId String projectId,
|
||||
@NotNull String connectionId) throws DBWebException;
|
||||
@NotNull String connectionId
|
||||
) throws DBWebException;
|
||||
|
||||
@WebProjectAction(requireProjectPermissions = {RMConstants.PERMISSION_PROJECT_DATASOURCES_EDIT})
|
||||
WebConnectionInfo copyConnectionFromNode(
|
||||
@NotNull WebSession webSession,
|
||||
@Nullable @WebObjectId String projectId,
|
||||
@NotNull String nodePath,
|
||||
@NotNull WebConnectionConfig config) throws DBWebException;
|
||||
@NotNull Map<String, Object> connectionConfig
|
||||
) throws DBWebException;
|
||||
|
||||
@WebAction
|
||||
WebConnectionInfo testConnection(
|
||||
@NotNull WebSession webSession, @Nullable String projectId, @NotNull WebConnectionConfig connectionConfig) throws DBWebException;
|
||||
@NotNull WebSession webSession,
|
||||
@Nullable String projectId,
|
||||
@NotNull Map<String, Object> connectionConfig
|
||||
) throws DBWebException;
|
||||
|
||||
@WebAction
|
||||
WebNetworkEndpointInfo testNetworkHandler(@NotNull WebSession webSession, @NotNull WebNetworkHandlerConfigInput nhConfig) throws DBWebException;
|
||||
|
||||
+8
-10
@@ -17,11 +17,9 @@
|
||||
package io.cloudbeaver.service.core;
|
||||
|
||||
import graphql.TypeResolutionEnvironment;
|
||||
import graphql.schema.DataFetchingEnvironment;
|
||||
import graphql.schema.idl.TypeRuntimeWiring;
|
||||
import io.cloudbeaver.DBWebException;
|
||||
import io.cloudbeaver.WebServiceUtils;
|
||||
import io.cloudbeaver.model.WebConnectionConfig;
|
||||
import io.cloudbeaver.model.WebNetworkHandlerConfigInput;
|
||||
import io.cloudbeaver.model.session.WebSession;
|
||||
import io.cloudbeaver.server.WebAppSessionManager;
|
||||
@@ -105,16 +103,20 @@ public class WebServiceBindingCore extends WebServiceBindingBase<DBWServiceCore>
|
||||
.dataFetcher("changeSessionLanguage", env -> getService(env).changeSessionLanguage(getWebSession(env), env.getArgument("locale")))
|
||||
|
||||
.dataFetcher("createConnection", env -> getService(env).createConnection(
|
||||
getWebSession(env), getProjectReference(env), getConnectionConfig(env)))
|
||||
getWebSession(env), getProjectReference(env), env.getArgument("config"))
|
||||
)
|
||||
.dataFetcher("updateConnection", env -> getService(env).updateConnection(
|
||||
getWebSession(env), getProjectReference(env), getConnectionConfig(env)))
|
||||
getWebSession(env), getProjectReference(env), env.getArgument("config"))
|
||||
)
|
||||
.dataFetcher("deleteConnection", env -> getService(env).deleteConnection(
|
||||
getWebSession(env), getProjectReference(env), env.getArgument("id")))
|
||||
.dataFetcher("copyConnectionFromNode", env -> getService(env).copyConnectionFromNode(
|
||||
getWebSession(env),
|
||||
getProjectReference(env),
|
||||
env.getArgument("nodePath"),
|
||||
new WebConnectionConfig(env.getArgument("config"))))
|
||||
env.getArgument("config")
|
||||
)
|
||||
)
|
||||
.dataFetcher("initConnection", env -> {
|
||||
List<Map<String, Object>> networkCredentials = env.getArgument("networkCredentials");
|
||||
List<WebNetworkHandlerConfigInput> nhc = null;
|
||||
@@ -134,7 +136,7 @@ public class WebServiceBindingCore extends WebServiceBindingBase<DBWServiceCore>
|
||||
}
|
||||
)
|
||||
.dataFetcher("testConnection", env -> getService(env).testConnection(
|
||||
getWebSession(env), getProjectReference(env), getConnectionConfig(env)
|
||||
getWebSession(env), getProjectReference(env), env.getArgument("config")
|
||||
))
|
||||
.dataFetcher("testNetworkHandler", env -> getService(env).testNetworkHandler(
|
||||
getWebSession(env), new WebNetworkHandlerConfigInput(env.getArgument("config"))
|
||||
@@ -177,8 +179,4 @@ public class WebServiceBindingCore extends WebServiceBindingBase<DBWServiceCore>
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
private WebConnectionConfig getConnectionConfig(DataFetchingEnvironment env) {
|
||||
return new WebConnectionConfig(env.getArgument("config"));
|
||||
}
|
||||
}
|
||||
|
||||
+220
-83
@@ -44,23 +44,29 @@ import org.jkiss.dbeaver.model.app.DBPDataSourceRegistry;
|
||||
import org.jkiss.dbeaver.model.app.DBPProject;
|
||||
import org.jkiss.dbeaver.model.connection.DBPConnectionConfiguration;
|
||||
import org.jkiss.dbeaver.model.connection.DBPDriver;
|
||||
import org.jkiss.dbeaver.model.exec.DBCConnectException;
|
||||
import org.jkiss.dbeaver.model.navigator.DBNBrowseSettings;
|
||||
import org.jkiss.dbeaver.model.navigator.DBNDataSource;
|
||||
import org.jkiss.dbeaver.model.navigator.DBNModel;
|
||||
import org.jkiss.dbeaver.model.navigator.DBNNode;
|
||||
import org.jkiss.dbeaver.model.net.DBWHandlerConfiguration;
|
||||
import org.jkiss.dbeaver.model.net.DBWHandlerType;
|
||||
import org.jkiss.dbeaver.model.net.DBWNetworkHandler;
|
||||
import org.jkiss.dbeaver.model.net.DBWTunnel;
|
||||
import org.jkiss.dbeaver.model.net.ssh.SSHSession;
|
||||
import org.jkiss.dbeaver.model.rm.RMProjectType;
|
||||
import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
|
||||
import org.jkiss.dbeaver.model.websocket.event.datasource.WSDataSourceProperty;
|
||||
import org.jkiss.dbeaver.model.secret.DBSSecretController;
|
||||
import org.jkiss.dbeaver.model.secret.DBSSecretValue;
|
||||
import org.jkiss.dbeaver.registry.DataSourceDescriptor;
|
||||
import org.jkiss.dbeaver.registry.DataSourceProviderRegistry;
|
||||
import org.jkiss.dbeaver.registry.network.NetworkHandlerDescriptor;
|
||||
import org.jkiss.dbeaver.registry.network.NetworkHandlerRegistry;
|
||||
import org.jkiss.dbeaver.registry.settings.ProductSettingDescriptor;
|
||||
import org.jkiss.dbeaver.registry.settings.ProductSettingsRegistry;
|
||||
import org.jkiss.dbeaver.runtime.DBWorkbench;
|
||||
import org.jkiss.dbeaver.runtime.jobs.ConnectionTestJob;
|
||||
import org.jkiss.dbeaver.utils.RuntimeUtils;
|
||||
import org.jkiss.utils.CommonUtils;
|
||||
|
||||
import java.util.*;
|
||||
@@ -280,7 +286,7 @@ public class WebServiceCore implements DBWServiceCore {
|
||||
@Nullable String projectId,
|
||||
@NotNull String connectionId
|
||||
) throws DBWebException {
|
||||
return WebAppUtils.getWebApplication().getConnectionController().getConnectionState(webSession, projectId, connectionId);
|
||||
return WebDataSourceUtils.getWebConnectionInfo(webSession, projectId, connectionId);
|
||||
}
|
||||
|
||||
|
||||
@@ -295,65 +301,137 @@ public class WebServiceCore implements DBWServiceCore {
|
||||
boolean sharedCredentials,
|
||||
@Nullable String selectedSecretId
|
||||
) throws DBWebException {
|
||||
return WebAppUtils.getWebApplication().getConnectionController().initConnection(webSession, projectId,
|
||||
connectionId, authProperties, networkCredentials, saveCredentials, sharedCredentials, selectedSecretId);
|
||||
WebConnectionInfo connectionInfo = WebDataSourceUtils.getWebConnectionInfo(webSession, projectId, connectionId);
|
||||
connectionInfo.validateConnection();
|
||||
connectionInfo.setSavedCredentials(authProperties, networkCredentials);
|
||||
|
||||
var dataSourceContainer = connectionInfo.getDataSourceContainer();
|
||||
if (dataSourceContainer.isConnected()) {
|
||||
throw new DBWebException("Datasource '" + dataSourceContainer.getName() + "' is already connected");
|
||||
}
|
||||
if (dataSourceContainer.isSharedCredentials() && selectedSecretId != null) {
|
||||
List<DBSSecretValue> allSecrets;
|
||||
try {
|
||||
allSecrets = dataSourceContainer.listSharedCredentials();
|
||||
} catch (DBException e) {
|
||||
throw new DBWebException("Error loading connection secret", e);
|
||||
}
|
||||
DBSSecretValue selectedSecret =
|
||||
allSecrets.stream()
|
||||
.filter(secret -> selectedSecretId.equals(secret.getUniqueId()))
|
||||
.findFirst().orElse(null);
|
||||
if (selectedSecret == null) {
|
||||
throw new DBWebException("Secret not found:" + selectedSecretId);
|
||||
}
|
||||
dataSourceContainer.setSelectedSharedCredentials(selectedSecret);
|
||||
}
|
||||
|
||||
boolean oldSavePassword = dataSourceContainer.isSavePassword();
|
||||
DBRProgressMonitor monitor = webSession.getProgressMonitor();
|
||||
validateDriverLibrariesPresence(dataSourceContainer);
|
||||
try {
|
||||
boolean connect = dataSourceContainer.connect(monitor, true, false);
|
||||
} catch (Exception e) {
|
||||
if (e instanceof DBCConnectException) {
|
||||
Throwable rootCause = CommonUtils.getRootCause(e);
|
||||
if (rootCause instanceof ClassNotFoundException) {
|
||||
throwDriverNotFoundException(dataSourceContainer);
|
||||
}
|
||||
}
|
||||
throw new DBWebException("Error connecting to database", e);
|
||||
} finally {
|
||||
dataSourceContainer.setSavePassword(oldSavePassword);
|
||||
connectionInfo.clearCache();
|
||||
}
|
||||
// Mark all specified network configs as saved
|
||||
boolean[] saveConfig = new boolean[1];
|
||||
|
||||
if (networkCredentials != null) {
|
||||
networkCredentials.forEach(c -> {
|
||||
if (CommonUtils.toBoolean(c.isSavePassword())) {
|
||||
DBWHandlerConfiguration handlerCfg = dataSourceContainer.getConnectionConfiguration()
|
||||
.getHandler(c.getId());
|
||||
if (handlerCfg != null &&
|
||||
// check username param only for ssh config
|
||||
!(CommonUtils.isEmpty(c.getUserName()) && CommonUtils.equalObjects(
|
||||
handlerCfg.getType(),
|
||||
DBWHandlerType.TUNNEL
|
||||
))
|
||||
) {
|
||||
WebDataSourceUtils.updateHandlerCredentials(handlerCfg, c);
|
||||
handlerCfg.setSavePassword(true);
|
||||
saveConfig[0] = true;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
if (saveCredentials) {
|
||||
// Save all passed credentials in the datasource container
|
||||
WebDataSourceUtils.saveAuthProperties(
|
||||
dataSourceContainer,
|
||||
dataSourceContainer.getConnectionConfiguration(),
|
||||
authProperties,
|
||||
true,
|
||||
sharedCredentials
|
||||
);
|
||||
|
||||
var project = dataSourceContainer.getProject();
|
||||
if (project.isUseSecretStorage()) {
|
||||
try {
|
||||
dataSourceContainer.persistSecrets(
|
||||
DBSSecretController.getProjectSecretController(dataSourceContainer.getProject())
|
||||
);
|
||||
} catch (DBException e) {
|
||||
throw new DBWebException("Failed to save credentials", e);
|
||||
}
|
||||
}
|
||||
|
||||
WebDataSourceUtils.saveCredentialsInDataSource(
|
||||
connectionInfo,
|
||||
dataSourceContainer,
|
||||
dataSourceContainer.getConnectionConfiguration()
|
||||
);
|
||||
saveConfig[0] = true;
|
||||
}
|
||||
if (WebServiceUtils.isGlobalProject(dataSourceContainer.getProject())) {
|
||||
// Do not flush config for global project (only admin can do it - CB-2415)
|
||||
if (saveCredentials) {
|
||||
connectionInfo.setCredentialsSavedInSession(true);
|
||||
}
|
||||
saveConfig[0] = false;
|
||||
}
|
||||
if (saveConfig[0]) {
|
||||
dataSourceContainer.persistConfiguration();
|
||||
}
|
||||
|
||||
return connectionInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public WebConnectionInfo createConnection(
|
||||
@NotNull WebSession webSession,
|
||||
@Nullable String projectId,
|
||||
@NotNull WebConnectionConfig connectionConfig
|
||||
@NotNull Map<String, Object> connectionConfig
|
||||
) throws DBWebException {
|
||||
DBPDataSourceContainer dataSourceContainer =
|
||||
WebAppUtils.getWebApplication().getConnectionController().createDataSourceContainer(webSession, projectId, connectionConfig);
|
||||
return WebAppUtils.getWebApplication().getConnectionController().createConnection(
|
||||
webSession,
|
||||
projectId,
|
||||
dataSourceContainer.getRegistry(),
|
||||
dataSourceContainer
|
||||
);
|
||||
return getProjectById(webSession, projectId).createConnection(connectionConfig);
|
||||
}
|
||||
|
||||
@Override
|
||||
public WebConnectionInfo updateConnection(
|
||||
@NotNull WebSession webSession,
|
||||
@Nullable String projectId,
|
||||
@NotNull WebConnectionConfig config
|
||||
@NotNull Map<String, Object> connectionConfig
|
||||
) throws DBWebException {
|
||||
DBPDataSourceContainer dataSourceContainer =
|
||||
WebAppUtils.getWebApplication().getConnectionController().getDatasourceConnection(webSession, projectId, config);
|
||||
return WebAppUtils.getWebApplication().getConnectionController().updateConnection(
|
||||
webSession,
|
||||
projectId,
|
||||
config,
|
||||
dataSourceContainer,
|
||||
dataSourceContainer.getRegistry()
|
||||
);
|
||||
}
|
||||
|
||||
private WSDataSourceProperty getDatasourceEventProperty(
|
||||
DataSourceDescriptor oldDataSource,
|
||||
DBPDataSourceContainer dataSource
|
||||
) {
|
||||
if (!oldDataSource.equalConfiguration((DataSourceDescriptor) dataSource)) {
|
||||
return WSDataSourceProperty.CONFIGURATION;
|
||||
}
|
||||
|
||||
var nameChanged = !CommonUtils.equalObjects(oldDataSource.getName(), dataSource.getName());
|
||||
var descriptionChanged = !CommonUtils.equalObjects(oldDataSource.getDescription(), dataSource.getDescription());
|
||||
if (nameChanged && descriptionChanged) {
|
||||
return WSDataSourceProperty.CONFIGURATION;
|
||||
}
|
||||
|
||||
return nameChanged ? WSDataSourceProperty.NAME : WSDataSourceProperty.CONFIGURATION;
|
||||
return getProjectById(webSession, projectId).updateConnection(connectionConfig);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean deleteConnection(
|
||||
@NotNull WebSession webSession, @Nullable String projectId, @NotNull String connectionId
|
||||
@NotNull WebSession webSession,
|
||||
@Nullable String projectId,
|
||||
@NotNull String connectionId
|
||||
) throws DBWebException {
|
||||
return WebAppUtils.getWebApplication().getConnectionController().deleteConnection(webSession, projectId, connectionId);
|
||||
return getProjectById(webSession, projectId).deleteConnection(connectionId);
|
||||
|
||||
}
|
||||
|
||||
@@ -362,7 +440,7 @@ public class WebServiceCore implements DBWServiceCore {
|
||||
@NotNull WebSession webSession,
|
||||
@Nullable String projectId,
|
||||
@NotNull String nodePath,
|
||||
@NotNull WebConnectionConfig config
|
||||
@NotNull Map<String, Object> connectionConfig
|
||||
) throws DBWebException {
|
||||
try {
|
||||
DBNModel navigatorModel = webSession.getNavigatorModelOrThrow();
|
||||
@@ -373,19 +451,20 @@ public class WebServiceCore implements DBWServiceCore {
|
||||
if (srcNode == null) {
|
||||
throw new DBException("Node '" + nodePath + "' not found");
|
||||
}
|
||||
if (!(srcNode instanceof DBNDataSource)) {
|
||||
if (!(srcNode instanceof DBNDataSource dbnDataSource)) {
|
||||
throw new DBException("Node '" + nodePath + "' is not a datasource node");
|
||||
}
|
||||
DBPDataSourceContainer dataSourceTemplate = ((DBNDataSource) srcNode).getDataSourceContainer();
|
||||
DBPDataSourceContainer dataSourceTemplate = dbnDataSource.getDataSourceContainer();
|
||||
|
||||
DBPDataSourceContainer newDataSource = dataSourceRegistry.createDataSource(dataSourceTemplate);
|
||||
DataSourceDescriptor newDataSource = dataSourceRegistry.createDataSource(dataSourceTemplate);
|
||||
|
||||
ServletApplication app = ServletAppUtils.getServletApplication();
|
||||
if (app instanceof WebApplication webApplication) {
|
||||
((DataSourceDescriptor) newDataSource).setNavigatorSettings(
|
||||
webApplication.getAppConfiguration().getDefaultNavigatorSettings());
|
||||
newDataSource.setNavigatorSettings(webApplication.getAppConfiguration().getDefaultNavigatorSettings());
|
||||
}
|
||||
|
||||
WebConnectionConfig config = project.getConnectionConfigInput(connectionConfig);
|
||||
|
||||
// Copy props from config
|
||||
if (!CommonUtils.isEmpty(config.getName())) {
|
||||
newDataSource.setName(config.getName());
|
||||
@@ -407,12 +486,84 @@ public class WebServiceCore implements DBWServiceCore {
|
||||
public WebConnectionInfo testConnection(
|
||||
@NotNull WebSession webSession,
|
||||
@Nullable String projectId,
|
||||
@NotNull WebConnectionConfig connectionConfig
|
||||
@NotNull Map<String, Object> connectionConfig
|
||||
) throws DBWebException {
|
||||
DataSourceDescriptor dataSourceDescriptor = WebAppUtils.getWebApplication().getConnectionController()
|
||||
.prepareTestConnection(webSession, projectId, connectionConfig);
|
||||
return WebAppUtils.getWebApplication().getConnectionController()
|
||||
.testConnection(webSession, projectId, connectionConfig, dataSourceDescriptor);
|
||||
WebSessionProjectImpl project = getProjectById(webSession, projectId);
|
||||
WebConnectionConfig configInput = project.getConnectionConfigInput(connectionConfig);
|
||||
|
||||
DataSourceDescriptor dataSource = (DataSourceDescriptor) WebDataSourceUtils.getLocalOrGlobalDataSource(
|
||||
webSession, projectId, configInput.getConnectionId());
|
||||
|
||||
DataSourceDescriptor testDataSource;
|
||||
if (dataSource != null) {
|
||||
try {
|
||||
// Check that creds are saved to trigger secrets resolve
|
||||
dataSource.isCredentialsSaved();
|
||||
} catch (DBException e) {
|
||||
throw new DBWebException("Can't determine whether datasource credentials are saved", e);
|
||||
}
|
||||
|
||||
testDataSource = (DataSourceDescriptor) dataSource.createCopy(dataSource.getRegistry());
|
||||
WebDataSourceUtils.setConnectionConfiguration(
|
||||
testDataSource.getDriver(),
|
||||
testDataSource.getConnectionConfiguration(),
|
||||
configInput
|
||||
);
|
||||
if (configInput.getSelectedSecretId() != null) {
|
||||
try {
|
||||
dataSource.listSharedCredentials()
|
||||
.stream()
|
||||
.filter(secret -> configInput.getSelectedSecretId().equals(secret.getSubjectId()))
|
||||
.findFirst()
|
||||
.ifPresent(testDataSource::setSelectedSharedCredentials);
|
||||
|
||||
} catch (DBException e) {
|
||||
throw new DBWebException("Failed to load secret value: " + configInput.getSelectedSecretId());
|
||||
}
|
||||
}
|
||||
WebDataSourceUtils.saveAuthProperties(
|
||||
testDataSource,
|
||||
testDataSource.getConnectionConfiguration(),
|
||||
configInput.getCredentials(),
|
||||
true,
|
||||
false,
|
||||
true
|
||||
);
|
||||
} else {
|
||||
testDataSource = project.getDataSourceContainerFromInput(connectionConfig);
|
||||
}
|
||||
validateDriverLibrariesPresence(testDataSource);
|
||||
webSession.provideAuthParameters(
|
||||
webSession.getProgressMonitor(),
|
||||
testDataSource,
|
||||
testDataSource.getConnectionConfiguration()
|
||||
);
|
||||
testDataSource.setSavePassword(true); // We need for test to avoid password callback
|
||||
testDataSource.setAccessCheckRequired(!webSession.hasPermission(DBWConstants.PERMISSION_ADMIN));
|
||||
try {
|
||||
ConnectionTestJob ct = new ConnectionTestJob(
|
||||
testDataSource, param -> {
|
||||
}
|
||||
);
|
||||
ct.run(webSession.getProgressMonitor());
|
||||
if (ct.getConnectError() != null) {
|
||||
if (ct.getConnectError() instanceof DBCConnectException error) {
|
||||
Throwable rootCause = CommonUtils.getRootCause(error);
|
||||
if (rootCause instanceof ClassNotFoundException) {
|
||||
throwDriverNotFoundException(testDataSource);
|
||||
}
|
||||
}
|
||||
throw new DBWebException("Connection failed", ct.getConnectError());
|
||||
}
|
||||
WebConnectionInfo connectionInfo = project.createConnectionInfo(testDataSource);
|
||||
connectionInfo.setConnectError(ct.getConnectError());
|
||||
connectionInfo.setServerVersion(ct.getServerVersion());
|
||||
connectionInfo.setClientVersion(ct.getClientVersion());
|
||||
connectionInfo.setConnectTime(RuntimeUtils.formatExecutionTime(ct.getConnectTime()));
|
||||
return connectionInfo;
|
||||
} catch (DBException e) {
|
||||
throw new DBWebException("Error connecting to database", e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -471,42 +622,15 @@ public class WebServiceCore implements DBWServiceCore {
|
||||
|
||||
@Override
|
||||
public WebConnectionInfo closeConnection(
|
||||
@NotNull WebSession webSession, @Nullable String projectId, @NotNull String connectionId
|
||||
) throws DBWebException {
|
||||
return closeAndDeleteConnection(webSession, projectId, connectionId, false);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private WebConnectionInfo closeAndDeleteConnection(
|
||||
@NotNull WebSession webSession,
|
||||
@NotNull String projectId,
|
||||
@NotNull String connectionId,
|
||||
boolean forceDelete
|
||||
@Nullable String projectId,
|
||||
@NotNull String connectionId
|
||||
) throws DBWebException {
|
||||
WebSessionProjectImpl project = getProjectById(webSession, projectId);
|
||||
WebConnectionInfo connectionInfo = project.getWebConnectionInfo(connectionId);
|
||||
|
||||
DBPDataSourceContainer dataSourceContainer = connectionInfo.getDataSourceContainer();
|
||||
boolean disconnected = WebDataSourceUtils.disconnectDataSource(webSession, dataSourceContainer);
|
||||
if (forceDelete) {
|
||||
DBPDataSourceRegistry registry = project.getDataSourceRegistry();
|
||||
registry.removeDataSource(dataSourceContainer);
|
||||
try {
|
||||
registry.checkForErrors();
|
||||
} catch (DBException e) {
|
||||
try {
|
||||
registry.addDataSource(dataSourceContainer);
|
||||
} catch (DBException ex) {
|
||||
log.error("Error re-adding after delete attempt", e);
|
||||
}
|
||||
throw new DBWebException("Failed to delete connection", e);
|
||||
}
|
||||
project.removeConnection(dataSourceContainer);
|
||||
} else {
|
||||
// Just reset saved credentials
|
||||
connectionInfo.clearCache();
|
||||
}
|
||||
|
||||
return connectionInfo;
|
||||
}
|
||||
|
||||
@@ -611,11 +735,24 @@ public class WebServiceCore implements DBWServiceCore {
|
||||
return new WebGroupPropertiesInfo<>(webSession, ProductSettingsRegistry.getInstance().getSettings());
|
||||
}
|
||||
|
||||
private WebSessionProjectImpl getProjectById(WebSession webSession, String projectId) throws DBWebException {
|
||||
@NotNull
|
||||
private WebSessionProjectImpl getProjectById(@NotNull WebSession webSession, @Nullable String projectId) throws DBWebException {
|
||||
WebSessionProjectImpl project = webSession.getProjectById(projectId);
|
||||
if (project == null) {
|
||||
throw new DBWebException("Project '" + projectId + "' not found");
|
||||
}
|
||||
return project;
|
||||
}
|
||||
|
||||
private void validateDriverLibrariesPresence(@NotNull DBPDataSourceContainer container) throws DBWebException {
|
||||
if (!DBWorkbench.isDistributed() && container.getDriver().getDriverLoader(container).needsExternalDependencies()) {
|
||||
throwDriverNotFoundException(container);
|
||||
}
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private static String throwDriverNotFoundException(@NotNull DBPDataSourceContainer container) throws DBWebException {
|
||||
throw new DBWebException("Driver files for %s are not found. Please ask the administrator to download it."
|
||||
.formatted(container.getDriver().getName()));
|
||||
}
|
||||
}
|
||||
|
||||
+2
-1
@@ -35,6 +35,7 @@ import io.cloudbeaver.service.DBWServiceServerConfigurator;
|
||||
import io.cloudbeaver.service.admin.*;
|
||||
import io.cloudbeaver.service.security.SMUtils;
|
||||
import io.cloudbeaver.utils.ServletAppUtils;
|
||||
import io.cloudbeaver.utils.WebDataSourceUtils;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import org.jkiss.code.NotNull;
|
||||
import org.jkiss.code.Nullable;
|
||||
@@ -701,7 +702,7 @@ public class WebServiceAdmin implements DBWServiceAdmin {
|
||||
// driver is removed from disabled list
|
||||
// we need to enable if it is embedded
|
||||
try {
|
||||
DBPDriver driver = WebServiceUtils.getDriverById(driverId);
|
||||
DBPDriver driver = WebDataSourceUtils.getDriverById(driverId);
|
||||
if (driver.isEmbedded()) {
|
||||
enabledIds.add(driverId);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user