From 36266135370041e2e472a5b243be7df4ebd90528 Mon Sep 17 00:00:00 2001 From: Ainur Date: Tue, 24 Dec 2024 11:13:14 +0100 Subject: [PATCH 01/12] CB-6051 wip --- .../registry/WebDriverRegistry.java | 5 +++++ .../src/io/cloudbeaver/server/CBPlatform.java | 17 +++++++++++++--- .../src/io/cloudbeaver/WebServiceUtils.java | 7 +++++++ .../model/WebDatabaseDriverInfo.java | 6 +++--- .../model/WebDriverLibraryInfo.java | 20 +++++++++++++++---- .../service/core/impl/WebServiceCore.java | 5 ++++- 6 files changed, 49 insertions(+), 11 deletions(-) diff --git a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/registry/WebDriverRegistry.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/registry/WebDriverRegistry.java index 132d8806ff..7ea1b8611a 100644 --- a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/registry/WebDriverRegistry.java +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/registry/WebDriverRegistry.java @@ -63,4 +63,9 @@ public boolean isDriverEnabled(DBPDriver driver) { return webDrivers.contains(driver.getFullId()); } + + public boolean validateDriverFilesAvailability() { + return true; + } + } diff --git a/server/bundles/io.cloudbeaver.server.ce/src/io/cloudbeaver/server/CBPlatform.java b/server/bundles/io.cloudbeaver.server.ce/src/io/cloudbeaver/server/CBPlatform.java index 3adab6265c..93928cf52c 100644 --- a/server/bundles/io.cloudbeaver.server.ce/src/io/cloudbeaver/server/CBPlatform.java +++ b/server/bundles/io.cloudbeaver.server.ce/src/io/cloudbeaver/server/CBPlatform.java @@ -18,6 +18,7 @@ package io.cloudbeaver.server; import io.cloudbeaver.auth.NoAuthCredentialsProvider; +import io.cloudbeaver.registry.WebDriverRegistry; import io.cloudbeaver.server.jobs.SessionStateJob; import io.cloudbeaver.server.jobs.WebDataSourceMonitorJob; import io.cloudbeaver.server.jobs.WebSessionMonitorJob; @@ -39,6 +40,7 @@ import java.io.IOException; import java.nio.file.Files; +import java.nio.file.Path; import java.util.ArrayList; import java.util.List; import java.util.stream.Collectors; @@ -142,18 +144,19 @@ public boolean isShuttingDown() { public void refreshApplicableDrivers() { this.applicableDrivers.clear(); + assert application != null; + WebDriverRegistry driverRegistry = application.getDriverRegistry(); for (DBPDataSourceProviderDescriptor dspd : DataSourceProviderRegistry.getInstance().getEnabledDataSourceProviders()) { for (DBPDriver driver : dspd.getEnabledDrivers()) { List libraries = driver.getDriverLibraries(); { - if (!application.getDriverRegistry().isDriverEnabled(driver)) { + if (!driverRegistry.isDriverEnabled(driver)) { continue; } boolean hasAllFiles = true, hasJars = false; for (DBPDriverLibrary lib : libraries) { - if (!DBWorkbench.isDistributed() && !lib.isOptional() && lib.getType() != DBPDriverLibrary.FileType.license && - (lib.getLocalFile() == null || !Files.exists(lib.getLocalFile()))) + if (driverRegistry.validateDriverFilesAvailability() && !isDriverLibraryFilePresent(lib)) { hasAllFiles = false; log.error("\tDriver '" + driver.getId() + "' is missing library '" + lib.getDisplayName() + "'"); @@ -172,6 +175,14 @@ public void refreshApplicableDrivers() { log.info("Available drivers: " + applicableDrivers.stream().map(DBPDriver::getFullName).collect(Collectors.joining(","))); } + private boolean isDriverLibraryFilePresent(@NotNull DBPDriverLibrary lib) { + if (lib.getType() == DBPDriverLibrary.FileType.license) { + return true; + } + Path localFile = lib.getLocalFile(); + return localFile != null && Files.exists(localFile); + } + @NotNull @Override public DBFileController createFileController() { 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 a74ff5bafd..b58aa495eb 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/WebServiceUtils.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/WebServiceUtils.java @@ -400,4 +400,11 @@ public static WebPropertyInfo[] getObjectFilteredProperties( } return webProps.toArray(new WebPropertyInfo[0]); } + + public static void validateDriverLibrariesPresence(@NotNull DBPDataSourceContainer container) throws DBWebException { + if (container.getDriver().needsExternalDependencies()) { + throw new DBWebException("Driver files for %s are not found. Please, ask administrator to download it." + .formatted(container.getDriver().getName())); + } + } } diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/model/WebDatabaseDriverInfo.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/model/WebDatabaseDriverInfo.java index 47aabec821..b868dc05f9 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/model/WebDatabaseDriverInfo.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/model/WebDatabaseDriverInfo.java @@ -53,7 +53,7 @@ public class WebDatabaseDriverInfo { public static final String URL_DATABASE_FIELD = ".*(?:\\{(?:database|file|folder)}).*"; private final WebSession webSession; private final DBPDriver driver; - private String id; + private final String id; public WebDatabaseDriverInfo(WebSession webSession, DBPDriver driver) { this.webSession = webSession; @@ -296,13 +296,13 @@ public boolean getRequiresDatabaseName() { @Property public WebDriverLibraryInfo[] getDriverLibraries() { return driver.getDriverLibraries().stream() - .map(dbpDriverLibrary -> new WebDriverLibraryInfo(webSession, dbpDriverLibrary)) + .map(dbpDriverLibrary -> new WebDriverLibraryInfo(driver, dbpDriverLibrary)) .toArray(WebDriverLibraryInfo[]::new); } @Property public boolean isDriverInstalled() { - return !driver.needsExternalDependencies(webSession.getProgressMonitor()); + return !driver.needsExternalDependencies(); } @Property diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/model/WebDriverLibraryInfo.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/model/WebDriverLibraryInfo.java index fdf9b75d29..ab2c73b1e5 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/model/WebDriverLibraryInfo.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/model/WebDriverLibraryInfo.java @@ -17,18 +17,23 @@ package io.cloudbeaver.model; import io.cloudbeaver.WebServiceUtils; -import io.cloudbeaver.model.session.WebSession; import org.jkiss.code.NotNull; +import org.jkiss.dbeaver.model.connection.DBPDriver; import org.jkiss.dbeaver.model.connection.DBPDriverLibrary; import org.jkiss.dbeaver.model.meta.Property; +import org.jkiss.dbeaver.registry.driver.DriverDescriptor; + +import java.util.List; public class WebDriverLibraryInfo { - private final WebSession webSession; + @NotNull + private final DBPDriver driver; + @NotNull private final DBPDriverLibrary driverLibrary; - public WebDriverLibraryInfo(@NotNull WebSession webSession, @NotNull DBPDriverLibrary driverLibrary) { - this.webSession = webSession; + public WebDriverLibraryInfo(@NotNull DBPDriver driver, @NotNull DBPDriverLibrary driverLibrary) { + this.driver = driver; this.driverLibrary = driverLibrary; } @@ -43,6 +48,13 @@ public String getName() { return driverLibrary.getDisplayName(); } + @Property + public List getLibraryFiles() { + return ((DriverDescriptor) driver).getLibraryFiles(driverLibrary).stream() + .map(f -> f.getFile().getFileName().toString()) + .toList(); + } + @Property public String getIcon() { return WebServiceUtils.makeIconId(driverLibrary.getIcon()); 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 4461424b01..d487760586 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 @@ -366,8 +366,10 @@ public WebConnectionInfo initConnection( } boolean oldSavePassword = dataSourceContainer.isSavePassword(); + DBRProgressMonitor monitor = webSession.getProgressMonitor(); + WebServiceUtils.validateDriverLibrariesPresence(dataSourceContainer); try { - boolean connect = dataSourceContainer.connect(webSession.getProgressMonitor(), true, false); + boolean connect = dataSourceContainer.connect(monitor, true, false); if (connect) { webSession.addSessionEvent( new WSDataSourceConnectEvent( @@ -755,6 +757,7 @@ public WebConnectionInfo testConnection( testDataSource = (DataSourceDescriptor) WebServiceUtils.createConnectionFromConfig(connectionConfig, sessionRegistry); } + WebServiceUtils.validateDriverLibrariesPresence(testDataSource); webSession.provideAuthParameters(webSession.getProgressMonitor(), testDataSource, testDataSource.getConnectionConfiguration()); From ea113439f7fce9bb791f7fc871f0f0232773dbad Mon Sep 17 00:00:00 2001 From: Ainur Date: Tue, 24 Dec 2024 13:15:26 +0100 Subject: [PATCH 02/12] CB-6051 refresh drivers after loading server config --- .../src/io/cloudbeaver/server/CBApplication.java | 1 + .../src/io/cloudbeaver/server/CBPlatform.java | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/server/bundles/io.cloudbeaver.server.ce/src/io/cloudbeaver/server/CBApplication.java b/server/bundles/io.cloudbeaver.server.ce/src/io/cloudbeaver/server/CBApplication.java index ebe007cceb..24d0b2bd7c 100644 --- a/server/bundles/io.cloudbeaver.server.ce/src/io/cloudbeaver/server/CBApplication.java +++ b/server/bundles/io.cloudbeaver.server.ce/src/io/cloudbeaver/server/CBApplication.java @@ -735,6 +735,7 @@ protected void sendConfigChangedEvent(SMCredentialsProvider credentialsProvider) public abstract CBServerConfigurationController getServerConfigurationController(); private void refreshDisabledDriversConfig() { + CBPlatform.getInstance().refreshApplicableDrivers(); CBAppConfig config = getAppConfiguration(); Set disabledDrivers = new LinkedHashSet<>(Arrays.asList(config.getDisabledDrivers())); for (DBPDriver driver : CBPlatform.getInstance().getApplicableDrivers()) { diff --git a/server/bundles/io.cloudbeaver.server.ce/src/io/cloudbeaver/server/CBPlatform.java b/server/bundles/io.cloudbeaver.server.ce/src/io/cloudbeaver/server/CBPlatform.java index 93928cf52c..0ac02e0a0f 100644 --- a/server/bundles/io.cloudbeaver.server.ce/src/io/cloudbeaver/server/CBPlatform.java +++ b/server/bundles/io.cloudbeaver.server.ce/src/io/cloudbeaver/server/CBPlatform.java @@ -78,8 +78,6 @@ protected synchronized void initialize() { log.info("Initialize web platform...: "); this.preferenceStore = new WebServerPreferenceStore(WebPlatformActivator.getInstance().getPreferences()); super.initialize(); - refreshApplicableDrivers(); - scheduleServerJobs(); log.info("Web platform initialized (" + (System.currentTimeMillis() - startTime) + "ms)"); } From e297174aa23daac39512b2aa669034366877d1e4 Mon Sep 17 00:00:00 2001 From: Ainur Date: Tue, 24 Dec 2024 17:44:00 +0100 Subject: [PATCH 03/12] CB-6051 api for lib file info --- .../schema/service.core.graphqls | 7 +++ .../model/WebDriverLibraryFileInfo.java | 53 +++++++++++++++++++ .../model/WebDriverLibraryInfo.java | 12 +++-- 3 files changed, 69 insertions(+), 3 deletions(-) create mode 100644 server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/model/WebDriverLibraryFileInfo.java diff --git a/server/bundles/io.cloudbeaver.server/schema/service.core.graphqls b/server/bundles/io.cloudbeaver.server/schema/service.core.graphqls index ccd536c6a4..379306478b 100644 --- a/server/bundles/io.cloudbeaver.server/schema/service.core.graphqls +++ b/server/bundles/io.cloudbeaver.server/schema/service.core.graphqls @@ -269,6 +269,13 @@ type DriverLibraryInfo { id: ID! name: String! icon: String + libraryFiles: [DriverFileInfo!] +} + +type DriverFileInfo @since(version: "24.3.2") { + id: ID! + fileName: String! + icon: String } enum ResultDataFormat { diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/model/WebDriverLibraryFileInfo.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/model/WebDriverLibraryFileInfo.java new file mode 100644 index 0000000000..b04729f6de --- /dev/null +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/model/WebDriverLibraryFileInfo.java @@ -0,0 +1,53 @@ +/* + * DBeaver - Universal Database Manager + * Copyright (C) 2010-2024 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.model; + +import io.cloudbeaver.WebServiceUtils; +import org.jkiss.code.NotNull; +import org.jkiss.dbeaver.model.DBIcon; +import org.jkiss.dbeaver.model.connection.DBPDriverLibrary; +import org.jkiss.dbeaver.model.meta.Property; +import org.jkiss.dbeaver.registry.driver.DriverDescriptor; + +public class WebDriverLibraryFileInfo { + + @NotNull + private final DriverDescriptor.DriverFileInfo fileInfo; + + public WebDriverLibraryFileInfo(@NotNull DriverDescriptor.DriverFileInfo fileInfo) { + this.fileInfo = fileInfo; + } + + + @Property + public String getId() { + return fileInfo.getId(); + } + + @Property + public String getFileName() { + return fileInfo.toString(); + } + + @Property + public String getIcon() { + if (fileInfo.getType() == DBPDriverLibrary.FileType.license) { + return WebServiceUtils.makeIconId(DBIcon.TYPE_TEXT); + } + return WebServiceUtils.makeIconId(DBIcon.JAR); + } +} diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/model/WebDriverLibraryInfo.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/model/WebDriverLibraryInfo.java index ab2c73b1e5..d8e3ad9844 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/model/WebDriverLibraryInfo.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/model/WebDriverLibraryInfo.java @@ -18,6 +18,7 @@ import io.cloudbeaver.WebServiceUtils; import org.jkiss.code.NotNull; +import org.jkiss.code.Nullable; import org.jkiss.dbeaver.model.connection.DBPDriver; import org.jkiss.dbeaver.model.connection.DBPDriverLibrary; import org.jkiss.dbeaver.model.meta.Property; @@ -49,9 +50,14 @@ public String getName() { } @Property - public List getLibraryFiles() { - return ((DriverDescriptor) driver).getLibraryFiles(driverLibrary).stream() - .map(f -> f.getFile().getFileName().toString()) + @Nullable + public List getLibraryFiles() { + var libraryFiles = ((DriverDescriptor) driver).getLibraryFiles(driverLibrary); + if (libraryFiles == null) { + return null; + } + return libraryFiles.stream() + .map(WebDriverLibraryFileInfo::new) .toList(); } From 85baf9c0a1f342b046761ecd389a4e01c8a5388d Mon Sep 17 00:00:00 2001 From: naumov Date: Tue, 24 Dec 2024 22:17:22 +0100 Subject: [PATCH 04/12] CB-6071 show installed status --- .../src/queries/fragments/DatabaseDriver.gql | 2 ++ .../src/DriverSelector/Driver.module.css | 18 +++++++++++++++++- .../src/DriverSelector/Driver.tsx | 11 +++++++++-- .../plugin-connection-custom/src/locales/en.ts | 5 ++++- .../plugin-connection-custom/src/locales/fr.ts | 5 ++++- .../plugin-connection-custom/src/locales/it.ts | 5 ++++- .../plugin-connection-custom/src/locales/ru.ts | 5 ++++- .../plugin-connection-custom/src/locales/zh.ts | 5 ++++- 8 files changed, 48 insertions(+), 8 deletions(-) diff --git a/webapp/packages/core-sdk/src/queries/fragments/DatabaseDriver.gql b/webapp/packages/core-sdk/src/queries/fragments/DatabaseDriver.gql index 7a84c0a15a..6d9b9e30b0 100644 --- a/webapp/packages/core-sdk/src/queries/fragments/DatabaseDriver.gql +++ b/webapp/packages/core-sdk/src/queries/fragments/DatabaseDriver.gql @@ -22,6 +22,8 @@ fragment DatabaseDriver on DriverInfo { applicableAuthModels applicableNetworkHandlers configurationTypes + driverId + driverInstalled mainProperties @include(if: $includeMainProperties) { ...DriverPropertyInfo diff --git a/webapp/packages/plugin-connection-custom/src/DriverSelector/Driver.module.css b/webapp/packages/plugin-connection-custom/src/DriverSelector/Driver.module.css index 1563215dc9..e05eacc1fa 100644 --- a/webapp/packages/plugin-connection-custom/src/DriverSelector/Driver.module.css +++ b/webapp/packages/plugin-connection-custom/src/DriverSelector/Driver.module.css @@ -5,8 +5,24 @@ * Licensed under the Apache License, Version 2.0. * you may not use this file except in compliance with the License. */ +.icon { + position: relative; +} + .staticImage { box-sizing: border-box; width: 24px; max-height: 24px; -}; +} + +.indicator { + position: absolute; + bottom: 2px; + right: 0; + width: 12px; + height: 12px; + display: flex; + border-radius: 50%; + background-color: var(--theme-surface); + border: 1px solid var(--theme-surface); +} diff --git a/webapp/packages/plugin-connection-custom/src/DriverSelector/Driver.tsx b/webapp/packages/plugin-connection-custom/src/DriverSelector/Driver.tsx index fdb52fe310..9fbf58bf0d 100644 --- a/webapp/packages/plugin-connection-custom/src/DriverSelector/Driver.tsx +++ b/webapp/packages/plugin-connection-custom/src/DriverSelector/Driver.tsx @@ -8,7 +8,7 @@ import { observer } from 'mobx-react-lite'; import { useCallback } from 'react'; -import { ListItem, ListItemDescription, ListItemIcon, ListItemName, s, StaticImage, useS } from '@cloudbeaver/core-blocks'; +import { IconOrImage, ListItem, ListItemDescription, ListItemIcon, ListItemName, s, StaticImage, useS, useTranslate } from '@cloudbeaver/core-blocks'; import style from './Driver.module.css'; @@ -17,6 +17,7 @@ export interface IDriver { icon?: string; name?: string; description?: string; + driverInstalled?: boolean; } interface Props { @@ -25,13 +26,19 @@ interface Props { } export const Driver = observer(function Driver({ driver, onSelect }) { + const translate = useTranslate(); const select = useCallback(() => onSelect(driver.id), [driver]); const styles = useS(style); return ( - + + {!driver.driverInstalled && ( +
+ +
+ )}
{driver.name} {driver.description} diff --git a/webapp/packages/plugin-connection-custom/src/locales/en.ts b/webapp/packages/plugin-connection-custom/src/locales/en.ts index 3c03aca9cf..290e841494 100644 --- a/webapp/packages/plugin-connection-custom/src/locales/en.ts +++ b/webapp/packages/plugin-connection-custom/src/locales/en.ts @@ -5,4 +5,7 @@ * Licensed under the Apache License, Version 2.0. * you may not use this file except in compliance with the License. */ -export default [['plugin_connection_custom_action_custom_label', 'New Connection']]; +export default [ + ['plugin_connection_custom_action_custom_label', 'New Connection'], + ['plugin_connection_custom_drivers_driver_not_installed', 'Driver is not installed'], +]; diff --git a/webapp/packages/plugin-connection-custom/src/locales/fr.ts b/webapp/packages/plugin-connection-custom/src/locales/fr.ts index 4c0f72d04d..63aeb3523b 100644 --- a/webapp/packages/plugin-connection-custom/src/locales/fr.ts +++ b/webapp/packages/plugin-connection-custom/src/locales/fr.ts @@ -5,4 +5,7 @@ * Licensed under the Apache License, Version 2.0. * you may not use this file except in compliance with the License. */ -export default [['plugin_connection_custom_action_custom_label', 'Nouvelle connexion']]; +export default [ + ['plugin_connection_custom_action_custom_label', 'Nouvelle connexion'], + ['plugin_connection_custom_drivers_driver_not_installed', 'Driver is not installed'], +]; diff --git a/webapp/packages/plugin-connection-custom/src/locales/it.ts b/webapp/packages/plugin-connection-custom/src/locales/it.ts index 3c03aca9cf..290e841494 100644 --- a/webapp/packages/plugin-connection-custom/src/locales/it.ts +++ b/webapp/packages/plugin-connection-custom/src/locales/it.ts @@ -5,4 +5,7 @@ * Licensed under the Apache License, Version 2.0. * you may not use this file except in compliance with the License. */ -export default [['plugin_connection_custom_action_custom_label', 'New Connection']]; +export default [ + ['plugin_connection_custom_action_custom_label', 'New Connection'], + ['plugin_connection_custom_drivers_driver_not_installed', 'Driver is not installed'], +]; diff --git a/webapp/packages/plugin-connection-custom/src/locales/ru.ts b/webapp/packages/plugin-connection-custom/src/locales/ru.ts index 4d4f153ef8..76eb1d7456 100644 --- a/webapp/packages/plugin-connection-custom/src/locales/ru.ts +++ b/webapp/packages/plugin-connection-custom/src/locales/ru.ts @@ -5,4 +5,7 @@ * Licensed under the Apache License, Version 2.0. * you may not use this file except in compliance with the License. */ -export default [['plugin_connection_custom_action_custom_label', 'Новое подключение']]; +export default [ + ['plugin_connection_custom_action_custom_label', 'Новое подключение'], + ['plugin_connection_custom_drivers_driver_not_installed', 'Драйвер не установлен'], +]; diff --git a/webapp/packages/plugin-connection-custom/src/locales/zh.ts b/webapp/packages/plugin-connection-custom/src/locales/zh.ts index 0de6a0635e..b2c7c30da4 100644 --- a/webapp/packages/plugin-connection-custom/src/locales/zh.ts +++ b/webapp/packages/plugin-connection-custom/src/locales/zh.ts @@ -5,4 +5,7 @@ * Licensed under the Apache License, Version 2.0. * you may not use this file except in compliance with the License. */ -export default [['plugin_connection_custom_action_custom_label', '新建连接']]; +export default [ + ['plugin_connection_custom_action_custom_label', '新建连接'], + ['plugin_connection_custom_drivers_driver_not_installed', 'Driver is not installed'], +]; From 2d4d151a0be64a49ed54fd78e689b65c8c1b81b7 Mon Sep 17 00:00:00 2001 From: naumov Date: Wed, 25 Dec 2024 19:16:01 +0100 Subject: [PATCH 05/12] CB-6051 make icon larger --- .../src/DriverSelector/Driver.module.css | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/webapp/packages/plugin-connection-custom/src/DriverSelector/Driver.module.css b/webapp/packages/plugin-connection-custom/src/DriverSelector/Driver.module.css index e05eacc1fa..2467b6cf2c 100644 --- a/webapp/packages/plugin-connection-custom/src/DriverSelector/Driver.module.css +++ b/webapp/packages/plugin-connection-custom/src/DriverSelector/Driver.module.css @@ -19,8 +19,8 @@ position: absolute; bottom: 2px; right: 0; - width: 12px; - height: 12px; + width: 14px; + height: 14px; display: flex; border-radius: 50%; background-color: var(--theme-surface); From 690d71db6138898d0e53d46ec6ecfa526b14f313 Mon Sep 17 00:00:00 2001 From: Ainur Date: Thu, 26 Dec 2024 11:33:00 +0100 Subject: [PATCH 06/12] CB-6051 move out applicable drivers from platform class --- .../registry/WebDriverRegistry.java | 50 +++++++++++++++-- .../io/cloudbeaver/server/CBApplication.java | 4 +- .../src/io/cloudbeaver/server/CBPlatform.java | 56 ------------------- .../src/io/cloudbeaver/WebServiceUtils.java | 2 +- .../cloudbeaver/server/BaseWebPlatform.java | 3 - .../service/core/impl/WebServiceCore.java | 6 +- .../admin/impl/ConnectionSearcher.java | 5 +- .../service/admin/impl/WebServiceAdmin.java | 4 +- 8 files changed, 56 insertions(+), 74 deletions(-) diff --git a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/registry/WebDriverRegistry.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/registry/WebDriverRegistry.java index 7ea1b8611a..ca632515c5 100644 --- a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/registry/WebDriverRegistry.java +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/registry/WebDriverRegistry.java @@ -19,11 +19,20 @@ import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IExtensionRegistry; import org.eclipse.core.runtime.Platform; +import org.jkiss.code.NotNull; import org.jkiss.dbeaver.Log; +import org.jkiss.dbeaver.model.connection.DBPDataSourceProviderDescriptor; import org.jkiss.dbeaver.model.connection.DBPDriver; +import org.jkiss.dbeaver.model.connection.DBPDriverLibrary; +import org.jkiss.dbeaver.registry.DataSourceProviderRegistry; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; import java.util.HashSet; +import java.util.List; import java.util.Set; +import java.util.stream.Collectors; public class WebDriverRegistry { @@ -42,6 +51,7 @@ public synchronized static WebDriverRegistry getInstance() { return instance; } + private final List applicableDrivers = new ArrayList<>(); private final Set webDrivers = new HashSet<>(); protected WebDriverRegistry() { @@ -59,13 +69,45 @@ private void loadExtensions(IExtensionRegistry registry) { } } - public boolean isDriverEnabled(DBPDriver driver) { - return webDrivers.contains(driver.getFullId()); + public List getApplicableDrivers() { + return applicableDrivers; } + public void refreshApplicableDrivers() { + this.applicableDrivers.clear(); + this.applicableDrivers.addAll( + DataSourceProviderRegistry.getInstance().getEnabledDataSourceProviders().stream() + .map(DBPDataSourceProviderDescriptor::getEnabledDrivers) + .flatMap(List::stream) + .filter(this::isDriverApplicable) + .toList()); + log.info("Available drivers: " + applicableDrivers.stream().map(DBPDriver::getFullName).collect(Collectors.joining(","))); + } - public boolean validateDriverFilesAvailability() { - return true; + protected boolean isDriverApplicable(@NotNull DBPDriver driver) { + List libraries = driver.getDriverLibraries(); + if (!webDrivers.contains(driver.getFullId())) { + return false; + } + boolean hasAllFiles = true; + for (DBPDriverLibrary lib : libraries) { + if (!isDriverLibraryFilePresent(lib)) { + hasAllFiles = false; + log.error("\tDriver '" + driver.getId() + "' is missing library '" + lib.getDisplayName() + "'"); + } else { + if (lib.getType() == DBPDriverLibrary.FileType.jar) { + return true; + } + } + } + return hasAllFiles; } + private boolean isDriverLibraryFilePresent(@NotNull DBPDriverLibrary lib) { + if (lib.getType() == DBPDriverLibrary.FileType.license) { + return true; + } + Path localFile = lib.getLocalFile(); + return localFile != null && Files.exists(localFile); + } } diff --git a/server/bundles/io.cloudbeaver.server.ce/src/io/cloudbeaver/server/CBApplication.java b/server/bundles/io.cloudbeaver.server.ce/src/io/cloudbeaver/server/CBApplication.java index 24d0b2bd7c..0f6df490d6 100644 --- a/server/bundles/io.cloudbeaver.server.ce/src/io/cloudbeaver/server/CBApplication.java +++ b/server/bundles/io.cloudbeaver.server.ce/src/io/cloudbeaver/server/CBApplication.java @@ -735,10 +735,10 @@ protected void sendConfigChangedEvent(SMCredentialsProvider credentialsProvider) public abstract CBServerConfigurationController getServerConfigurationController(); private void refreshDisabledDriversConfig() { - CBPlatform.getInstance().refreshApplicableDrivers(); + getDriverRegistry().refreshApplicableDrivers(); CBAppConfig config = getAppConfiguration(); Set disabledDrivers = new LinkedHashSet<>(Arrays.asList(config.getDisabledDrivers())); - for (DBPDriver driver : CBPlatform.getInstance().getApplicableDrivers()) { + for (DBPDriver driver : getDriverRegistry().getApplicableDrivers()) { if (!driver.isEmbedded() || config.isDriverForceEnabled(driver.getFullId())) { continue; } diff --git a/server/bundles/io.cloudbeaver.server.ce/src/io/cloudbeaver/server/CBPlatform.java b/server/bundles/io.cloudbeaver.server.ce/src/io/cloudbeaver/server/CBPlatform.java index 0ac02e0a0f..14f7640a66 100644 --- a/server/bundles/io.cloudbeaver.server.ce/src/io/cloudbeaver/server/CBPlatform.java +++ b/server/bundles/io.cloudbeaver.server.ce/src/io/cloudbeaver/server/CBPlatform.java @@ -18,7 +18,6 @@ package io.cloudbeaver.server; import io.cloudbeaver.auth.NoAuthCredentialsProvider; -import io.cloudbeaver.registry.WebDriverRegistry; import io.cloudbeaver.server.jobs.SessionStateJob; import io.cloudbeaver.server.jobs.WebDataSourceMonitorJob; import io.cloudbeaver.server.jobs.WebSessionMonitorJob; @@ -28,22 +27,13 @@ import org.jkiss.code.Nullable; import org.jkiss.dbeaver.Log; import org.jkiss.dbeaver.model.DBFileController; -import org.jkiss.dbeaver.model.connection.DBPDataSourceProviderDescriptor; -import org.jkiss.dbeaver.model.connection.DBPDriver; -import org.jkiss.dbeaver.model.connection.DBPDriverLibrary; import org.jkiss.dbeaver.model.preferences.DBPPreferenceStore; import org.jkiss.dbeaver.model.runtime.AbstractJob; import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor; -import org.jkiss.dbeaver.registry.DataSourceProviderRegistry; import org.jkiss.dbeaver.runtime.DBWorkbench; import org.jkiss.utils.IOUtils; import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.util.ArrayList; -import java.util.List; -import java.util.stream.Collectors; /** * CBPlatform @@ -59,7 +49,6 @@ public class CBPlatform extends BaseWebPlatform { private static CBApplication application = null; private WebServerPreferenceStore preferenceStore; - protected final List applicableDrivers = new ArrayList<>(); public static CBPlatform getInstance() { return (CBPlatform) DBWorkbench.getPlatform(); @@ -124,10 +113,6 @@ public CBApplication getApplication() { return application; } - public List getApplicableDrivers() { - return applicableDrivers; - } - @NotNull @Override @@ -140,47 +125,6 @@ public boolean isShuttingDown() { return false; } - public void refreshApplicableDrivers() { - this.applicableDrivers.clear(); - assert application != null; - WebDriverRegistry driverRegistry = application.getDriverRegistry(); - - for (DBPDataSourceProviderDescriptor dspd : DataSourceProviderRegistry.getInstance().getEnabledDataSourceProviders()) { - for (DBPDriver driver : dspd.getEnabledDrivers()) { - List libraries = driver.getDriverLibraries(); - { - if (!driverRegistry.isDriverEnabled(driver)) { - continue; - } - boolean hasAllFiles = true, hasJars = false; - for (DBPDriverLibrary lib : libraries) { - if (driverRegistry.validateDriverFilesAvailability() && !isDriverLibraryFilePresent(lib)) - { - hasAllFiles = false; - log.error("\tDriver '" + driver.getId() + "' is missing library '" + lib.getDisplayName() + "'"); - } else { - if (lib.getType() == DBPDriverLibrary.FileType.jar) { - hasJars = true; - } - } - } - if (hasAllFiles || hasJars) { - applicableDrivers.add(driver); - } - } - } - } - log.info("Available drivers: " + applicableDrivers.stream().map(DBPDriver::getFullName).collect(Collectors.joining(","))); - } - - private boolean isDriverLibraryFilePresent(@NotNull DBPDriverLibrary lib) { - if (lib.getType() == DBPDriverLibrary.FileType.license) { - return true; - } - Path localFile = lib.getLocalFile(); - return localFile != null && Files.exists(localFile); - } - @NotNull @Override public DBFileController createFileController() { 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 b58aa495eb..aa95ad9388 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/WebServiceUtils.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/WebServiceUtils.java @@ -365,7 +365,7 @@ public static List getEnabledAuthProviders() { */ @NotNull public static Set getApplicableDriversIds() { - return WebAppUtils.getWebPlatform().getApplicableDrivers().stream() + return WebAppUtils.getWebApplication().getDriverRegistry().getApplicableDrivers().stream() .map(DBPDriver::getId) .collect(Collectors.toSet()); } diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/BaseWebPlatform.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/BaseWebPlatform.java index d12d76f740..7ce34b1661 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/BaseWebPlatform.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/BaseWebPlatform.java @@ -24,7 +24,6 @@ import org.jkiss.dbeaver.model.DBConstants; import org.jkiss.dbeaver.model.app.DBACertificateStorage; import org.jkiss.dbeaver.model.app.DBPWorkspace; -import org.jkiss.dbeaver.model.connection.DBPDriver; import org.jkiss.dbeaver.model.impl.app.DefaultCertificateStorage; import org.jkiss.dbeaver.model.qm.QMRegistry; import org.jkiss.dbeaver.model.qm.QMUtils; @@ -41,7 +40,6 @@ import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; -import java.util.List; public abstract class BaseWebPlatform extends BasePlatformImpl { private static final Log log = Log.getLog(BaseWebPlatform.class); @@ -166,5 +164,4 @@ public QMRegistry getQueryManager() { return queryManager; } - public abstract List getApplicableDrivers(); } 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 d487760586..a80ceec8de 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 @@ -84,7 +84,7 @@ public WebServerConfig getServerConfig() { @Override public List getDriverList(@NotNull WebSession webSession, String driverId) { List result = new ArrayList<>(); - for (DBPDriver driver : WebAppUtils.getWebPlatform().getApplicableDrivers()) { + for (DBPDriver driver : WebAppUtils.getWebApplication().getDriverRegistry().getApplicableDrivers()) { if (driverId == null || driverId.equals(driver.getFullId())) { result.add(new WebDatabaseDriverInfo(webSession, driver)); } @@ -141,7 +141,7 @@ public List getTemplateDataSources() throws DBWebException for (DBPDataSourceContainer ds : dsRegistry.getDataSources()) { if (ds.isTemplate()) { - if (WebAppUtils.getWebPlatform().getApplicableDrivers().contains(ds.getDriver())) { + if (WebAppUtils.getWebApplication().getDriverRegistry().getApplicableDrivers().contains(ds.getDriver())) { result.add(new WebDataSourceConfig(ds)); } else { log.debug("Template datasource '" + ds.getName() + "' ignored - driver is not applicable"); @@ -180,7 +180,7 @@ private void getTemplateConnectionsFromProject( for (DBPDataSourceContainer ds : registry.getDataSources()) { if (ds.isTemplate() && project.getDataSourceFilter().filter(ds) && - WebAppUtils.getWebPlatform().getApplicableDrivers().contains(ds.getDriver())) { + WebAppUtils.getWebApplication().getDriverRegistry().getApplicableDrivers().contains(ds.getDriver())) { result.add(new WebConnectionInfo(webSession, ds)); } } diff --git a/server/bundles/io.cloudbeaver.service.admin/src/io/cloudbeaver/service/admin/impl/ConnectionSearcher.java b/server/bundles/io.cloudbeaver.service.admin/src/io/cloudbeaver/service/admin/impl/ConnectionSearcher.java index 8292df8c2c..fd58a295ff 100644 --- a/server/bundles/io.cloudbeaver.service.admin/src/io/cloudbeaver/service/admin/impl/ConnectionSearcher.java +++ b/server/bundles/io.cloudbeaver.service.admin/src/io/cloudbeaver/service/admin/impl/ConnectionSearcher.java @@ -21,6 +21,7 @@ import io.cloudbeaver.model.utils.ConfigurationUtils; import io.cloudbeaver.server.CBApplication; import io.cloudbeaver.server.CBPlatform; +import io.cloudbeaver.server.WebAppUtils; import io.cloudbeaver.service.admin.AdminConnectionSearchInfo; import org.jkiss.dbeaver.model.connection.DBPDriver; import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor; @@ -44,12 +45,10 @@ public class ConnectionSearcher implements DBRRunnableWithProgress { private final WebSession webSession; private final String[] hostNames; private final List foundConnections = new ArrayList<>(); - private List availableDrivers = new ArrayList<>(); public ConnectionSearcher(WebSession webSession, String[] hostNames) { this.webSession = webSession; this.hostNames = hostNames; - this.availableDrivers.addAll(CBPlatform.getInstance().getApplicableDrivers()); } public List getFoundConnections() { @@ -107,7 +106,7 @@ private void searchConnections(DBRProgressMonitor monitor, String hostName, Stri int checkTimeout = 150; Map portCache = new HashMap<>(); - for (DBPDriver driver : availableDrivers) { + for (DBPDriver driver : WebAppUtils.getWebApplication().getDriverRegistry().getApplicableDrivers()) { monitor.subTask("Check '" + driver.getName() + "' on '" + hostName + "'"); if (!CommonUtils.isEmpty(driver.getDefaultPort()) && !isPortInBlockList(CommonUtils.toInt(driver.getDefaultPort()))) { updatePortInfo(portCache, hostName, displayName, driver, checkTimeout); 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 96e1fab90a..f499ff68a2 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 @@ -30,7 +30,7 @@ import io.cloudbeaver.registry.*; import io.cloudbeaver.server.CBApplication; import io.cloudbeaver.server.CBConstants; -import io.cloudbeaver.server.CBPlatform; +import io.cloudbeaver.server.WebAppUtils; import io.cloudbeaver.service.DBWServiceServerConfigurator; import io.cloudbeaver.service.admin.*; import io.cloudbeaver.service.security.SMUtils; @@ -633,7 +633,7 @@ public boolean configureServer(WebSession webSession, Map params // Just reload session state webSession.refreshUserData(); } - CBPlatform.getInstance().refreshApplicableDrivers(); + WebAppUtils.getWebApplication().getDriverRegistry().refreshApplicableDrivers(); } catch (Throwable e) { throw new DBWebException("Error configuring server", e); } From 861a29befd15bf167b0761f6206c7613a35dec9e Mon Sep 17 00:00:00 2001 From: Ainur Date: Fri, 27 Dec 2024 11:48:40 +0100 Subject: [PATCH 07/12] CB-6051 fix detect external dependencies for te --- .../src/io/cloudbeaver/server/CBPlatform.java | 7 ------- .../src/io/cloudbeaver/model/WebDatabaseDriverInfo.java | 2 +- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/server/bundles/io.cloudbeaver.server.ce/src/io/cloudbeaver/server/CBPlatform.java b/server/bundles/io.cloudbeaver.server.ce/src/io/cloudbeaver/server/CBPlatform.java index 14f7640a66..8477321ff6 100644 --- a/server/bundles/io.cloudbeaver.server.ce/src/io/cloudbeaver/server/CBPlatform.java +++ b/server/bundles/io.cloudbeaver.server.ce/src/io/cloudbeaver/server/CBPlatform.java @@ -17,7 +17,6 @@ package io.cloudbeaver.server; -import io.cloudbeaver.auth.NoAuthCredentialsProvider; import io.cloudbeaver.server.jobs.SessionStateJob; import io.cloudbeaver.server.jobs.WebDataSourceMonitorJob; import io.cloudbeaver.server.jobs.WebSessionMonitorJob; @@ -26,7 +25,6 @@ import org.jkiss.code.NotNull; import org.jkiss.code.Nullable; import org.jkiss.dbeaver.Log; -import org.jkiss.dbeaver.model.DBFileController; import org.jkiss.dbeaver.model.preferences.DBPPreferenceStore; import org.jkiss.dbeaver.model.runtime.AbstractJob; import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor; @@ -125,9 +123,4 @@ public boolean isShuttingDown() { return false; } - @NotNull - @Override - public DBFileController createFileController() { - return getApplication().createFileController(new NoAuthCredentialsProvider()); - } } diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/model/WebDatabaseDriverInfo.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/model/WebDatabaseDriverInfo.java index b868dc05f9..691cb78e24 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/model/WebDatabaseDriverInfo.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/model/WebDatabaseDriverInfo.java @@ -302,7 +302,7 @@ public WebDriverLibraryInfo[] getDriverLibraries() { @Property public boolean isDriverInstalled() { - return !driver.needsExternalDependencies(); + return driver.canDownloadDriverLibraries(); } @Property From 1cda7060ac3f53604e6ddd106505282b061ce6e8 Mon Sep 17 00:00:00 2001 From: naumov Date: Sun, 29 Dec 2024 23:06:28 +0100 Subject: [PATCH 08/12] CB-6051 add driver status to the connection form --- .../src/DriverSelector/Driver.tsx | 2 +- .../src/ConnectionForm/Options/Options.tsx | 13 +++++++++++-- .../packages/plugin-connections/src/locales/en.ts | 1 + .../packages/plugin-connections/src/locales/fr.ts | 1 + .../packages/plugin-connections/src/locales/it.ts | 1 + .../packages/plugin-connections/src/locales/ru.ts | 1 + .../packages/plugin-connections/src/locales/zh.ts | 1 + 7 files changed, 17 insertions(+), 3 deletions(-) diff --git a/webapp/packages/plugin-connection-custom/src/DriverSelector/Driver.tsx b/webapp/packages/plugin-connection-custom/src/DriverSelector/Driver.tsx index 9fbf58bf0d..86ab72b4e4 100644 --- a/webapp/packages/plugin-connection-custom/src/DriverSelector/Driver.tsx +++ b/webapp/packages/plugin-connection-custom/src/DriverSelector/Driver.tsx @@ -36,7 +36,7 @@ export const Driver = observer(function Driver({ driver, onSelect }) { {!driver.driverInstalled && (
- +
)}
diff --git a/webapp/packages/plugin-connections/src/ConnectionForm/Options/Options.tsx b/webapp/packages/plugin-connections/src/ConnectionForm/Options/Options.tsx index d37e416c24..6c1e532adb 100644 --- a/webapp/packages/plugin-connections/src/ConnectionForm/Options/Options.tsx +++ b/webapp/packages/plugin-connections/src/ConnectionForm/Options/Options.tsx @@ -14,11 +14,13 @@ import { Combobox, Container, FieldCheckbox, + Flex, Form, FormFieldDescription, getComputed, Group, GroupTitle, + IconOrImage, InputField, Link, ObjectPropertyInfoForm, @@ -28,6 +30,7 @@ import { Textarea, useAdministrationSettings, useFormValidator, + usePermission, useResource, useS, useTranslate, @@ -35,7 +38,7 @@ import { import { DatabaseAuthModelsResource, type DBDriver, DBDriverResource, isLocalConnection } from '@cloudbeaver/core-connections'; import { useService } from '@cloudbeaver/core-di'; import { ProjectInfoResource } from '@cloudbeaver/core-projects'; -import { ServerConfigResource } from '@cloudbeaver/core-root'; +import { EAdminPermission, ServerConfigResource } from '@cloudbeaver/core-root'; import { DriverConfigurationType } from '@cloudbeaver/core-sdk'; import { type TabContainerPanelComponent, TabsContext, useAuthenticationAction } from '@cloudbeaver/core-ui'; import { EMPTY_ARRAY } from '@cloudbeaver/core-utils'; @@ -76,6 +79,7 @@ const driverConfiguration: IDriverConfiguration[] = [ ]; export const Options: TabContainerPanelComponent = observer(function Options({ state }) { + const isAdmin = usePermission(EAdminPermission.admin); const serverConfigResource = useResource(Options, ServerConfigResource, undefined); const projectInfoResource = useService(ProjectInfoResource); const service = useService(ConnectionFormService); @@ -187,7 +191,12 @@ export const Options: TabContainerPanelComponent = observe tiny fill > - {translate('connections_connection_driver')} + + {isAdmin && !driver?.driverInstalled && ( + + )} + {translate('connections_connection_driver')} + {configurationTypes.length > 1 && ( diff --git a/webapp/packages/plugin-connections/src/locales/en.ts b/webapp/packages/plugin-connections/src/locales/en.ts index 61d5f9f09f..77505452bb 100644 --- a/webapp/packages/plugin-connections/src/locales/en.ts +++ b/webapp/packages/plugin-connections/src/locales/en.ts @@ -45,4 +45,5 @@ export default [ 'There are multiple credentials available for authentication.\nPlease choose credentials you want to use.', ], ['plugin_connections_connection_create_menu_title', 'Connection'], + ['plugin_connections_connection_driver_not_installed', 'Driver is not installed. You can install it in the "Administration" part.'], ]; diff --git a/webapp/packages/plugin-connections/src/locales/fr.ts b/webapp/packages/plugin-connections/src/locales/fr.ts index 5fb33cc349..3dc8842cb2 100644 --- a/webapp/packages/plugin-connections/src/locales/fr.ts +++ b/webapp/packages/plugin-connections/src/locales/fr.ts @@ -54,4 +54,5 @@ export default [ ['plugin_connections_connection_form_shared_credentials_manage_info_tab_link', 'Onglet Identifiants'], ['plugin_connections_connection_auth_secret_description', 'Veuillez sélectionner les identifiants fournis par une de vos équipes'], ['plugin_connections_connection_create_menu_title', 'Connection'], + ['plugin_connections_connection_driver_not_installed', 'Driver is not installed. You can install it in the "Administration" part.'], ]; diff --git a/webapp/packages/plugin-connections/src/locales/it.ts b/webapp/packages/plugin-connections/src/locales/it.ts index 1789dfe180..52c6997b77 100644 --- a/webapp/packages/plugin-connections/src/locales/it.ts +++ b/webapp/packages/plugin-connections/src/locales/it.ts @@ -47,4 +47,5 @@ export default [ 'There are multiple credentials available for authentication.\nPlease choose credentials you want to use.', ], ['plugin_connections_connection_create_menu_title', 'Connection'], + ['plugin_connections_connection_driver_not_installed', 'Driver is not installed. You can install it in the "Administration" part.'], ]; diff --git a/webapp/packages/plugin-connections/src/locales/ru.ts b/webapp/packages/plugin-connections/src/locales/ru.ts index e85d1f46cc..c1f4974c6f 100644 --- a/webapp/packages/plugin-connections/src/locales/ru.ts +++ b/webapp/packages/plugin-connections/src/locales/ru.ts @@ -45,4 +45,5 @@ export default [ 'У вас есть несколько учетных записей для авторизации.\nВыберите учетную запись из списка.', ], ['plugin_connections_connection_create_menu_title', 'Подключение'], + ['plugin_connections_connection_driver_not_installed', 'Драйвер не установлен. Вы можете установить его в "Администрированой" части.'], ]; diff --git a/webapp/packages/plugin-connections/src/locales/zh.ts b/webapp/packages/plugin-connections/src/locales/zh.ts index c22e3872d0..da7d9284ac 100644 --- a/webapp/packages/plugin-connections/src/locales/zh.ts +++ b/webapp/packages/plugin-connections/src/locales/zh.ts @@ -41,4 +41,5 @@ export default [ ['plugin_connections_connection_form_shared_credentials_manage_info_tab_link', '凭证页签'], ['plugin_connections_connection_auth_secret_description', '有多个凭证可用于身份验证.\n请选择您要使用的凭证。'], ['plugin_connections_connection_create_menu_title', 'Connection'], + ['plugin_connections_connection_driver_not_installed', 'Driver is not installed. You can install it in the "Administration" part.'], ]; From c89b9a7833fefbb6eb255a735a753333f44d661e Mon Sep 17 00:00:00 2001 From: Ainur Date: Tue, 31 Dec 2024 13:05:39 +0100 Subject: [PATCH 09/12] CB-6051 fix error if driver is not found --- .../src/io/cloudbeaver/WebServiceUtils.java | 7 ------ .../service/core/impl/WebServiceCore.java | 24 +++++++++++++++++-- 2 files changed, 22 insertions(+), 9 deletions(-) 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 aa95ad9388..a3edc537b6 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/WebServiceUtils.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/WebServiceUtils.java @@ -400,11 +400,4 @@ public static WebPropertyInfo[] getObjectFilteredProperties( } return webProps.toArray(new WebPropertyInfo[0]); } - - public static void validateDriverLibrariesPresence(@NotNull DBPDataSourceContainer container) throws DBWebException { - if (container.getDriver().needsExternalDependencies()) { - throw new DBWebException("Driver files for %s are not found. Please, ask administrator to download it." - .formatted(container.getDriver().getName())); - } - } } 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 a80ceec8de..966c51472b 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 @@ -44,6 +44,7 @@ import org.jkiss.dbeaver.model.app.DBPProject; import org.jkiss.dbeaver.model.connection.DBPConnectionConfiguration; import org.jkiss.dbeaver.model.connection.DBPDriver; +import org.jkiss.dbeaver.model.exec.DBCConnectException; import org.jkiss.dbeaver.model.navigator.*; import org.jkiss.dbeaver.model.net.DBWHandlerConfiguration; import org.jkiss.dbeaver.model.net.DBWHandlerType; @@ -62,6 +63,7 @@ import org.jkiss.dbeaver.registry.network.NetworkHandlerDescriptor; import org.jkiss.dbeaver.registry.network.NetworkHandlerRegistry; import org.jkiss.dbeaver.registry.settings.ProductSettingsRegistry; +import org.jkiss.dbeaver.runtime.DBWorkbench; import org.jkiss.dbeaver.runtime.jobs.ConnectionTestJob; import org.jkiss.dbeaver.utils.RuntimeUtils; import org.jkiss.utils.CommonUtils; @@ -367,7 +369,7 @@ public WebConnectionInfo initConnection( boolean oldSavePassword = dataSourceContainer.isSavePassword(); DBRProgressMonitor monitor = webSession.getProgressMonitor(); - WebServiceUtils.validateDriverLibrariesPresence(dataSourceContainer); + validateDriverLibrariesPresence(dataSourceContainer); try { boolean connect = dataSourceContainer.connect(monitor, true, false); if (connect) { @@ -757,7 +759,7 @@ public WebConnectionInfo testConnection( testDataSource = (DataSourceDescriptor) WebServiceUtils.createConnectionFromConfig(connectionConfig, sessionRegistry); } - WebServiceUtils.validateDriverLibrariesPresence(testDataSource); + validateDriverLibrariesPresence(testDataSource); webSession.provideAuthParameters(webSession.getProgressMonitor(), testDataSource, testDataSource.getConnectionConfiguration()); @@ -770,6 +772,12 @@ public WebConnectionInfo testConnection( }); ct.run(webSession.getProgressMonitor()); if (ct.getConnectError() != null) { + if (ct.getConnectError() instanceof DBCConnectException error) { + Throwable rootCause = CommonUtils.getRootCause(error); + if (rootCause instanceof ClassNotFoundException) { + throwDriverNotFoundException(testDataSource); + } + } throw new DBWebException("Connection failed", ct.getConnectError()); } WebConnectionInfo connectionInfo = new WebConnectionInfo(webSession, testDataSource); @@ -1019,4 +1027,16 @@ private WebSessionProjectImpl getProjectById(WebSession webSession, String proje } return project; } + + private void validateDriverLibrariesPresence(@NotNull DBPDataSourceContainer container) throws DBWebException { + if (!DBWorkbench.isDistributed() && container.getDriver().needsExternalDependencies()) { + throwDriverNotFoundException(container); + } + } + + @NotNull + private static String throwDriverNotFoundException(@NotNull DBPDataSourceContainer container) throws DBWebException { + throw new DBWebException("Driver files for %s are not found. Please, ask administrator to download it." + .formatted(container.getDriver().getName())); + } } From 04150531311055d32f01723bda78206b0bc9a6bf Mon Sep 17 00:00:00 2001 From: Ainur Date: Mon, 6 Jan 2025 13:36:17 +0100 Subject: [PATCH 10/12] CB-6051 add comments --- .../src/io/cloudbeaver/registry/WebDriverRegistry.java | 3 +++ .../io/cloudbeaver/service/admin/impl/ConnectionSearcher.java | 3 +++ 2 files changed, 6 insertions(+) diff --git a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/registry/WebDriverRegistry.java b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/registry/WebDriverRegistry.java index ca632515c5..6b01362c4d 100644 --- a/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/registry/WebDriverRegistry.java +++ b/server/bundles/io.cloudbeaver.model/src/io/cloudbeaver/registry/WebDriverRegistry.java @@ -73,6 +73,9 @@ public List getApplicableDrivers() { return applicableDrivers; } + /** + * Updates info about applicable drivers (f.e. some changes were made in driver config file). + */ public void refreshApplicableDrivers() { this.applicableDrivers.clear(); this.applicableDrivers.addAll( diff --git a/server/bundles/io.cloudbeaver.service.admin/src/io/cloudbeaver/service/admin/impl/ConnectionSearcher.java b/server/bundles/io.cloudbeaver.service.admin/src/io/cloudbeaver/service/admin/impl/ConnectionSearcher.java index fd58a295ff..0f2df31b78 100644 --- a/server/bundles/io.cloudbeaver.service.admin/src/io/cloudbeaver/service/admin/impl/ConnectionSearcher.java +++ b/server/bundles/io.cloudbeaver.service.admin/src/io/cloudbeaver/service/admin/impl/ConnectionSearcher.java @@ -51,6 +51,9 @@ public ConnectionSearcher(WebSession webSession, String[] hostNames) { this.hostNames = hostNames; } + /** + * Returns all found connections in a current machine. + */ public List getFoundConnections() { synchronized (foundConnections) { return new ArrayList<>(foundConnections); From 3c98139d9534570e73972e23011a2f6dfad27774 Mon Sep 17 00:00:00 2001 From: Ainur Date: Thu, 9 Jan 2025 11:11:11 +0100 Subject: [PATCH 11/12] CB-6051 add param that checks when libs can be downloaded --- .../schema/service.core.graphqls | 1 + .../io/cloudbeaver/model/WebDatabaseDriverInfo.java | 12 +++++++----- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/server/bundles/io.cloudbeaver.server/schema/service.core.graphqls b/server/bundles/io.cloudbeaver.server/schema/service.core.graphqls index 379306478b..9b4603d8ec 100644 --- a/server/bundles/io.cloudbeaver.server/schema/service.core.graphqls +++ b/server/bundles/io.cloudbeaver.server/schema/service.core.graphqls @@ -261,6 +261,7 @@ type DriverInfo { configurationTypes: [DriverConfigurationType]! + downloadable: Boolean! @since(version: "24.3.3") driverInstalled: Boolean! driverLibraries: [DriverLibraryInfo!]! } diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/model/WebDatabaseDriverInfo.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/model/WebDatabaseDriverInfo.java index 691cb78e24..5a620ea9c2 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/model/WebDatabaseDriverInfo.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/model/WebDatabaseDriverInfo.java @@ -25,10 +25,7 @@ import org.jkiss.dbeaver.DBException; import org.jkiss.dbeaver.Log; import org.jkiss.dbeaver.model.DBConstants; -import org.jkiss.dbeaver.model.connection.DBPAuthModelDescriptor; -import org.jkiss.dbeaver.model.connection.DBPConnectionConfiguration; -import org.jkiss.dbeaver.model.connection.DBPDriver; -import org.jkiss.dbeaver.model.connection.DBPDriverConfigurationType; +import org.jkiss.dbeaver.model.connection.*; import org.jkiss.dbeaver.model.impl.auth.AuthModelDatabaseNative; import org.jkiss.dbeaver.model.meta.Property; import org.jkiss.dbeaver.model.preferences.DBPPropertyDescriptor; @@ -302,7 +299,12 @@ public WebDriverLibraryInfo[] getDriverLibraries() { @Property public boolean isDriverInstalled() { - return driver.canDownloadDriverLibraries(); + return driver.isDriverInstalled(); + } + + @Property + public boolean isDownloadable() { + return driver.getDriverLibraries().stream().anyMatch(DBPDriverLibrary::isDownloadable); } @Property From 5dbc8fb0e3d397f7b4c6b8337f678caf1701f1a7 Mon Sep 17 00:00:00 2001 From: naumov Date: Thu, 9 Jan 2025 13:18:46 +0100 Subject: [PATCH 12/12] CB-6051 add downloadable flag --- .../packages/core-sdk/src/queries/fragments/DatabaseDriver.gql | 1 + 1 file changed, 1 insertion(+) diff --git a/webapp/packages/core-sdk/src/queries/fragments/DatabaseDriver.gql b/webapp/packages/core-sdk/src/queries/fragments/DatabaseDriver.gql index 6d9b9e30b0..aad8588889 100644 --- a/webapp/packages/core-sdk/src/queries/fragments/DatabaseDriver.gql +++ b/webapp/packages/core-sdk/src/queries/fragments/DatabaseDriver.gql @@ -24,6 +24,7 @@ fragment DatabaseDriver on DriverInfo { configurationTypes driverId driverInstalled + downloadable mainProperties @include(if: $includeMainProperties) { ...DriverPropertyInfo