From bd851433e77e6eb8f60ce5cc3c1b06a7d6f4f4ed Mon Sep 17 00:00:00 2001 From: Alexander Skoblikov Date: Wed, 25 Dec 2024 22:30:58 +0300 Subject: [PATCH] dbeaver/pro#3739 event registry (#3159) Co-authored-by: Daria Marutkina <125263541+dariamarutkina@users.noreply.github.com> --- .../io/cloudbeaver/WebSessionProjectImpl.java | 16 +++++----- .../rm/local/LocalResourceController.java | 3 -- .../cloudbeaver/model/session/WebSession.java | 2 -- ...WSObjectPermissionUpdatedEventHandler.java | 10 +++---- .../WSRmResourceUpdatedEventHandlerImpl.java | 9 +++--- .../server/events/WSUserEventHandler.java | 12 ++------ .../events/WSAbstractProjectEventHandler.java | 4 +-- .../WSDataSourceUpdatedEventHandlerImpl.java | 3 +- .../events/WSProjectUpdatedEventHandler.java | 7 ++--- .../server/websockets/CBEventsWebSocket.java | 30 +++++++++++++------ 10 files changed, 45 insertions(+), 51 deletions(-) diff --git a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/WebSessionProjectImpl.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/WebSessionProjectImpl.java index 9cbeeb1aa6..5c4d20aa81 100644 --- a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/WebSessionProjectImpl.java +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/WebSessionProjectImpl.java @@ -28,7 +28,7 @@ import org.jkiss.dbeaver.model.navigator.DBNModel; import org.jkiss.dbeaver.model.rm.RMProject; import org.jkiss.dbeaver.model.rm.RMUtils; -import org.jkiss.dbeaver.model.websocket.event.WSEventType; +import org.jkiss.dbeaver.model.websocket.event.datasource.WSDataSourceEvent; import org.jkiss.dbeaver.registry.DataSourceDescriptor; import org.jkiss.dbeaver.runtime.jobs.DisconnectJob; @@ -189,9 +189,9 @@ public List getConnections() { * updates data sources based on event in web session * * @param dataSourceIds list of updated connections - * @param type type of event + * @param eventId id of event */ - public synchronized boolean updateProjectDataSources(@NotNull List dataSourceIds, @NotNull WSEventType type) { + public synchronized boolean updateProjectDataSources(@NotNull List dataSourceIds, @NotNull String eventId) { var sendDataSourceUpdatedEvent = false; DBPDataSourceRegistry registry = getDataSourceRegistry(); // save old connections @@ -202,7 +202,7 @@ public synchronized boolean updateProjectDataSources(@NotNull List dataS DBPDataSourceContainer::getId, Function.identity()) ); - if (type == WSEventType.DATASOURCE_CREATED || type == WSEventType.DATASOURCE_UPDATED) { + if (WSDataSourceEvent.CREATED.equals(eventId) || WSDataSourceEvent.UPDATED.equals(eventId)) { registry.refreshConfig(dataSourceIds); } for (String dsId : dataSourceIds) { @@ -210,14 +210,14 @@ public synchronized boolean updateProjectDataSources(@NotNull List dataS if (ds == null) { continue; } - switch (type) { - case DATASOURCE_CREATED -> { + switch (eventId) { + case WSDataSourceEvent.CREATED -> { addConnection(ds); sendDataSourceUpdatedEvent = true; } - case DATASOURCE_UPDATED -> // if settings were changed we need to send event + case WSDataSourceEvent.UPDATED -> // if settings were changed we need to send event sendDataSourceUpdatedEvent |= !ds.equalSettings(oldDataSources.get(dsId)); - case DATASOURCE_DELETED -> { + case WSDataSourceEvent.DELETED -> { WebDataSourceUtils.disconnectDataSource(webSession, ds); if (registry instanceof DBPDataSourceRegistryCache dsrc) { dsrc.removeDataSourceFromList(ds); 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 e64f4adb84..197a6d9b7a 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 @@ -39,7 +39,6 @@ import org.jkiss.dbeaver.model.security.SMObjectType; import org.jkiss.dbeaver.model.sql.DBQuotaException; import org.jkiss.dbeaver.model.websocket.event.MessageType; -import org.jkiss.dbeaver.model.websocket.event.WSEventType; import org.jkiss.dbeaver.model.websocket.event.WSSessionLogUpdatedEvent; import org.jkiss.dbeaver.registry.ResourceTypeDescriptor; import org.jkiss.dbeaver.registry.ResourceTypeRegistry; @@ -777,7 +776,6 @@ protected T doProjectOperation(String projectId, RMFileOperation operatio if (credentialsProvider.getActiveUserCredentials() != null) { ServletAppUtils.getServletApplication().getEventController().addEvent( new WSSessionLogUpdatedEvent( - WSEventType.SESSION_LOG_UPDATED, credentialsProvider.getActiveUserCredentials().getSmSessionId(), credentialsProvider.getActiveUserCredentials().getUserId(), MessageType.ERROR, @@ -796,7 +794,6 @@ protected T doFileReadOperation(String projectId, Path file, RMFileOperation if (credentialsProvider.getActiveUserCredentials() != null) { ServletAppUtils.getServletApplication().getEventController().addEvent( new WSSessionLogUpdatedEvent( - WSEventType.SESSION_LOG_UPDATED, credentialsProvider.getActiveUserCredentials().getSmSessionId(), credentialsProvider.getActiveUserCredentials().getUserId(), MessageType.ERROR, diff --git a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/session/WebSession.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/session/WebSession.java index 2fa8b79262..ec40d7510b 100644 --- a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/session/WebSession.java +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/model/session/WebSession.java @@ -64,7 +64,6 @@ import org.jkiss.dbeaver.model.security.SMController; import org.jkiss.dbeaver.model.sql.DBQuotaException; import org.jkiss.dbeaver.model.websocket.event.MessageType; -import org.jkiss.dbeaver.model.websocket.event.WSEventType; import org.jkiss.dbeaver.model.websocket.event.WSSessionLogUpdatedEvent; import org.jkiss.dbeaver.runtime.DBWorkbench; import org.jkiss.utils.CommonUtils; @@ -602,7 +601,6 @@ public void addSessionMessage(WebServerMessage message) { sessionMessages.add(message); } addSessionEvent(new WSSessionLogUpdatedEvent( - WSEventType.SESSION_LOG_UPDATED, this.userContext.getSmSessionId(), this.userContext.getUserId(), MessageType.ERROR, diff --git a/server/bundles/io.cloudbeaver.server.ce/src/io/cloudbeaver/server/events/WSObjectPermissionUpdatedEventHandler.java b/server/bundles/io.cloudbeaver.server.ce/src/io/cloudbeaver/server/events/WSObjectPermissionUpdatedEventHandler.java index 32d9a7a88f..a46ca14f99 100644 --- a/server/bundles/io.cloudbeaver.server.ce/src/io/cloudbeaver/server/events/WSObjectPermissionUpdatedEventHandler.java +++ b/server/bundles/io.cloudbeaver.server.ce/src/io/cloudbeaver/server/events/WSObjectPermissionUpdatedEventHandler.java @@ -20,7 +20,6 @@ import io.cloudbeaver.model.session.BaseWebSession; import io.cloudbeaver.model.session.WebSession; import io.cloudbeaver.server.CBApplication; -import io.cloudbeaver.server.CBPlatform; import io.cloudbeaver.service.security.SMUtils; import io.cloudbeaver.utils.ServletAppUtils; import org.jkiss.code.NotNull; @@ -28,7 +27,6 @@ import org.jkiss.dbeaver.Log; import org.jkiss.dbeaver.model.security.SMAdminController; import org.jkiss.dbeaver.model.security.SMObjectPermissionsGrant; -import org.jkiss.dbeaver.model.websocket.event.WSEventType; import org.jkiss.dbeaver.model.websocket.event.WSProjectUpdateEvent; import org.jkiss.dbeaver.model.websocket.event.datasource.WSDataSourceEvent; import org.jkiss.dbeaver.model.websocket.event.datasource.WSDataSourceProperty; @@ -108,7 +106,7 @@ private Consumer getUpdateUserDataSourcesInfoConsumer( return; } boolean isAccessibleNow = project.findWebConnectionInfo(dataSourceId) != null; - if (WSEventType.OBJECT_PERMISSIONS_UPDATED.getEventId().equals(event.getId())) { + if (WSObjectPermissionEvent.UPDATED.equals(event.getId())) { if (isAccessibleNow || !shouldBeAccessible) { return; } @@ -122,7 +120,7 @@ private Consumer getUpdateUserDataSourcesInfoConsumer( WSDataSourceProperty.CONFIGURATION ) ); - } else if (WSEventType.OBJECT_PERMISSIONS_DELETED.getEventId().equals(event.getId())) { + } else if (WSObjectPermissionEvent.DELETED.equals(event.getId())) { if (!isAccessibleNow || shouldBeAccessible) { return; } @@ -147,7 +145,7 @@ private Consumer getUpdateUserProjectsInfoConsumer( ) { return (activeUserSession) -> { try { - if (WSEventType.OBJECT_PERMISSIONS_UPDATED.getEventId().equals(event.getId())) { + if (WSObjectPermissionEvent.UPDATED.equals(event.getId())) { var accessibleProjectIds = activeUserSession.getUserContext().getAccessibleProjectIds(); if (accessibleProjectIds.contains(event.getObjectId())) { return; @@ -160,7 +158,7 @@ private Consumer getUpdateUserProjectsInfoConsumer( projectId ) ); - } else if (WSEventType.OBJECT_PERMISSIONS_DELETED.getEventId().equals(event.getId())) { + } else if (WSObjectPermissionEvent.DELETED.equals(event.getId())) { activeUserSession.removeSessionProject(projectId); activeUserSession.addSessionEvent( WSProjectUpdateEvent.delete( diff --git a/server/bundles/io.cloudbeaver.server.ce/src/io/cloudbeaver/server/events/WSRmResourceUpdatedEventHandlerImpl.java b/server/bundles/io.cloudbeaver.server.ce/src/io/cloudbeaver/server/events/WSRmResourceUpdatedEventHandlerImpl.java index 3466b93b0d..130558de14 100644 --- a/server/bundles/io.cloudbeaver.server.ce/src/io/cloudbeaver/server/events/WSRmResourceUpdatedEventHandlerImpl.java +++ b/server/bundles/io.cloudbeaver.server.ce/src/io/cloudbeaver/server/events/WSRmResourceUpdatedEventHandlerImpl.java @@ -25,7 +25,6 @@ import org.jkiss.dbeaver.Log; import org.jkiss.dbeaver.model.rm.RMEvent; import org.jkiss.dbeaver.model.rm.RMEventManager; -import org.jkiss.dbeaver.model.websocket.event.WSEventType; import org.jkiss.dbeaver.model.websocket.event.resource.WSResourceUpdatedEvent; /** @@ -41,7 +40,7 @@ protected void updateSessionData(@NotNull BaseWebSession activeUserSession, @Not if (activeUserSession instanceof WebSession) { var webSession = (WebSession) activeUserSession; acceptChangesInNavigatorTree( - WSEventType.valueById(event.getId()), + event.getId(), event.getResourcePath(), webSession.getProjectById(event.getProjectId()) ); @@ -49,14 +48,14 @@ protected void updateSessionData(@NotNull BaseWebSession activeUserSession, @Not activeUserSession.addSessionEvent(event); } - private void acceptChangesInNavigatorTree(WSEventType eventType, String resourcePath, WebProjectImpl project) { - if (eventType == WSEventType.RM_RESOURCE_CREATED) { + private void acceptChangesInNavigatorTree(@NotNull String eventId, String resourcePath, WebProjectImpl project) { + if (WSResourceUpdatedEvent.CREATED.equals(eventId)) { RMEventManager.fireEvent( new RMEvent(RMEvent.Action.RESOURCE_ADD, project.getRMProject(), resourcePath) ); - } else if (eventType == WSEventType.RM_RESOURCE_DELETED) { + } else if (WSResourceUpdatedEvent.DELETED.equals(eventId)) { RMEventManager.fireEvent( new RMEvent(RMEvent.Action.RESOURCE_DELETE, project.getRMProject(), diff --git a/server/bundles/io.cloudbeaver.server.ce/src/io/cloudbeaver/server/events/WSUserEventHandler.java b/server/bundles/io.cloudbeaver.server.ce/src/io/cloudbeaver/server/events/WSUserEventHandler.java index 4ed0e17124..72aadb6de6 100644 --- a/server/bundles/io.cloudbeaver.server.ce/src/io/cloudbeaver/server/events/WSUserEventHandler.java +++ b/server/bundles/io.cloudbeaver.server.ce/src/io/cloudbeaver/server/events/WSUserEventHandler.java @@ -17,24 +17,18 @@ package io.cloudbeaver.server.events; import io.cloudbeaver.server.CBApplication; -import io.cloudbeaver.server.CBPlatform; import org.jkiss.code.NotNull; import org.jkiss.dbeaver.model.websocket.WSEventHandler; import org.jkiss.dbeaver.model.websocket.event.WSAbstractEvent; -import org.jkiss.dbeaver.model.websocket.event.WSEventType; import org.jkiss.dbeaver.model.websocket.event.WSUserCloseSessionsEvent; import org.jkiss.dbeaver.model.websocket.event.WSUserDeletedEvent; public class WSUserEventHandler implements WSEventHandler { @Override public void handleEvent(@NotNull EVENT event) { - var eventType = WSEventType.valueById(event.getId()); - if (eventType == null) { - return; - } var sessionManager = CBApplication.getInstance().getSessionManager(); - switch (eventType) { - case CLOSE_USER_SESSIONS: + switch (event.getId()) { + case WSUserCloseSessionsEvent.ID: if (event instanceof WSUserCloseSessionsEvent closeSessionsEvent) { if (closeSessionsEvent.getSessionIds().isEmpty()) { sessionManager.closeAllSessions(closeSessionsEvent.getSessionId()); @@ -43,7 +37,7 @@ public void handleEvent(@NotNull EVENT event) { } } break; - case USER_DELETED: + case WSUserDeletedEvent.ID: if (event instanceof WSUserDeletedEvent userDeletedEvent) { sessionManager.closeUserSession(userDeletedEvent); } diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/events/WSAbstractProjectEventHandler.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/events/WSAbstractProjectEventHandler.java index fd3a879f73..a31ebecfda 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/events/WSAbstractProjectEventHandler.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/events/WSAbstractProjectEventHandler.java @@ -18,7 +18,6 @@ import io.cloudbeaver.model.session.BaseWebSession; import org.jkiss.code.NotNull; -import org.jkiss.dbeaver.model.websocket.event.WSEventType; import org.jkiss.dbeaver.model.websocket.event.WSProjectEvent; /** @@ -29,7 +28,6 @@ public abstract class WSAbstractProjectEventHandler { @@ -33,10 +32,10 @@ protected void updateSessionData(@NotNull BaseWebSession activeUserSession, @Not var eventId = event.getId(); var projectId = event.getProjectId(); try { - if (eventId.equals(WSEventType.RM_PROJECT_ADDED.getEventId())) { + if (WSProjectUpdateEvent.ADDED.equals(eventId)) { activeUserSession.addSessionProject(projectId); log.info("Project '" + projectId + "' added to '" + activeUserSession.getSessionId() + "' session"); - } else if (eventId.equals(WSEventType.RM_PROJECT_REMOVED.getEventId())) { + } else if (WSProjectUpdateEvent.REMOVED.equals(eventId)) { activeUserSession.removeSessionProject(projectId); log.info("Project '" + projectId + "' removed from '" + activeUserSession.getSessionId() + "' session"); } @@ -49,7 +48,7 @@ protected void updateSessionData(@NotNull BaseWebSession activeUserSession, @Not @Override protected boolean isAcceptableInSession(@NotNull BaseWebSession activeUserSession, @NotNull WSProjectUpdateEvent event) { return !WSWebUtils.isSessionIdEquals(activeUserSession, event.getSessionId()) && - (event.getId().equals(WSEventType.RM_PROJECT_REMOVED.getEventId()) || + (event.getId().equals(WSProjectUpdateEvent.REMOVED) || activeUserSession.getUserContext().hasPermission(DBWConstants.PERMISSION_ADMIN)); } } diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/websockets/CBEventsWebSocket.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/websockets/CBEventsWebSocket.java index 465ba6c43e..924a58fce6 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/websockets/CBEventsWebSocket.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/websockets/CBEventsWebSocket.java @@ -24,8 +24,10 @@ import org.jkiss.code.Nullable; import org.jkiss.dbeaver.Log; import org.jkiss.dbeaver.model.websocket.event.WSClientEvent; -import org.jkiss.dbeaver.model.websocket.event.WSClientEventType; import org.jkiss.dbeaver.model.websocket.event.WSEvent; +import org.jkiss.dbeaver.model.websocket.event.client.WSSessionPingClientEvent; +import org.jkiss.dbeaver.model.websocket.event.client.WSSubscribeOnTopicClientEvent; +import org.jkiss.dbeaver.model.websocket.event.client.WSUnsubscribeFromTopicClientEvent; import org.jkiss.dbeaver.model.websocket.event.client.WSUpdateActiveProjectsClientEvent; import org.jkiss.dbeaver.model.websocket.event.session.WSAccessTokenExpiredEvent; import org.jkiss.dbeaver.model.websocket.event.session.WSSocketConnectedEvent; @@ -66,33 +68,43 @@ public void onMessage(String message) { if (CommonUtils.isEmpty(message)) { return; } - var clientEvent = CBAbstractWebSocket.gson.fromJson(message, WSClientEvent.class); - var clientEventType = WSClientEventType.valueById(clientEvent.getId()); if (webSession == null) { log.warn("No web session for browser event"); return; } - if (clientEventType == null) { + WSClientEvent clientEvent; + try { + clientEvent = CBAbstractWebSocket.gson.fromJson(message, WSClientEvent.class); + } catch (Exception e) { + if (webSession != null) { + webSession.addSessionError( + new DBWebException("Invalid websocket event: " + e.getMessage()) + ); + } + log.error("Error parsing websocket event: " + e.getMessage(), e); + return; + } + if (clientEvent.getId() == null) { webSession.addSessionError( new DBWebException("Invalid websocket event: " + message) ); return; } - switch (clientEventType) { - case TOPIC_SUBSCRIBE: { + switch (clientEvent.getId()) { + case WSSubscribeOnTopicClientEvent.ID: { webSession.getEventsFilter().subscribeOnEventTopic(clientEvent.getTopicId()); break; } - case TOPIC_UNSUBSCRIBE: { + case WSUnsubscribeFromTopicClientEvent.ID: { webSession.getEventsFilter().unsubscribeFromEventTopic(clientEvent.getTopicId()); break; } - case ACTIVE_PROJECTS: { + case WSUpdateActiveProjectsClientEvent.ID: { var projectEvent = (WSUpdateActiveProjectsClientEvent) clientEvent; webSession.getEventsFilter().setSubscribedProjects(projectEvent.getProjectIds()); break; } - case SESSION_PING: { + case WSSessionPingClientEvent.ID: { if (webSession instanceof WebSession session) { session.updateInfo(true); }