mirror of
https://github.com/dbeaver/cloudbeaver.git
synced 2026-10-24 23:05:29 +08:00
dbeaver/pro#6249 fix events for changing extensions (#3667)
* dbeaver/pro#6249 fix events for changing extensions * dbeaver/pro#6249 send connection updated info event on rm side --------- Co-authored-by: Daria Marutkina <125263541+dariamarutkina@users.noreply.github.com>
This commit is contained in:
+2
-1
@@ -35,6 +35,7 @@ import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
|
||||
import org.jkiss.dbeaver.model.secret.DBSSecretController;
|
||||
import org.jkiss.dbeaver.model.struct.DBSObjectFilter;
|
||||
import org.jkiss.dbeaver.registry.DataSourceConfigurationManager;
|
||||
import org.jkiss.dbeaver.registry.DataSourceParseResults;
|
||||
import org.jkiss.dbeaver.registry.DataSourcePersistentRegistry;
|
||||
import org.jkiss.dbeaver.registry.DataSourceRegistry;
|
||||
|
||||
@@ -377,7 +378,7 @@ public class WebGlobalProjectRegistryProxy implements DBPDataSourceRegistry, Dat
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean loadDataSources(
|
||||
public DataSourceParseResults loadDataSources(
|
||||
@NotNull List<DBPDataSourceConfigurationStorage> storages,
|
||||
@NotNull DataSourceConfigurationManager manager,
|
||||
@Nullable Collection<String> dataSourceIds, boolean refresh,
|
||||
|
||||
@@ -29,13 +29,16 @@ import org.jkiss.dbeaver.model.navigator.DBNModel;
|
||||
import org.jkiss.dbeaver.model.rm.RMProject;
|
||||
import org.jkiss.dbeaver.model.rm.RMUtils;
|
||||
import org.jkiss.dbeaver.model.websocket.event.datasource.WSDataSourceEvent;
|
||||
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 java.nio.file.Path;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class WebSessionProjectImpl extends WebProjectImpl {
|
||||
private static final Log log = Log.getLog(WebSessionProjectImpl.class);
|
||||
@@ -194,40 +197,31 @@ public class WebSessionProjectImpl extends WebProjectImpl {
|
||||
/**
|
||||
* updates data sources based on event in web session
|
||||
*
|
||||
* @param dataSourceIds list of updated connections
|
||||
* @param eventId id of event
|
||||
* @param event data source updated event
|
||||
*/
|
||||
public synchronized boolean updateProjectDataSources(@NotNull List<String> dataSourceIds, @NotNull String eventId) {
|
||||
public synchronized boolean updateProjectDataSources(@NotNull WSDataSourceEvent event) {
|
||||
var sendDataSourceUpdatedEvent = false;
|
||||
DBPDataSourceRegistry registry = getDataSourceRegistry();
|
||||
// save old connections
|
||||
var oldDataSources = dataSourceIds.stream()
|
||||
.map(registry::getDataSource)
|
||||
.filter(Objects::nonNull)
|
||||
.collect(Collectors.toMap(
|
||||
DBPDataSourceContainer::getId,
|
||||
registry::createDataSource)
|
||||
);
|
||||
if (WSDataSourceEvent.CREATED.equals(eventId) || WSDataSourceEvent.UPDATED.equals(eventId)) {
|
||||
registry.refreshConfig(dataSourceIds);
|
||||
if (WSDataSourceEvent.CREATED.equals(event.getId()) || WSDataSourceEvent.UPDATED.equals(event.getId())) {
|
||||
registry.refreshConfig(event.getDataSourceIds());
|
||||
}
|
||||
for (String dsId : dataSourceIds) {
|
||||
for (String dsId : event.getDataSourceIds()) {
|
||||
DataSourceDescriptor ds = (DataSourceDescriptor) registry.getDataSource(dsId);
|
||||
if (ds == null) {
|
||||
continue;
|
||||
}
|
||||
switch (eventId) {
|
||||
switch (event.getId()) {
|
||||
case WSDataSourceEvent.CREATED -> {
|
||||
addConnection(ds);
|
||||
sendDataSourceUpdatedEvent = true;
|
||||
}
|
||||
case WSDataSourceEvent.UPDATED -> {
|
||||
boolean connectionUpdated = !ds.equalSettings(oldDataSources.get(dsId));
|
||||
if (connectionUpdated) {
|
||||
sendDataSourceUpdatedEvent = true;
|
||||
if (event.getProperty() == WSDataSourceProperty.CONFIGURATION) {
|
||||
WebDataSourceUtils.disconnectDataSource(webSession, ds);
|
||||
}
|
||||
// if settings were changed we need to send event
|
||||
if (event.getProperty() != WSDataSourceProperty.INTERNAL) {
|
||||
sendDataSourceUpdatedEvent = true;
|
||||
}
|
||||
}
|
||||
case WSDataSourceEvent.DELETED -> {
|
||||
WebDataSourceUtils.disconnectDataSource(webSession, ds);
|
||||
|
||||
+17
-4
@@ -149,27 +149,37 @@ public abstract class BaseLocalResourceController implements RMController {
|
||||
@NotNull String projectId,
|
||||
@NotNull String configuration,
|
||||
@Nullable List<String> dataSourceIds
|
||||
) throws DBException {
|
||||
return updateProjectDataSourcesConfig(projectId, configuration, dataSourceIds) != null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected DataSourceParseResults updateProjectDataSourcesConfig(
|
||||
@NotNull String projectId,
|
||||
@NotNull String configuration,
|
||||
@Nullable List<String> dataSourceIds
|
||||
) throws DBException {
|
||||
try (var lock = lockController.lock(projectId, "updateProjectDataSources")) {
|
||||
DBPProject project = getWebProject(projectId, false);
|
||||
return doFileWriteOperation(projectId, project.getMetadataFolder(false),
|
||||
return doFileWriteOperation(
|
||||
projectId, project.getMetadataFolder(false),
|
||||
() -> {
|
||||
DBPDataSourceRegistry registry = project.getDataSourceRegistry();
|
||||
DBPDataSourceConfigurationStorage storage = new DataSourceMemoryStorage(configuration.getBytes(
|
||||
StandardCharsets.UTF_8));
|
||||
DataSourceConfigurationManager manager = new DataSourceConfigurationManagerBuffer();
|
||||
var configChanged = ((DataSourcePersistentRegistry) registry).loadDataSources(
|
||||
final DataSourceParseResults parseResults = ((DataSourcePersistentRegistry) registry).loadDataSources(
|
||||
List.of(storage),
|
||||
manager,
|
||||
dataSourceIds,
|
||||
true,
|
||||
false
|
||||
dataSourceIds == null
|
||||
);
|
||||
registry.checkForErrors();
|
||||
log.debug("Save data sources configuration in project '" + projectId + "'");
|
||||
((DataSourcePersistentRegistry) registry).saveDataSources();
|
||||
registry.checkForErrors();
|
||||
return configChanged;
|
||||
return parseResults;
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -217,6 +227,7 @@ public abstract class BaseLocalResourceController implements RMController {
|
||||
var parent = result.getParent();
|
||||
var parentFolder = parent == null ? null : registry.getFolder(parent.toString().replace("\\", "/"));
|
||||
DBPDataSourceFolder newFolder = registry.addFolder(parentFolder, newName);
|
||||
((DataSourcePersistentRegistry) registry).saveDataSources();
|
||||
registry.checkForErrors();
|
||||
return null;
|
||||
}
|
||||
@@ -244,6 +255,7 @@ public abstract class BaseLocalResourceController implements RMController {
|
||||
log.warn("Can not find folder by path [" + folderPath + "] for deletion");
|
||||
}
|
||||
}
|
||||
((DataSourcePersistentRegistry) registry).saveDataSources();
|
||||
registry.checkForErrors();
|
||||
return null;
|
||||
}
|
||||
@@ -265,6 +277,7 @@ public abstract class BaseLocalResourceController implements RMController {
|
||||
DBPDataSourceRegistry registry = project.getDataSourceRegistry();
|
||||
registry.moveFolder(oldPath, newPath);
|
||||
registry.checkForErrors();
|
||||
((DataSourcePersistentRegistry) registry).saveDataSources();
|
||||
return null;
|
||||
}
|
||||
);
|
||||
|
||||
+241
@@ -28,18 +28,26 @@ 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.app.DBPWorkspace;
|
||||
import org.jkiss.dbeaver.model.auth.SMCredentials;
|
||||
import org.jkiss.dbeaver.model.auth.SMCredentialsProvider;
|
||||
import org.jkiss.dbeaver.model.fs.lock.FileLockController;
|
||||
import org.jkiss.dbeaver.model.impl.app.BaseProjectImpl;
|
||||
import org.jkiss.dbeaver.model.impl.auth.SessionContextImpl;
|
||||
import org.jkiss.dbeaver.model.navigator.DBNLocalFolder;
|
||||
import org.jkiss.dbeaver.model.rm.*;
|
||||
import org.jkiss.dbeaver.model.security.SMController;
|
||||
import org.jkiss.dbeaver.model.security.SMObjectType;
|
||||
import org.jkiss.dbeaver.model.sql.DBQuotaException;
|
||||
import org.jkiss.dbeaver.model.websocket.event.MessageType;
|
||||
import org.jkiss.dbeaver.model.websocket.event.WSSessionLogUpdatedEvent;
|
||||
import org.jkiss.dbeaver.model.websocket.event.datasource.WSDataSourceEvent;
|
||||
import org.jkiss.dbeaver.model.websocket.event.datasource.WSDataSourceProperty;
|
||||
import org.jkiss.dbeaver.model.websocket.event.datasource.WSDatasourceFolderEvent;
|
||||
import org.jkiss.dbeaver.registry.DataSourceDescriptor;
|
||||
import org.jkiss.dbeaver.registry.DataSourceParseResults;
|
||||
import org.jkiss.dbeaver.registry.ResourceTypeDescriptor;
|
||||
import org.jkiss.dbeaver.registry.ResourceTypeRegistry;
|
||||
import org.jkiss.dbeaver.runtime.DBWorkbench;
|
||||
@@ -334,6 +342,239 @@ public class LocalResourceController extends BaseLocalResourceController {
|
||||
return project;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createProjectDataSources(
|
||||
@NotNull String projectId,
|
||||
@NotNull String configuration,
|
||||
@Nullable List<String> dataSourceIds
|
||||
) throws DBException {
|
||||
super.createProjectDataSources(projectId, configuration, dataSourceIds);
|
||||
if (credentialsProvider.getActiveUserCredentials() != null && dataSourceIds != null) {
|
||||
ServletAppUtils.getServletApplication().getEventController().addEvent(
|
||||
WSDataSourceEvent.create(
|
||||
credentialsProvider.getActiveUserCredentials().getSmSessionId(),
|
||||
credentialsProvider.getActiveUserCredentials().getUserId(),
|
||||
projectId,
|
||||
dataSourceIds,
|
||||
WSDataSourceProperty.CONFIGURATION
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean updateProjectDataSources(
|
||||
@NotNull String projectId,
|
||||
@NotNull String configuration,
|
||||
@Nullable List<String> dataSourceIds
|
||||
) throws DBException {
|
||||
DBPDataSourceRegistry registry = getWebProject(projectId, false).getDataSourceRegistry();
|
||||
Map<String, DataSourceDescriptor> oldDataSources = registry.getDataSources().stream()
|
||||
.filter(ds -> dataSourceIds == null || dataSourceIds.contains(ds.getId()))
|
||||
.collect(Collectors.toMap(
|
||||
DBPDataSourceContainer::getId,
|
||||
registry::createDataSource
|
||||
)
|
||||
);
|
||||
DataSourceParseResults parseResults = super.updateProjectDataSourcesConfig(projectId, configuration, dataSourceIds);
|
||||
sendDataSourcesConfigUpdatedEvent(registry, oldDataSources, parseResults);
|
||||
return parseResults != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteProjectDataSources(@NotNull String projectId, @NotNull String[] dataSourceIds) throws DBException {
|
||||
super.deleteProjectDataSources(projectId, dataSourceIds);
|
||||
if (credentialsProvider.getActiveUserCredentials() != null && dataSourceIds.length > 0) {
|
||||
ServletAppUtils.getServletApplication().getEventController().addEvent(
|
||||
WSDataSourceEvent.delete(
|
||||
credentialsProvider.getActiveUserCredentials().getSmSessionId(),
|
||||
credentialsProvider.getActiveUserCredentials().getUserId(),
|
||||
projectId,
|
||||
Arrays.asList(dataSourceIds),
|
||||
WSDataSourceProperty.CONFIGURATION
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void createProjectDataSourceFolder(@NotNull String projectId, @NotNull String folderPath) throws DBException {
|
||||
super.createProjectDataSourceFolder(projectId, folderPath);
|
||||
if (credentialsProvider.getActiveUserCredentials() != null) {
|
||||
ServletAppUtils.getServletApplication().getEventController().addEvent(
|
||||
WSDatasourceFolderEvent.create(
|
||||
credentialsProvider.getActiveUserCredentials().getSmSessionId(),
|
||||
credentialsProvider.getActiveUserCredentials().getUserId(),
|
||||
projectId,
|
||||
List.of(createNodePathFromFolderPath(projectId, folderPath))
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void moveProjectDataSourceFolder(
|
||||
@NotNull String projectId,
|
||||
@NotNull String oldPath,
|
||||
@NotNull String newPath
|
||||
) throws DBException {
|
||||
super.moveProjectDataSourceFolder(projectId, oldPath, newPath);
|
||||
if (credentialsProvider.getActiveUserCredentials() != null) {
|
||||
ServletAppUtils.getServletApplication().getEventController().addEvent(
|
||||
WSDatasourceFolderEvent.delete(
|
||||
credentialsProvider.getActiveUserCredentials().getSmSessionId(),
|
||||
credentialsProvider.getActiveUserCredentials().getUserId(),
|
||||
projectId,
|
||||
List.of(createNodePathFromFolderPath(projectId, oldPath))
|
||||
)
|
||||
);
|
||||
ServletAppUtils.getServletApplication().getEventController().addEvent(
|
||||
WSDatasourceFolderEvent.create(
|
||||
credentialsProvider.getActiveUserCredentials().getSmSessionId(),
|
||||
credentialsProvider.getActiveUserCredentials().getUserId(),
|
||||
projectId,
|
||||
List.of(createNodePathFromFolderPath(projectId, newPath))
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deleteProjectDataSourceFolders(@NotNull String projectId, @NotNull String[] folderPaths, boolean dropContents)
|
||||
throws DBException {
|
||||
super.deleteProjectDataSourceFolders(projectId, folderPaths, dropContents);
|
||||
if (credentialsProvider.getActiveUserCredentials() != null) {
|
||||
ServletAppUtils.getServletApplication().getEventController().addEvent(
|
||||
WSDatasourceFolderEvent.create(
|
||||
credentialsProvider.getActiveUserCredentials().getSmSessionId(),
|
||||
credentialsProvider.getActiveUserCredentials().getUserId(),
|
||||
projectId,
|
||||
Arrays.stream(folderPaths).map(
|
||||
p -> createNodePathFromFolderPath(projectId, p)
|
||||
).collect(Collectors.toList())
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private String createNodePathFromFolderPath(String projectId, String folderPath) {
|
||||
return DBNLocalFolder.makeLocalFolderItemPath(projectId, folderPath);
|
||||
}
|
||||
|
||||
private void sendDataSourcesConfigUpdatedEvent(
|
||||
@NotNull DBPDataSourceRegistry registry,
|
||||
@NotNull Map<String, DataSourceDescriptor> oldDataSources,
|
||||
@Nullable DataSourceParseResults parseResults
|
||||
) {
|
||||
if (parseResults == null || credentialsProvider.getActiveUserCredentials() == null || oldDataSources.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
List<String> updatedConfigurationDataSourceIds = new ArrayList<>();
|
||||
List<String> updatedNameDataSourceIds = new ArrayList<>();
|
||||
List<String> updatedInternalConfigurationDataSourceIds = new ArrayList<>();
|
||||
|
||||
for (Map.Entry<String, DataSourceDescriptor> entry : oldDataSources.entrySet()) {
|
||||
String dsId = entry.getKey();
|
||||
DataSourceDescriptor oldDs = entry.getValue();
|
||||
DataSourceDescriptor newDs = (DataSourceDescriptor) registry.getDataSource(dsId);
|
||||
if (newDs == null) {
|
||||
continue;
|
||||
}
|
||||
if (!oldDs.equalConfiguration(newDs)) {
|
||||
updatedConfigurationDataSourceIds.add(dsId);
|
||||
} else if (!oldDs.isLooselyEqualTo(newDs)) {
|
||||
updatedNameDataSourceIds.add(dsId);
|
||||
} else if (!oldDs.equalInternalConfiguration(newDs)) {
|
||||
updatedInternalConfigurationDataSourceIds.add(dsId);
|
||||
}
|
||||
}
|
||||
|
||||
if (!updatedConfigurationDataSourceIds.isEmpty()) {
|
||||
ServletAppUtils.getServletApplication().getEventController().addEvent(
|
||||
WSDataSourceEvent.update(
|
||||
credentialsProvider.getActiveUserCredentials().getSmSessionId(),
|
||||
credentialsProvider.getActiveUserCredentials().getUserId(),
|
||||
registry.getProject().getId(),
|
||||
updatedConfigurationDataSourceIds,
|
||||
WSDataSourceProperty.CONFIGURATION
|
||||
)
|
||||
);
|
||||
}
|
||||
if (!updatedNameDataSourceIds.isEmpty()) {
|
||||
ServletAppUtils.getServletApplication().getEventController().addEvent(
|
||||
WSDataSourceEvent.update(
|
||||
credentialsProvider.getActiveUserCredentials().getSmSessionId(),
|
||||
credentialsProvider.getActiveUserCredentials().getUserId(),
|
||||
registry.getProject().getId(),
|
||||
updatedNameDataSourceIds,
|
||||
WSDataSourceProperty.NAME
|
||||
)
|
||||
);
|
||||
}
|
||||
if (!updatedInternalConfigurationDataSourceIds.isEmpty()) {
|
||||
ServletAppUtils.getServletApplication().getEventController().addEvent(
|
||||
WSDataSourceEvent.update(
|
||||
credentialsProvider.getActiveUserCredentials().getSmSessionId(),
|
||||
credentialsProvider.getActiveUserCredentials().getUserId(),
|
||||
registry.getProject().getId(),
|
||||
updatedInternalConfigurationDataSourceIds,
|
||||
WSDataSourceProperty.INTERNAL
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (!parseResults.addedDataSources.isEmpty()) {
|
||||
ServletAppUtils.getServletApplication().getEventController().addEvent(
|
||||
WSDataSourceEvent.create(
|
||||
credentialsProvider.getActiveUserCredentials().getSmSessionId(),
|
||||
credentialsProvider.getActiveUserCredentials().getUserId(),
|
||||
registry.getProject().getId(),
|
||||
updatedNameDataSourceIds,
|
||||
WSDataSourceProperty.CONFIGURATION
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (!parseResults.removedDataSources.isEmpty()) {
|
||||
ServletAppUtils.getServletApplication().getEventController().addEvent(
|
||||
WSDataSourceEvent.delete(
|
||||
credentialsProvider.getActiveUserCredentials().getSmSessionId(),
|
||||
credentialsProvider.getActiveUserCredentials().getUserId(),
|
||||
registry.getProject().getId(),
|
||||
updatedNameDataSourceIds,
|
||||
WSDataSourceProperty.CONFIGURATION
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (!parseResults.addedFolders.isEmpty()) {
|
||||
ServletAppUtils.getServletApplication().getEventController().addEvent(
|
||||
WSDatasourceFolderEvent.create(
|
||||
credentialsProvider.getActiveUserCredentials().getSmSessionId(),
|
||||
credentialsProvider.getActiveUserCredentials().getUserId(),
|
||||
registry.getProject().getId(),
|
||||
parseResults.addedFolders.stream().map(
|
||||
f -> createNodePathFromFolderPath(registry.getProject().getId(), f.getFolderPath())
|
||||
).toList()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
if (!parseResults.removedFolders.isEmpty()) {
|
||||
ServletAppUtils.getServletApplication().getEventController().addEvent(
|
||||
WSDatasourceFolderEvent.delete(
|
||||
credentialsProvider.getActiveUserCredentials().getSmSessionId(),
|
||||
credentialsProvider.getActiveUserCredentials().getUserId(),
|
||||
registry.getProject().getId(),
|
||||
parseResults.removedFolders.stream().map(
|
||||
f -> createNodePathFromFolderPath(registry.getProject().getId(), f.getFolderPath())
|
||||
).toList()
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public RMResource[] listResources(
|
||||
|
||||
-6
@@ -21,7 +21,6 @@ import io.cloudbeaver.model.WebConnectionFolderInfo;
|
||||
import io.cloudbeaver.model.session.WebSession;
|
||||
import org.jkiss.code.Nullable;
|
||||
import org.jkiss.dbeaver.model.DBPDataSourceFolder;
|
||||
import org.jkiss.dbeaver.model.app.DBPDataSourceRegistry;
|
||||
import org.jkiss.utils.CommonUtils;
|
||||
|
||||
public class WebConnectionFolderUtils {
|
||||
@@ -45,9 +44,4 @@ public class WebConnectionFolderUtils {
|
||||
throw new DBWebException("Folder name '" + folderName + "' contains illegal characters: /");
|
||||
}
|
||||
}
|
||||
|
||||
public static DBPDataSourceFolder createFolder(WebConnectionFolderInfo parentFolder, String newName, DBPDataSourceRegistry registry) throws DBWebException {
|
||||
DBPDataSourceFolder folder = registry.addFolder(parentFolder == null ? null : parentFolder.getDataSourceFolder(), newName);
|
||||
return folder;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -318,9 +318,11 @@ public class WebServiceUtils extends WebCommonUtils {
|
||||
return container.getName() + " [" + container.getId() + "]";
|
||||
}
|
||||
|
||||
public static void updateConfigAndRefreshDatabases(WebSession session, String projectId) throws DBWebException {
|
||||
public static void refreshDatabases(WebSession session, String projectId) throws DBWebException {
|
||||
DBNProject projectNode = session.getNavigatorModelOrThrow().getRoot().getProjectNode(session.getProjectById(projectId));
|
||||
DBNModel.updateConfigAndRefreshDatabases(projectNode.getDatabases());
|
||||
if (projectNode != null) {
|
||||
projectNode.getDatabases().refreshChildren();
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isGlobalProject(DBPProject project) {
|
||||
|
||||
+1
-4
@@ -39,10 +39,7 @@ public class WSDataSourceUpdatedEventHandlerImpl extends WSAbstractProjectEventH
|
||||
log.debug("Project " + event.getProjectId() + " is not found in session " + webSession.getSessionId());
|
||||
return;
|
||||
}
|
||||
sendEvent = project.updateProjectDataSources(
|
||||
event.getDataSourceIds(),
|
||||
event.getId()
|
||||
);
|
||||
sendEvent = project.updateProjectDataSources(event);
|
||||
}
|
||||
if (sendEvent) {
|
||||
activeUserSession.addSessionEvent(event);
|
||||
|
||||
-47
@@ -24,7 +24,6 @@ import io.cloudbeaver.model.WebPropertyInfo;
|
||||
import io.cloudbeaver.model.session.WebSession;
|
||||
import io.cloudbeaver.utils.ServletAppUtils;
|
||||
import io.cloudbeaver.utils.WebDataSourceUtils;
|
||||
import io.cloudbeaver.utils.WebEventUtils;
|
||||
import org.jkiss.code.NotNull;
|
||||
import org.jkiss.code.Nullable;
|
||||
import org.jkiss.dbeaver.DBException;
|
||||
@@ -38,8 +37,6 @@ 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.model.websocket.WSConstants;
|
||||
import org.jkiss.dbeaver.model.websocket.event.datasource.WSDataSourceProperty;
|
||||
import org.jkiss.dbeaver.registry.DataSourceDescriptor;
|
||||
import org.jkiss.dbeaver.runtime.DBWorkbench;
|
||||
import org.jkiss.dbeaver.runtime.jobs.ConnectionTestJob;
|
||||
@@ -100,13 +97,6 @@ public class ConnectionControllerCE implements ConnectionController {
|
||||
WebConnectionInfo connectionInfo = project.addConnection(newDataSource);
|
||||
webSession.addInfoMessage("New connection was created - " + WebServiceUtils.getConnectionContainerInfo(
|
||||
newDataSource));
|
||||
WebEventUtils.addDataSourceUpdatedEvent(
|
||||
webSession.getProjectById(projectId),
|
||||
webSession,
|
||||
connectionInfo.getId(),
|
||||
WSConstants.EventAction.CREATE,
|
||||
WSDataSourceProperty.CONFIGURATION
|
||||
);
|
||||
log.info(String.format(
|
||||
"New connection was created: [info=%s, user=%s]",
|
||||
WebServiceUtils.getConnectionContainerInfo(newDataSource),
|
||||
@@ -190,7 +180,6 @@ public class ConnectionControllerCE implements ConnectionController {
|
||||
DBPDataSourceRegistry sessionRegistry
|
||||
) throws DBWebException {
|
||||
WebConnectionInfo connectionInfo = WebDataSourceUtils.getWebConnectionInfo(webSession, projectId, config.getConnectionId());
|
||||
boolean sendEvent = !((DataSourceDescriptor) dataSource).equalSettings(getOldDataSource(dataSource));
|
||||
if (!isSharedCredentials(dataSource)) {
|
||||
// secret controller is responsible for notification, password changes applied after checks
|
||||
WebServiceUtils.saveAuthProperties(
|
||||
@@ -201,24 +190,12 @@ public class ConnectionControllerCE implements ConnectionController {
|
||||
config.isSharedCredentials()
|
||||
);
|
||||
}
|
||||
|
||||
WSDataSourceProperty property = getDatasourceEventProperty(getOldDataSource(dataSource), dataSource);
|
||||
|
||||
try {
|
||||
sessionRegistry.updateDataSource(dataSource);
|
||||
sessionRegistry.checkForErrors();
|
||||
} catch (DBException e) {
|
||||
throw new DBWebException("Failed to update connection", e);
|
||||
}
|
||||
if (sendEvent) {
|
||||
WebEventUtils.addDataSourceUpdatedEvent(
|
||||
webSession.getProjectById(projectId),
|
||||
webSession,
|
||||
connectionInfo.getId(),
|
||||
WSConstants.EventAction.UPDATE,
|
||||
property
|
||||
);
|
||||
}
|
||||
log.info(String.format(
|
||||
"Connection updated: [info=%s, userId=%s]",
|
||||
WebServiceUtils.getConnectionContainerInfo(dataSource),
|
||||
@@ -238,13 +215,6 @@ public class ConnectionControllerCE implements ConnectionController {
|
||||
webSession.addInfoMessage("Delete connection - " +
|
||||
WebServiceUtils.getConnectionContainerInfo(connectionInfo.getDataSourceContainer()));
|
||||
closeAndDeleteConnection(webSession, projectId, connectionId, true);
|
||||
WebEventUtils.addDataSourceUpdatedEvent(
|
||||
webSession.getProjectById(projectId),
|
||||
webSession,
|
||||
connectionId,
|
||||
WSConstants.EventAction.DELETE,
|
||||
WSDataSourceProperty.CONFIGURATION
|
||||
);
|
||||
|
||||
log.info(String.format(
|
||||
"Connection deleted: [info=%s, userId=%s]",
|
||||
@@ -361,23 +331,6 @@ public class ConnectionControllerCE implements ConnectionController {
|
||||
return project;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private WebConnectionInfo closeAndDeleteConnection(
|
||||
@NotNull WebSession webSession,
|
||||
|
||||
+21
-71
@@ -27,7 +27,10 @@ import io.cloudbeaver.server.WebAppUtils;
|
||||
import io.cloudbeaver.server.WebApplication;
|
||||
import io.cloudbeaver.service.core.DBWServiceCore;
|
||||
import io.cloudbeaver.service.security.SMUtils;
|
||||
import io.cloudbeaver.utils.*;
|
||||
import io.cloudbeaver.utils.ServletAppUtils;
|
||||
import io.cloudbeaver.utils.WebCommonUtils;
|
||||
import io.cloudbeaver.utils.WebConnectionFolderUtils;
|
||||
import io.cloudbeaver.utils.WebDataSourceUtils;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import org.jkiss.code.NotNull;
|
||||
@@ -41,14 +44,16 @@ 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.navigator.*;
|
||||
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.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.WSConstants;
|
||||
import org.jkiss.dbeaver.model.websocket.event.datasource.WSDataSourceProperty;
|
||||
import org.jkiss.dbeaver.registry.DataSourceDescriptor;
|
||||
import org.jkiss.dbeaver.registry.DataSourceProviderRegistry;
|
||||
@@ -56,7 +61,6 @@ 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.utils.CommonUtils;
|
||||
|
||||
import java.util.*;
|
||||
@@ -393,15 +397,7 @@ public class WebServiceCore implements DBWServiceCore {
|
||||
dataSourceRegistry.addDataSource(newDataSource);
|
||||
|
||||
dataSourceRegistry.checkForErrors();
|
||||
WebConnectionInfo connectionInfo = project.addConnection(newDataSource);
|
||||
WebEventUtils.addDataSourceUpdatedEvent(
|
||||
webSession.getProjectById(projectId),
|
||||
webSession,
|
||||
connectionInfo.getId(),
|
||||
WSConstants.EventAction.CREATE,
|
||||
WSDataSourceProperty.CONFIGURATION
|
||||
);
|
||||
return connectionInfo;
|
||||
return project.addConnection(newDataSource);
|
||||
} catch (DBException e) {
|
||||
throw new DBWebException("Error copying connection", e);
|
||||
}
|
||||
@@ -536,25 +532,18 @@ public class WebServiceCore implements DBWServiceCore {
|
||||
) throws DBWebException {
|
||||
WebConnectionFolderUtils.validateConnectionFolder(folderName);
|
||||
session.addInfoMessage("Create new folder");
|
||||
WebConnectionFolderInfo parentNode = null;
|
||||
WebConnectionFolderInfo parentFolder = null;
|
||||
try {
|
||||
if (parentPath != null) {
|
||||
parentNode = WebConnectionFolderUtils.getFolderInfo(session, projectId, parentPath);
|
||||
parentFolder = WebConnectionFolderUtils.getFolderInfo(session, projectId, parentPath);
|
||||
}
|
||||
WebProjectImpl project = getProjectById(session, projectId);
|
||||
DBPDataSourceRegistry sessionRegistry = project.getDataSourceRegistry();
|
||||
DBPDataSourceFolder newFolder = WebConnectionFolderUtils.createFolder(parentNode,
|
||||
folderName,
|
||||
sessionRegistry);
|
||||
WebConnectionFolderInfo folderInfo = new WebConnectionFolderInfo(session, newFolder);
|
||||
WebServiceUtils.updateConfigAndRefreshDatabases(session, projectId);
|
||||
WebEventUtils.addNavigatorNodeUpdatedEvent(
|
||||
session.getProjectById(projectId),
|
||||
session,
|
||||
DBNLocalFolder.makeLocalFolderItemPath(newFolder),
|
||||
WSConstants.EventAction.CREATE
|
||||
DBPDataSourceRegistry registry = project.getDataSourceRegistry();
|
||||
DBPDataSourceFolder newFolder = registry.addFolder(
|
||||
parentFolder == null ? null : parentFolder.getDataSourceFolder(), folderName
|
||||
);
|
||||
return folderInfo;
|
||||
WebServiceUtils.refreshDatabases(session, projectId);
|
||||
return new WebConnectionFolderInfo(session, newFolder);
|
||||
} catch (DBException e) {
|
||||
throw new DBWebException(e.getMessage(), e);
|
||||
}
|
||||
@@ -565,26 +554,12 @@ public class WebServiceCore implements DBWServiceCore {
|
||||
@NotNull WebSession session,
|
||||
@Nullable String projectId,
|
||||
@NotNull String folderPath,
|
||||
@NotNull String newName
|
||||
@NotNull String newPath
|
||||
) throws DBWebException {
|
||||
WebConnectionFolderUtils.validateConnectionFolder(newName);
|
||||
WebConnectionFolderUtils.validateConnectionFolder(newPath);
|
||||
WebConnectionFolderInfo folderInfo = WebConnectionFolderUtils.getFolderInfo(session, projectId, folderPath);
|
||||
var oldFolderNode = DBNLocalFolder.makeLocalFolderItemPath(folderInfo.getDataSourceFolder());
|
||||
folderInfo.getDataSourceFolder().setName(newName);
|
||||
var newFolderNode = DBNLocalFolder.makeLocalFolderItemPath(folderInfo.getDataSourceFolder());
|
||||
WebServiceUtils.updateConfigAndRefreshDatabases(session, projectId);
|
||||
WebEventUtils.addNavigatorNodeUpdatedEvent(
|
||||
session.getProjectById(projectId),
|
||||
session,
|
||||
oldFolderNode,
|
||||
WSConstants.EventAction.DELETE
|
||||
);
|
||||
WebEventUtils.addNavigatorNodeUpdatedEvent(
|
||||
session.getProjectById(projectId),
|
||||
session,
|
||||
newFolderNode,
|
||||
WSConstants.EventAction.CREATE
|
||||
);
|
||||
folderInfo.getDataSourceFolder().setName(newPath);
|
||||
WebServiceUtils.refreshDatabases(session, projectId);
|
||||
return folderInfo;
|
||||
}
|
||||
|
||||
@@ -599,17 +574,10 @@ public class WebServiceCore implements DBWServiceCore {
|
||||
if (folder.getDataSourceRegistry().getProject() != project) {
|
||||
throw new DBWebException("Global folder '" + folderInfo.getId() + "' cannot be deleted");
|
||||
}
|
||||
var folderNode = DBNLocalFolder.makeLocalFolderItemPath(folderInfo.getDataSourceFolder());
|
||||
session.addInfoMessage("Delete folder");
|
||||
DBPDataSourceRegistry sessionRegistry = project.getDataSourceRegistry();
|
||||
sessionRegistry.removeFolder(folderInfo.getDataSourceFolder(), false);
|
||||
WebServiceUtils.updateConfigAndRefreshDatabases(session, projectId);
|
||||
WebEventUtils.addNavigatorNodeUpdatedEvent(
|
||||
session.getProjectById(projectId),
|
||||
session,
|
||||
folderNode,
|
||||
WSConstants.EventAction.DELETE
|
||||
);
|
||||
WebServiceUtils.refreshDatabases(session, projectId);
|
||||
} catch (DBException e) {
|
||||
throw new DBWebException(e.getMessage(), e);
|
||||
}
|
||||
@@ -624,12 +592,6 @@ public class WebServiceCore implements DBWServiceCore {
|
||||
DataSourceDescriptor dataSourceDescriptor = ((DataSourceDescriptor) connectionInfo.getDataSourceContainer());
|
||||
dataSourceDescriptor.setNavigatorSettings(settings);
|
||||
dataSourceDescriptor.persistConfiguration();
|
||||
WebEventUtils.addDataSourceUpdatedEvent(
|
||||
webSession.getProjectById(projectId),
|
||||
webSession,
|
||||
id,
|
||||
WSConstants.EventAction.UPDATE,
|
||||
WSDataSourceProperty.CONFIGURATION);
|
||||
return connectionInfo;
|
||||
}
|
||||
|
||||
@@ -656,16 +618,4 @@ public class WebServiceCore implements DBWServiceCore {
|
||||
}
|
||||
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()));
|
||||
}
|
||||
}
|
||||
|
||||
+3
-40
@@ -55,7 +55,6 @@ import org.jkiss.dbeaver.model.struct.DBSObjectFilter;
|
||||
import org.jkiss.dbeaver.model.struct.rdb.DBSCatalog;
|
||||
import org.jkiss.dbeaver.model.struct.rdb.DBSSchema;
|
||||
import org.jkiss.dbeaver.model.websocket.WSConstants;
|
||||
import org.jkiss.dbeaver.model.websocket.event.datasource.WSDataSourceProperty;
|
||||
import org.jkiss.dbeaver.model.websocket.event.resource.WSResourceProperty;
|
||||
import org.jkiss.dbeaver.runtime.DBWorkbench;
|
||||
import org.jkiss.utils.CommonUtils;
|
||||
@@ -461,28 +460,10 @@ public class WebServiceNavigator implements DBWServiceNavigator {
|
||||
if (siblings.contains(newName)) {
|
||||
throw new DBWebException("Name " + newName + " is unavailable or invalid");
|
||||
}
|
||||
var oldNodePath = node.getNodeItemPath();
|
||||
node.rename(session.getProgressMonitor(), newName);
|
||||
var newNodePath = node.getNodeItemPath();
|
||||
addNavigatorNodeMoveEvent(session, node, oldNodePath, newNodePath);
|
||||
return node.getName();
|
||||
}
|
||||
|
||||
private void addNavigatorNodeMoveEvent(@NotNull WebSession session, DBNNode node, String oldNodePath, String newNodePath) {
|
||||
WebEventUtils.addNavigatorNodeUpdatedEvent(
|
||||
node.getOwnerProject(),
|
||||
session,
|
||||
oldNodePath,
|
||||
WSConstants.EventAction.DELETE
|
||||
);
|
||||
WebEventUtils.addNavigatorNodeUpdatedEvent(
|
||||
node.getOwnerProject(),
|
||||
session,
|
||||
newNodePath,
|
||||
WSConstants.EventAction.CREATE
|
||||
);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private String renameRmResourceNode(@NotNull WebSession session, DBNNode node, @NotNull String newName) throws DBException {
|
||||
if (newName.contains("/") || newName.contains("\\")) {
|
||||
@@ -570,14 +551,7 @@ public class WebServiceNavigator implements DBWServiceNavigator {
|
||||
throw e;
|
||||
}
|
||||
} else if (node instanceof DBNLocalFolder) {
|
||||
var nodePath = node.getNodeItemPath();
|
||||
node.getOwnerProject().getDataSourceRegistry().removeFolder(((DBNLocalFolder) node).getFolder(), false);
|
||||
WebEventUtils.addNavigatorNodeUpdatedEvent(
|
||||
session.getProjectById(projectId),
|
||||
session,
|
||||
nodePath,
|
||||
WSConstants.EventAction.DELETE
|
||||
);
|
||||
} else if (node instanceof DBNResourceManagerResource) {
|
||||
DBNResourceManagerResource rmResource = ((DBNResourceManagerResource) node);
|
||||
String resourceProjectId = rmResource.getResourceProject().getId();
|
||||
@@ -592,7 +566,7 @@ public class WebServiceNavigator implements DBWServiceNavigator {
|
||||
}
|
||||
}
|
||||
if (containsFolderNodes) {
|
||||
WebServiceUtils.updateConfigAndRefreshDatabases(session, projectId);
|
||||
WebServiceUtils.refreshDatabases(session, projectId);
|
||||
}
|
||||
return nodes.size();
|
||||
|
||||
@@ -645,15 +619,7 @@ public class WebServiceNavigator implements DBWServiceNavigator {
|
||||
folder = localFolderNode.getFolder();
|
||||
}
|
||||
dataSourceNode.moveToFolder(folderNode.getOwnerProject(), folder);
|
||||
node.getOwnerProject().getDataSourceRegistry().updateDataSource(
|
||||
dataSourceNode.getDataSourceContainer());
|
||||
WebEventUtils.addDataSourceUpdatedEvent(
|
||||
node.getOwnerProject(),
|
||||
session,
|
||||
dataSourceNode.getDataSourceContainer().getId(),
|
||||
WSConstants.EventAction.UPDATE,
|
||||
WSDataSourceProperty.CONFIGURATION
|
||||
);
|
||||
node.getOwnerProject().getDataSourceRegistry().updateDataSource(dataSourceNode.getDataSourceContainer());
|
||||
} else if (node instanceof DBNLocalFolder dbnLocalFolder) {
|
||||
DBPDataSourceFolder parentFolder = null;
|
||||
if (folderNode instanceof DBNLocalFolder parentFolderNode) {
|
||||
@@ -667,15 +633,12 @@ public class WebServiceNavigator implements DBWServiceNavigator {
|
||||
throw new DBWebException("Node " + folderNodePath + " contains folder with name '" + node.getName() + "'");
|
||||
}
|
||||
}
|
||||
var oldNodePath = node.getNodeItemPath();
|
||||
node.getOwnerProject().getDataSourceRegistry().moveFolder(
|
||||
dbnLocalFolder.getFolder().getFolderPath(),
|
||||
dbnLocalFolder.generateNewFolderPath(parentFolder, dbnLocalFolder.getNodeDisplayName())
|
||||
);
|
||||
node.getOwnerProject().getDataSourceRegistry().checkForErrors();
|
||||
var newNodePath = node.getNodeItemPath();
|
||||
WebServiceUtils.updateConfigAndRefreshDatabases(session, node.getOwnerProject().getId());
|
||||
addNavigatorNodeMoveEvent(session, node, oldNodePath, newNodePath);
|
||||
WebServiceUtils.refreshDatabases(session, node.getOwnerProject().getId());
|
||||
} else if (node instanceof DBNResourceManagerResource) {
|
||||
boolean rmNewNode = folderNode instanceof DBNAbstractResourceManagerNode;
|
||||
DBNResourceManagerResource rmOldNode = (DBNResourceManagerResource) node;
|
||||
|
||||
Reference in New Issue
Block a user