From b25e2de939fb19c0f1d20bdf5598166acb2615ec Mon Sep 17 00:00:00 2001 From: Ainur Date: Tue, 18 Oct 2022 12:08:22 +0200 Subject: [PATCH 01/14] CB-2186 datasource updated events --- .../cloudbeaver/events/CBEventConstants.java | 1 + .../bundles/io.cloudbeaver.server/plugin.xml | 1 + .../src/io/cloudbeaver/WebServiceUtils.java | 9 +++ .../io/cloudbeaver/server/CBApplication.java | 4 ++ .../events/CBProjectUpdatedEventHandler.java | 60 +++++++++++++++++++ .../service/core/impl/WebServiceCore.java | 12 +++- .../navigator/impl/WebServiceNavigator.java | 16 +++++ 7 files changed, 100 insertions(+), 3 deletions(-) create mode 100644 server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/events/CBProjectUpdatedEventHandler.java diff --git a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/events/CBEventConstants.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/events/CBEventConstants.java index 35aabe6f19..c0443ff844 100644 --- a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/events/CBEventConstants.java +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/events/CBEventConstants.java @@ -21,4 +21,5 @@ package io.cloudbeaver.events; */ public interface CBEventConstants { String CLOUDBEAVER_CONFIG_CHANGED = "cb_config_changed"; + String CLOUDBEAVER_PROJECT_UPDATED = "cb_project_updated"; } diff --git a/server/bundles/io.cloudbeaver.server/plugin.xml b/server/bundles/io.cloudbeaver.server/plugin.xml index 48e94d9dbf..d16d6382c0 100644 --- a/server/bundles/io.cloudbeaver.server/plugin.xml +++ b/server/bundles/io.cloudbeaver.server/plugin.xml @@ -50,6 +50,7 @@ + diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/WebServiceUtils.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/WebServiceUtils.java index 4145216faf..d8f3c6e815 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/WebServiceUtils.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/WebServiceUtils.java @@ -19,6 +19,8 @@ package io.cloudbeaver; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.InstanceCreator; +import io.cloudbeaver.events.CBEvent; +import io.cloudbeaver.events.CBEventConstants; import io.cloudbeaver.model.WebConnectionConfig; import io.cloudbeaver.model.WebConnectionFolderInfo; import io.cloudbeaver.model.WebNetworkHandlerConfigInput; @@ -58,6 +60,7 @@ import org.jkiss.utils.CommonUtils; import java.io.InputStream; import java.util.HashMap; import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; /** @@ -339,5 +342,11 @@ public class WebServiceUtils extends WebCommonUtils { return project.getId().equals(RMProjectType.GLOBAL.getPrefix() + "_" + CBApplication.getInstance().getDefaultProjectName()); } + public static void addProjectUpdatedEvent(List projectIds) { + CBApplication.getInstance().getEventController().addEvent( + new CBEvent(CBEventConstants.CLOUDBEAVER_PROJECT_UPDATED, Map.of("projects", projectIds)) + ); + } + } diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/CBApplication.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/CBApplication.java index 7d4ff0593d..2b0473ca43 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/CBApplication.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/CBApplication.java @@ -1007,4 +1007,8 @@ public class CBApplication extends BaseWebApplication implements WebAuthApplicat public WebDriverRegistry getDriverRegistry() { return WebDriverRegistry.getInstance(); } + + public CBEventController getEventController() { + return eventController; + } } diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/events/CBProjectUpdatedEventHandler.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/events/CBProjectUpdatedEventHandler.java new file mode 100644 index 0000000000..01d43eaf29 --- /dev/null +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/events/CBProjectUpdatedEventHandler.java @@ -0,0 +1,60 @@ +/* + * DBeaver - Universal Database Manager + * Copyright (C) 2010-2022 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.server.events; + +import io.cloudbeaver.events.CBEvent; +import io.cloudbeaver.events.CBEventConstants; +import io.cloudbeaver.events.CBEventHandler; +import io.cloudbeaver.model.session.WebSession; +import io.cloudbeaver.server.CBPlatform; +import org.jkiss.code.NotNull; +import org.jkiss.dbeaver.Log; +import org.jkiss.dbeaver.model.app.DBPProject; +import org.jkiss.dbeaver.model.data.json.JSONUtils; + +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +/** + * Notify all active user session that project has been updated + */ +public class CBProjectUpdatedEventHandler implements CBEventHandler { + private static final Log log = Log.getLog(CBProjectUpdatedEventHandler.class); + + @NotNull + @Override + public String getSupportedEventType() { + return CBEventConstants.CLOUDBEAVER_PROJECT_UPDATED; + } + + @Override + public void handleEvent(@NotNull CBEvent event) { + log.debug(getSupportedEventType() + " event handled"); + Collection allSessions = CBPlatform.getInstance().getSessionManager().getAllActiveSessions(); + List projects = JSONUtils.getStringList(event.getEventData(), "projects"); + for (WebSession activeUserSession : allSessions) { + List availableProjectIds = activeUserSession.getAccessibleProjects().stream() + .map(DBPProject::getId).collect(Collectors.toList()); + if (Collections.disjoint(availableProjectIds, projects)) { + continue; + } + activeUserSession.refreshUserData(); + } + } +} diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/core/impl/WebServiceCore.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/core/impl/WebServiceCore.java index 7889510c17..5293041b3f 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/core/impl/WebServiceCore.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/core/impl/WebServiceCore.java @@ -21,6 +21,7 @@ import io.cloudbeaver.DBWConstants; import io.cloudbeaver.DBWebException; import io.cloudbeaver.WebServiceUtils; import io.cloudbeaver.events.CBEvent; +import io.cloudbeaver.events.CBEventConstants; import io.cloudbeaver.model.*; import io.cloudbeaver.model.session.WebSession; import io.cloudbeaver.registry.WebHandlerRegistry; @@ -52,7 +53,6 @@ import org.jkiss.dbeaver.model.net.DBWTunnel; import org.jkiss.dbeaver.model.net.ssh.SSHImplementation; import org.jkiss.dbeaver.model.rm.RMProjectType; import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor; -import org.jkiss.dbeaver.registry.BaseProjectImpl; import org.jkiss.dbeaver.registry.DataSourceDescriptor; import org.jkiss.dbeaver.registry.DataSourceProviderRegistry; import org.jkiss.dbeaver.registry.network.NetworkHandlerDescriptor; @@ -402,6 +402,7 @@ public class WebServiceCore implements DBWServiceCore { WebConnectionInfo connectionInfo = new WebConnectionInfo(webSession, newDataSource); webSession.addConnection(connectionInfo); webSession.addInfoMessage("New connection was created - " + WebServiceUtils.getConnectionContainerInfo(newDataSource)); + WebServiceUtils.addProjectUpdatedEvent(List.of(projectId)); return connectionInfo; } @@ -439,7 +440,7 @@ public class WebServiceCore implements DBWServiceCore { } catch (DBException e) { throw new DBWebException("Failed to update connection", e); } - + WebServiceUtils.addProjectUpdatedEvent(List.of(projectId)); return connectionInfo; } @@ -453,6 +454,7 @@ public class WebServiceCore implements DBWServiceCore { webSession.addInfoMessage("Delete connection - " + WebServiceUtils.getConnectionContainerInfo(connectionInfo.getDataSourceContainer())); closeAndDeleteConnection(webSession, projectId, connectionId, true); + WebServiceUtils.addProjectUpdatedEvent(List.of(projectId)); return true; } @@ -529,6 +531,7 @@ public class WebServiceCore implements DBWServiceCore { WebConnectionInfo connectionInfo = new WebConnectionInfo(webSession, newDataSource); dataSourceRegistry.checkForErrors(); webSession.addConnection(connectionInfo); + WebServiceUtils.addProjectUpdatedEvent(List.of(projectId)); return connectionInfo; } catch (DBException e) { throw new DBWebException("Error copying connection", e); @@ -707,7 +710,7 @@ public class WebServiceCore implements DBWServiceCore { DBPDataSourceFolder newFolder = WebServiceUtils.createFolder(parentNode, folderName, sessionRegistry); WebConnectionFolderInfo folderInfo = new WebConnectionFolderInfo(session, newFolder); WebServiceUtils.updateConfigAndRefreshDatabases(session, projectId); - + WebServiceUtils.addProjectUpdatedEvent(List.of(projectId)); return folderInfo; } catch (DBException e) { throw new DBWebException(e.getMessage(), e); @@ -725,6 +728,7 @@ public class WebServiceCore implements DBWServiceCore { WebConnectionFolderInfo folderInfo = WebConnectionFolderUtils.getFolderInfo(session, projectId, folderPath); folderInfo.getDataSourceFolder().setName(newName); WebServiceUtils.updateConfigAndRefreshDatabases(session, projectId); + WebServiceUtils.addProjectUpdatedEvent(List.of(projectId)); return folderInfo; } @@ -742,6 +746,7 @@ public class WebServiceCore implements DBWServiceCore { DBPDataSourceRegistry sessionRegistry = session.getProjectById(projectId).getDataSourceRegistry(); sessionRegistry.removeFolder(folderInfo.getDataSourceFolder(), false); WebServiceUtils.updateConfigAndRefreshDatabases(session, projectId); + WebServiceUtils.addProjectUpdatedEvent(List.of(projectId)); } catch (DBException e) { throw new DBWebException(e.getMessage(), e); } @@ -756,6 +761,7 @@ public class WebServiceCore implements DBWServiceCore { DataSourceDescriptor dataSourceDescriptor = ((DataSourceDescriptor)connectionInfo.getDataSourceContainer()); dataSourceDescriptor.setNavigatorSettings(settings); dataSourceDescriptor.persistConfiguration(); + WebServiceUtils.addProjectUpdatedEvent(List.of(projectId)); return connectionInfo; } diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/navigator/impl/WebServiceNavigator.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/navigator/impl/WebServiceNavigator.java index 93d6198b9c..dc1f1f097f 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/navigator/impl/WebServiceNavigator.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/navigator/impl/WebServiceNavigator.java @@ -341,6 +341,8 @@ public class WebServiceNavigator implements DBWServiceNavigator { if (node == null) { throw new DBWebException("Navigator node '" + nodePath + "' not found"); } + List projectIds = new ArrayList<>(); + addProjectIdForEvent(projectIds, node); checkProjectEditAccess(node, session); if (node.supportsRename()) { if (node instanceof DBNLocalFolder) { @@ -354,6 +356,7 @@ public class WebServiceNavigator implements DBWServiceNavigator { } } node.rename(session.getProgressMonitor(), newName); + WebServiceUtils.addProjectUpdatedEvent(projectIds); return node.getName(); } if (node instanceof DBNDatabaseNode) { @@ -378,12 +381,14 @@ public class WebServiceNavigator implements DBWServiceNavigator { String projectId = null; boolean containsFolderNodes = false; Map nodes = new LinkedHashMap<>(); + List projectIds = new ArrayList<>(); for (String path : nodePaths) { DBNNode node = session.getNavigatorModel().getNodeByPath(monitor, path); if (node == null) { throw new DBWebException("Navigator node '" + path + "' not found"); } checkProjectEditAccess(node, session); + addProjectIdForEvent(projectIds, node); if (node instanceof DBNDatabaseNode) { DBSObject object = ((DBNDatabaseNode) node).getObject(); DBEObjectMaker objectDeleter = DBWorkbench.getPlatform().getEditorsRegistry().getObjectManager( @@ -424,6 +429,7 @@ public class WebServiceNavigator implements DBWServiceNavigator { if (containsFolderNodes) { WebServiceUtils.updateConfigAndRefreshDatabases(session, projectId); } + WebServiceUtils.addProjectUpdatedEvent(projectIds); return nodes.size(); } catch (DBException e) { @@ -458,12 +464,14 @@ public class WebServiceNavigator implements DBWServiceNavigator { DBRProgressMonitor monitor = session.getProgressMonitor(); DBNNode folderNode; folderNode = session.getNavigatorModel().getNodeByPath(monitor, folderNodePath); + List projectIds = new ArrayList<>(); for (String path : nodePaths) { DBNNode node = session.getNavigatorModel().getNodeByPath(monitor, path); if (node == null) { throw new DBWebException("Navigator node '" + path + "' not found"); } checkProjectEditAccess(node, session); + addProjectIdForEvent(projectIds, node); if (node instanceof DBNDataSource) { DBPDataSourceFolder folder = WebConnectionFolderUtils.getParentFolder(folderNode); ((DBNDataSource) node).moveToFolder(folderNode.getOwnerProject(), folder); @@ -500,12 +508,20 @@ public class WebServiceNavigator implements DBWServiceNavigator { throw new DBWebException("Navigator node '" + path + "' is not a data source node"); } } + WebServiceUtils.addProjectUpdatedEvent(projectIds); return true; } catch (DBException e) { throw new DBWebException("Error moving navigator nodes " + nodePaths, e); } } + private void addProjectIdForEvent(List projectIds, DBNNode node) { + String ownerProject = node.getOwnerProject().getId(); + if (!projectIds.contains(ownerProject)) { + projectIds.add(ownerProject); // for updating project in all sessions + } + } + private String renameDatabaseObject(WebSession session, DBNDatabaseNode node, String newName) throws DBException { if (node.getParentNode() instanceof DBNContainer) { DBSObject object = node.getObject(); From 3548ac700a4bcf980955dcc3f5d08f4b7723d028 Mon Sep 17 00:00:00 2001 From: Ainur Date: Fri, 21 Oct 2022 12:52:16 +0200 Subject: [PATCH 02/14] CB-2186 datasource updated events fixes --- .../cloudbeaver/events/CBEventConstants.java | 3 +- .../cloudbeaver/model/app/WebApplication.java | 3 ++ .../rm/local/LocalResourceController.java | 4 ++ .../src/io/cloudbeaver/utils/WebAppUtils.java | 24 +++++++-- .../bundles/io.cloudbeaver.server/plugin.xml | 3 +- .../src/io/cloudbeaver/WebServiceUtils.java | 10 ---- .../io/cloudbeaver/server/CBApplication.java | 1 + .../CBDatasourceUpdatedEventHandlerImpl.java | 49 +++++++++++++++++++ .../events/CBProjectUpdatedEventHandler.java | 22 ++------- .../CBRmResourceUpdatedEventHandlerImpl.java | 45 +++++++++++++++++ .../service/core/impl/WebServiceCore.java | 20 ++++---- .../navigator/impl/WebServiceNavigator.java | 16 ------ 12 files changed, 142 insertions(+), 58 deletions(-) create mode 100644 server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/events/CBDatasourceUpdatedEventHandlerImpl.java create mode 100644 server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/events/CBRmResourceUpdatedEventHandlerImpl.java diff --git a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/events/CBEventConstants.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/events/CBEventConstants.java index c0443ff844..4f0d640631 100644 --- a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/events/CBEventConstants.java +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/events/CBEventConstants.java @@ -21,5 +21,6 @@ package io.cloudbeaver.events; */ public interface CBEventConstants { String CLOUDBEAVER_CONFIG_CHANGED = "cb_config_changed"; - String CLOUDBEAVER_PROJECT_UPDATED = "cb_project_updated"; + String CLOUDBEAVER_DATASOURCE_UPDATED = "cb_datasource_updated"; + String CLOUDBEAVER_RM_RESOURCE_UPDATED = "cb_rm_resource_deleted"; } diff --git a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/app/WebApplication.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/app/WebApplication.java index 98fd6b91b0..a4db2db804 100644 --- a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/app/WebApplication.java +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/app/WebApplication.java @@ -18,6 +18,7 @@ package io.cloudbeaver.model.app; import io.cloudbeaver.DataSourceFilter; import io.cloudbeaver.VirtualProjectImpl; +import io.cloudbeaver.events.CBEventController; import org.jkiss.code.NotNull; import org.jkiss.dbeaver.DBException; import org.jkiss.dbeaver.model.app.DBPApplication; @@ -76,6 +77,8 @@ public interface WebApplication extends DBPApplication { String getApplicationInstanceId() throws DBException; + CBEventController getEventController(); + /** * Port this server listens on */ diff --git a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/local/LocalResourceController.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/local/LocalResourceController.java index 918414cf82..30105ae5a6 100644 --- a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/local/LocalResourceController.java +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/local/LocalResourceController.java @@ -18,6 +18,7 @@ package io.cloudbeaver.model.rm.local; import io.cloudbeaver.DBWConstants; import io.cloudbeaver.VirtualProjectImpl; +import io.cloudbeaver.events.CBEventConstants; import io.cloudbeaver.model.rm.RMUtils; import io.cloudbeaver.service.security.SMUtils; import io.cloudbeaver.service.sql.WebSQLConstants; @@ -392,6 +393,7 @@ public class LocalResourceController implements RMController { } catch (IOException e) { throw new DBException("Error creating resource '" + resourcePath + "'", e); } + WebAppUtils.addRmResourceUpdatedEvent(CBEventConstants.CLOUDBEAVER_RM_RESOURCE_UPDATED, projectId, resourcePath); return DEFAULT_CHANGE_ID; } @@ -412,6 +414,7 @@ public class LocalResourceController implements RMController { } catch (IOException e) { throw new DBException("Error moving resource '" + oldResourcePath + "'", e); } + WebAppUtils.addRmResourceUpdatedEvent(CBEventConstants.CLOUDBEAVER_RM_RESOURCE_UPDATED, projectId, oldResourcePath); return DEFAULT_CHANGE_ID; } @@ -442,6 +445,7 @@ public class LocalResourceController implements RMController { rmResourcePath ) ); + WebAppUtils.addRmResourceUpdatedEvent(CBEventConstants.CLOUDBEAVER_RM_RESOURCE_UPDATED, projectId, resourcePath); } @Override diff --git a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/utils/WebAppUtils.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/utils/WebAppUtils.java index 8f1ecf3442..366e418f97 100644 --- a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/utils/WebAppUtils.java +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/utils/WebAppUtils.java @@ -17,6 +17,8 @@ package io.cloudbeaver.utils; import io.cloudbeaver.auth.NoAuthCredentialsProvider; +import io.cloudbeaver.events.CBEvent; +import io.cloudbeaver.events.CBEventConstants; import io.cloudbeaver.model.app.WebApplication; import io.cloudbeaver.model.app.WebAuthApplication; import org.jkiss.code.NotNull; @@ -33,10 +35,7 @@ import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.nio.file.Path; -import java.util.HashMap; -import java.util.HashSet; -import java.util.Map; -import java.util.Set; +import java.util.*; public class WebAppUtils { private static final Log log = Log.getLog(WebAppUtils.class); @@ -163,4 +162,21 @@ public class WebAppUtils { String globalConfigurationName = getWebApplication().getDefaultProjectName(); return RMProjectType.GLOBAL.getPrefix() + "_" + globalConfigurationName; } + + public static void addDatasourceUpdatedEvent(String projectId) { + getWebApplication().getEventController().addEvent( + new CBEvent(CBEventConstants.CLOUDBEAVER_DATASOURCE_UPDATED, Map.of("projectId", projectId)) + ); + } + + public static void addRmResourceUpdatedEvent(String eventId, String projectId, String resourcePath) { + getWebApplication().getEventController().addEvent( + new CBEvent(eventId, + Map.of( + "projectId", projectId, + "resourcePath", resourcePath + ) + ) + ); + } } diff --git a/server/bundles/io.cloudbeaver.server/plugin.xml b/server/bundles/io.cloudbeaver.server/plugin.xml index d16d6382c0..2d61bfbb37 100644 --- a/server/bundles/io.cloudbeaver.server/plugin.xml +++ b/server/bundles/io.cloudbeaver.server/plugin.xml @@ -50,7 +50,8 @@ - + \ + diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/WebServiceUtils.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/WebServiceUtils.java index d8f3c6e815..8dee743f17 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/WebServiceUtils.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/WebServiceUtils.java @@ -19,8 +19,6 @@ package io.cloudbeaver; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.google.gson.InstanceCreator; -import io.cloudbeaver.events.CBEvent; -import io.cloudbeaver.events.CBEventConstants; import io.cloudbeaver.model.WebConnectionConfig; import io.cloudbeaver.model.WebConnectionFolderInfo; import io.cloudbeaver.model.WebNetworkHandlerConfigInput; @@ -46,7 +44,6 @@ import org.jkiss.dbeaver.model.navigator.DBNModel; import org.jkiss.dbeaver.model.navigator.DBNProject; import org.jkiss.dbeaver.model.net.DBWHandlerConfiguration; import org.jkiss.dbeaver.model.net.ssh.SSHConstants; -import org.jkiss.dbeaver.model.rm.RMProject; import org.jkiss.dbeaver.model.rm.RMProjectType; import org.jkiss.dbeaver.registry.DataSourceDescriptor; import org.jkiss.dbeaver.registry.DataSourceNavigatorSettings; @@ -60,7 +57,6 @@ import org.jkiss.utils.CommonUtils; import java.io.InputStream; import java.util.HashMap; import java.util.LinkedHashMap; -import java.util.List; import java.util.Map; /** @@ -342,11 +338,5 @@ public class WebServiceUtils extends WebCommonUtils { return project.getId().equals(RMProjectType.GLOBAL.getPrefix() + "_" + CBApplication.getInstance().getDefaultProjectName()); } - public static void addProjectUpdatedEvent(List projectIds) { - CBApplication.getInstance().getEventController().addEvent( - new CBEvent(CBEventConstants.CLOUDBEAVER_PROJECT_UPDATED, Map.of("projects", projectIds)) - ); - } - } diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/CBApplication.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/CBApplication.java index 2b0473ca43..5a82b7b2de 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/CBApplication.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/CBApplication.java @@ -1008,6 +1008,7 @@ public class CBApplication extends BaseWebApplication implements WebAuthApplicat return WebDriverRegistry.getInstance(); } + @Override public CBEventController getEventController() { return eventController; } diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/events/CBDatasourceUpdatedEventHandlerImpl.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/events/CBDatasourceUpdatedEventHandlerImpl.java new file mode 100644 index 0000000000..249edf9e14 --- /dev/null +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/events/CBDatasourceUpdatedEventHandlerImpl.java @@ -0,0 +1,49 @@ +/* + * DBeaver - Universal Database Manager + * Copyright (C) 2010-2022 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.server.events; + +import io.cloudbeaver.events.CBEvent; +import io.cloudbeaver.events.CBEventConstants; +import io.cloudbeaver.model.session.WebSession; +import org.jkiss.code.NotNull; +import org.jkiss.dbeaver.model.app.DBPProject; +import org.jkiss.dbeaver.model.data.json.JSONUtils; + +import java.util.Map; + +/** + * Notify all active user session that datasource has been updated + */ +public class CBDatasourceUpdatedEventHandlerImpl extends CBProjectUpdatedEventHandler { + @NotNull + @Override + public String getSupportedEventType() { + return CBEventConstants.CLOUDBEAVER_DATASOURCE_UPDATED; + } + + @Override + protected void updateSessionData(WebSession activeUserSession, CBEvent event) { + String projectId = JSONUtils.getString(event.getEventData(), "project"); + DBPProject project = activeUserSession.getProjectById(projectId); + if (project == null) { + return; + } + activeUserSession.refreshUserData(); + activeUserSession.addSessionEvent(event); + } +} + diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/events/CBProjectUpdatedEventHandler.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/events/CBProjectUpdatedEventHandler.java index 01d43eaf29..9e86d159e2 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/events/CBProjectUpdatedEventHandler.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/events/CBProjectUpdatedEventHandler.java @@ -17,44 +17,32 @@ package io.cloudbeaver.server.events; import io.cloudbeaver.events.CBEvent; -import io.cloudbeaver.events.CBEventConstants; import io.cloudbeaver.events.CBEventHandler; import io.cloudbeaver.model.session.WebSession; import io.cloudbeaver.server.CBPlatform; import org.jkiss.code.NotNull; import org.jkiss.dbeaver.Log; -import org.jkiss.dbeaver.model.app.DBPProject; -import org.jkiss.dbeaver.model.data.json.JSONUtils; import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.stream.Collectors; /** * Notify all active user session that project has been updated */ -public class CBProjectUpdatedEventHandler implements CBEventHandler { +public abstract class CBProjectUpdatedEventHandler implements CBEventHandler { private static final Log log = Log.getLog(CBProjectUpdatedEventHandler.class); @NotNull @Override - public String getSupportedEventType() { - return CBEventConstants.CLOUDBEAVER_PROJECT_UPDATED; - } + public abstract String getSupportedEventType(); @Override public void handleEvent(@NotNull CBEvent event) { log.debug(getSupportedEventType() + " event handled"); Collection allSessions = CBPlatform.getInstance().getSessionManager().getAllActiveSessions(); - List projects = JSONUtils.getStringList(event.getEventData(), "projects"); for (WebSession activeUserSession : allSessions) { - List availableProjectIds = activeUserSession.getAccessibleProjects().stream() - .map(DBPProject::getId).collect(Collectors.toList()); - if (Collections.disjoint(availableProjectIds, projects)) { - continue; - } - activeUserSession.refreshUserData(); + updateSessionData(activeUserSession, event); } } + + protected abstract void updateSessionData(WebSession activeUserSession, CBEvent event); } diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/events/CBRmResourceUpdatedEventHandlerImpl.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/events/CBRmResourceUpdatedEventHandlerImpl.java new file mode 100644 index 0000000000..206bcc9862 --- /dev/null +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/events/CBRmResourceUpdatedEventHandlerImpl.java @@ -0,0 +1,45 @@ +/* + * DBeaver - Universal Database Manager + * Copyright (C) 2010-2022 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.server.events; + +import io.cloudbeaver.events.CBEvent; +import io.cloudbeaver.events.CBEventConstants; +import io.cloudbeaver.model.session.WebSession; +import org.jkiss.code.NotNull; +import org.jkiss.dbeaver.model.app.DBPProject; +import org.jkiss.dbeaver.model.data.json.JSONUtils; + +/** + * Notify all active user session that rm resource has been updated + */ +public class CBRmResourceUpdatedEventHandlerImpl extends CBProjectUpdatedEventHandler { + @NotNull + @Override + public String getSupportedEventType() { + return CBEventConstants.CLOUDBEAVER_RM_RESOURCE_UPDATED; + } + + @Override + protected void updateSessionData(WebSession activeUserSession, CBEvent event) { + String projectId = JSONUtils.getString(event.getEventData(), "project"); + DBPProject project = activeUserSession.getProjectById(projectId); + if (project == null) { + return; + } + activeUserSession.addSessionEvent(event); + } +} diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/core/impl/WebServiceCore.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/core/impl/WebServiceCore.java index 5293041b3f..9774fb2b26 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/core/impl/WebServiceCore.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/core/impl/WebServiceCore.java @@ -21,7 +21,6 @@ import io.cloudbeaver.DBWConstants; import io.cloudbeaver.DBWebException; import io.cloudbeaver.WebServiceUtils; import io.cloudbeaver.events.CBEvent; -import io.cloudbeaver.events.CBEventConstants; import io.cloudbeaver.model.*; import io.cloudbeaver.model.session.WebSession; import io.cloudbeaver.registry.WebHandlerRegistry; @@ -30,6 +29,7 @@ import io.cloudbeaver.server.CBApplication; import io.cloudbeaver.server.CBPlatform; import io.cloudbeaver.service.core.DBWServiceCore; import io.cloudbeaver.service.security.SMUtils; +import io.cloudbeaver.utils.WebAppUtils; import io.cloudbeaver.utils.WebConnectionFolderUtils; import io.cloudbeaver.utils.WebDataSourceUtils; import org.jkiss.code.NotNull; @@ -402,7 +402,7 @@ public class WebServiceCore implements DBWServiceCore { WebConnectionInfo connectionInfo = new WebConnectionInfo(webSession, newDataSource); webSession.addConnection(connectionInfo); webSession.addInfoMessage("New connection was created - " + WebServiceUtils.getConnectionContainerInfo(newDataSource)); - WebServiceUtils.addProjectUpdatedEvent(List.of(projectId)); + WebAppUtils.addDatasourceUpdatedEvent(projectId); return connectionInfo; } @@ -440,7 +440,7 @@ public class WebServiceCore implements DBWServiceCore { } catch (DBException e) { throw new DBWebException("Failed to update connection", e); } - WebServiceUtils.addProjectUpdatedEvent(List.of(projectId)); + WebAppUtils.addDatasourceUpdatedEvent(projectId); return connectionInfo; } @@ -454,7 +454,7 @@ public class WebServiceCore implements DBWServiceCore { webSession.addInfoMessage("Delete connection - " + WebServiceUtils.getConnectionContainerInfo(connectionInfo.getDataSourceContainer())); closeAndDeleteConnection(webSession, projectId, connectionId, true); - WebServiceUtils.addProjectUpdatedEvent(List.of(projectId)); + WebAppUtils.addDatasourceUpdatedEvent(projectId); return true; } @@ -491,6 +491,8 @@ public class WebServiceCore implements DBWServiceCore { WebConnectionInfo connectionInfo = new WebConnectionInfo(webSession, newDataSource); webSession.addConnection(connectionInfo); + WebAppUtils.addDatasourceUpdatedEvent(projectId); + return connectionInfo; } @@ -531,7 +533,7 @@ public class WebServiceCore implements DBWServiceCore { WebConnectionInfo connectionInfo = new WebConnectionInfo(webSession, newDataSource); dataSourceRegistry.checkForErrors(); webSession.addConnection(connectionInfo); - WebServiceUtils.addProjectUpdatedEvent(List.of(projectId)); + WebAppUtils.addDatasourceUpdatedEvent(projectId); return connectionInfo; } catch (DBException e) { throw new DBWebException("Error copying connection", e); @@ -710,7 +712,7 @@ public class WebServiceCore implements DBWServiceCore { DBPDataSourceFolder newFolder = WebServiceUtils.createFolder(parentNode, folderName, sessionRegistry); WebConnectionFolderInfo folderInfo = new WebConnectionFolderInfo(session, newFolder); WebServiceUtils.updateConfigAndRefreshDatabases(session, projectId); - WebServiceUtils.addProjectUpdatedEvent(List.of(projectId)); + WebAppUtils.addDatasourceUpdatedEvent(projectId); return folderInfo; } catch (DBException e) { throw new DBWebException(e.getMessage(), e); @@ -728,7 +730,7 @@ public class WebServiceCore implements DBWServiceCore { WebConnectionFolderInfo folderInfo = WebConnectionFolderUtils.getFolderInfo(session, projectId, folderPath); folderInfo.getDataSourceFolder().setName(newName); WebServiceUtils.updateConfigAndRefreshDatabases(session, projectId); - WebServiceUtils.addProjectUpdatedEvent(List.of(projectId)); + WebAppUtils.addDatasourceUpdatedEvent(projectId); return folderInfo; } @@ -746,7 +748,7 @@ public class WebServiceCore implements DBWServiceCore { DBPDataSourceRegistry sessionRegistry = session.getProjectById(projectId).getDataSourceRegistry(); sessionRegistry.removeFolder(folderInfo.getDataSourceFolder(), false); WebServiceUtils.updateConfigAndRefreshDatabases(session, projectId); - WebServiceUtils.addProjectUpdatedEvent(List.of(projectId)); + WebAppUtils.addDatasourceUpdatedEvent(projectId); } catch (DBException e) { throw new DBWebException(e.getMessage(), e); } @@ -761,7 +763,7 @@ public class WebServiceCore implements DBWServiceCore { DataSourceDescriptor dataSourceDescriptor = ((DataSourceDescriptor)connectionInfo.getDataSourceContainer()); dataSourceDescriptor.setNavigatorSettings(settings); dataSourceDescriptor.persistConfiguration(); - WebServiceUtils.addProjectUpdatedEvent(List.of(projectId)); + WebAppUtils.addDatasourceUpdatedEvent(projectId); return connectionInfo; } diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/navigator/impl/WebServiceNavigator.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/navigator/impl/WebServiceNavigator.java index dc1f1f097f..93d6198b9c 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/navigator/impl/WebServiceNavigator.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/navigator/impl/WebServiceNavigator.java @@ -341,8 +341,6 @@ public class WebServiceNavigator implements DBWServiceNavigator { if (node == null) { throw new DBWebException("Navigator node '" + nodePath + "' not found"); } - List projectIds = new ArrayList<>(); - addProjectIdForEvent(projectIds, node); checkProjectEditAccess(node, session); if (node.supportsRename()) { if (node instanceof DBNLocalFolder) { @@ -356,7 +354,6 @@ public class WebServiceNavigator implements DBWServiceNavigator { } } node.rename(session.getProgressMonitor(), newName); - WebServiceUtils.addProjectUpdatedEvent(projectIds); return node.getName(); } if (node instanceof DBNDatabaseNode) { @@ -381,14 +378,12 @@ public class WebServiceNavigator implements DBWServiceNavigator { String projectId = null; boolean containsFolderNodes = false; Map nodes = new LinkedHashMap<>(); - List projectIds = new ArrayList<>(); for (String path : nodePaths) { DBNNode node = session.getNavigatorModel().getNodeByPath(monitor, path); if (node == null) { throw new DBWebException("Navigator node '" + path + "' not found"); } checkProjectEditAccess(node, session); - addProjectIdForEvent(projectIds, node); if (node instanceof DBNDatabaseNode) { DBSObject object = ((DBNDatabaseNode) node).getObject(); DBEObjectMaker objectDeleter = DBWorkbench.getPlatform().getEditorsRegistry().getObjectManager( @@ -429,7 +424,6 @@ public class WebServiceNavigator implements DBWServiceNavigator { if (containsFolderNodes) { WebServiceUtils.updateConfigAndRefreshDatabases(session, projectId); } - WebServiceUtils.addProjectUpdatedEvent(projectIds); return nodes.size(); } catch (DBException e) { @@ -464,14 +458,12 @@ public class WebServiceNavigator implements DBWServiceNavigator { DBRProgressMonitor monitor = session.getProgressMonitor(); DBNNode folderNode; folderNode = session.getNavigatorModel().getNodeByPath(monitor, folderNodePath); - List projectIds = new ArrayList<>(); for (String path : nodePaths) { DBNNode node = session.getNavigatorModel().getNodeByPath(monitor, path); if (node == null) { throw new DBWebException("Navigator node '" + path + "' not found"); } checkProjectEditAccess(node, session); - addProjectIdForEvent(projectIds, node); if (node instanceof DBNDataSource) { DBPDataSourceFolder folder = WebConnectionFolderUtils.getParentFolder(folderNode); ((DBNDataSource) node).moveToFolder(folderNode.getOwnerProject(), folder); @@ -508,20 +500,12 @@ public class WebServiceNavigator implements DBWServiceNavigator { throw new DBWebException("Navigator node '" + path + "' is not a data source node"); } } - WebServiceUtils.addProjectUpdatedEvent(projectIds); return true; } catch (DBException e) { throw new DBWebException("Error moving navigator nodes " + nodePaths, e); } } - private void addProjectIdForEvent(List projectIds, DBNNode node) { - String ownerProject = node.getOwnerProject().getId(); - if (!projectIds.contains(ownerProject)) { - projectIds.add(ownerProject); // for updating project in all sessions - } - } - private String renameDatabaseObject(WebSession session, DBNDatabaseNode node, String newName) throws DBException { if (node.getParentNode() instanceof DBNContainer) { DBSObject object = node.getObject(); From 609cd15415c8bfe0d178a1fcb20fae2cf87c5c15 Mon Sep 17 00:00:00 2001 From: Ainur Date: Fri, 21 Oct 2022 17:35:40 +0200 Subject: [PATCH 03/14] CB-2186 datasource updated events fixes --- .../model/rm/local/LocalResourceController.java | 2 -- .../io.cloudbeaver.server/schema/service.core.graphqls | 4 +++- .../service/navigator/impl/WebServiceNavigator.java | 5 +++++ .../src/io/cloudbeaver/service/rm/impl/WebServiceRM.java | 7 ++++++- 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/local/LocalResourceController.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/local/LocalResourceController.java index 1082bdabcb..a1e18a636b 100644 --- a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/local/LocalResourceController.java +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/local/LocalResourceController.java @@ -418,7 +418,6 @@ public class LocalResourceController implements RMController { } catch (IOException e) { throw new DBException("Error moving resource '" + oldResourcePath + "'", e); } - WebAppUtils.addRmResourceUpdatedEvent(CBEventConstants.CLOUDBEAVER_RM_RESOURCE_UPDATED, projectId, oldResourcePath); return DEFAULT_CHANGE_ID; } @@ -449,7 +448,6 @@ public class LocalResourceController implements RMController { rmResourcePath ) ); - WebAppUtils.addRmResourceUpdatedEvent(CBEventConstants.CLOUDBEAVER_RM_RESOURCE_UPDATED, projectId, resourcePath); } @Override diff --git a/server/bundles/io.cloudbeaver.server/schema/service.core.graphqls b/server/bundles/io.cloudbeaver.server/schema/service.core.graphqls index d8652e7f17..ebb4d479cc 100644 --- a/server/bundles/io.cloudbeaver.server/schema/service.core.graphqls +++ b/server/bundles/io.cloudbeaver.server/schema/service.core.graphqls @@ -387,7 +387,9 @@ type LogEntry { } enum CBEventType { - cb_config_changed + cb_config_changed, + cb_datasource_updated, + cb_resource_updated } type CBEvent { diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/navigator/impl/WebServiceNavigator.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/navigator/impl/WebServiceNavigator.java index 93d6198b9c..a6a1e01016 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/navigator/impl/WebServiceNavigator.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/navigator/impl/WebServiceNavigator.java @@ -19,6 +19,7 @@ package io.cloudbeaver.service.navigator.impl; import io.cloudbeaver.DBWebException; import io.cloudbeaver.WebServiceUtils; +import io.cloudbeaver.events.CBEventConstants; import io.cloudbeaver.model.WebCommandContext; import io.cloudbeaver.model.WebConnectionInfo; import io.cloudbeaver.model.rm.DBNAbstractResourceManagerNode; @@ -30,6 +31,7 @@ import io.cloudbeaver.service.navigator.WebCatalog; import io.cloudbeaver.service.navigator.WebNavigatorNodeInfo; import io.cloudbeaver.service.navigator.WebStructContainers; import io.cloudbeaver.service.security.SMUtils; +import io.cloudbeaver.utils.WebAppUtils; import io.cloudbeaver.utils.WebConnectionFolderUtils; import org.jkiss.code.NotNull; import org.jkiss.code.Nullable; @@ -469,6 +471,7 @@ public class WebServiceNavigator implements DBWServiceNavigator { ((DBNDataSource) node).moveToFolder(folderNode.getOwnerProject(), folder); node.getOwnerProject().getDataSourceRegistry().updateDataSource( ((DBNDataSource) node).getDataSourceContainer()); + WebAppUtils.addDatasourceUpdatedEvent(node.getOwnerProject().getId()); } else if (node instanceof DBNLocalFolder) { DBPDataSourceFolder folder = WebConnectionFolderUtils.getParentFolder(folderNode); if (folder != null) { @@ -481,6 +484,7 @@ public class WebServiceNavigator implements DBWServiceNavigator { } ((DBNLocalFolder) node).getFolder().setParent(folder); WebServiceUtils.updateConfigAndRefreshDatabases(session, node.getOwnerProject().getId()); + WebAppUtils.addDatasourceUpdatedEvent(node.getOwnerProject().getId()); } else if (node instanceof DBNResourceManagerResource) { boolean rmNewNode = folderNode instanceof DBNAbstractResourceManagerNode; DBNResourceManagerResource rmOldNode = (DBNResourceManagerResource) node; @@ -496,6 +500,7 @@ public class WebServiceNavigator implements DBWServiceNavigator { } String resourcePath = rmOldNode.getResourceFolder(); session.getRmController().moveResource(projectId, resourcePath, newPath); + WebAppUtils.addRmResourceUpdatedEvent(CBEventConstants.CLOUDBEAVER_RM_RESOURCE_UPDATED, projectId, resourcePath); } else { throw new DBWebException("Navigator node '" + path + "' is not a data source node"); } diff --git a/server/bundles/io.cloudbeaver.service.rm/src/io/cloudbeaver/service/rm/impl/WebServiceRM.java b/server/bundles/io.cloudbeaver.service.rm/src/io/cloudbeaver/service/rm/impl/WebServiceRM.java index 5b8864e406..3152131d7f 100644 --- a/server/bundles/io.cloudbeaver.service.rm/src/io/cloudbeaver/service/rm/impl/WebServiceRM.java +++ b/server/bundles/io.cloudbeaver.service.rm/src/io/cloudbeaver/service/rm/impl/WebServiceRM.java @@ -17,12 +17,14 @@ package io.cloudbeaver.service.rm.impl; import io.cloudbeaver.DBWebException; +import io.cloudbeaver.events.CBEventConstants; import io.cloudbeaver.model.session.WebSession; import io.cloudbeaver.service.admin.AdminPermissionInfo; import io.cloudbeaver.service.rm.DBWServiceRM; import io.cloudbeaver.service.rm.model.RMProjectPermissions; import io.cloudbeaver.service.rm.model.RMSubjectProjectPermissions; import io.cloudbeaver.service.security.SMUtils; +import io.cloudbeaver.utils.WebAppUtils; import org.jkiss.code.NotNull; import org.jkiss.code.Nullable; import org.jkiss.dbeaver.DBException; @@ -137,7 +139,9 @@ public class WebServiceRM implements DBWServiceRM { ) throws DBException { checkIsRmEnabled(webSession); try { - return getResourceController(webSession).createResource(projectId, resourcePath, isFolder); + String result = getResourceController(webSession).createResource(projectId, resourcePath, isFolder); + WebAppUtils.addRmResourceUpdatedEvent(CBEventConstants.CLOUDBEAVER_RM_RESOURCE_UPDATED, projectId, resourcePath); + return result; } catch (Exception e) { throw new DBWebException("Error creating resource " + resourcePath, e); } @@ -151,6 +155,7 @@ public class WebServiceRM implements DBWServiceRM { checkIsRmEnabled(webSession); try { getResourceController(webSession).deleteResource(projectId, resourcePath, false); + WebAppUtils.addRmResourceUpdatedEvent(CBEventConstants.CLOUDBEAVER_RM_RESOURCE_UPDATED, projectId, resourcePath); return true; } catch (Exception e) { throw new DBWebException("Error deleting resource " + resourcePath, e); From 81fec49209a466d00cd1a6c946c30d0182eb8478 Mon Sep 17 00:00:00 2001 From: Ainur Date: Mon, 24 Oct 2022 14:04:05 +0200 Subject: [PATCH 04/14] CB-2186 add event for adding rm node to navigator model --- .../rm/DBNAbstractResourceManagerNode.java | 17 +++++++++ .../model/rm/DBNResourceManagerRoot.java | 25 +++++++++---- .../rm/local/LocalResourceController.java | 35 +++++++++++++------ .../CBRmResourceUpdatedEventHandlerImpl.java | 33 ++++++++++++++++- 4 files changed, 92 insertions(+), 18 deletions(-) diff --git a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/DBNAbstractResourceManagerNode.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/DBNAbstractResourceManagerNode.java index bc1fccd4e2..fc9eacb7fd 100644 --- a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/DBNAbstractResourceManagerNode.java +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/DBNAbstractResourceManagerNode.java @@ -31,4 +31,21 @@ public abstract class DBNAbstractResourceManagerNode extends DBNNode implements node.removeChildResourceNode(resourcePath); } } + + public void addChildResourceNode(@NotNull Queue resourcePath) { + if (children == null || resourcePath.isEmpty()) { + return; + } + var expectedResource = resourcePath.poll(); + var node = RMNavigatorUtils.findResourceNode(children, expectedResource); + if (node == null) { // we are in expected parent node + DBNResourceManagerResource newResourceNode = new DBNResourceManagerResource(this, expectedResource); + ArrayUtils.add(DBNResourceManagerResource.class, children, newResourceNode); + return; + } + + if (resourcePath.size() > 1) { + node.addChildResourceNode(resourcePath); + } + } } diff --git a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/DBNResourceManagerRoot.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/DBNResourceManagerRoot.java index de59ccc520..b8a38cef62 100644 --- a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/DBNResourceManagerRoot.java +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/DBNResourceManagerRoot.java @@ -18,6 +18,7 @@ package io.cloudbeaver.model.rm; import io.cloudbeaver.model.session.WebSession; +import org.jkiss.code.NotNull; import org.jkiss.dbeaver.DBException; import org.jkiss.dbeaver.model.DBPHiddenObject; import org.jkiss.dbeaver.model.DBPImage; @@ -28,10 +29,7 @@ import org.jkiss.dbeaver.model.navigator.DBNProject; import org.jkiss.dbeaver.model.rm.*; import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor; -import java.util.ArrayDeque; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; +import java.util.*; public class DBNResourceManagerRoot extends DBNNode implements DBPHiddenObject, RMEventListener { @@ -126,13 +124,26 @@ public class DBNResourceManagerRoot extends DBNNode implements DBPHiddenObject, case RESOURCE_DELETE: deleteResourceNode(event.getProject(), event.getResourceTree()); break; + case RESOURCE_ADD: + addResourceNode(event.getProject(), event.getResourceTree()); + break; } } private void deleteResourceNode(RMProject project, List resourcePath) { - var projectNode = Arrays.stream(projects) - .filter(rmProjectNode -> rmProjectNode.getProject().getId().equals(project.getId())) - .findFirst(); + var projectNode = getProjectNode(project); projectNode.ifPresent(dbnResourceManagerProject -> dbnResourceManagerProject.removeChildResourceNode(new ArrayDeque<>(resourcePath))); } + + @NotNull + private Optional getProjectNode(RMProject project) { + return Arrays.stream(projects) + .filter(rmProjectNode -> rmProjectNode.getProject().getId().equals(project.getId())) + .findFirst(); + } + + private void addResourceNode(RMProject project, List resourcePath) { + var projectNode = getProjectNode(project); + projectNode.ifPresent(dbnResourceManagerProject -> dbnResourceManagerProject.addChildResourceNode(new ArrayDeque<>(resourcePath))); + } } diff --git a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/local/LocalResourceController.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/local/LocalResourceController.java index a1e18a636b..aa771d7d5f 100644 --- a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/local/LocalResourceController.java +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/local/LocalResourceController.java @@ -18,7 +18,6 @@ package io.cloudbeaver.model.rm.local; import io.cloudbeaver.DBWConstants; import io.cloudbeaver.VirtualProjectImpl; -import io.cloudbeaver.events.CBEventConstants; import io.cloudbeaver.model.rm.RMUtils; import io.cloudbeaver.service.security.SMUtils; import io.cloudbeaver.service.sql.WebSQLConstants; @@ -397,7 +396,7 @@ public class LocalResourceController implements RMController { } catch (IOException e) { throw new DBException("Error creating resource '" + resourcePath + "'", e); } - WebAppUtils.addRmResourceUpdatedEvent(CBEventConstants.CLOUDBEAVER_RM_RESOURCE_UPDATED, projectId, resourcePath); + fireRmResourceAddEvent(projectId, resourcePath); return DEFAULT_CHANGE_ID; } @@ -408,6 +407,7 @@ public class LocalResourceController implements RMController { @NotNull String newResourcePath ) throws DBException { Path oldTargetPath = getTargetPath(projectId, oldResourcePath); + List rmOldResourcePath = makeResourcePath(projectId, oldTargetPath, false); if (!Files.exists(oldTargetPath)) { throw new DBException("Resource '" + oldTargetPath + "' doesn't exists"); } @@ -418,6 +418,8 @@ public class LocalResourceController implements RMController { } catch (IOException e) { throw new DBException("Error moving resource '" + oldResourcePath + "'", e); } + fireRmResourceDeleteEvent(projectId, rmOldResourcePath); + fireRmResourceAddEvent(projectId, newResourcePath); return DEFAULT_CHANGE_ID; } @@ -442,12 +444,7 @@ public class LocalResourceController implements RMController { VirtualProjectImpl project = getProjectMetadata(projectId); project.resetResourceProperties(resourcePath); - RMEventManager.fireEvent( - new RMEvent(RMEvent.Action.RESOURCE_DELETE, - makeProjectFromId(projectId, false), - rmResourcePath - ) - ); + fireRmResourceDeleteEvent(projectId, rmResourcePath); } @Override @@ -501,7 +498,9 @@ public class LocalResourceController implements RMController { } catch (IOException e) { throw new DBException("Error reading resource '" + resourcePath + "'", e); } - + if (!forceOverwrite) { + fireRmResourceAddEvent(projectId, resourcePath); + } return DEFAULT_CHANGE_ID; } @@ -708,10 +707,26 @@ public class LocalResourceController implements RMController { return getProjectPath(projectId).toAbsolutePath().relativize(path).toString().replace('\\', IPath.SEPARATOR); } + private void fireRmResourceAddEvent(@NotNull String projectId, @NotNull String resourcePath) throws DBException { + RMEventManager.fireEvent( + new RMEvent(RMEvent.Action.RESOURCE_ADD, + getProject(projectId, false, false), + Arrays.asList(getResourcePath(projectId, resourcePath))) + ); + } + + private void fireRmResourceDeleteEvent(@NotNull String projectId, @NotNull List resourcePath) throws DBException { + RMEventManager.fireEvent( + new RMEvent(RMEvent.Action.RESOURCE_DELETE, + makeProjectFromId(projectId, false), + resourcePath + ) + ); + } + public static Builder builder(SMCredentialsProvider credentialsProvider, SMController smController) { return new Builder(credentialsProvider, smController); } - public static final class Builder { private final SMCredentialsProvider credentialsProvider; private final SMController smController; diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/events/CBRmResourceUpdatedEventHandlerImpl.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/events/CBRmResourceUpdatedEventHandlerImpl.java index 206bcc9862..2a598be376 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/events/CBRmResourceUpdatedEventHandlerImpl.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/events/CBRmResourceUpdatedEventHandlerImpl.java @@ -16,12 +16,18 @@ */ package io.cloudbeaver.server.events; +import io.cloudbeaver.VirtualProjectImpl; import io.cloudbeaver.events.CBEvent; import io.cloudbeaver.events.CBEventConstants; import io.cloudbeaver.model.session.WebSession; import org.jkiss.code.NotNull; +import org.jkiss.dbeaver.DBException; import org.jkiss.dbeaver.model.app.DBPProject; import org.jkiss.dbeaver.model.data.json.JSONUtils; +import org.jkiss.dbeaver.model.rm.*; + +import java.util.Arrays; +import java.util.List; /** * Notify all active user session that rm resource has been updated @@ -36,10 +42,35 @@ public class CBRmResourceUpdatedEventHandlerImpl extends CBProjectUpdatedEventHa @Override protected void updateSessionData(WebSession activeUserSession, CBEvent event) { String projectId = JSONUtils.getString(event.getEventData(), "project"); - DBPProject project = activeUserSession.getProjectById(projectId); + String eventType = JSONUtils.getString(event.getEventData(), "eventType"); + String resourcePath = JSONUtils.getString(event.getEventData(), "resourcePath"); + if (projectId == null || eventType == null || resourcePath == null) { + return; + } + VirtualProjectImpl project = activeUserSession.getProjectById(projectId); if (project == null) { return; } + RMController rmController = activeUserSession.getRmController(); + List rmResourcePath; + try { + rmResourcePath = Arrays.asList(rmController.getResourcePath(projectId, resourcePath)); + } catch (DBException e) { + return; + } + if (eventType.equals("create")) { + RMEventManager.fireEvent( + new RMEvent(RMEvent.Action.RESOURCE_ADD, + project.getRmProject(), + rmResourcePath) + ); + } else if (eventType.equals("delete")) { + RMEventManager.fireEvent( + new RMEvent(RMEvent.Action.RESOURCE_DELETE, + project.getRmProject(), + rmResourcePath) + ); + } activeUserSession.addSessionEvent(event); } } From 82e6d8327513753a5671c780d82b96e79c6edba0 Mon Sep 17 00:00:00 2001 From: Ainur Date: Mon, 24 Oct 2022 15:02:15 +0200 Subject: [PATCH 05/14] CB-2186 event fixes --- .../src/io/cloudbeaver/utils/WebAppUtils.java | 7 +++++-- .../CBDatasourceUpdatedEventHandlerImpl.java | 8 +++----- .../service/core/impl/WebServiceCore.java | 18 +++++++++--------- .../navigator/impl/WebServiceNavigator.java | 4 ++-- 4 files changed, 19 insertions(+), 18 deletions(-) diff --git a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/utils/WebAppUtils.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/utils/WebAppUtils.java index 5c10deb362..4f7becaaf8 100644 --- a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/utils/WebAppUtils.java +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/utils/WebAppUtils.java @@ -205,9 +205,12 @@ public class WebAppUtils { return RMProjectType.GLOBAL.getPrefix() + "_" + globalConfigurationName; } - public static void addDatasourceUpdatedEvent(String projectId) { + public static void addDatasourceUpdatedEvent(DBPProject project) { + if (project == null) { + return; + } getWebApplication().getEventController().addEvent( - new CBEvent(CBEventConstants.CLOUDBEAVER_DATASOURCE_UPDATED, Map.of("projectId", projectId)) + new CBEvent(CBEventConstants.CLOUDBEAVER_DATASOURCE_UPDATED, Map.of("projectId", project.getId())) ); } diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/events/CBDatasourceUpdatedEventHandlerImpl.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/events/CBDatasourceUpdatedEventHandlerImpl.java index 249edf9e14..278811cb93 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/events/CBDatasourceUpdatedEventHandlerImpl.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/events/CBDatasourceUpdatedEventHandlerImpl.java @@ -16,15 +16,13 @@ */ package io.cloudbeaver.server.events; +import io.cloudbeaver.VirtualProjectImpl; import io.cloudbeaver.events.CBEvent; import io.cloudbeaver.events.CBEventConstants; import io.cloudbeaver.model.session.WebSession; import org.jkiss.code.NotNull; -import org.jkiss.dbeaver.model.app.DBPProject; import org.jkiss.dbeaver.model.data.json.JSONUtils; -import java.util.Map; - /** * Notify all active user session that datasource has been updated */ @@ -38,8 +36,8 @@ public class CBDatasourceUpdatedEventHandlerImpl extends CBProjectUpdatedEventHa @Override protected void updateSessionData(WebSession activeUserSession, CBEvent event) { String projectId = JSONUtils.getString(event.getEventData(), "project"); - DBPProject project = activeUserSession.getProjectById(projectId); - if (project == null) { + VirtualProjectImpl project = activeUserSession.getProjectById(projectId); + if (project == null || !project.getRmProject().isShared()) { return; } activeUserSession.refreshUserData(); diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/core/impl/WebServiceCore.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/core/impl/WebServiceCore.java index 9774fb2b26..03d30df93e 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/core/impl/WebServiceCore.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/core/impl/WebServiceCore.java @@ -402,7 +402,7 @@ public class WebServiceCore implements DBWServiceCore { WebConnectionInfo connectionInfo = new WebConnectionInfo(webSession, newDataSource); webSession.addConnection(connectionInfo); webSession.addInfoMessage("New connection was created - " + WebServiceUtils.getConnectionContainerInfo(newDataSource)); - WebAppUtils.addDatasourceUpdatedEvent(projectId); + WebAppUtils.addDatasourceUpdatedEvent(webSession.getProjectById(projectId)); return connectionInfo; } @@ -440,7 +440,7 @@ public class WebServiceCore implements DBWServiceCore { } catch (DBException e) { throw new DBWebException("Failed to update connection", e); } - WebAppUtils.addDatasourceUpdatedEvent(projectId); + WebAppUtils.addDatasourceUpdatedEvent(webSession.getProjectById(projectId)); return connectionInfo; } @@ -454,7 +454,7 @@ public class WebServiceCore implements DBWServiceCore { webSession.addInfoMessage("Delete connection - " + WebServiceUtils.getConnectionContainerInfo(connectionInfo.getDataSourceContainer())); closeAndDeleteConnection(webSession, projectId, connectionId, true); - WebAppUtils.addDatasourceUpdatedEvent(projectId); + WebAppUtils.addDatasourceUpdatedEvent(webSession.getProjectById(projectId)); return true; } @@ -491,7 +491,7 @@ public class WebServiceCore implements DBWServiceCore { WebConnectionInfo connectionInfo = new WebConnectionInfo(webSession, newDataSource); webSession.addConnection(connectionInfo); - WebAppUtils.addDatasourceUpdatedEvent(projectId); + WebAppUtils.addDatasourceUpdatedEvent(webSession.getProjectById(projectId)); return connectionInfo; } @@ -533,7 +533,7 @@ public class WebServiceCore implements DBWServiceCore { WebConnectionInfo connectionInfo = new WebConnectionInfo(webSession, newDataSource); dataSourceRegistry.checkForErrors(); webSession.addConnection(connectionInfo); - WebAppUtils.addDatasourceUpdatedEvent(projectId); + WebAppUtils.addDatasourceUpdatedEvent(webSession.getProjectById(projectId)); return connectionInfo; } catch (DBException e) { throw new DBWebException("Error copying connection", e); @@ -712,7 +712,7 @@ public class WebServiceCore implements DBWServiceCore { DBPDataSourceFolder newFolder = WebServiceUtils.createFolder(parentNode, folderName, sessionRegistry); WebConnectionFolderInfo folderInfo = new WebConnectionFolderInfo(session, newFolder); WebServiceUtils.updateConfigAndRefreshDatabases(session, projectId); - WebAppUtils.addDatasourceUpdatedEvent(projectId); + WebAppUtils.addDatasourceUpdatedEvent(session.getProjectById(projectId)); return folderInfo; } catch (DBException e) { throw new DBWebException(e.getMessage(), e); @@ -730,7 +730,7 @@ public class WebServiceCore implements DBWServiceCore { WebConnectionFolderInfo folderInfo = WebConnectionFolderUtils.getFolderInfo(session, projectId, folderPath); folderInfo.getDataSourceFolder().setName(newName); WebServiceUtils.updateConfigAndRefreshDatabases(session, projectId); - WebAppUtils.addDatasourceUpdatedEvent(projectId); + WebAppUtils.addDatasourceUpdatedEvent(session.getProjectById(projectId)); return folderInfo; } @@ -748,7 +748,7 @@ public class WebServiceCore implements DBWServiceCore { DBPDataSourceRegistry sessionRegistry = session.getProjectById(projectId).getDataSourceRegistry(); sessionRegistry.removeFolder(folderInfo.getDataSourceFolder(), false); WebServiceUtils.updateConfigAndRefreshDatabases(session, projectId); - WebAppUtils.addDatasourceUpdatedEvent(projectId); + WebAppUtils.addDatasourceUpdatedEvent(session.getProjectById(projectId)); } catch (DBException e) { throw new DBWebException(e.getMessage(), e); } @@ -763,7 +763,7 @@ public class WebServiceCore implements DBWServiceCore { DataSourceDescriptor dataSourceDescriptor = ((DataSourceDescriptor)connectionInfo.getDataSourceContainer()); dataSourceDescriptor.setNavigatorSettings(settings); dataSourceDescriptor.persistConfiguration(); - WebAppUtils.addDatasourceUpdatedEvent(projectId); + WebAppUtils.addDatasourceUpdatedEvent(webSession.getProjectById(projectId)); return connectionInfo; } diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/navigator/impl/WebServiceNavigator.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/navigator/impl/WebServiceNavigator.java index a6a1e01016..097ec1818c 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/navigator/impl/WebServiceNavigator.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/navigator/impl/WebServiceNavigator.java @@ -471,7 +471,7 @@ public class WebServiceNavigator implements DBWServiceNavigator { ((DBNDataSource) node).moveToFolder(folderNode.getOwnerProject(), folder); node.getOwnerProject().getDataSourceRegistry().updateDataSource( ((DBNDataSource) node).getDataSourceContainer()); - WebAppUtils.addDatasourceUpdatedEvent(node.getOwnerProject().getId()); + WebAppUtils.addDatasourceUpdatedEvent(node.getOwnerProject()); } else if (node instanceof DBNLocalFolder) { DBPDataSourceFolder folder = WebConnectionFolderUtils.getParentFolder(folderNode); if (folder != null) { @@ -484,7 +484,7 @@ public class WebServiceNavigator implements DBWServiceNavigator { } ((DBNLocalFolder) node).getFolder().setParent(folder); WebServiceUtils.updateConfigAndRefreshDatabases(session, node.getOwnerProject().getId()); - WebAppUtils.addDatasourceUpdatedEvent(node.getOwnerProject().getId()); + WebAppUtils.addDatasourceUpdatedEvent(node.getOwnerProject()); } else if (node instanceof DBNResourceManagerResource) { boolean rmNewNode = folderNode instanceof DBNAbstractResourceManagerNode; DBNResourceManagerResource rmOldNode = (DBNResourceManagerResource) node; From 90190d2a30d8cd8123c2d0ca64dd5ff3713b964f Mon Sep 17 00:00:00 2001 From: Ainur Date: Tue, 25 Oct 2022 10:47:10 +0200 Subject: [PATCH 06/14] CB-2186 event fixes --- .../rm/local/LocalResourceController.java | 6 +++++- .../src/io/cloudbeaver/utils/WebAppUtils.java | 7 +++++-- .../bundles/io.cloudbeaver.server/plugin.xml | 2 +- ...> CBDataSourceUpdatedEventHandlerImpl.java} | 2 +- .../service/core/impl/WebServiceCore.java | 18 +++++++++--------- .../navigator/impl/WebServiceNavigator.java | 4 ++-- 6 files changed, 23 insertions(+), 16 deletions(-) rename server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/events/{CBDatasourceUpdatedEventHandlerImpl.java => CBDataSourceUpdatedEventHandlerImpl.java} (96%) diff --git a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/local/LocalResourceController.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/local/LocalResourceController.java index aa771d7d5f..76190eaba4 100644 --- a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/local/LocalResourceController.java +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/local/LocalResourceController.java @@ -296,7 +296,11 @@ public class LocalResourceController implements RMController { } @Override - public void saveProjectDataSources(@NotNull String projectId, @NotNull String configuration) throws DBException { + public void saveProjectDataSources( + @NotNull String projectId, + @NotNull String configuration, + @NotNull String[] dataSourceIds + ) throws DBException { final DBPProject project = getProjectMetadata(projectId); final DBPDataSourceRegistry registry = project.getDataSourceRegistry(); final DBPDataSourceConfigurationStorage storage = new DataSourceMemoryStorage(configuration.getBytes(StandardCharsets.UTF_8)); diff --git a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/utils/WebAppUtils.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/utils/WebAppUtils.java index 4f7becaaf8..9d3fb72cb2 100644 --- a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/utils/WebAppUtils.java +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/utils/WebAppUtils.java @@ -205,12 +205,15 @@ public class WebAppUtils { return RMProjectType.GLOBAL.getPrefix() + "_" + globalConfigurationName; } - public static void addDatasourceUpdatedEvent(DBPProject project) { + public static void addDataSourceUpdatedEvent(DBPProject project, String datasourceId) { if (project == null) { return; } getWebApplication().getEventController().addEvent( - new CBEvent(CBEventConstants.CLOUDBEAVER_DATASOURCE_UPDATED, Map.of("projectId", project.getId())) + new CBEvent( + CBEventConstants.CLOUDBEAVER_DATASOURCE_UPDATED, + Map.of("projectId", project.getId(), "dataSourceIds", new String[] {datasourceId}) + ) ); } diff --git a/server/bundles/io.cloudbeaver.server/plugin.xml b/server/bundles/io.cloudbeaver.server/plugin.xml index 2d61bfbb37..7e5a924ae6 100644 --- a/server/bundles/io.cloudbeaver.server/plugin.xml +++ b/server/bundles/io.cloudbeaver.server/plugin.xml @@ -50,7 +50,7 @@ - \ + \ diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/events/CBDatasourceUpdatedEventHandlerImpl.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/events/CBDataSourceUpdatedEventHandlerImpl.java similarity index 96% rename from server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/events/CBDatasourceUpdatedEventHandlerImpl.java rename to server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/events/CBDataSourceUpdatedEventHandlerImpl.java index 278811cb93..103f667efa 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/events/CBDatasourceUpdatedEventHandlerImpl.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/events/CBDataSourceUpdatedEventHandlerImpl.java @@ -26,7 +26,7 @@ import org.jkiss.dbeaver.model.data.json.JSONUtils; /** * Notify all active user session that datasource has been updated */ -public class CBDatasourceUpdatedEventHandlerImpl extends CBProjectUpdatedEventHandler { +public class CBDataSourceUpdatedEventHandlerImpl extends CBProjectUpdatedEventHandler { @NotNull @Override public String getSupportedEventType() { diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/core/impl/WebServiceCore.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/core/impl/WebServiceCore.java index 03d30df93e..5b46964097 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/core/impl/WebServiceCore.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/core/impl/WebServiceCore.java @@ -402,7 +402,7 @@ public class WebServiceCore implements DBWServiceCore { WebConnectionInfo connectionInfo = new WebConnectionInfo(webSession, newDataSource); webSession.addConnection(connectionInfo); webSession.addInfoMessage("New connection was created - " + WebServiceUtils.getConnectionContainerInfo(newDataSource)); - WebAppUtils.addDatasourceUpdatedEvent(webSession.getProjectById(projectId)); + WebAppUtils.addDataSourceUpdatedEvent(webSession.getProjectById(projectId), connectionInfo.getId()); return connectionInfo; } @@ -440,7 +440,7 @@ public class WebServiceCore implements DBWServiceCore { } catch (DBException e) { throw new DBWebException("Failed to update connection", e); } - WebAppUtils.addDatasourceUpdatedEvent(webSession.getProjectById(projectId)); + WebAppUtils.addDataSourceUpdatedEvent(webSession.getProjectById(projectId), connectionInfo.getId()); return connectionInfo; } @@ -454,7 +454,7 @@ public class WebServiceCore implements DBWServiceCore { webSession.addInfoMessage("Delete connection - " + WebServiceUtils.getConnectionContainerInfo(connectionInfo.getDataSourceContainer())); closeAndDeleteConnection(webSession, projectId, connectionId, true); - WebAppUtils.addDatasourceUpdatedEvent(webSession.getProjectById(projectId)); + WebAppUtils.addDataSourceUpdatedEvent(webSession.getProjectById(projectId), connectionId); return true; } @@ -491,7 +491,7 @@ public class WebServiceCore implements DBWServiceCore { WebConnectionInfo connectionInfo = new WebConnectionInfo(webSession, newDataSource); webSession.addConnection(connectionInfo); - WebAppUtils.addDatasourceUpdatedEvent(webSession.getProjectById(projectId)); + WebAppUtils.addDataSourceUpdatedEvent(webSession.getProjectById(projectId), connectionInfo.getId()); return connectionInfo; } @@ -533,7 +533,7 @@ public class WebServiceCore implements DBWServiceCore { WebConnectionInfo connectionInfo = new WebConnectionInfo(webSession, newDataSource); dataSourceRegistry.checkForErrors(); webSession.addConnection(connectionInfo); - WebAppUtils.addDatasourceUpdatedEvent(webSession.getProjectById(projectId)); + WebAppUtils.addDataSourceUpdatedEvent(webSession.getProjectById(projectId), connectionInfo.getId()); return connectionInfo; } catch (DBException e) { throw new DBWebException("Error copying connection", e); @@ -712,7 +712,7 @@ public class WebServiceCore implements DBWServiceCore { DBPDataSourceFolder newFolder = WebServiceUtils.createFolder(parentNode, folderName, sessionRegistry); WebConnectionFolderInfo folderInfo = new WebConnectionFolderInfo(session, newFolder); WebServiceUtils.updateConfigAndRefreshDatabases(session, projectId); - WebAppUtils.addDatasourceUpdatedEvent(session.getProjectById(projectId)); + WebAppUtils.addDataSourceUpdatedEvent(session.getProjectById(projectId), folderInfo.getId()); return folderInfo; } catch (DBException e) { throw new DBWebException(e.getMessage(), e); @@ -730,7 +730,7 @@ public class WebServiceCore implements DBWServiceCore { WebConnectionFolderInfo folderInfo = WebConnectionFolderUtils.getFolderInfo(session, projectId, folderPath); folderInfo.getDataSourceFolder().setName(newName); WebServiceUtils.updateConfigAndRefreshDatabases(session, projectId); - WebAppUtils.addDatasourceUpdatedEvent(session.getProjectById(projectId)); + WebAppUtils.addDataSourceUpdatedEvent(session.getProjectById(projectId), folderInfo.getId()); return folderInfo; } @@ -748,7 +748,7 @@ public class WebServiceCore implements DBWServiceCore { DBPDataSourceRegistry sessionRegistry = session.getProjectById(projectId).getDataSourceRegistry(); sessionRegistry.removeFolder(folderInfo.getDataSourceFolder(), false); WebServiceUtils.updateConfigAndRefreshDatabases(session, projectId); - WebAppUtils.addDatasourceUpdatedEvent(session.getProjectById(projectId)); + WebAppUtils.addDataSourceUpdatedEvent(session.getProjectById(projectId), folderInfo.getId()); } catch (DBException e) { throw new DBWebException(e.getMessage(), e); } @@ -763,7 +763,7 @@ public class WebServiceCore implements DBWServiceCore { DataSourceDescriptor dataSourceDescriptor = ((DataSourceDescriptor)connectionInfo.getDataSourceContainer()); dataSourceDescriptor.setNavigatorSettings(settings); dataSourceDescriptor.persistConfiguration(); - WebAppUtils.addDatasourceUpdatedEvent(webSession.getProjectById(projectId)); + WebAppUtils.addDataSourceUpdatedEvent(webSession.getProjectById(projectId), id); return connectionInfo; } diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/navigator/impl/WebServiceNavigator.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/navigator/impl/WebServiceNavigator.java index 097ec1818c..8ec9ccb4cb 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/navigator/impl/WebServiceNavigator.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/navigator/impl/WebServiceNavigator.java @@ -471,7 +471,7 @@ public class WebServiceNavigator implements DBWServiceNavigator { ((DBNDataSource) node).moveToFolder(folderNode.getOwnerProject(), folder); node.getOwnerProject().getDataSourceRegistry().updateDataSource( ((DBNDataSource) node).getDataSourceContainer()); - WebAppUtils.addDatasourceUpdatedEvent(node.getOwnerProject()); + WebAppUtils.addDataSourceUpdatedEvent(node.getOwnerProject(), ((DBNDataSource) node).getDataSourceContainer().getId()); } else if (node instanceof DBNLocalFolder) { DBPDataSourceFolder folder = WebConnectionFolderUtils.getParentFolder(folderNode); if (folder != null) { @@ -484,7 +484,7 @@ public class WebServiceNavigator implements DBWServiceNavigator { } ((DBNLocalFolder) node).getFolder().setParent(folder); WebServiceUtils.updateConfigAndRefreshDatabases(session, node.getOwnerProject().getId()); - WebAppUtils.addDatasourceUpdatedEvent(node.getOwnerProject()); + WebAppUtils.addDataSourceUpdatedEvent(node.getOwnerProject(), ((DBNLocalFolder) node).getFolder().getFolderPath()); } else if (node instanceof DBNResourceManagerResource) { boolean rmNewNode = folderNode instanceof DBNAbstractResourceManagerNode; DBNResourceManagerResource rmOldNode = (DBNResourceManagerResource) node; From 3213bc82fddf2b8598069818c79c91274e95a227 Mon Sep 17 00:00:00 2001 From: Ainur Date: Tue, 25 Oct 2022 11:43:54 +0200 Subject: [PATCH 07/14] CB-2186 datasource event fixes --- .../server/events/CBDataSourceUpdatedEventHandlerImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/events/CBDataSourceUpdatedEventHandlerImpl.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/events/CBDataSourceUpdatedEventHandlerImpl.java index 103f667efa..7c3b770698 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/events/CBDataSourceUpdatedEventHandlerImpl.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/events/CBDataSourceUpdatedEventHandlerImpl.java @@ -35,7 +35,7 @@ public class CBDataSourceUpdatedEventHandlerImpl extends CBProjectUpdatedEventHa @Override protected void updateSessionData(WebSession activeUserSession, CBEvent event) { - String projectId = JSONUtils.getString(event.getEventData(), "project"); + String projectId = JSONUtils.getString(event.getEventData(), "projectId"); VirtualProjectImpl project = activeUserSession.getProjectById(projectId); if (project == null || !project.getRmProject().isShared()) { return; From 94c4d6ab62dd0cf05dea1a2c00be17e254a4f238 Mon Sep 17 00:00:00 2001 From: naumov Date: Tue, 25 Oct 2022 15:58:42 +0400 Subject: [PATCH 08/14] CB-2665 remove templates from de --- .../packages/core-sdk/src/queries/session/serverConfig.gql | 1 + webapp/packages/core-sdk/src/sdk.ts | 4 +++- .../ConnectionForm/Options/ConnectionOptionsTabService.ts | 5 +++-- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/webapp/packages/core-sdk/src/queries/session/serverConfig.gql b/webapp/packages/core-sdk/src/queries/session/serverConfig.gql index 938c97d35e..b440e3dfbc 100644 --- a/webapp/packages/core-sdk/src/queries/session/serverConfig.gql +++ b/webapp/packages/core-sdk/src/queries/session/serverConfig.gql @@ -25,6 +25,7 @@ query serverConfig { configurationMode developmentMode redirectOnFederatedAuth + distributed enabledFeatures enabledAuthProviders diff --git a/webapp/packages/core-sdk/src/sdk.ts b/webapp/packages/core-sdk/src/sdk.ts index 8935632b87..51507f533b 100644 --- a/webapp/packages/core-sdk/src/sdk.ts +++ b/webapp/packages/core-sdk/src/sdk.ts @@ -1541,6 +1541,7 @@ export interface ServerConfig { defaultNavigatorSettings: NavigatorSettings; developmentMode?: Maybe; disabledDrivers: Array; + distributed: Scalars['Boolean']; enabledAuthProviders: Array; enabledFeatures: Array; hostName: Scalars['String']; @@ -2699,7 +2700,7 @@ export type ReadSessionLogQuery = { log: Array<{ time?: any, type: string, messa export type ServerConfigQueryVariables = Exact<{ [key: string]: never; }>; -export type ServerConfigQuery = { serverConfig: { name: string, version: string, workspaceId: string, serverURL: string, rootURI: string, hostName: string, productConfiguration: any, supportsCustomConnections?: boolean, supportsConnectionBrowser?: boolean, supportsWorkspaces?: boolean, sessionExpireTime?: number, anonymousAccessEnabled?: boolean, adminCredentialsSaveEnabled?: boolean, publicCredentialsSaveEnabled?: boolean, resourceManagerEnabled?: boolean, licenseRequired: boolean, licenseValid: boolean, configurationMode?: boolean, developmentMode?: boolean, redirectOnFederatedAuth?: boolean, enabledFeatures: Array, enabledAuthProviders: Array, resourceQuotas: any, disabledDrivers: Array, supportedLanguages: Array<{ isoCode: string, displayName?: string, nativeName?: string }>, defaultNavigatorSettings: { showSystemObjects: boolean, showUtilityObjects: boolean, showOnlyEntities: boolean, mergeEntities: boolean, hideFolders: boolean, hideSchemas: boolean, hideVirtualModel: boolean }, productInfo: { id: string, version: string, latestVersionInfo?: string, name: string, description?: string, buildTime: string, releaseTime: string, licenseInfo?: string } } }; +export type ServerConfigQuery = { serverConfig: { name: string, version: string, workspaceId: string, serverURL: string, rootURI: string, hostName: string, productConfiguration: any, supportsCustomConnections?: boolean, supportsConnectionBrowser?: boolean, supportsWorkspaces?: boolean, sessionExpireTime?: number, anonymousAccessEnabled?: boolean, adminCredentialsSaveEnabled?: boolean, publicCredentialsSaveEnabled?: boolean, resourceManagerEnabled?: boolean, licenseRequired: boolean, licenseValid: boolean, configurationMode?: boolean, developmentMode?: boolean, redirectOnFederatedAuth?: boolean, distributed: boolean, enabledFeatures: Array, enabledAuthProviders: Array, resourceQuotas: any, disabledDrivers: Array, supportedLanguages: Array<{ isoCode: string, displayName?: string, nativeName?: string }>, defaultNavigatorSettings: { showSystemObjects: boolean, showUtilityObjects: boolean, showOnlyEntities: boolean, mergeEntities: boolean, hideFolders: boolean, hideSchemas: boolean, hideVirtualModel: boolean }, productInfo: { id: string, version: string, latestVersionInfo?: string, name: string, description?: string, buildTime: string, releaseTime: string, licenseInfo?: string } } }; export type SessionPermissionsQueryVariables = Exact<{ [key: string]: never; }>; @@ -4317,6 +4318,7 @@ export const ServerConfigDocument = ` configurationMode developmentMode redirectOnFederatedAuth + distributed enabledFeatures enabledAuthProviders supportedLanguages { diff --git a/webapp/packages/plugin-connections/src/ConnectionForm/Options/ConnectionOptionsTabService.ts b/webapp/packages/plugin-connections/src/ConnectionForm/Options/ConnectionOptionsTabService.ts index 7b304fcc06..d09e98bcf4 100644 --- a/webapp/packages/plugin-connections/src/ConnectionForm/Options/ConnectionOptionsTabService.ts +++ b/webapp/packages/plugin-connections/src/ConnectionForm/Options/ConnectionOptionsTabService.ts @@ -15,7 +15,7 @@ import { Bootstrap, injectable } from '@cloudbeaver/core-di'; import type { IExecutionContextProvider } from '@cloudbeaver/core-executor'; import { LocalizationService } from '@cloudbeaver/core-localization'; import { ProjectInfoResource } from '@cloudbeaver/core-projects'; -import { PermissionsService } from '@cloudbeaver/core-root'; +import { PermissionsService, ServerConfigResource } from '@cloudbeaver/core-root'; import { CachedMapAllKey, DriverConfigurationType, isObjectPropertyInfoStateEqual, ObjectPropertyInfo } from '@cloudbeaver/core-sdk'; import { getUniqueName, isValuesEqual } from '@cloudbeaver/core-utils'; @@ -30,6 +30,7 @@ import { Options } from './Options'; @injectable() export class ConnectionOptionsTabService extends Bootstrap { constructor( + private readonly serverConfigResource: ServerConfigResource, private readonly projectInfoResource: ProjectInfoResource, private readonly connectionFormService: ConnectionFormService, private readonly dbDriverResource: DBDriverResource, @@ -95,7 +96,7 @@ export class ConnectionOptionsTabService extends Bootstrap { const adminPermission = this.permissionsService.has(EAdminPermission.admin); const originLocal = !state.info || isLocalConnection(state.info); - return adminPermission && originLocal && isProjectShared; + return adminPermission && originLocal && isProjectShared && !this.serverConfigResource.data?.distributed; } private async save( From 3f51fd29bc987681f8b0670258a75aef0f846860 Mon Sep 17 00:00:00 2001 From: Ainur Date: Tue, 25 Oct 2022 15:40:06 +0200 Subject: [PATCH 09/14] CB-2186 event name fix --- .../src/io/cloudbeaver/events/CBEventConstants.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/events/CBEventConstants.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/events/CBEventConstants.java index 4f0d640631..cd57965ad9 100644 --- a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/events/CBEventConstants.java +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/events/CBEventConstants.java @@ -22,5 +22,5 @@ package io.cloudbeaver.events; public interface CBEventConstants { String CLOUDBEAVER_CONFIG_CHANGED = "cb_config_changed"; String CLOUDBEAVER_DATASOURCE_UPDATED = "cb_datasource_updated"; - String CLOUDBEAVER_RM_RESOURCE_UPDATED = "cb_rm_resource_deleted"; + String CLOUDBEAVER_RM_RESOURCE_UPDATED = "cb_rm_resource_updated"; } From 706b60132eb8c4f0e89d75de8182516bbd5031bb Mon Sep 17 00:00:00 2001 From: Ainur Date: Tue, 25 Oct 2022 19:08:04 +0200 Subject: [PATCH 10/14] CB-2186 send resource path in events --- .../rm/DBNAbstractResourceManagerNode.java | 2 +- .../CBRmResourceUpdatedEventHandlerImpl.java | 21 ++++++++++--------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/DBNAbstractResourceManagerNode.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/DBNAbstractResourceManagerNode.java index fc9eacb7fd..5361a810d5 100644 --- a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/DBNAbstractResourceManagerNode.java +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/DBNAbstractResourceManagerNode.java @@ -40,7 +40,7 @@ public abstract class DBNAbstractResourceManagerNode extends DBNNode implements var node = RMNavigatorUtils.findResourceNode(children, expectedResource); if (node == null) { // we are in expected parent node DBNResourceManagerResource newResourceNode = new DBNResourceManagerResource(this, expectedResource); - ArrayUtils.add(DBNResourceManagerResource.class, children, newResourceNode); + children = ArrayUtils.add(DBNResourceManagerResource.class, children, newResourceNode); return; } diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/events/CBRmResourceUpdatedEventHandlerImpl.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/events/CBRmResourceUpdatedEventHandlerImpl.java index 2a598be376..9800c97709 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/events/CBRmResourceUpdatedEventHandlerImpl.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/events/CBRmResourceUpdatedEventHandlerImpl.java @@ -16,6 +16,8 @@ */ package io.cloudbeaver.server.events; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; import io.cloudbeaver.VirtualProjectImpl; import io.cloudbeaver.events.CBEvent; import io.cloudbeaver.events.CBEventConstants; @@ -33,6 +35,9 @@ import java.util.List; * Notify all active user session that rm resource has been updated */ public class CBRmResourceUpdatedEventHandlerImpl extends CBProjectUpdatedEventHandler { + + private static final Gson gson = new GsonBuilder().create(); + @NotNull @Override public String getSupportedEventType() { @@ -41,9 +46,11 @@ public class CBRmResourceUpdatedEventHandlerImpl extends CBProjectUpdatedEventHa @Override protected void updateSessionData(WebSession activeUserSession, CBEvent event) { - String projectId = JSONUtils.getString(event.getEventData(), "project"); + String projectId = JSONUtils.getString(event.getEventData(), "projectId"); String eventType = JSONUtils.getString(event.getEventData(), "eventType"); String resourcePath = JSONUtils.getString(event.getEventData(), "resourcePath"); + RMResource[] resourceParsedPath = gson.fromJson( + gson.toJson(JSONUtils.getObjectList(event.getEventData(), "resourceParsedPath")), RMResource[].class); if (projectId == null || eventType == null || resourcePath == null) { return; } @@ -51,20 +58,14 @@ public class CBRmResourceUpdatedEventHandlerImpl extends CBProjectUpdatedEventHa if (project == null) { return; } - RMController rmController = activeUserSession.getRmController(); - List rmResourcePath; - try { - rmResourcePath = Arrays.asList(rmController.getResourcePath(projectId, resourcePath)); - } catch (DBException e) { - return; - } - if (eventType.equals("create")) { + List rmResourcePath = Arrays.asList(resourceParsedPath); + if (eventType.equals("TYPE_CREATE")) { RMEventManager.fireEvent( new RMEvent(RMEvent.Action.RESOURCE_ADD, project.getRmProject(), rmResourcePath) ); - } else if (eventType.equals("delete")) { + } else if (eventType.equals("TYPE_DELETE")) { RMEventManager.fireEvent( new RMEvent(RMEvent.Action.RESOURCE_DELETE, project.getRmProject(), From c0574f1eb261f536467994e1bc3a32d49a3bbe08 Mon Sep 17 00:00:00 2001 From: serge-rider Date: Tue, 25 Oct 2022 20:43:36 -0400 Subject: [PATCH 11/14] Bump postgresql from 42.3.3 to 42.5.0 --- server/drivers/postgresql/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/drivers/postgresql/pom.xml b/server/drivers/postgresql/pom.xml index fda1b17e9c..79f7c1c225 100644 --- a/server/drivers/postgresql/pom.xml +++ b/server/drivers/postgresql/pom.xml @@ -18,7 +18,7 @@ org.postgresql postgresql - 42.3.3 + 42.5.0 net.postgis From 04afb9eb01f3a71527953570fed09c68c2a64cee Mon Sep 17 00:00:00 2001 From: Ainur Date: Wed, 26 Oct 2022 13:53:01 +0200 Subject: [PATCH 12/14] CB-2186 connection folder fixes --- .../io/cloudbeaver/model/rm/local/LocalResourceController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/local/LocalResourceController.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/local/LocalResourceController.java index 76190eaba4..84fb5ac1bf 100644 --- a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/local/LocalResourceController.java +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/local/LocalResourceController.java @@ -299,7 +299,7 @@ public class LocalResourceController implements RMController { public void saveProjectDataSources( @NotNull String projectId, @NotNull String configuration, - @NotNull String[] dataSourceIds + @Nullable List dataSourceIds ) throws DBException { final DBPProject project = getProjectMetadata(projectId); final DBPDataSourceRegistry registry = project.getDataSourceRegistry(); From 9c39f2b11611d41ee7e2527229526b22df07f618 Mon Sep 17 00:00:00 2001 From: serge-rider Date: Wed, 26 Oct 2022 08:36:13 -0400 Subject: [PATCH 13/14] Remove dead code --- deploy/build.bat | 8 -------- deploy/build.sh | 8 -------- 2 files changed, 16 deletions(-) diff --git a/deploy/build.bat b/deploy/build.bat index 4ba5e94ba0..1e84e13607 100644 --- a/deploy/build.bat +++ b/deploy/build.bat @@ -20,7 +20,6 @@ mkdir cloudbeaver\web echo Pull cloudbeaver platform cd ..\.. -rem IF NOT EXIST react-data-grid git clone https://github.com/dbeaver/react-data-grid.git echo Pull dbeaver platform @@ -54,16 +53,9 @@ echo Build static content cd ..\ -rem cd ..\react-data-grid -rem call npm i -rem call npm run build -rem call npm run build:types -rem call yarn link - cd ..\cloudbeaver\webapp call yarn -rem call yarn link "react-data-grid" call lerna bootstrap call lerna run build --no-bail --stream --scope=@cloudbeaver/product-default &::-- -- --env source-map diff --git a/deploy/build.sh b/deploy/build.sh index 9e14523585..cabe4319f5 100755 --- a/deploy/build.sh +++ b/deploy/build.sh @@ -18,7 +18,6 @@ mkdir ./cloudbeaver/web echo "Pull cloudbeaver platform" cd ../.. -#[ ! -d react-data-grid ] && git clone https://github.com/dbeaver/react-data-grid.git echo "Pull dbeaver platform" [ ! -d dbeaver ] && git clone https://github.com/dbeaver/dbeaver.git @@ -54,16 +53,9 @@ echo "Build static content" cd ../ -#cd ../react-data-grid -#npm i -#npm run build -#npm run build:types -#yarn link - cd ../cloudbeaver/webapp yarn -#yarn link "react-data-grid" lerna run bootstrap lerna run build --no-bail --stream --scope=@cloudbeaver/product-default #-- -- --env source-map if [[ "$?" -ne 0 ]] ; then From a968a64c5c9faa6e1d0e196659bae9b35ea43b85 Mon Sep 17 00:00:00 2001 From: Ainur Date: Wed, 26 Oct 2022 14:28:14 +0200 Subject: [PATCH 14/14] CB-2186 rm resource add child event fix --- .../model/rm/DBNAbstractResourceManagerNode.java | 16 +++++++++++++--- .../schema/service.core.graphqls | 2 +- 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/DBNAbstractResourceManagerNode.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/DBNAbstractResourceManagerNode.java index 5361a810d5..7792ca1aad 100644 --- a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/DBNAbstractResourceManagerNode.java +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/rm/DBNAbstractResourceManagerNode.java @@ -1,9 +1,11 @@ package io.cloudbeaver.model.rm; import org.jkiss.code.NotNull; +import org.jkiss.dbeaver.DBException; import org.jkiss.dbeaver.model.DBPObjectWithDetails; import org.jkiss.dbeaver.model.navigator.DBNNode; import org.jkiss.dbeaver.model.rm.RMResource; +import org.jkiss.dbeaver.model.runtime.VoidProgressMonitor; import org.jkiss.utils.ArrayUtils; import java.util.Queue; @@ -33,7 +35,15 @@ public abstract class DBNAbstractResourceManagerNode extends DBNNode implements } public void addChildResourceNode(@NotNull Queue resourcePath) { - if (children == null || resourcePath.isEmpty()) { + if (children == null) { + // initialize children + try { + getChildren(new VoidProgressMonitor()); + } catch (DBException e) { + return; + } + } + if (resourcePath.isEmpty()) { return; } var expectedResource = resourcePath.poll(); @@ -43,9 +53,9 @@ public abstract class DBNAbstractResourceManagerNode extends DBNNode implements children = ArrayUtils.add(DBNResourceManagerResource.class, children, newResourceNode); return; } - - if (resourcePath.size() > 1) { + if (resourcePath.size() > 0) { node.addChildResourceNode(resourcePath); } + } } diff --git a/server/bundles/io.cloudbeaver.server/schema/service.core.graphqls b/server/bundles/io.cloudbeaver.server/schema/service.core.graphqls index ebb4d479cc..feede70095 100644 --- a/server/bundles/io.cloudbeaver.server/schema/service.core.graphqls +++ b/server/bundles/io.cloudbeaver.server/schema/service.core.graphqls @@ -389,7 +389,7 @@ type LogEntry { enum CBEventType { cb_config_changed, cb_datasource_updated, - cb_resource_updated + cb_rm_resource_updated } type CBEvent {