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

[Backport release/8.6] feat(jdbc): Don't use URI as it breaks when using the hash char #2514

Merged
merged 1 commit into from
May 10, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
import io.camunda.connector.jdbc.model.request.JdbcRequest;
import io.camunda.connector.jdbc.model.request.SupportedDatabase;
import io.camunda.connector.jdbc.model.request.connection.JdbcConnection;
import java.net.URISyntaxException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
Expand All @@ -37,8 +36,6 @@ public static Connection openConnection(JdbcRequest request) {
return conn;
} catch (ClassNotFoundException e) {
throw new ConnectorException("Cannot find class: " + driverClassName);
} catch (URISyntaxException e) {
throw new ConnectorException("Cannot parse the Database connection URL: " + e.getMessage());
} catch (SQLException e) {
throw new ConnectorException("Cannot create the Database connection: " + e.getMessage());
}
Expand All @@ -52,8 +49,7 @@ public static Connection openConnection(JdbcRequest request) {
* href="https://mariadb.com/kb/en/about-mariadb-connector-j/#jdbcmysql-scheme-compatibility">Compatibility
* details</a>
*/
private static String ensureMySQLCompatibleUrl(String url, SupportedDatabase database)
throws URISyntaxException {
private static String ensureMySQLCompatibleUrl(String url, SupportedDatabase database) {
if (database == SupportedDatabase.MYSQL) {
return ConnectionParameterHelper.addQueryParameterToURL(url, "permitMysqlScheme");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@
*/
package io.camunda.connector.jdbc.utils;

import java.net.URI;
import java.net.URISyntaxException;

/**
* Helper class to add parameters to a URL. Parameters values can be added to the URL as well, but
* it is optional.
Expand All @@ -17,32 +14,13 @@
*/
public class ConnectionParameterHelper {

public static String addQueryParameterToURL(String urlString, String paramName)
throws URISyntaxException {
public static String addQueryParameterToURL(String urlString, String paramName) {
return addQueryParameterToURL(urlString, paramName, null);
}

public static String addQueryParameterToURL(String urlString, String paramName, String paramValue)
throws URISyntaxException {
URI uri = new URI(urlString);
// Check if the URL already has query parameters
int queryParamsIndex = urlString.indexOf('?');
String query;
if (queryParamsIndex == -1) {
// No query parameters
query = "?";
} else {
// Query parameters already exist let's add the new one
query = "&";
}
query += paramName;
// Value is optional
if (paramValue != null) {
query += "=" + paramValue;
}
// jdbc:mysql//localhost:3306?paramName=paramValue for instance is not detected as a regular
// URI,
// so we need to reconstruct the URI using the scheme and the scheme specific part
return new URI(uri.getScheme() + ":" + uri.getSchemeSpecificPart() + query).toString();
public static String addQueryParameterToURL(
String urlString, String paramName, String paramValue) {
String separator = urlString.contains("?") ? "&" : "?";
return urlString + separator + paramName + (paramValue != null ? "=" + paramValue : "");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

public class ConnectionParameterHelperTest {
@Test
void shouldCreateQueryParameters_whenNoExistingQueryParameters() throws Exception {
void shouldCreateQueryParameters_whenNoExistingQueryParameters() {
String urlString = "jdbc:mysql//localhost:3306";
String paramName = "paramName";
String paramValue = "paramValue";
Expand All @@ -22,7 +22,7 @@ void shouldCreateQueryParameters_whenNoExistingQueryParameters() throws Exceptio
}

@Test
void shouldNotCreateQueryParameters_whenExistingQueryParameters() throws Exception {
void shouldNotCreateQueryParameters_whenExistingQueryParameters() {
String urlString = "jdbc:mysql//localhost:3306?existingParam=existingValue";
String paramName = "paramName";
String paramValue = "paramValue";
Expand All @@ -32,43 +32,80 @@ void shouldNotCreateQueryParameters_whenExistingQueryParameters() throws Excepti
}

@Test
void shouldCreateQueryParameters_whenNoParamValue() throws Exception {
void shouldCreateQueryParameters_whenNoParamValue() {
String urlString = "jdbc:mysql//localhost:3306";
String paramName = "paramName";
String result = ConnectionParameterHelper.addQueryParameterToURL(urlString, paramName);
assertThat(result).isEqualTo(urlString + "?paramName");
}

@Test
void shouldCreateQueryParameters_whenNoParamValueAndExistingQueryParameters() throws Exception {
void shouldCreateQueryParameters_whenNoParamValueAndExistingQueryParameters() {
String urlString = "jdbc:mysql//localhost:3306?existingParam=existingValue";
String paramName = "paramName";
String result = ConnectionParameterHelper.addQueryParameterToURL(urlString, paramName);
assertThat(result).isEqualTo(urlString + "&paramName");
}

@Test
void shouldCreateQueryParametersAfterPath_whenQueryPathExistsAndNoParamValue() throws Exception {
void shouldCreateQueryParametersAfterPath_whenQueryPathExistsAndNoParamValue() {
String urlString = "jdbc:mysql//localhost:3306/database";
String paramName = "paramName";
String result = ConnectionParameterHelper.addQueryParameterToURL(urlString, paramName);
assertThat(result).isEqualTo(urlString + "?paramName");
}

@Test
void shouldCreateQueryParametersAfterPath_whenQueryPathExistsAndQueryParametersExist()
throws Exception {
void shouldCreateQueryParametersAfterPath_whenQueryPathExistsAndQueryParametersExist() {
String urlString = "jdbc:mysql//localhost:3306/database?existingParam=existingValue";
String paramName = "paramName";
String result = ConnectionParameterHelper.addQueryParameterToURL(urlString, paramName);
assertThat(result).isEqualTo(urlString + "&paramName");
}

@Test
void shouldCreateQueryParametersAfterPath_whenEmptyPath() throws Exception {
void shouldCreateQueryParametersAfterPath_whenEmptyPath() {
String urlString = "jdbc:mysql//localhost:3306/";
String paramName = "paramName";
String result = ConnectionParameterHelper.addQueryParameterToURL(urlString, paramName);
assertThat(result).isEqualTo(urlString + "?paramName");
}

@Test
void
shouldCreateQueryParametersAfterPath_whenQueryPathExistsAndQueryParametersExistAndPasswordHasWeirdChars() {
String urlString = "jdbc:mysql//localhost:3306/database?user=test&password=ab#!xij:()_s23";
String paramName = "paramName";
String result = ConnectionParameterHelper.addQueryParameterToURL(urlString, paramName);
assertThat(result).isEqualTo(urlString + "&paramName");
}

@Test
void shouldCreateQueryParameters_whenMultipleExistingQueryParameters() {
String urlString =
"jdbc:mysql//localhost:3306?existingParam1=existingValue1&existingParam2=existingValue2";
String paramName = "paramName";
String paramValue = "paramValue";
String result =
ConnectionParameterHelper.addQueryParameterToURL(urlString, paramName, paramValue);
assertThat(result).isEqualTo(urlString + "&paramName=paramValue");
}

@Test
void shouldHandleEmptyParamValue() {
String urlString = "jdbc:mysql//localhost:3306";
String paramName = "paramName";
String paramValue = "";
String result =
ConnectionParameterHelper.addQueryParameterToURL(urlString, paramName, paramValue);
assertThat(result).isEqualTo(urlString + "?paramName=");
}

@Test
void shouldHandleNullParamValue() {
String urlString = "jdbc:mysql//localhost:3306";
String paramName = "paramName";
String result = ConnectionParameterHelper.addQueryParameterToURL(urlString, paramName, null);
assertThat(result).isEqualTo(urlString + "?paramName");
}
}