Skip to content

Commit

Permalink
CB-6051 ability to download drivers (#3155)
Browse files Browse the repository at this point in the history
  • Loading branch information
yagudin10 authored Jan 14, 2025
1 parent 12cfcbc commit 1d4c00e
Show file tree
Hide file tree
Showing 29 changed files with 280 additions and 101 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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 {

Expand All @@ -42,6 +51,7 @@ public synchronized static WebDriverRegistry getInstance() {
return instance;
}

private final List<DBPDriver> applicableDrivers = new ArrayList<>();
private final Set<String> webDrivers = new HashSet<>();

protected WebDriverRegistry() {
Expand All @@ -59,8 +69,48 @@ private void loadExtensions(IExtensionRegistry registry) {
}
}

public boolean isDriverEnabled(DBPDriver driver) {
return webDrivers.contains(driver.getFullId());
public List<DBPDriver> 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(
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(",")));
}

protected boolean isDriverApplicable(@NotNull DBPDriver driver) {
List<? extends DBPDriverLibrary> 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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -735,9 +735,10 @@ protected void sendConfigChangedEvent(SMCredentialsProvider credentialsProvider)
public abstract CBServerConfigurationController<T> getServerConfigurationController();

private void refreshDisabledDriversConfig() {
getDriverRegistry().refreshApplicableDrivers();
CBAppConfig config = getAppConfiguration();
Set<String> 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;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -26,22 +25,13 @@
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.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.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
* CBPlatform
Expand All @@ -57,7 +47,6 @@ public class CBPlatform extends BaseWebPlatform {
private static CBApplication<?> application = null;

private WebServerPreferenceStore preferenceStore;
protected final List<DBPDriver> applicableDrivers = new ArrayList<>();

public static CBPlatform getInstance() {
return (CBPlatform) DBWorkbench.getPlatform();
Expand All @@ -76,8 +65,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)");
}
Expand Down Expand Up @@ -124,10 +111,6 @@ public CBApplication<?> getApplication() {
return application;
}

public List<DBPDriver> getApplicableDrivers() {
return applicableDrivers;
}


@NotNull
@Override
Expand All @@ -140,41 +123,4 @@ public boolean isShuttingDown() {
return false;
}

public void refreshApplicableDrivers() {
this.applicableDrivers.clear();

for (DBPDataSourceProviderDescriptor dspd : DataSourceProviderRegistry.getInstance().getEnabledDataSourceProviders()) {
for (DBPDriver driver : dspd.getEnabledDrivers()) {
List<? extends DBPDriverLibrary> libraries = driver.getDriverLibraries();
{
if (!application.getDriverRegistry().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())))
{
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(",")));
}

@NotNull
@Override
public DBFileController createFileController() {
return getApplication().createFileController(new NoAuthCredentialsProvider());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,7 @@ type DriverInfo {

configurationTypes: [DriverConfigurationType]!

downloadable: Boolean! @since(version: "24.3.3")
driverInstalled: Boolean!
driverLibraries: [DriverLibraryInfo!]!
}
Expand All @@ -269,6 +270,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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,7 @@ public static List<WebAuthProviderDescriptor> getEnabledAuthProviders() {
*/
@NotNull
public static Set<String> getApplicableDriversIds() {
return WebAppUtils.getWebPlatform().getApplicableDrivers().stream()
return WebAppUtils.getWebApplication().getDriverRegistry().getApplicableDrivers().stream()
.map(DBPDriver::getId)
.collect(Collectors.toSet());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -53,7 +50,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;
Expand Down Expand Up @@ -296,13 +293,18 @@ 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.isDriverInstalled();
}

@Property
public boolean isDownloadable() {
return driver.getDriverLibraries().stream().anyMatch(DBPDriverLibrary::isDownloadable);
}

@Property
Expand Down
Original file line number Diff line number Diff line change
@@ -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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,24 @@
package io.cloudbeaver.model;

import io.cloudbeaver.WebServiceUtils;
import io.cloudbeaver.model.session.WebSession;
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;
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;
}

Expand All @@ -43,6 +49,18 @@ public String getName() {
return driverLibrary.getDisplayName();
}

@Property
@Nullable
public List<WebDriverLibraryFileInfo> getLibraryFiles() {
var libraryFiles = ((DriverDescriptor) driver).getLibraryFiles(driverLibrary);
if (libraryFiles == null) {
return null;
}
return libraryFiles.stream()
.map(WebDriverLibraryFileInfo::new)
.toList();
}

@Property
public String getIcon() {
return WebServiceUtils.makeIconId(driverLibrary.getIcon());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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);
Expand Down Expand Up @@ -166,5 +164,4 @@ public QMRegistry getQueryManager() {
return queryManager;
}

public abstract List<DBPDriver> getApplicableDrivers();
}
Loading

0 comments on commit 1d4c00e

Please sign in to comment.