Skip to content

Commit

Permalink
Add support for kdb and kurrent protocols
Browse files Browse the repository at this point in the history
  • Loading branch information
w1am committed Dec 18, 2024
1 parent 82d0c02 commit 90505c5
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 42 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
*/
public class ConnectionSettingsBuilder {
private static final Logger logger = LoggerFactory.getLogger(ConnectionSettingsBuilder.class);
private static final Set<String> SUPPORTED_PROTOCOLS = new HashSet<>(Arrays.asList("esdb", "esdb+discover", "kurrent", "kdb", "kdb+discover", "kurrent+discover"));

private boolean _dnsDiscover = false;
private int _maxDiscoverAttempts = 3;
private int _discoveryInterval = 500;
Expand Down Expand Up @@ -257,10 +259,13 @@ void parseGossipSeed(String host) {
}

static KurrentDBClientSettings parseFromUrl(ConnectionSettingsBuilder builder, URL url) {
if (!url.getProtocol().equals("esdb") && !url.getProtocol().equals("esdb+discover"))
if (!SUPPORTED_PROTOCOLS.contains(url.getProtocol()))
throw new RuntimeException(String.format("Unknown URL scheme: %s", url.getProtocol()));

builder.dnsDiscover(url.getProtocol().equals("esdb+discover"));
if (url.getProtocol().startsWith("esdb"))
logger.warn("The 'esdb' protocol is deprecated. Please use 'kurrent' or 'kdb' instead.");

builder.dnsDiscover(url.getProtocol().endsWith("+discover"));

if (url.getUserInfo() != null && !url.getUserInfo().isEmpty()) {
String[] splits = url.getUserInfo().split(":", 2);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,20 +14,20 @@ public static Stream<Arguments> invalidConnectionStrings() {
return Stream.of(
Arguments.of("localhost"),
Arguments.of("https://console.eventstore.cloud/"),
Arguments.of("esbd+discovery://localhost"),
Arguments.of("esdb://my:great@username:UyeXx8$^PsOo4jG88FlCauR1Coz25q@host?nodePreference=follower&tlsVerifyCert=false"),
Arguments.of("esdb://host1,host2:200:300?tlsVerifyCert=false"),
Arguments.of("esdb://localhost/&tlsVerifyCert=false"),
Arguments.of("esdb://localhost?tlsVerifyCert=false?nodePreference=follower"),
Arguments.of("esdb://localhost?tlsVerifyCert=false&nodePreference=any"),
Arguments.of("esdb://localhost?tlsVerifyCert=if you feel like it"),
Arguments.of("esdb://localhost?keepAliveInterval=-3"),
Arguments.of("esdb://localhost?keepAliveInterval=sdfksjsfl"),
Arguments.of("esdb://localhost?keepAliveTimeout=sdfksjsfl"),
Arguments.of("esdb://localhost?keepAliveTimeout=-3"),
Arguments.of("esdb://localhost?nodePreference=read_only_replica"),
Arguments.of("esdb://localhost?userCertFile=/path/to/cert"),
Arguments.of("esdb://localhost?userKeyFile=/path/to/key")
Arguments.of("kurnt+discovery://localhost"),
Arguments.of("kurrent://my:great@username:UyeXx8$^PsOo4jG88FlCauR1Coz25q@host?nodePreference=follower&tlsVerifyCert=false"),
Arguments.of("kurrent://host1,host2:200:300?tlsVerifyCert=false"),
Arguments.of("kurrent://localhost/&tlsVerifyCert=false"),
Arguments.of("kurrent://localhost?tlsVerifyCert=false?nodePreference=follower"),
Arguments.of("kurrent://localhost?tlsVerifyCert=false&nodePreference=any"),
Arguments.of("kurrent://localhost?tlsVerifyCert=if you feel like it"),
Arguments.of("kurrent://localhost?keepAliveInterval=-3"),
Arguments.of("kurrent://localhost?keepAliveInterval=sdfksjsfl"),
Arguments.of("kurrent://localhost?keepAliveTimeout=sdfksjsfl"),
Arguments.of("kurrent://localhost?keepAliveTimeout=-3"),
Arguments.of("kurrent://localhost?nodePreference=read_only_replica"),
Arguments.of("kurrent://localhost?userCertFile=/path/to/cert"),
Arguments.of("kurrent://localhost?userKeyFile=/path/to/key")
);
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package io.kurrent.dbclient.misc;

import java.net.InetSocketAddress;
import java.util.Arrays;
import java.util.List;
import java.util.stream.IntStream;
import java.util.stream.Stream;

Expand All @@ -16,110 +18,115 @@
public class ParseValidConnectionStringTests {
private final JsonMapper mapper = new JsonMapper();

private static final List<String> PROTOCOLS = List.of("esdb", "kurrent", "kdb");

public static Stream<Arguments> validConnectionStrings() {
return Stream.of(
List<Arguments> baseConnectionStrings = Arrays.asList(
Arguments.of(
"esdb://localhost",
"://localhost",
"{\"dnsDiscover\":false,\"maxDiscoverAttempts\":3,\"discoveryInterval\":500,\"gossipTimeout\":3000,\"nodePreference\":\"leader\",\"tls\":true,\"tlsVerifyCert\":true,\"throwOnAppendFailure\":true,\"hosts\":[{\"address\":\"localhost\",\"port\":2113}]}"
),
Arguments.of(
"esdb://localhost:2114",
"://localhost:2114",
"{\"dnsDiscover\":false,\"maxDiscoverAttempts\":3,\"discoveryInterval\":500,\"gossipTimeout\":3000,\"nodePreference\":\"leader\",\"tls\":true,\"tlsVerifyCert\":true,\"throwOnAppendFailure\":true,\"hosts\":[{\"address\":\"localhost\",\"port\":2114}]}"
),
Arguments.of(
"esdb://user:pass@localhost:2114",
"://user:pass@localhost:2114",
"{\"dnsDiscover\":false,\"maxDiscoverAttempts\":3,\"discoveryInterval\":500,\"gossipTimeout\":3000,\"nodePreference\":\"leader\",\"tls\":true,\"tlsVerifyCert\":true,\"throwOnAppendFailure\":true,\"defaultCredentials\":{\"login\":\"user\",\"password\":\"pass\"},\"hosts\":[{\"address\":\"localhost\",\"port\":2114}]}"
),
Arguments.of(
"esdb://user:pass@localhost:2114/",
"://user:pass@localhost:2114/",
"{\"dnsDiscover\":false,\"maxDiscoverAttempts\":3,\"discoveryInterval\":500,\"gossipTimeout\":3000,\"nodePreference\":\"leader\",\"tls\":true,\"tlsVerifyCert\":true,\"throwOnAppendFailure\":true,\"defaultCredentials\":{\"login\":\"user\",\"password\":\"pass\"},\"hosts\":[{\"address\":\"localhost\",\"port\":2114}]}"
),
Arguments.of(
"esdb://user:pass@localhost:2114/?tlsVerifyCert=false",
"://user:pass@localhost:2114/?tlsVerifyCert=false",
"{\"dnsDiscover\":false,\"maxDiscoverAttempts\":3,\"discoveryInterval\":500,\"gossipTimeout\":3000,\"nodePreference\":\"leader\",\"tls\":true,\"tlsVerifyCert\":false,\"throwOnAppendFailure\":true,\"defaultCredentials\":{\"login\":\"user\",\"password\":\"pass\"},\"hosts\":[{\"address\":\"localhost\",\"port\":2114}]}"
),
Arguments.of(
"esdb://user:pass@localhost:2114?tlsVerifyCert=false",
"://user:pass@localhost:2114?tlsVerifyCert=false",
"{\"dnsDiscover\":false,\"maxDiscoverAttempts\":3,\"discoveryInterval\":500,\"gossipTimeout\":3000,\"nodePreference\":\"leader\",\"tls\":true,\"tlsVerifyCert\":false,\"throwOnAppendFailure\":true,\"defaultCredentials\":{\"login\":\"user\",\"password\":\"pass\"},\"hosts\":[{\"address\":\"localhost\",\"port\":2114}]}"
),
Arguments.of(
"esdb://user:pass@localhost:2114?tls=false",
"://user:pass@localhost:2114?tls=false",
"{\"dnsDiscover\":false,\"maxDiscoverAttempts\":3,\"discoveryInterval\":500,\"gossipTimeout\":3000,\"nodePreference\":\"leader\",\"tls\":false,\"tlsVerifyCert\":true,\"throwOnAppendFailure\":true,\"defaultCredentials\":{\"login\":\"user\",\"password\":\"pass\"},\"hosts\":[{\"address\":\"localhost\",\"port\":2114}]}"
),
Arguments.of(
"esdb://host1,host2,host3",
"://host1,host2,host3",
"{\"dnsDiscover\":false,\"maxDiscoverAttempts\":3,\"discoveryInterval\":500,\"gossipTimeout\":3000,\"nodePreference\":\"leader\",\"tls\":true,\"tlsVerifyCert\":true,\"throwOnAppendFailure\":true,\"hosts\":[{\"address\":\"host1\",\"port\":2113},{\"address\":\"host2\",\"port\":2113},{\"address\":\"host3\",\"port\":2113}]}"
),
Arguments.of(
"esdb://host1:1234,host2:4321,host3:3231",
"://host1:1234,host2:4321,host3:3231",
"{\"dnsDiscover\":false,\"maxDiscoverAttempts\":3,\"discoveryInterval\":500,\"gossipTimeout\":3000,\"nodePreference\":\"leader\",\"tls\":true,\"tlsVerifyCert\":true,\"throwOnAppendFailure\":true,\"hosts\":[{\"address\":\"host1\",\"port\":1234},{\"address\":\"host2\",\"port\":4321},{\"address\":\"host3\",\"port\":3231}]}"
),
Arguments.of(
"esdb://bubaqp2rh41uf5akmj0g-0.mesdb.eventstore.cloud:2113,bubaqp2rh41uf5akmj0g-1.mesdb.eventstore.cloud:2113,bubaqp2rh41uf5akmj0g-2.mesdb.eventstore.cloud:2113",
"://bubaqp2rh41uf5akmj0g-0.mesdb.eventstore.cloud:2113,bubaqp2rh41uf5akmj0g-1.mesdb.eventstore.cloud:2113,bubaqp2rh41uf5akmj0g-2.mesdb.eventstore.cloud:2113",
"{\"dnsDiscover\":false,\"maxDiscoverAttempts\":3,\"discoveryInterval\":500,\"gossipTimeout\":3000,\"nodePreference\":\"leader\",\"tls\":true,\"tlsVerifyCert\":true,\"throwOnAppendFailure\":true,\"hosts\":[{\"address\":\"bubaqp2rh41uf5akmj0g-0.mesdb.eventstore.cloud\",\"port\":2113},{\"address\":\"bubaqp2rh41uf5akmj0g-1.mesdb.eventstore.cloud\",\"port\":2113},{\"address\":\"bubaqp2rh41uf5akmj0g-2.mesdb.eventstore.cloud\",\"port\":2113}]}"
),
Arguments.of(
"esdb://user:pass@host1:1234,host2:4321,host3:3231?nodePreference=follower",
"://user:pass@host1:1234,host2:4321,host3:3231?nodePreference=follower",
"{\"dnsDiscover\":false,\"maxDiscoverAttempts\":3,\"discoveryInterval\":500,\"gossipTimeout\":3000,\"nodePreference\":\"follower\",\"tls\":true,\"tlsVerifyCert\":true,\"throwOnAppendFailure\":true,\"defaultCredentials\":{\"login\":\"user\",\"password\":\"pass\"},\"hosts\":[{\"address\":\"host1\",\"port\":1234},{\"address\":\"host2\",\"port\":4321},{\"address\":\"host3\",\"port\":3231}]}"
),
Arguments.of(
"esdb://host1,host2,host3?tls=false",
"://host1,host2,host3?tls=false",
"{\"dnsDiscover\":false,\"maxDiscoverAttempts\":3,\"discoveryInterval\":500,\"gossipTimeout\":3000,\"nodePreference\":\"leader\",\"tls\":false,\"tlsVerifyCert\":true,\"throwOnAppendFailure\":true,\"hosts\":[{\"address\":\"host1\",\"port\":2113},{\"address\":\"host2\",\"port\":2113},{\"address\":\"host3\",\"port\":2113}]}"
),
Arguments.of(
"esdb://127.0.0.1:21573?tls=false",
"://127.0.0.1:21573?tls=false",
"{\"dnsDiscover\":false,\"maxDiscoverAttempts\":3,\"discoveryInterval\":500,\"gossipTimeout\":3000,\"nodePreference\":\"leader\",\"tls\":false,\"tlsVerifyCert\":true,\"throwOnAppendFailure\":true,\"hosts\":[{\"address\":\"127.0.0.1\",\"port\":21573}]}"
),
Arguments.of(
"esdb://host1,host2,host3?tlsVerifyCert=false",
"://host1,host2,host3?tlsVerifyCert=false",
"{\"dnsDiscover\":false,\"maxDiscoverAttempts\":3,\"discoveryInterval\":500,\"gossipTimeout\":3000,\"nodePreference\":\"leader\",\"tls\":true,\"tlsVerifyCert\":false,\"throwOnAppendFailure\":true,\"hosts\":[{\"address\":\"host1\",\"port\":2113},{\"address\":\"host2\",\"port\":2113},{\"address\":\"host3\",\"port\":2113}]}"
),
Arguments.of(
"esdb+discover://user:pass@host?nodePreference=follower&tlsVerifyCert=false",
"+discover://user:pass@host?nodePreference=follower&tlsVerifyCert=false",
"{\"dnsDiscover\":true,\"maxDiscoverAttempts\":3,\"discoveryInterval\":500,\"gossipTimeout\":3000,\"nodePreference\":\"follower\",\"tls\":true,\"tlsVerifyCert\":false,\"throwOnAppendFailure\":true,\"defaultCredentials\":{\"login\":\"user\",\"password\":\"pass\"},\"hosts\":[{\"address\":\"host\",\"port\":2113}]}"
),
Arguments.of(
"esdb://my%3Agreat%40username:UyeXx8%24%5EPsOo4jG88FlCauR1Coz25q@host?nodePreference=follower&tlsVerifyCert=false",
"://my%3Agreat%40username:UyeXx8%24%5EPsOo4jG88FlCauR1Coz25q@host?nodePreference=follower&tlsVerifyCert=false",
"{\"dnsDiscover\":false,\"maxDiscoverAttempts\":3,\"discoveryInterval\":500,\"gossipTimeout\":3000,\"nodePreference\":\"follower\",\"tls\":true,\"tlsVerifyCert\":false,\"throwOnAppendFailure\":true,\"defaultCredentials\":{\"login\":\"my:great@username\",\"password\":\"UyeXx8$^PsOo4jG88FlCauR1Coz25q\"},\"hosts\":[{\"address\":\"host\",\"port\":2113}]}"
),
Arguments.of(
"esdb://host?maxDiscoverAttempts=200&discoveryInterval=1000&gossipTimeout=1&nodePreference=leader&tls=false&tlsVerifyCert=false&throwOnAppendFailure=false",
"://host?maxDiscoverAttempts=200&discoveryInterval=1000&gossipTimeout=1&nodePreference=leader&tls=false&tlsVerifyCert=false&throwOnAppendFailure=false",
"{\"dnsDiscover\":false,\"maxDiscoverAttempts\":200,\"discoveryInterval\":1000,\"gossipTimeout\":1,\"nodePreference\":\"leader\",\"tls\":false,\"tlsVerifyCert\":false,\"throwOnAppendFailure\":false,\"hosts\":[{\"address\":\"host\",\"port\":2113}]}"
),
Arguments.of(
"esdb://host?MaxDiscoverAttempts=200&discoveryinterval=1000&GOSSIPTIMEOUT=1&nOdEpReFeReNcE=leader&TLS=false&TlsVerifyCert=false&THROWOnAppendFailure=false",
"://host?MaxDiscoverAttempts=200&discoveryinterval=1000&GOSSIPTIMEOUT=1&nOdEpReFeReNcE=leader&TLS=false&TlsVerifyCert=false&THROWOnAppendFailure=false",
"{\"dnsDiscover\":false,\"maxDiscoverAttempts\":200,\"discoveryInterval\":1000,\"gossipTimeout\":1,\"nodePreference\":\"leader\",\"tls\":false,\"tlsVerifyCert\":false,\"throwOnAppendFailure\":false,\"hosts\":[{\"address\":\"host\",\"port\":2113}]}"
),
Arguments.of(
"esdb://localhost?keepAliveTimeout=20&keepAliveInterval=10",
"://localhost?keepAliveTimeout=20&keepAliveInterval=10",
"{\"dnsDiscover\":false,\"maxDiscoverAttempts\":3,\"discoveryInterval\":500,\"gossipTimeout\":3000,\"nodePreference\":\"leader\",\"tls\":true,\"tlsVerifyCert\":true,\"throwOnAppendFailure\":true,\"hosts\":[{\"address\":\"localhost\",\"port\":2113}], \"keepAliveTimeout\": \"20\", \"keepAliveInterval\": \"10\"}"
),
Arguments.of(
"esdb://localhost?keepAliveTimeout=20&keepAliveInterval=10&nodePreference=readOnlyReplica",
"://localhost?keepAliveTimeout=20&keepAliveInterval=10&nodePreference=readOnlyReplica",
"{\"dnsDiscover\":false,\"maxDiscoverAttempts\":3,\"discoveryInterval\":500,\"gossipTimeout\":3000,\"nodePreference\":\"readOnlyReplica\",\"tls\":true,\"tlsVerifyCert\":true,\"throwOnAppendFailure\":true,\"hosts\":[{\"address\":\"localhost\",\"port\":2113}], \"keepAliveTimeout\": \"20\", \"keepAliveInterval\": \"10\"}"
),
Arguments.of(
"esdb://127.0.0.1:21573?defaultDeadline=60000",
"://127.0.0.1:21573?defaultDeadline=60000",
"{\"dnsDiscover\":false,\"maxDiscoverAttempts\":3,\"discoveryInterval\":500,\"gossipTimeout\":3000,\"nodePreference\":\"leader\",\"tls\":true,\"tlsVerifyCert\":true,\"throwOnAppendFailure\":true,\"hosts\":[{\"address\":\"127.0.0.1\",\"port\":21573}], \"defaultDeadline\": 60000}"
),
Arguments.of(
"esdb://127.0.0.1:21573?tlsCaFile=/path/to/cert",
"://127.0.0.1:21573?tlsCaFile=/path/to/cert",
"{\"dnsDiscover\":false,\"maxDiscoverAttempts\":3,\"discoveryInterval\":500,\"gossipTimeout\":3000,\"nodePreference\":\"leader\",\"tls\":true,\"tlsVerifyCert\":true,\"throwOnAppendFailure\":true,\"hosts\":[{\"address\":\"127.0.0.1\",\"port\":21573}], \"tlsCaFile\": \"/path/to/cert\"}"
),
Arguments.of(
"esdb://127.0.0.1:21573?userCertFile=/path/to/cert&userKeyFile=/path/to/key",
"://127.0.0.1:21573?userCertFile=/path/to/cert&userKeyFile=/path/to/key",
"{\"dnsDiscover\":false,\"maxDiscoverAttempts\":3,\"discoveryInterval\":500,\"gossipTimeout\":3000,\"nodePreference\":\"leader\",\"tls\":true,\"tlsVerifyCert\":true,\"throwOnAppendFailure\":true,\"hosts\":[{\"address\":\"127.0.0.1\",\"port\":21573}], \"defaultClientCertificate\": {\"clientCertFile\": \"/path/to/cert\", \"clientKeyFile\": \"/path/to/key\"}}"
),
Arguments.of(
"esdb://localhost?feature=foobar",
"://localhost?feature=foobar",
"{\"dnsDiscover\":false,\"maxDiscoverAttempts\":3,\"discoveryInterval\":500,\"gossipTimeout\":3000,\"nodePreference\":\"leader\",\"tls\":true,\"tlsVerifyCert\":true,\"throwOnAppendFailure\":true,\"hosts\":[{\"address\":\"localhost\",\"port\":2113}], \"features\": \"foobar\"}"
),
Arguments.of(
"esdb://localhost?feature=foobar&feature=baz",
"://localhost?feature=foobar&feature=baz",
"{\"dnsDiscover\":false,\"maxDiscoverAttempts\":3,\"discoveryInterval\":500,\"gossipTimeout\":3000,\"nodePreference\":\"leader\",\"tls\":true,\"tlsVerifyCert\":true,\"throwOnAppendFailure\":true,\"hosts\":[{\"address\":\"localhost\",\"port\":2113}], \"features\": [\"foobar\", \"baz\"]}"
)
);

return baseConnectionStrings.stream()
.flatMap(base -> PROTOCOLS.stream()
.map(protocol -> Arguments.of(protocol + base.get()[0], base.get()[1])));
}

public void assertEquals(KurrentDBClientSettings settings, KurrentDBClientSettings other) {
Expand Down

0 comments on commit 90505c5

Please sign in to comment.