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 14d324158e..9c4b6b6c32 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 @@ -676,6 +676,10 @@ public class WebSession extends AbstractSessionPersistent implements SMSession, } } + public void addInfoMessage(String message) { + addSessionMessage(new WebServerMessage(WebServerMessage.MessageType.INFO, message)); + } + public List readLog(Integer maxEntries, Boolean clearLog) { synchronized (sessionMessages) { List messages = new ArrayList<>(); 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 ada59adda2..5110bfb1db 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/WebServiceUtils.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/WebServiceUtils.java @@ -363,4 +363,11 @@ public class WebServiceUtils extends WebCommonUtils { WebActionParameters.saveToSession(webSession, actionParameters); } + public static String getConnectionContainerInfo(DBPDataSourceContainer container) { + if (container == null) { + return null; + } + return container.getName() + " [" + container.getId() + "]"; + } + } 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 d4d5e89d9a..3fa497576e 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 @@ -289,6 +289,7 @@ public class WebServiceCore implements DBWServiceCore { if (!CBApplication.getInstance().getAppConfiguration().isSupportsCustomConnections()) { throw new DBWebException("New connection create is restricted by server configuration"); } + webSession.addInfoMessage("Create new connection"); DBPDataSourceRegistry sessionRegistry = webSession.getSingletonProject().getDataSourceRegistry(); DBPDataSourceContainer newDataSource = WebServiceUtils.createConnectionFromConfig(connectionConfig, sessionRegistry); @@ -301,6 +302,7 @@ public class WebServiceCore implements DBWServiceCore { WebConnectionInfo connectionInfo = new WebConnectionInfo(webSession, newDataSource); webSession.addConnection(connectionInfo); + webSession.addInfoMessage("New connection was created - " + WebServiceUtils.getConnectionContainerInfo(newDataSource)); return connectionInfo; } @@ -315,6 +317,7 @@ public class WebServiceCore implements DBWServiceCore { WebConnectionInfo connectionInfo = webSession.getWebConnectionInfo(config.getConnectionId()); DBPDataSourceContainer dataSource = connectionInfo.getDataSourceContainer(); + webSession.addInfoMessage("Update connection - " + WebServiceUtils.getConnectionContainerInfo(dataSource)); if (!CommonUtils.isEmpty(config.getName())) { dataSource.setName(config.getName()); @@ -336,6 +339,8 @@ public class WebServiceCore implements DBWServiceCore { if (connectionInfo.getDataSourceContainer().getProject() != webSession.getSingletonProject()) { throw new DBWebException("Global connection '" + connectionInfo.getName() + "' configuration cannot be deleted"); } + webSession.addInfoMessage("Delete connection - " + + WebServiceUtils.getConnectionContainerInfo(connectionInfo.getDataSourceContainer())); closeAndDeleteConnection(webSession, connectionId, true); return true; } diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebSQLProcessor.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebSQLProcessor.java index ee3a486998..1286efa9b6 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebSQLProcessor.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebSQLProcessor.java @@ -67,12 +67,13 @@ public class WebSQLProcessor implements WebSessionProvider { private AtomicInteger contextId = new AtomicInteger(); - WebSQLProcessor(@NotNull WebSession webSession, @NotNull WebConnectionInfo connection) { + WebSQLProcessor(@NotNull WebSession webSession, @NotNull WebConnectionInfo connection) { this.webSession = webSession; this.connection = connection; syntaxManager = new SQLSyntaxManager(); - syntaxManager.init(connection.getDataSource().getSQLDialect(), connection.getDataSourceContainer().getPreferenceStore()); + syntaxManager.init( + connection.getDataSource().getSQLDialect(), connection.getDataSourceContainer().getPreferenceStore()); ruleManager = new SQLRuleManager(syntaxManager); ruleManager.loadRules(connection.getDataSource(), false); @@ -296,7 +297,7 @@ public class WebSQLProcessor implements WebSessionProvider { try (DBCSession session = executionContext.openSession(monitor, DBCExecutionPurpose.USER, "Update data in container")) { DBCTransactionManager txnManager = DBUtils.getTransactionManager(executionContext); boolean revertToAutoCommit = false; - if (txnManager != null && txnManager.isSupportsTransactions() && txnManager.isAutoCommit()) { + if (txnManager != null && txnManager.isSupportsTransactions() && txnManager.isAutoCommit()) { txnManager.setAutoCommit(monitor, false); revertToAutoCommit = true; } @@ -563,11 +564,11 @@ public class WebSQLProcessor implements WebSessionProvider { if (!(realCellValue instanceof DBDValue)) { try { realCellValue = updateAttribute.getValueHandler().getValueFromObject( - session, - updateAttribute, - cellRawValue, - false, - true); + session, + updateAttribute, + cellRawValue, + false, + true); } catch (DBCException e) { //checks if this function is used only for script generation if (justGenerateScript) { @@ -624,11 +625,12 @@ public class WebSQLProcessor implements WebSessionProvider { public String readLobValue( - @NotNull DBRProgressMonitor monitor, - @NotNull WebSQLContextInfo contextInfo, - @NotNull String resultsId, - @NotNull Integer lobColumnIndex, - @Nullable WebSQLResultsRow row) throws DBException { + @NotNull DBRProgressMonitor monitor, + @NotNull WebSQLContextInfo contextInfo, + @NotNull String resultsId, + @NotNull Integer lobColumnIndex, + @Nullable WebSQLResultsRow row + ) throws DBException { WebSQLResultsInfo resultsInfo = contextInfo.getResults(resultsId); DBDRowIdentifier rowIdentifier = resultsInfo.getDefaultRowIdentifier(); @@ -648,17 +650,17 @@ public class WebSQLProcessor implements WebSessionProvider { boolean isDocumentValue = keyAttributes.length == 1 && keyAttribute.getDataKind() == DBPDataKind.DOCUMENT && dataContainer instanceof DBSDocumentLocator; if (isDocumentValue) { rowValues[i] = - makeDocumentInputValue(session, (DBSDocumentLocator) dataContainer, resultsInfo, row); + makeDocumentInputValue(session, (DBSDocumentLocator) dataContainer, resultsInfo, row); } else { Object inputCellValue = row.getData().get(keyAttribute.getOrdinalPosition()); rowValues[i] = keyAttribute.getValueHandler().getValueFromObject( - session, - keyAttribute, - convertInputCellValue(session, keyAttribute, - inputCellValue, false), - false, - true); + session, + keyAttribute, + convertInputCellValue(session, keyAttribute, + inputCellValue, false), + false, + true); } final DBDAttributeConstraint constraint = new DBDAttributeConstraint(keyAttribute); constraint.setOperator(DBCLogicalOperator.EQUALS); @@ -667,8 +669,8 @@ public class WebSQLProcessor implements WebSessionProvider { } dataFilter.addConstraints(constraints); DBCStatistics statistics = dataContainer.readData( - executionSource, session, dataReceiver, dataFilter, - 0, 1, DBSDataContainer.FLAG_NONE, 1); + executionSource, session, dataReceiver, dataFilter, + 0, 1, DBSDataContainer.FLAG_NONE, 1); try { return dataReceiver.createLobFile(session); } catch (Exception e) { diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebSQLResultServlet.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebSQLResultServlet.java index 5eebfc5b99..b711238394 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebSQLResultServlet.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/WebSQLResultServlet.java @@ -69,6 +69,7 @@ public class WebSQLResultServlet extends WebServiceServletBase { } File dataFile = new File(WebSQLDataLOBReceiver.DATA_EXPORT_FOLDER, valuePath); + session.addInfoMessage("Download LOB file ..."); response.setHeader("Content-Type", "application/octet-stream"); response.setHeader("Content-Disposition", "attachment; filename=\"" + dataFile.getName() + "\""); response.setHeader("Content-Length", String.valueOf(dataFile.length())); diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/impl/WebServiceSQL.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/impl/WebServiceSQL.java index e8b5d88d1f..7813cd0e13 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/impl/WebServiceSQL.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/service/sql/impl/WebServiceSQL.java @@ -38,7 +38,10 @@ import org.jkiss.dbeaver.model.exec.DBExecUtils; import org.jkiss.dbeaver.model.impl.sql.BasicSQLDialect; import org.jkiss.dbeaver.model.navigator.DBNNode; import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor; -import org.jkiss.dbeaver.model.sql.*; +import org.jkiss.dbeaver.model.sql.SQLDialect; +import org.jkiss.dbeaver.model.sql.SQLQuery; +import org.jkiss.dbeaver.model.sql.SQLScriptElement; +import org.jkiss.dbeaver.model.sql.SQLUtils; import org.jkiss.dbeaver.model.sql.completion.SQLCompletionAnalyzer; import org.jkiss.dbeaver.model.sql.completion.SQLCompletionProposalBase; import org.jkiss.dbeaver.model.sql.completion.SQLCompletionRequest; @@ -266,7 +269,7 @@ public class WebServiceSQL implements DBWServiceSQL { try { sqlContext.setDefaults(catalogName, schemaName); } catch (DBCException e) { - throw new DBWebException("Error changing context defaul schema/catalog", e); + throw new DBWebException("Error changing context default schema/catalog", e); } } diff --git a/server/bundles/io.cloudbeaver.service.admin/src/io/cloudbeaver/service/admin/impl/WebServiceAdmin.java b/server/bundles/io.cloudbeaver.service.admin/src/io/cloudbeaver/service/admin/impl/WebServiceAdmin.java index 1432f0d635..0e1d0a28b7 100644 --- a/server/bundles/io.cloudbeaver.service.admin/src/io/cloudbeaver/service/admin/impl/WebServiceAdmin.java +++ b/server/bundles/io.cloudbeaver.service.admin/src/io/cloudbeaver/service/admin/impl/WebServiceAdmin.java @@ -126,6 +126,8 @@ public class WebServiceAdmin implements DBWServiceAdmin { if (userName.isEmpty()) { throw new DBWebException("Empty user name"); } + webSession.addInfoMessage("Create new user - " + userName); + try { var securityController = webSession.getAdminSecurityController(); securityController.createUser(userName, Map.of()); @@ -141,6 +143,7 @@ public class WebServiceAdmin implements DBWServiceAdmin { if (CommonUtils.equalObjects(userName, webSession.getUser().getUserId())) { throw new DBWebException("You cannot delete yourself"); } + webSession.addInfoMessage("Delete user - " + userName); try { webSession.getAdminSecurityController().deleteUser(userName); return true; @@ -155,6 +158,7 @@ public class WebServiceAdmin implements DBWServiceAdmin { if (roleId.isEmpty()) { throw new DBWebException("Empty role ID"); } + webSession.addInfoMessage("Create new role - " + roleId); try { webSession.getAdminSecurityController().createRole(roleId, roleName, description, webSession.getUser().getUserId()); SMRole newRole = webSession.getAdminSecurityController().findRole(roleId); @@ -170,6 +174,9 @@ public class WebServiceAdmin implements DBWServiceAdmin { if (roleId.isEmpty()) { throw new DBWebException("Empty role ID"); } + + webSession.addInfoMessage("Update role - " + roleId); + try { webSession.getAdminSecurityController().updateRole(roleId, roleName, description); SMRole newRole = webSession.getAdminSecurityController().findRole(roleId); @@ -182,6 +189,8 @@ public class WebServiceAdmin implements DBWServiceAdmin { @Override public boolean deleteRole(@NotNull WebSession webSession, String roleId) throws DBWebException { try { + webSession.addInfoMessage("Delete role - " + roleId); + var adminSecurityController = webSession.getAdminSecurityController(); SMRole[] userRoles = adminSecurityController.getUserRoles(webSession.getUser().getUserId()); if (Arrays.stream(userRoles).anyMatch(DBRole -> DBRole.getRoleId().equals(roleId))) { @@ -250,6 +259,8 @@ public class WebServiceAdmin implements DBWServiceAdmin { if (grantor == null) { throw new DBWebException("Cannot change permissions in anonymous mode"); } + webSession.addInfoMessage("Set permissions to subject - " + roleID); + try { webSession.getAdminSecurityController().setSubjectPermissions(roleID, permissions, grantor.getUserId()); return true; @@ -264,6 +275,8 @@ public class WebServiceAdmin implements DBWServiceAdmin { if (authProvider == null) { throw new DBWebException("Invalid auth provider '" + providerId + "'"); } + webSession.addInfoMessage("Set credentials for user - " + userID); + // Check userId credential. // FIXME: It is actually a hack. All crdentials must be passed from client if (LocalAuthProvider.PROVIDER_ID.equals(providerId)) { @@ -286,6 +299,7 @@ public class WebServiceAdmin implements DBWServiceAdmin { if (CommonUtils.equalObjects(userID, webSession.getUser().getUserId())) { throw new DBWebException("You cannot edit your own permissions"); } + webSession.addInfoMessage("Enable user - " + userID); try { webSession.getAdminSecurityController().enableUser(userID, enabled); return true; @@ -322,10 +336,15 @@ public class WebServiceAdmin implements DBWServiceAdmin { @Override public WebConnectionInfo createConnectionConfiguration(@NotNull WebSession webSession, @NotNull WebConnectionConfig config) throws DBWebException { + + webSession.addInfoMessage("Create new connection"); DBPDataSourceRegistry registry = WebServiceUtils.getGlobalDataSourceRegistry(); DBPDataSourceContainer dataSource = WebServiceUtils.createConnectionFromConfig(config, registry); registry.addDataSource(dataSource); registry.flushConfig(); + webSession.addInfoMessage( + "New connection was created - " + WebServiceUtils.getConnectionContainerInfo(dataSource) + ); return new WebConnectionInfo(webSession, dataSource); } @@ -369,6 +388,9 @@ public class WebServiceAdmin implements DBWServiceAdmin { if (dataSource == null) { throw new DBWebException("Connection '" + id + "' not found"); } + webSession.addInfoMessage( + "Update connection - " + WebServiceUtils.getConnectionContainerInfo(dataSource) + ); WebServiceUtils.updateConnectionFromConfig(dataSource, config); dataSource.persistConfiguration(); // Update local datasource as well. We use it for connection tests @@ -387,6 +409,10 @@ public class WebServiceAdmin implements DBWServiceAdmin { if (dataSource == null) { throw new DBWebException("Connection '" + id + "' not found"); } + + webSession.addInfoMessage( + "Delete connection - " + WebServiceUtils.getConnectionContainerInfo(dataSource) + ); WebServiceUtils.getGlobalDataSourceRegistry().removeDataSource(dataSource); WebServiceUtils.getGlobalDataSourceRegistry().flushConfig(); @@ -447,6 +473,7 @@ public class WebServiceAdmin implements DBWServiceAdmin { if (authProvider == null) { throw new DBWebException("Auth provider '" + providerId + "' not found"); } + webSession.addInfoMessage("Save configuration for auth provider - " + providerId); AuthProviderConfig providerConfig = new AuthProviderConfig(); providerConfig.setProvider(providerId); @@ -466,6 +493,8 @@ public class WebServiceAdmin implements DBWServiceAdmin { @Override public boolean deleteAuthProviderConfiguration(@NotNull WebSession webSession, @NotNull String id) throws DBWebException { + webSession.addInfoMessage("Delete configuration for auth provider - " + id); + if (CBApplication.getInstance().getAppConfiguration().deleteAuthProviderConfiguration(id)) { try { CBApplication.getInstance().flushConfiguration(); diff --git a/server/bundles/io.cloudbeaver.service.auth/src/io/cloudbeaver/service/auth/impl/WebServiceAuthImpl.java b/server/bundles/io.cloudbeaver.service.auth/src/io/cloudbeaver/service/auth/impl/WebServiceAuthImpl.java index dc32d57912..66d3cd47ff 100644 --- a/server/bundles/io.cloudbeaver.service.auth/src/io/cloudbeaver/service/auth/impl/WebServiceAuthImpl.java +++ b/server/bundles/io.cloudbeaver.service.auth/src/io/cloudbeaver/service/auth/impl/WebServiceAuthImpl.java @@ -318,6 +318,7 @@ public class WebServiceAuthImpl implements DBWServiceAuth { @Override public boolean setUserConfigurationParameter(@NotNull WebSession webSession, @NotNull String name, @Nullable String value) throws DBWebException { + webSession.addInfoMessage("Set user parameter - " + name); try { webSession.getSecurityController().setUserParameter( webSession.getUser().getUserId(), diff --git a/server/bundles/io.cloudbeaver.service.data.transfer/src/io/cloudbeaver/service/data/transfer/impl/WebDataTransferServlet.java b/server/bundles/io.cloudbeaver.service.data.transfer/src/io/cloudbeaver/service/data/transfer/impl/WebDataTransferServlet.java index f787740570..3ab5a9471f 100644 --- a/server/bundles/io.cloudbeaver.service.data.transfer/src/io/cloudbeaver/service/data/transfer/impl/WebDataTransferServlet.java +++ b/server/bundles/io.cloudbeaver.service.data.transfer/src/io/cloudbeaver/service/data/transfer/impl/WebDataTransferServlet.java @@ -57,7 +57,7 @@ public class WebDataTransferServlet extends WebServiceServletBase { } File dataFile = taskInfo.getDataFile(); - + session.addInfoMessage("Download data ..."); response.setHeader("Content-Type", processor.getContentType()); response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\""); response.setHeader("Content-Length", String.valueOf(dataFile.length())); diff --git a/server/bundles/io.cloudbeaver.service.data.transfer/src/io/cloudbeaver/service/data/transfer/impl/WebServiceDataTransfer.java b/server/bundles/io.cloudbeaver.service.data.transfer/src/io/cloudbeaver/service/data/transfer/impl/WebServiceDataTransfer.java index 95a0bcc5b2..7f3860c785 100644 --- a/server/bundles/io.cloudbeaver.service.data.transfer/src/io/cloudbeaver/service/data/transfer/impl/WebServiceDataTransfer.java +++ b/server/bundles/io.cloudbeaver.service.data.transfer/src/io/cloudbeaver/service/data/transfer/impl/WebServiceDataTransfer.java @@ -143,6 +143,7 @@ public class WebServiceDataTransfer implements DBWServiceDataTransfer { private WebAsyncTaskInfo asyncExportFromDataContainer(WebSQLProcessor sqlProcessor, WebDataTransferParameters parameters, DBSDataContainer dataContainer, @Nullable WebSQLResultsInfo resultsInfo) { + sqlProcessor.getWebSession().addInfoMessage("Export data"); DataTransferProcessorDescriptor processor = DataTransferRegistry.getInstance().getProcessor(parameters.getProcessorId()); WebAsyncTaskProcessor runnable = new WebAsyncTaskProcessor() { @Override