Skip to content

Commit

Permalink
Merge branch 'devel' into CB-5292-keep-alive-all-drivers
Browse files Browse the repository at this point in the history
  • Loading branch information
devnaumov authored Jun 21, 2024
2 parents c979618 + 124fa7f commit 35e14ae
Show file tree
Hide file tree
Showing 165 changed files with 2,031 additions and 2,072 deletions.
4 changes: 2 additions & 2 deletions .vscode/tasks.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,15 +42,15 @@
"package",
"-q",
"exec:java",
"-Dexec.args= -eclipse.version ${eclipse-version} -config ${workspaceFolder}/../idea-workspace-dbeaver/rcp-gen.properties -productFile ${workspaceFolder}/server/product/web-server/CloudbeaverServer.product -projectsFolder ${workspaceFolder}/../ -eclipse ${workspaceFolder}/../dbeaver-workspace/dependencies -output ${workspaceFolder}/../dbeaver-workspace/products/CloudbeaverServer.product"
"-Dexec.args= -eclipse.version ${eclipse-version} -config ${workspaceFolder}/../idea-workspace-dbeaver/osgi-app.properties -productFile ${workspaceFolder}/server/product/web-server/CloudbeaverServer.product -projectsFolder ${workspaceFolder}/../ -eclipse ${workspaceFolder}/../dbeaver-workspace/dependencies -output ${workspaceFolder}/../dbeaver-workspace/products/CloudbeaverServer.product"
]
},
"windows": {
"args": [
"package",
"-q",
"exec:java",
"-Dexec.args= -eclipse.version ${eclipse-version} -config ${workspaceFolder}/../idea-workspace-dbeaver/rcp-gen.properties -productFile ${workspaceFolder}/server/product/web-server/CloudbeaverServer.product -projectsFolder ${workspaceFolder}/../ -eclipse ${workspaceFolder}/../dbeaver-workspace/dependencies -output ${workspaceFolder}/../dbeaver-workspace/products/CloudbeaverServer.product"
"-Dexec.args= -eclipse.version ${eclipse-version} -config ${workspaceFolder}/../cloudbeaver/osgi-app.properties"
]
},
"options": {
Expand Down
3 changes: 3 additions & 0 deletions generate_workspace.cmd
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
SET mypath=%~dp0

.\..\idea-rcp-launch-config-generator\runGenerator.cmd -f %mypath%
1 change: 1 addition & 0 deletions generate_workspace.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
./../idea-rcp-launch-config-generator/runGenerator.sh -f $(dirname "$0")
27 changes: 27 additions & 0 deletions osgi-app.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
workspaceName=cloudbeaver
featuresPaths=\
dbeaver/features;\
cloudbeaver/server/features;
bundlesPaths=\
dbeaver-common/modules;\
dbeaver/plugins;\
cloudbeaver/server/bundles;
repositories=\
https://p2.dev.dbeaver.com/eclipse-repo/;\
https://download.eclipse.org/releases/${eclipse-version}/;
testBundles=\
org.junit;\
org.mockito.mockito-core;\
junit-jupiter-api;\
org.opentest4j
productsPaths=\
dbeaver/product/community/DBeaver.product;\
cloudbeaver/server/product/web-server/CloudbeaverServer.product:../../opt/cloudbeaver;
ideaConfigurationFilesPaths=\
dbeaver/.ide/idea/copyright;\
dbeaver/.ide/idea/scopes;
testBundlePaths=\
dbeaver/test;\
cloudbeaver/server/test;
additionalModuleRoots=\
opt;
1 change: 1 addition & 0 deletions server/bundles/io.cloudbeaver.model/META-INF/MANIFEST.MF
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ Export-Package: io.cloudbeaver,
io.cloudbeaver.service.admin,
io.cloudbeaver.service.security,
io.cloudbeaver.service.sql,
io.cloudbeaver.test,
io.cloudbeaver.utils,
io.cloudbeaver.utils.file
Automatic-Module-Name: io.cloudbeaver.model
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,16 +105,7 @@ public boolean isMultiuser() {

protected boolean loadServerConfiguration() throws DBException {
Path configFilePath = getMainConfigurationFilePath().toAbsolutePath();
Path configFolder = configFilePath.getParent();

// Configure logging
Path logbackConfigPath = getLogbackConfigPath(configFolder);

if (logbackConfigPath == null) {
System.err.println("Can't find slf4j configuration file in " + configFilePath.getParent());
} else {
System.setProperty("logback.configurationFile", logbackConfigPath.toString());
}
Log.setLogHandler(new SLF4JLogHandler());

// Load config file
Expand Down Expand Up @@ -210,7 +201,9 @@ public static Map<String, Object> getServerConfigProps(Map<String, Object> confi
}

@SuppressWarnings("unchecked")
public static void patchConfigurationWithProperties(Map<String, Object> configProps, IVariableResolver varResolver) {
public static void patchConfigurationWithProperties(
Map<String, Object> configProps, IVariableResolver varResolver
) {
for (Map.Entry<String, Object> entry : configProps.entrySet()) {
Object propValue = entry.getValue();
if (propValue instanceof String) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
/*
* 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.test;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import org.jkiss.code.NotNull;
import org.jkiss.code.Nullable;
import org.jkiss.dbeaver.DBException;
import org.jkiss.dbeaver.model.data.json.JSONUtils;
import org.jkiss.dbeaver.utils.GeneralUtils;

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

/**
* GraphQL client for tests.
*/
public class WebGQLClient {
private static final Gson gson = new GsonBuilder()
.setPrettyPrinting()
.create();
public static final String GQL_AUTHENTICATE = """
query authLogin($provider: ID!, $configuration: ID, $credentials: Object, $linkUser: Boolean, $forceSessionsLogout: Boolean) {
result: authLogin(
provider: $provider
configuration: $configuration
credentials: $credentials
linkUser: $linkUser
forceSessionsLogout: $forceSessionsLogout
) {
authId
authStatus
}
}""";

@NotNull
private final HttpClient httpClient;
@NotNull
private final String apiUrl;

public WebGQLClient(@NotNull HttpClient httpClient, @NotNull String apiUrl) {
this.httpClient = httpClient;
this.apiUrl = apiUrl;
}

/**
* Sends GraphQL request without additional headers
*
* @param query GraphQL query
* @param variables GraphQL query variables
* @return GraphQL response
*/
@NotNull
public <T> T sendQuery(@NotNull String query, @Nullable Map<String, Object> variables) throws Exception {
return sendQueryWithHeaders(query, variables, List.of());
}

/**
* Sends GraphQL request without additional headers
*
* @param query GraphQL query
* @param variables GraphQL query variables
* @param headers HTTP request headers
* @return GraphQL response
*/
@NotNull
public <T> T sendQueryWithHeaders(
@NotNull String query,
@Nullable Map<String, Object> variables,
@NotNull List<String> headers
) throws Exception {
HttpRequest.Builder requestBuilder = HttpRequest.newBuilder()
.uri(URI.create(apiUrl))
.POST(HttpRequest.BodyPublishers.ofString(makeGQLRequest(query, variables)))
.setHeader("TE-Client-Version", GeneralUtils.getMajorVersion())
.header("Content-Type", "application/json");
if (!headers.isEmpty()) {
requestBuilder.headers(headers.toArray(String[]::new));
}
HttpRequest request = requestBuilder.build();
HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
Map<String, Object> body = gson.fromJson(
response.body(),
JSONUtils.MAP_TYPE_TOKEN
);
if (body.containsKey("errors")) {
String message = JSONUtils.getString(JSONUtils.getObjectList(body, "errors").get(0), "message");
throw new DBException(message);
}
// graphql response will be in "data" key
return (T) JSONUtils.getObject(body, "data").get("result");
}

@NotNull
private String makeGQLRequest(@NotNull String text, @Nullable Map<String, Object> variables) {
Map<String, Object> request = new LinkedHashMap<>();
request.put("query", text);
if (variables != null && !variables.isEmpty()) {
request.put("variables", variables);
}

return gson.toJson(request, Map.class);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,62 +17,15 @@

package io.cloudbeaver.utils;

import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import org.jkiss.dbeaver.model.data.json.JSONUtils;
import org.jkiss.dbeaver.utils.GeneralUtils;

import java.io.File;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Collections;
import java.util.List;
import java.util.Map;

public class WebTestUtils {

public static final String GQL_TEMPLATE_AUTH_LOGIN = "authLogin.json";

public static String readScriptTemplate(String templateName, Path scriptsPath) throws Exception {
Path templatePath = new File(String.valueOf(scriptsPath), templateName).toPath();
return Files.readString(templatePath);
}


public static Map<String, Object> doPost(String apiUrl, String input, HttpClient client) throws Exception {
return doPostWithHeaders(apiUrl, input, client, List.of());
}

public static Map<String, Object> doPostWithHeaders(
String apiUrl,
String input,
HttpClient client,
List<String> headers
) throws Exception {
HttpRequest.Builder requestBuilder = HttpRequest.newBuilder()
.uri(URI.create(apiUrl))
.POST(HttpRequest.BodyPublishers.ofString(input))
.setHeader("TE-Client-Version", GeneralUtils.getMajorVersion())
.header("Content-Type", "application/json");

if (!headers.isEmpty()) {
requestBuilder.headers(headers.toArray(String[]::new));
}
HttpRequest request = requestBuilder.build();
HttpResponse<String> response = client.send(request,
HttpResponse.BodyHandlers.ofString());

return new GsonBuilder().create().fromJson(
response.body(),
new TypeToken<Map<String, Object>>() {
}.getType()
);
}

public static boolean getServerStatus(HttpClient client, String apiUrl) {
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(apiUrl))
Expand All @@ -86,14 +39,4 @@ public static boolean getServerStatus(HttpClient client, String apiUrl) {
return false;
}
}

public static Map<String, Object> authenticateUser(HttpClient client, Path scriptsPath, String apiUrl) throws Exception {
String input = WebTestUtils.readScriptTemplate(GQL_TEMPLATE_AUTH_LOGIN, scriptsPath);
Map<String, Object> map = WebTestUtils.doPost(apiUrl, input, client);
Map<String, Object> data = JSONUtils.getObjectOrNull(map, "data");
if (data != null) {
return JSONUtils.getObjectOrNull(data, "authInfo");
}
return Collections.emptyMap();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,34 @@
package io.cloudbeaver.slf4j;

import ch.qos.logback.classic.spi.LogbackServiceProvider;
import org.slf4j.helpers.Reporter;

import java.nio.file.Files;
import java.nio.file.Path;

public class CloudBeaverLogServiceProvider extends LogbackServiceProvider {
private static final String LOGBACK_CONF_FILE_PROPERTY = "logback.configurationFile";
private static final String MAIN_LOGBACK_CONFIG = "conf/logback.xml";
private static final String CUSTOM_LOGBACK_CONFIG = "conf/custom/logback.xml";


public CloudBeaverLogServiceProvider() {
if (System.getProperty(LOGBACK_CONF_FILE_PROPERTY) != null) {
return;
}

String logbackConfig = null;
if (Files.exists(Path.of(CUSTOM_LOGBACK_CONFIG))) {
logbackConfig = CUSTOM_LOGBACK_CONFIG;
} else if (Files.exists(Path.of(MAIN_LOGBACK_CONFIG))) {
logbackConfig = MAIN_LOGBACK_CONFIG;
}

if (logbackConfig != null) {
System.setProperty(LOGBACK_CONF_FILE_PROPERTY, Path.of(logbackConfig).toString());
Reporter.info("Logback configuration is used: " + logbackConfig);
} else {
Reporter.info("No logback configuration found");
}
}
}
32 changes: 31 additions & 1 deletion server/product/web-server/CloudbeaverServer.product
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,37 @@

<configIni use="default">
</configIni>

<launcherArgs>
<programArgs>-web-config conf/cloudbeaver.conf -registryMultiLanguage</programArgs>
<programArgsMac></programArgsMac>
<vmArgs>
-Dfile.encoding=UTF-8
--add-modules=ALL-SYSTEM
--add-opens=java.base/java.io=ALL-UNNAMED
--add-opens=java.base/java.lang=ALL-UNNAMED
--add-opens=java.base/java.lang.reflect=ALL-UNNAMED
--add-opens=java.base/java.net=ALL-UNNAMED
--add-opens=java.base/java.nio=ALL-UNNAMED
--add-opens=java.base/java.nio.charset=ALL-UNNAMED
--add-opens=java.base/java.text=ALL-UNNAMED
--add-opens=java.base/java.time=ALL-UNNAMED
--add-opens=java.base/java.util=ALL-UNNAMED
--add-opens=java.base/java.util.concurrent=ALL-UNNAMED
--add-opens=java.base/java.util.concurrent.atomic=ALL-UNNAMED
--add-opens=java.base/jdk.internal.vm=ALL-UNNAMED
--add-opens=java.base/jdk.internal.misc=ALL-UNNAMED
--add-opens=java.base/sun.nio.ch=ALL-UNNAMED
--add-opens=java.base/sun.security.ssl=ALL-UNNAMED
--add-opens=java.base/sun.security.action=ALL-UNNAMED
--add-opens=java.base/sun.security.util=ALL-UNNAMED
--add-opens=java.security.jgss/sun.security.jgss=ALL-UNNAMED
--add-opens=java.security.jgss/sun.security.krb5=ALL-UNNAMED
--add-opens=java.base/java.util.concurrent.atomic=ALL-UNNAMED
--add-opens=java.sql/java.sql=ALL-UNNAMED
</vmArgs>
<vmArgsMac></vmArgsMac>
</launcherArgs>

<license>
<url>https://cloudbeaver.io/about/</url>
<text>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@
import io.cloudbeaver.service.rm.nio.RMNIOFileSystem;
import io.cloudbeaver.service.rm.nio.RMNIOFileSystemProvider;
import io.cloudbeaver.service.rm.nio.RMPath;
import io.cloudbeaver.test.WebGQLClient;
import io.cloudbeaver.test.platform.CEServerTestSuite;
import io.cloudbeaver.utils.WebTestUtils;
import org.jkiss.dbeaver.DBException;
import org.jkiss.dbeaver.model.auth.SMAuthStatus;
import org.jkiss.dbeaver.model.data.json.JSONUtils;
Expand Down Expand Up @@ -53,12 +53,12 @@ public class RMNIOTest {
@BeforeClass
public static void init() throws Exception {
var cookieManager = new CookieManager();
var client = HttpClient.newBuilder()
var httpClient = HttpClient.newBuilder()
.cookieHandler(cookieManager)
.version(HttpClient.Version.HTTP_2)
.build();
Map<String, Object> authInfo = WebTestUtils.authenticateUser(
client, CEServerTestSuite.getScriptsPath(), CEServerTestSuite.GQL_API_URL);
WebGQLClient client = CEServerTestSuite.createClient(httpClient);
Map<String, Object> authInfo = CEServerTestSuite.authenticateTestUser(client);
Assert.assertEquals(SMAuthStatus.SUCCESS.name(), JSONUtils.getString(authInfo, "authStatus"));

String sessionId = cookieManager.getCookieStore().getCookies()
Expand Down
Loading

0 comments on commit 35e14ae

Please sign in to comment.