Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Merged
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -443,4 +443,10 @@ public void addCloseListener(DBRRunnableParametrized<WebConnectionInfo> listener
closeListeners.add(listener);
}

@Property
public int getKeepAliveInterval() {
return dataSourceContainer.getConnectionConfiguration().getKeepAliveInterval();
}


}
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,8 @@ type ConnectionInfo {
databaseName: String
url: String

keepAliveInterval: Int!

properties: Object

template: Boolean!
Expand Down Expand Up @@ -465,6 +467,9 @@ input ConnectionConfig {
# Properties
properties: Object

# Keep-Alive interval
keepAliveInterval: Int

# Template connection
template: Boolean
# Read-onyl connection
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,9 @@ public static void setConnectionConfiguration(DBPDriver driver, DBPConnectionCon
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<>());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -80,6 +82,8 @@ public WebConnectionConfig(Map<String, Object> params) {
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");
Expand Down Expand Up @@ -222,4 +226,9 @@ public void setSaveCredentials(boolean saveCredentials) {
public Map<String, Object> getProviderProperties() {
return providerProperties;
}

@Property
public Integer getKeepAliveInterval() {
return keepAliveInterval;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

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;
Expand Down Expand Up @@ -165,6 +166,9 @@ protected void initialize() {
new SessionStateJob(this)
.scheduleMonitor();

new WebDataSourceMonitorJob(this)
.scheduleMonitor();

new AbstractJob("Delete temp folder") {
@Override
protected IStatus run(DBRProgressMonitor monitor) {
Expand Down
Original file line number Diff line number Diff line change
@@ -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())
);
}
}
3 changes: 3 additions & 0 deletions webapp/packages/core-connections/src/locales/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ 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_connection_keep_alive_max_value_error', 'Value cannot be more than {arg:keepAliveInterval}'],
['connections_network_handler_test', 'Test Tunnel'],
['connections_network_handler_test_fail', 'Tunnel test failed'],
['connections_network_handler_test_success', 'Tunnel test success'],
Expand Down
3 changes: 3 additions & 0 deletions webapp/packages/core-connections/src/locales/it.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,9 @@ 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_connection_keep_alive_max_value_error', 'Value cannot be more than {arg:keepAliveInterval}'],
['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'],
Expand Down
3 changes: 3 additions & 0 deletions webapp/packages/core-connections/src/locales/ru.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@ export default [
['connections_connection_test_fail', 'Не удалось выполнить подключение'],
['connections_connection_create_fail', 'Не удалось создать подключение'],
['connections_connection_save_fail', 'Не удалось сохранить подключение'],
['connections_connection_keep_alive', 'Поддерживать соединение (в секундах)'],
['connections_connection_keep_alive_tooltip', 'Не отключать соединение'],
['connections_connection_keep_alive_max_value_error', 'Значение не может быть больше {arg:keepAliveInterval}'],
['connections_network_handler_test', 'Проверить подключение'],
['connections_network_handler_test_fail', 'Не удалось установить соединение'],
['connections_network_handler_test_success', 'Соединение установлено'],
Expand Down
3 changes: 3 additions & 0 deletions webapp/packages/core-connections/src/locales/zh.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ 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_connection_keep_alive_max_value_error', 'Value cannot be more than {arg:keepAliveInterval}'],
['connections_network_handler_test', '测试隧道'],
['connections_network_handler_test_fail', '隧道测试失败'],
['connections_network_handler_test_success', '隧道测试成功'],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ fragment DatabaseConnection on ConnectionInfo {
name
description
driverId
keepAliveInterval

template
connected
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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')) {
Expand Down Expand Up @@ -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;
}
Expand Down Expand Up @@ -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();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ import {
getPropertyControlType,
Group,
GroupTitle,
InputField,
ObjectPropertyInfoForm,
useCustomInputValidation,
useObjectPropertyCategories,
useTranslate,
} from '@cloudbeaver/core-blocks';
Expand All @@ -28,9 +30,17 @@ 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 keepAliveRef = useCustomInputValidation<string>(value => {
if (Number(value) > MAX_KEEP_ALIVE_INTERVAL_IN_SECONDS) {
return translate('connections_connection_keep_alive_max_value_error', undefined, { keepAliveInterval: MAX_KEEP_ALIVE_INTERVAL_IN_SECONDS });
}
return null;
});
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we really need custom validation here? we set max value for input it should add browser default validation for this field

const supportedProperties = properties.filter(property => property.supportedConfigurationTypes?.some(type => type === config.configurationType));

const { categories, isUncategorizedExists } = useObjectPropertyCategories(supportedProperties);
Expand Down Expand Up @@ -74,6 +84,22 @@ export const ProviderPropertiesForm = observer<Props>(function ProviderPropertie
</>
)}

<InputField
ref={keepAliveRef}
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}>
Expand Down
Loading