CB-4309 add keep alive interval for data source (#2269)

* CB-4309 add keep alive interval for data source

* CB-4309 adds keep-alive checkbox to connection form additional fields

* CB-4309 removed custom validation for keep-alive setting

---------

Co-authored-by: s.teleshev <s.teleshev@mu.se>
Co-authored-by: Evgenia Bezborodova <139753579+EvgeniaBzzz@users.noreply.github.com>
This commit is contained in:
Ainur
2024-01-12 20:48:16 +03:00
committed by GitHub
co-authored by s.teleshev Evgenia Bezborodova
parent 5caffd0a04
commit f463ea558f
14 changed files with 116 additions and 2 deletions
+13
View File
@@ -50,6 +50,19 @@
"isDefault": true
}
},
{
"label": "Run Backend CE",
"type": "shell",
"windows": {
"command": "./run-server.bat"
},
"osx": {
"command": "./run-server.sh"
},
"options": {
"cwd": "${workspaceFolder}/deploy/cloudbeaver"
}
},
{
"label": "Yarn Install",
"type": "shell",
@@ -443,4 +443,10 @@ public class WebConnectionInfo {
closeListeners.add(listener);
}
@Property
public int getKeepAliveInterval() {
return dataSourceContainer.getConnectionConfiguration().getKeepAliveInterval();
}
}
@@ -314,6 +314,8 @@ type ConnectionInfo {
databaseName: String
url: String
keepAliveInterval: Int!
properties: Object
template: Boolean!
@@ -465,6 +467,9 @@ input ConnectionConfig {
# Properties
properties: Object
# Keep-Alive interval
keepAliveInterval: Int
# Template connection
template: Boolean
# Read-onyl connection
@@ -182,6 +182,9 @@ public class WebServiceUtils extends WebCommonUtils {
if (config.getAuthModelId() != null) {
dsConfig.setAuthModelId(config.getAuthModelId());
}
if (config.getKeepAliveInterval() >= 0) {
dsConfig.setKeepAliveInterval(config.getKeepAliveInterval());
}
// Save provider props
if (config.getProviderProperties() != null) {
dsConfig.setProviderProperties(new LinkedHashMap<>());
@@ -43,6 +43,8 @@ public class WebConnectionConfig {
private String databaseName;
private String url;
private int keepAliveInterval;
private String name;
private String description;
private String folder;
@@ -80,6 +82,8 @@ public class WebConnectionConfig {
databaseName = JSONUtils.getString(params, "databaseName");
url = JSONUtils.getString(params, "url");
keepAliveInterval = JSONUtils.getInteger(params, "keepAliveInterval", -1);
name = JSONUtils.getString(params, "name");
description = JSONUtils.getString(params, "description");
folder = JSONUtils.getString(params, "folder");
@@ -222,4 +226,9 @@ public class WebConnectionConfig {
public Map<String, Object> getProviderProperties() {
return providerProperties;
}
@Property
public Integer getKeepAliveInterval() {
return keepAliveInterval;
}
}
@@ -19,6 +19,7 @@ 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;
import io.cloudbeaver.service.session.WebSessionManager;
import org.eclipse.core.resources.ResourcesPlugin;
@@ -165,6 +166,9 @@ public class CBPlatform extends BasePlatformImpl {
new SessionStateJob(this)
.scheduleMonitor();
new WebDataSourceMonitorJob(this)
.scheduleMonitor();
new AbstractJob("Delete temp folder") {
@Override
protected IStatus run(DBRProgressMonitor monitor) {
@@ -0,0 +1,42 @@
/*
* DBeaver - Universal Database Manager
* Copyright (C) 2010-2023 DBeaver Corp and others
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.cloudbeaver.server.jobs;
import io.cloudbeaver.model.session.BaseWebSession;
import io.cloudbeaver.server.CBPlatform;
import org.jkiss.dbeaver.model.app.DBPPlatform;
import org.jkiss.dbeaver.runtime.jobs.DataSourceMonitorJob;
import java.util.Collection;
/**
* Web data source monitor job.
*/
public class WebDataSourceMonitorJob extends DataSourceMonitorJob {
public WebDataSourceMonitorJob(DBPPlatform platform) {
super(platform);
}
@Override
protected void doJob() {
Collection<BaseWebSession> allSessions = CBPlatform.getInstance().getSessionManager().getAllActiveSessions();
allSessions.parallelStream().forEach(
s -> checkDataSourceAliveInWorkspace(s.getWorkspace())
);
}
}
@@ -55,6 +55,8 @@ export default [
['connections_connection_test_fail', 'Connection test failed'],
['connections_connection_create_fail', 'Fail to create connection'],
['connections_connection_save_fail', 'Fail to save connection'],
['connections_connection_keep_alive', 'Keep alive (in seconds)'],
['connections_connection_keep_alive_tooltip', 'No auto disconnect'],
['connections_network_handler_test', 'Test Tunnel'],
['connections_network_handler_test_fail', 'Tunnel test failed'],
['connections_network_handler_test_success', 'Tunnel test success'],
@@ -53,6 +53,8 @@ export default [
['connections_connection_test_fail', 'Prova di connessione fallita'],
['connections_connection_create_fail', 'Errore di creazione connessione'],
['connections_connection_save_fail', 'Errore di salvataggio connessione'],
['connections_connection_keep_alive', 'Keep alive (in seconds)'],
['connections_connection_keep_alive_tooltip', 'No auto disconnect'],
['connections_network_handler_test', 'Prova il Tunnel'],
['connections_network_handler_test_fail', 'Prova del Tunnel fallita'],
['connections_network_handler_test_success', 'Prova del Tunnel terminata con successo'],
@@ -52,6 +52,8 @@ export default [
['connections_connection_test_fail', 'Не удалось выполнить подключение'],
['connections_connection_create_fail', 'Не удалось создать подключение'],
['connections_connection_save_fail', 'Не удалось сохранить подключение'],
['connections_connection_keep_alive', 'Поддерживать соединение (в секундах)'],
['connections_connection_keep_alive_tooltip', 'Не отключать соединение'],
['connections_network_handler_test', 'Проверить подключение'],
['connections_network_handler_test_fail', 'Не удалось установить соединение'],
['connections_network_handler_test_success', 'Соединение установлено'],
@@ -51,6 +51,8 @@ export default [
['connections_connection_test_fail', '连接测试失败'],
['connections_connection_create_fail', '无法创建连接'],
['connections_connection_save_fail', '无法保存连接'],
['connections_connection_keep_alive', 'Keep alive (in seconds)'],
['connections_connection_keep_alive_tooltip', 'No auto disconnect'],
['connections_network_handler_test', '测试隧道'],
['connections_network_handler_test_fail', '隧道测试失败'],
['connections_network_handler_test_success', '隧道测试成功'],
@@ -4,6 +4,7 @@ fragment DatabaseConnection on ConnectionInfo {
name
description
driverId
keepAliveInterval
template
connected
@@ -229,6 +229,8 @@ export class ConnectionOptionsTabService extends Bootstrap {
state.config.saveCredentials = state.info.credentialsSaved;
state.config.sharedCredentials = state.info.sharedCredentials;
state.config.keepAliveInterval = state.info.keepAliveInterval;
if (state.info.authProperties) {
for (const property of state.info.authProperties) {
if (!property.features.includes('password')) {
@@ -293,6 +295,8 @@ export class ConnectionOptionsTabService extends Bootstrap {
tempConfig.driverId = state.config.driverId;
tempConfig.keepAliveInterval = Number(state.config.keepAliveInterval);
if (!state.config.template && state.config.folder) {
tempConfig.folder = state.config.folder;
}
@@ -407,7 +411,8 @@ export class ConnectionOptionsTabService extends Bootstrap {
(config.saveCredentials !== undefined && config.saveCredentials !== data.info.credentialsSaved) ||
(config.sharedCredentials !== undefined && config.sharedCredentials !== data.info.sharedCredentials) ||
(config.providerProperties !== undefined &&
!isObjectPropertyInfoStateEqual(driver.providerProperties, config.providerProperties, data.info.providerProperties))
!isObjectPropertyInfoStateEqual(driver.providerProperties, config.providerProperties, data.info.providerProperties)) ||
(config.keepAliveInterval !== undefined && !isValuesEqual(config.keepAliveInterval, data.info.keepAliveInterval))
) {
stateContext.markEdited();
}
@@ -13,7 +13,9 @@ import {
getPropertyControlType,
Group,
GroupTitle,
InputField,
ObjectPropertyInfoForm,
useCustomInputValidation,
useObjectPropertyCategories,
useTranslate,
} from '@cloudbeaver/core-blocks';
@@ -28,9 +30,10 @@ interface Props {
readonly?: boolean;
}
const MAX_KEEP_ALIVE_INTERVAL_IN_SECONDS = 32767;
export const ProviderPropertiesForm = observer<Props>(function ProviderPropertiesForm({ config, properties, disabled, readonly }) {
const translate = useTranslate();
const supportedProperties = properties.filter(property => property.supportedConfigurationTypes?.some(type => type === config.configurationType));
const { categories, isUncategorizedExists } = useObjectPropertyCategories(supportedProperties);
@@ -74,6 +77,21 @@ export const ProviderPropertiesForm = observer<Props>(function ProviderPropertie
</>
)}
<InputField
type="number"
minLength={1}
min={0}
max={MAX_KEEP_ALIVE_INTERVAL_IN_SECONDS}
name="keepAliveInterval"
disabled={disabled}
readOnly={readonly}
defaultValue={config?.keepAliveInterval ?? 0}
title={translate('connections_connection_keep_alive_tooltip')}
state={config}
>
{translate('connections_connection_keep_alive')}
</InputField>
{categories.map((category, index) => (
<Container key={`${category}_${config.driverId}`} gap>
<Expandable label={category} defaultExpanded={index === 0}>