mirror of
https://github.com/dbeaver/cloudbeaver.git
synced 2026-09-24 16:04:36 +08:00
CB-423 Connection search on local host improvements (docker)
This commit is contained in:
@@ -1,4 +1,8 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Detect host machine IP Address (we need this when run in docker container)
|
||||
export CB_LOCAL_HOST_ADDR=$(ifconfig | grep -E "([0-9]{1,3}\.){3}[0-9]{1,3}" | grep -v 127.0.0.1 | awk '{ print $2 }' | cut -f2 -d: | head -n1)
|
||||
|
||||
launcherJar=( server/plugins/org.eclipse.equinox.launcher*.jar )
|
||||
|
||||
echo "Starting Cloudbeaver Server"
|
||||
|
||||
@@ -83,6 +83,7 @@ type ServerConfig {
|
||||
supportsConnectionBrowser: Boolean
|
||||
supportsWorkspaces: Boolean
|
||||
sessionExpireTime: Int
|
||||
localHostAddress: String
|
||||
|
||||
configurationMode: Boolean
|
||||
developmentMode: Boolean
|
||||
|
||||
@@ -92,6 +92,11 @@ public class WebServerConfig {
|
||||
return application.getMaxSessionIdleTime();
|
||||
}
|
||||
|
||||
@Property
|
||||
public String getLocalHostAddress() {
|
||||
return application.getLocalHostAddress();
|
||||
}
|
||||
|
||||
@Property
|
||||
public WebServerLanguage[] getSupportedLanguages() {
|
||||
List<PlatformLanguageDescriptor> langs = PlatformLanguageRegistry.getInstance().getLanguages();
|
||||
|
||||
@@ -46,10 +46,11 @@ import org.jkiss.utils.CommonUtils;
|
||||
import org.jkiss.utils.StandardConstants;
|
||||
|
||||
import java.io.*;
|
||||
import java.net.InetAddress;
|
||||
import java.net.NetworkInterface;
|
||||
import java.net.URL;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
* This class controls all aspects of the application's execution
|
||||
@@ -93,6 +94,8 @@ public class CBApplication extends BaseApplicationImpl {
|
||||
|
||||
private boolean develMode = false;
|
||||
private boolean configurationMode = false;
|
||||
private String localHostAddress;
|
||||
private final List<InetAddress> localInetAddresses = new ArrayList<>();
|
||||
|
||||
public CBApplication() {
|
||||
}
|
||||
@@ -181,6 +184,15 @@ public class CBApplication extends BaseApplicationImpl {
|
||||
configurationMode = CommonUtils.isEmpty(serverName);
|
||||
//|| CommonUtils.isEmpty(databaseConfiguration.getUser()) || CommonUtils.isEmpty(databaseConfiguration.getPassword());
|
||||
|
||||
// Determine address for local host
|
||||
localHostAddress = System.getenv(CBConstants.VAR_CB_LOCAL_HOST_ADDR);
|
||||
if (CommonUtils.isEmpty(localHostAddress)) {
|
||||
localHostAddress = System.getProperty(CBConstants.VAR_CB_LOCAL_HOST_ADDR);
|
||||
}
|
||||
if (CommonUtils.isEmpty(localHostAddress) || "127.0.0.1".equals(localHostAddress) || "::0".equals(localHostAddress)) {
|
||||
localHostAddress = "localhost";
|
||||
}
|
||||
|
||||
final Runtime runtime = Runtime.getRuntime();
|
||||
|
||||
Location instanceLoc = Platform.getInstanceLocation();
|
||||
@@ -222,6 +234,13 @@ public class CBApplication extends BaseApplicationImpl {
|
||||
if (configurationMode) {
|
||||
log.debug("\tServer is in configuration mode!");
|
||||
}
|
||||
{
|
||||
log.debug("\tLocal host addresses:");
|
||||
determineLocalAddresses();
|
||||
for (InetAddress ia : localInetAddresses) {
|
||||
log.debug("\t\t" + ia.getHostAddress() + " (" + ia.getCanonicalHostName() + ")");
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
try {
|
||||
@@ -248,6 +267,33 @@ public class CBApplication extends BaseApplicationImpl {
|
||||
return null;
|
||||
}
|
||||
|
||||
private void determineLocalAddresses() {
|
||||
try {
|
||||
// InetAddress localHost = InetAddress.getLocalHost();
|
||||
// InetAddress[] allMyIps = InetAddress.getAllByName(localHost.getCanonicalHostName());
|
||||
// for (InetAddress addr : allMyIps) {
|
||||
// System.out.println("Local addr: " + addr);
|
||||
// }
|
||||
boolean hasLoopbackAddress = false;
|
||||
for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {
|
||||
NetworkInterface intf = en.nextElement();
|
||||
for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements(); ) {
|
||||
InetAddress localInetAddress = enumIpAddr.nextElement();
|
||||
boolean loopbackAddress = localInetAddress.isLoopbackAddress();
|
||||
if (loopbackAddress ? !hasLoopbackAddress : !localInetAddress.isLinkLocalAddress()) {
|
||||
if (loopbackAddress) {
|
||||
hasLoopbackAddress = true;
|
||||
}
|
||||
localInetAddresses.add(localInetAddress);
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
log.error(e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private File getRuntimeConfigFile() {
|
||||
return new File(getDataDirectory(false), CBConstants.RUNTIME_CONFIG_FILE_NAME);
|
||||
@@ -403,6 +449,23 @@ public class CBApplication extends BaseApplicationImpl {
|
||||
return configurationMode;
|
||||
}
|
||||
|
||||
public String getLocalHostAddress() {
|
||||
return localHostAddress;
|
||||
}
|
||||
|
||||
public boolean isLocalInetAddress(String hostName) {
|
||||
for (InetAddress addr : localInetAddresses) {
|
||||
if (addr.getHostAddress().equals(hostName)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public List<InetAddress> getLocalInetAddresses() {
|
||||
return localInetAddresses;
|
||||
}
|
||||
|
||||
public synchronized void finishConfiguration(
|
||||
String newServerName,
|
||||
String adminName,
|
||||
|
||||
@@ -65,4 +65,7 @@ public class CBConstants {
|
||||
|
||||
public static final String DEFAUL_APP_ANONYMOUS_ROLE_NAME = "user";
|
||||
|
||||
public static final String VAR_CB_LOCAL_HOST_ADDR = "CB_LOCAL_HOST_ADDR";
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -81,7 +81,6 @@ public class CBPlatform extends BasePlatformImpl {
|
||||
private WebSessionManager sessionManager;
|
||||
private final List<DBPDriver> applicableDrivers = new ArrayList<>();
|
||||
|
||||
|
||||
public static CBPlatform getInstance() {
|
||||
if (instance == null) {
|
||||
synchronized (CBPlatform.class) {
|
||||
|
||||
+14
-4
@@ -20,18 +20,28 @@ import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class AdminConnectionSearchInfo {
|
||||
private final String host;
|
||||
private final String displayName;
|
||||
private final String hostAddr;
|
||||
private final int port;
|
||||
private List<String> possibleDrivers = new ArrayList<>();
|
||||
private String defaultDriver;
|
||||
|
||||
public AdminConnectionSearchInfo(String host, int driverPort) {
|
||||
this.host = host;
|
||||
public AdminConnectionSearchInfo(String displayName, String hostAddr, int driverPort) {
|
||||
this.displayName = displayName;
|
||||
this.hostAddr = hostAddr;
|
||||
this.port = driverPort;
|
||||
}
|
||||
|
||||
public String getDisplayName() {
|
||||
return displayName;
|
||||
}
|
||||
|
||||
public String getHostAddr() {
|
||||
return hostAddr;
|
||||
}
|
||||
|
||||
public String getHost() {
|
||||
return host;
|
||||
return hostAddr;
|
||||
}
|
||||
|
||||
public int getPort() {
|
||||
|
||||
+52
-17
@@ -20,14 +20,13 @@ import io.cloudbeaver.WebServiceUtils;
|
||||
import io.cloudbeaver.model.session.WebSession;
|
||||
import io.cloudbeaver.server.CBPlatform;
|
||||
import io.cloudbeaver.service.admin.AdminConnectionSearchInfo;
|
||||
import org.jkiss.dbeaver.DBException;
|
||||
import org.jkiss.dbeaver.model.connection.DBPDriver;
|
||||
import org.jkiss.dbeaver.model.runtime.DBRProgressMonitor;
|
||||
import org.jkiss.dbeaver.model.runtime.DBRRunnableWithProgress;
|
||||
import org.jkiss.dbeaver.registry.DataSourceRegistry;
|
||||
import org.jkiss.utils.CommonUtils;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.Socket;
|
||||
import java.net.SocketAddress;
|
||||
@@ -44,7 +43,7 @@ public class ConnectionSearcher implements DBRRunnableWithProgress {
|
||||
private final WebSession webSession;
|
||||
private final String[] hostNames;
|
||||
private final DataSourceRegistry tempRegistry;
|
||||
private List<AdminConnectionSearchInfo> foundConnections = new ArrayList<>();
|
||||
private final List<AdminConnectionSearchInfo> foundConnections = new ArrayList<>();
|
||||
private List<DBPDriver> availableDrivers = new ArrayList<>();
|
||||
|
||||
public ConnectionSearcher(WebSession webSession, String[] hostNames) {
|
||||
@@ -53,47 +52,83 @@ public class ConnectionSearcher implements DBRRunnableWithProgress {
|
||||
CBPlatform platform = CBPlatform.getInstance();
|
||||
this.tempRegistry = new DataSourceRegistry(platform, platform.getWorkspace().getActiveProject());
|
||||
|
||||
availableDrivers.addAll(CBPlatform.getInstance().getApplicableDrivers());
|
||||
this.availableDrivers.addAll(CBPlatform.getInstance().getApplicableDrivers());
|
||||
}
|
||||
|
||||
public List<AdminConnectionSearchInfo> getFoundConnections() {
|
||||
return foundConnections;
|
||||
synchronized (foundConnections) {
|
||||
return new ArrayList<>(foundConnections);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(DBRProgressMonitor monitor) throws InvocationTargetException {
|
||||
monitor.beginTask("Search connections", hostNames.length * availableDrivers.size());
|
||||
public void run(DBRProgressMonitor monitor) {
|
||||
List<String> finalHostNames = new ArrayList<>();
|
||||
Map<String, String> localHostNames = new HashMap<>();
|
||||
for (String hostName : hostNames) {
|
||||
monitor.subTask("Search connections on '" + hostName + "'");
|
||||
if (hostName.equals("localhost") || hostName.equals("local") || hostName.equals("127.0.0.1")) {
|
||||
for (InetAddress addr : CBPlatform.getInstance().getApplication().getLocalInetAddresses()) {
|
||||
String localHostAddress = addr.getHostAddress();
|
||||
finalHostNames.add(localHostAddress);
|
||||
localHostNames.put(localHostAddress, hostName);
|
||||
}
|
||||
} else {
|
||||
finalHostNames.add(hostName);
|
||||
}
|
||||
}
|
||||
|
||||
monitor.beginTask("Search connections", finalHostNames.size());
|
||||
try {
|
||||
for (String hostName : hostNames) {
|
||||
ThreadGroup tg = new ThreadGroup("Connection search");
|
||||
List<Thread> threadList = new ArrayList<>();
|
||||
for (String hostName : finalHostNames) {
|
||||
monitor.subTask("Search connections on '" + hostName + "'");
|
||||
searchConnections(monitor, hostName);
|
||||
String localName = localHostNames.get(hostName);
|
||||
if (localName == null) {
|
||||
localName = hostName;
|
||||
}
|
||||
String finalLocalName = localName;
|
||||
Runnable searchFunc = () -> searchConnections(monitor, hostName, finalLocalName);
|
||||
Thread t = new Thread(tg, searchFunc, "Search connection @" + hostName);
|
||||
threadList.add(t);
|
||||
t.start();
|
||||
}
|
||||
for (Thread t : threadList) {
|
||||
try {
|
||||
t.join();
|
||||
} catch (InterruptedException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
} catch (DBException e) {
|
||||
throw new InvocationTargetException(e);
|
||||
} finally {
|
||||
monitor.done();
|
||||
}
|
||||
}
|
||||
|
||||
private void searchConnections(DBRProgressMonitor monitor, String hostName) throws DBException {
|
||||
int checkTimeout = 250;
|
||||
private void searchConnections(DBRProgressMonitor monitor, String hostName, String displayName) {
|
||||
int checkTimeout = 150;
|
||||
Map<Integer, AdminConnectionSearchInfo> portCache = new HashMap<>();
|
||||
|
||||
for (DBPDriver driver : availableDrivers) {
|
||||
monitor.subTask("Check '" + driver.getName() + "' on '" + hostName + "'");
|
||||
if (!CommonUtils.isEmpty(driver.getDefaultPort())) {
|
||||
updatePortInfo(portCache, hostName, driver, checkTimeout);
|
||||
updatePortInfo(portCache, hostName, displayName, driver, checkTimeout);
|
||||
}
|
||||
monitor.worked(1);
|
||||
}
|
||||
for (AdminConnectionSearchInfo si : portCache.values()) {
|
||||
if (si.getDefaultDriver() != null) {
|
||||
foundConnections.add(si);
|
||||
synchronized (foundConnections) {
|
||||
if (foundConnections.stream().noneMatch(fsi -> fsi.getDisplayName().equals(displayName) && fsi.getPort() == si.getPort())) {
|
||||
foundConnections.add(si);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updatePortInfo(Map<Integer, AdminConnectionSearchInfo> portCache, String hostName, DBPDriver driver, int timeout) {
|
||||
private void updatePortInfo(Map<Integer, AdminConnectionSearchInfo> portCache, String hostName, String displayName, DBPDriver driver, int timeout) {
|
||||
int driverPort = CommonUtils.toInt(driver.getDefaultPort());
|
||||
if (driverPort <= 0) {
|
||||
return;
|
||||
@@ -105,7 +140,7 @@ public class ConnectionSearcher implements DBRRunnableWithProgress {
|
||||
searchInfo.getPossibleDrivers().add(driverId);
|
||||
return;
|
||||
}
|
||||
searchInfo = new AdminConnectionSearchInfo(hostName, driverPort);
|
||||
searchInfo = new AdminConnectionSearchInfo(displayName, hostName, driverPort);
|
||||
portCache.put(driverPort, searchInfo);
|
||||
|
||||
try {
|
||||
|
||||
+1
-6
@@ -41,7 +41,6 @@ import org.jkiss.dbeaver.model.exec.DBCException;
|
||||
import org.jkiss.dbeaver.model.navigator.DBNBrowseSettings;
|
||||
import org.jkiss.utils.CommonUtils;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
@@ -250,11 +249,7 @@ public class WebServiceAdmin implements DBWServiceAdmin {
|
||||
@Override
|
||||
public List<AdminConnectionSearchInfo> searchConnections(@NotNull WebSession webSession, @NotNull List<String> hostNames) throws DBWebException {
|
||||
ConnectionSearcher searcher = new ConnectionSearcher(webSession, hostNames.toArray(new String[0]));
|
||||
try {
|
||||
searcher.run(webSession.getProgressMonitor());
|
||||
} catch (InvocationTargetException e) {
|
||||
throw new DBWebException("Error searching connections", e.getTargetException());
|
||||
}
|
||||
searcher.run(webSession.getProgressMonitor());
|
||||
return searcher.getFoundConnections();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user