Merge pull request #1225 from dbeaver/tech/CB-2186

CB-2186 datasource updated events
This commit is contained in:
Alexander Skoblikov
2022-10-26 20:54:45 +03:00
committed by GitHub
16 changed files with 316 additions and 25 deletions
@@ -21,4 +21,6 @@ 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_updated";
}
@@ -18,6 +18,7 @@ package io.cloudbeaver.model.app;
import io.cloudbeaver.DataSourceFilter;
import io.cloudbeaver.VirtualProjectImpl;
import io.cloudbeaver.events.CBEventController;
import io.cloudbeaver.model.log.SLF4JLogHandler;
import io.cloudbeaver.model.rm.local.LocalResourceController;
import io.cloudbeaver.server.WebWorkspace;
@@ -198,4 +199,9 @@ public abstract class BaseWebApplication extends BaseApplicationImpl implements
throw new DBException("Error during generation instance id generation", e);
}
}
@Override
public CBEventController getEventController() {
return null;
}
}
@@ -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
*/
@@ -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;
@@ -31,4 +33,29 @@ public abstract class DBNAbstractResourceManagerNode extends DBNNode implements
node.removeChildResourceNode(resourcePath);
}
}
public void addChildResourceNode(@NotNull Queue<RMResource> resourcePath) {
if (children == null) {
// initialize children
try {
getChildren(new VoidProgressMonitor());
} catch (DBException e) {
return;
}
}
if (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);
children = ArrayUtils.add(DBNResourceManagerResource.class, children, newResourceNode);
return;
}
if (resourcePath.size() > 0) {
node.addChildResourceNode(resourcePath);
}
}
}
@@ -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<RMResource> 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<DBNResourceManagerProject> getProjectNode(RMProject project) {
return Arrays.stream(projects)
.filter(rmProjectNode -> rmProjectNode.getProject().getId().equals(project.getId()))
.findFirst();
}
private void addResourceNode(RMProject project, List<RMResource> resourcePath) {
var projectNode = getProjectNode(project);
projectNode.ifPresent(dbnResourceManagerProject -> dbnResourceManagerProject.addChildResourceNode(new ArrayDeque<>(resourcePath)));
}
}
@@ -293,7 +293,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,
@Nullable List<String> dataSourceIds
) throws DBException {
final DBPProject project = getProjectMetadata(projectId);
final DBPDataSourceRegistry registry = project.getDataSourceRegistry();
final DBPDataSourceConfigurationStorage storage = new DataSourceMemoryStorage(configuration.getBytes(StandardCharsets.UTF_8));
@@ -393,6 +397,7 @@ public class LocalResourceController implements RMController {
} catch (IOException e) {
throw new DBException("Error creating resource '" + resourcePath + "'", e);
}
fireRmResourceAddEvent(projectId, resourcePath);
return DEFAULT_CHANGE_ID;
}
@@ -403,6 +408,7 @@ public class LocalResourceController implements RMController {
@NotNull String newResourcePath
) throws DBException {
Path oldTargetPath = getTargetPath(projectId, oldResourcePath);
List<RMResource> rmOldResourcePath = makeResourcePath(projectId, oldTargetPath, false);
if (!Files.exists(oldTargetPath)) {
throw new DBException("Resource '" + oldTargetPath + "' doesn't exists");
}
@@ -413,6 +419,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;
}
@@ -437,12 +445,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
@@ -496,7 +499,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;
}
@@ -703,10 +708,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<RMResource> 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;
@@ -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;
@@ -34,10 +36,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);
@@ -205,4 +204,27 @@ public class WebAppUtils {
String globalConfigurationName = getWebApplication().getDefaultProjectName();
return RMProjectType.GLOBAL.getPrefix() + "_" + globalConfigurationName;
}
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(), "dataSourceIds", new String[] {datasourceId})
)
);
}
public static void addRmResourceUpdatedEvent(String eventId, String projectId, String resourcePath) {
getWebApplication().getEventController().addEvent(
new CBEvent(eventId,
Map.of(
"projectId", projectId,
"resourcePath", resourcePath
)
)
);
}
}
@@ -48,6 +48,8 @@
<extension point="io.cloudbeaver.event.handler">
<eventHandler class="io.cloudbeaver.server.events.CBConfigurationChangedEventHandler"/>
<eventHandler class="io.cloudbeaver.server.events.CBDataSourceUpdatedEventHandlerImpl"/>\
<eventHandler class="io.cloudbeaver.server.events.CBRmResourceUpdatedEventHandlerImpl"/>
</extension>
</plugin>
@@ -388,7 +388,9 @@ type LogEntry {
}
enum CBEventType {
cb_config_changed
cb_config_changed,
cb_datasource_updated,
cb_rm_resource_updated
}
type CBEvent {
@@ -1056,4 +1056,9 @@ public class CBApplication extends BaseWebApplication implements WebAuthApplicat
newConfig.put(key, newConfigValue);
}
}
@Override
public CBEventController getEventController() {
return eventController;
}
}
@@ -0,0 +1,47 @@
/*
* 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.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.data.json.JSONUtils;
/**
* 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(), "projectId");
VirtualProjectImpl project = activeUserSession.getProjectById(projectId);
if (project == null || !project.getRmProject().isShared()) {
return;
}
activeUserSession.refreshUserData();
activeUserSession.addSessionEvent(event);
}
}
@@ -0,0 +1,48 @@
/*
* 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.CBEventHandler;
import io.cloudbeaver.model.session.WebSession;
import io.cloudbeaver.server.CBPlatform;
import org.jkiss.code.NotNull;
import org.jkiss.dbeaver.Log;
import java.util.Collection;
/**
* Notify all active user session that project has been updated
*/
public abstract class CBProjectUpdatedEventHandler implements CBEventHandler {
private static final Log log = Log.getLog(CBProjectUpdatedEventHandler.class);
@NotNull
@Override
public abstract String getSupportedEventType();
@Override
public void handleEvent(@NotNull CBEvent event) {
log.debug(getSupportedEventType() + " event handled");
Collection<WebSession> allSessions = CBPlatform.getInstance().getSessionManager().getAllActiveSessions();
for (WebSession activeUserSession : allSessions) {
updateSessionData(activeUserSession, event);
}
}
protected abstract void updateSessionData(WebSession activeUserSession, CBEvent event);
}
@@ -0,0 +1,77 @@
/*
* 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 com.google.gson.Gson;
import com.google.gson.GsonBuilder;
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
*/
public class CBRmResourceUpdatedEventHandlerImpl extends CBProjectUpdatedEventHandler {
private static final Gson gson = new GsonBuilder().create();
@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(), "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;
}
VirtualProjectImpl project = activeUserSession.getProjectById(projectId);
if (project == null) {
return;
}
List<RMResource> rmResourcePath = Arrays.asList(resourceParsedPath);
if (eventType.equals("TYPE_CREATE")) {
RMEventManager.fireEvent(
new RMEvent(RMEvent.Action.RESOURCE_ADD,
project.getRmProject(),
rmResourcePath)
);
} else if (eventType.equals("TYPE_DELETE")) {
RMEventManager.fireEvent(
new RMEvent(RMEvent.Action.RESOURCE_DELETE,
project.getRmProject(),
rmResourcePath)
);
}
activeUserSession.addSessionEvent(event);
}
}
@@ -29,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;
@@ -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));
WebAppUtils.addDataSourceUpdatedEvent(webSession.getProjectById(projectId), connectionInfo.getId());
return connectionInfo;
}
@@ -439,7 +440,7 @@ public class WebServiceCore implements DBWServiceCore {
} catch (DBException e) {
throw new DBWebException("Failed to update connection", e);
}
WebAppUtils.addDataSourceUpdatedEvent(webSession.getProjectById(projectId), connectionInfo.getId());
return connectionInfo;
}
@@ -453,6 +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), connectionId);
return true;
}
@@ -489,6 +491,8 @@ public class WebServiceCore implements DBWServiceCore {
WebConnectionInfo connectionInfo = new WebConnectionInfo(webSession, newDataSource);
webSession.addConnection(connectionInfo);
WebAppUtils.addDataSourceUpdatedEvent(webSession.getProjectById(projectId), connectionInfo.getId());
return connectionInfo;
}
@@ -529,6 +533,7 @@ public class WebServiceCore implements DBWServiceCore {
WebConnectionInfo connectionInfo = new WebConnectionInfo(webSession, newDataSource);
dataSourceRegistry.checkForErrors();
webSession.addConnection(connectionInfo);
WebAppUtils.addDataSourceUpdatedEvent(webSession.getProjectById(projectId), connectionInfo.getId());
return connectionInfo;
} catch (DBException e) {
throw new DBWebException("Error copying connection", e);
@@ -707,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), folderInfo.getId());
return folderInfo;
} catch (DBException e) {
throw new DBWebException(e.getMessage(), e);
@@ -725,6 +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), folderInfo.getId());
return folderInfo;
}
@@ -742,6 +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), folderInfo.getId());
} catch (DBException e) {
throw new DBWebException(e.getMessage(), e);
}
@@ -756,6 +763,7 @@ public class WebServiceCore implements DBWServiceCore {
DataSourceDescriptor dataSourceDescriptor = ((DataSourceDescriptor)connectionInfo.getDataSourceContainer());
dataSourceDescriptor.setNavigatorSettings(settings);
dataSourceDescriptor.persistConfiguration();
WebAppUtils.addDataSourceUpdatedEvent(webSession.getProjectById(projectId), id);
return connectionInfo;
}
@@ -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(), ((DBNDataSource) node).getDataSourceContainer().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(), ((DBNLocalFolder) node).getFolder().getFolderPath());
} 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");
}
@@ -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);