Skip to content

Commit

Permalink
JVMCBC-1603 Parse appTelemetryPath from cluster topology
Browse files Browse the repository at this point in the history
Motivation
----------
Groundwork for application telemetry.

Modifications
-------------
Parse `appTelemetryPath` from app telemetry path
and add it to `HostAndServicePorts`.

Update `HostAndServicePorts.equals()` to include
field added by recent commits.

Change-Id: I6e6d51d872341a6405836ff6ee8730886c40c290
Reviewed-on: https://review.couchbase.org/c/couchbase-jvm-clients/+/222234
Tested-by: Build Bot <[email protected]>
Reviewed-by: Michael Reiche <[email protected]>
  • Loading branch information
dnault committed Jan 23, 2025
1 parent 98a0267 commit a5b8368
Show file tree
Hide file tree
Showing 6 changed files with 58 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ public NodeBuilder serverGroup(@Nullable String serverGroup) {

public HostAndServicePorts build() {
NodeIdentifier id = this.id != null ? this.id : new NodeIdentifier(canonicalHost, 8091, hostForNetworkConnections);
return new HostAndServicePorts(hostForNetworkConnections, ports, id, ketamaAuthority, serverGroup);
return new HostAndServicePorts(hostForNetworkConnections, ports, id, ketamaAuthority, serverGroup, null);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ public class HostAndServicePorts implements KetamaRingNode {
emptyMap(),
new NodeIdentifier("<inaccessible>", 0, "<inaccessible>"),
null,
null,
null
);

Expand All @@ -60,19 +61,22 @@ public class HostAndServicePorts implements KetamaRingNode {
private final NodeIdentifier id;
private final @Nullable HostAndPort ketamaAuthority;
private final @Nullable String serverGroup;
private final @Nullable String appTelemetryPath;

public HostAndServicePorts(
String host,
Map<ServiceType, Integer> ports,
NodeIdentifier id,
@Nullable HostAndPort ketamaAuthority,
@Nullable String serverGroup
@Nullable String serverGroup,
@Nullable String appTelemetryPath
) {
this.host = requireNonNull(host);
this.ports = unmodifiableMap(newEnumMap(ServiceType.class, ports));
this.id = requireNonNull(id);
this.ketamaAuthority = ketamaAuthority;
this.serverGroup = serverGroup;
this.appTelemetryPath = appTelemetryPath;
}

public boolean inaccessible() {
Expand Down Expand Up @@ -109,10 +113,23 @@ public Map<ServiceType, Integer> ports() {
return ports;
}

/**
* Returns the name of the server group this node belongs to,
* or null if Couchbase Server version is less than 7.6.2.
*/
public @Nullable String serverGroup() {
return serverGroup;
}

/**
* Returns the HTTP path that accepts application telemetry WebSocket connections
* (on management service part), or null if this node does not currently accept
* application telemetry connections.
*/
public @Nullable String appTelemetryPath() {
return appTelemetryPath;
}

public boolean has(ServiceType serviceType) {
return ports.containsKey(serviceType);
}
Expand All @@ -129,15 +146,15 @@ public HostAndServicePorts without(ServiceType service, ServiceType... moreServi
temp.remove(t);
}

return new HostAndServicePorts(this.host, temp, this.id, this.ketamaAuthority, this.serverGroup);
return new HostAndServicePorts(this.host, temp, this.id, this.ketamaAuthority, this.serverGroup, this.appTelemetryPath);
}

@Stability.Internal
public HostAndServicePorts withKetamaAuthority(@Nullable HostAndPort ketamaAuthority) {
if (Objects.equals(this.ketamaAuthority, ketamaAuthority)) {
return this;
}
return new HostAndServicePorts(this.host, this.ports, this.id, ketamaAuthority, this.serverGroup);
return new HostAndServicePorts(this.host, this.ports, this.id, ketamaAuthority, this.serverGroup, this.appTelemetryPath);
}

boolean matches(SeedNode seedNode) {
Expand All @@ -153,10 +170,14 @@ private boolean portEquals(ServiceType serviceType, int port) {

@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
HostAndServicePorts that = (HostAndServicePorts) o;
return host.equals(that.host) && ports.equals(that.ports) && Objects.equals(ketamaAuthority, that.ketamaAuthority);
return Objects.equals(host, that.host) &&
Objects.equals(ports, that.ports) &&
Objects.equals(id, that.id) &&
Objects.equals(ketamaAuthority, that.ketamaAuthority)
&& Objects.equals(serverGroup, that.serverGroup)
&& Objects.equals(appTelemetryPath, that.appTelemetryPath);
}

@Override
Expand All @@ -172,6 +193,7 @@ public String toString() {
", id=" + redactSystem(id) +
", ketamaAuthority=" + redactSystem(ketamaAuthority) +
", serverGroup=" + redactMeta(serverGroup) +
", appTelemetryPath=" + redactSystem(appTelemetryPath) +
'}';
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,16 +54,17 @@ public static Map<NetworkResolution, HostAndServicePorts> parse(
) {
Map<NetworkResolution, HostAndRawServicePorts> raw = parseIntermediate(json);
HostAndPort ketamaAuthority = getKetamaAuthority(raw);
String serverGroup = json.path("serverGroup").asText(); // Absent prior to Couchbase Server 7.6.2
final String serverGroupFinal = serverGroup.isEmpty() ? null : serverGroup;
String serverGroup = json.path("serverGroup").textValue(); // Added in Couchbase Server 7.6.2
String appTelemetryPath = json.path("appTelemetryPath").textValue(); // Added in Couchbase Server 8.0.0

return transformValues(raw, value ->
new HostAndServicePorts(
value.host,
portSelector.selectPorts(value.rawServicePorts),
getId(value.host, raw),
ketamaAuthority,
serverGroupFinal
serverGroup,
appTelemetryPath
)
);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,30 @@ void shouldParseServerGroupsIfPresent() {
);
}

@Test
void appTelemetryPathIsNullIfAbsent() {
ClusterTopology config = parser.parseResource("config_7.2.2_1kv_2query.json");
config.nodes().forEach(node -> assertNull(node.appTelemetryPath()));
}

@Test
void shouldParseAppTelemetryPathIfPresent() {
// TODO: replace with config from actual 8.0.0 build
ClusterTopology config = parser.parseResource("config_8.0.0-prerelease_app_telemetry.json");
assertEquals(
mapOf(
"192.168.106.128", "/foo",
"192.168.106.129", "/bar",
"192.168.106.130", "/zot"
),
config.nodes().stream()
.collect(toMap(
HostAndServicePorts::host,
hostAndServicePorts -> requireNonNull(hostAndServicePorts.appTelemetryPath(), "Missing app telemetry path: " + hostAndServicePorts)
))
);
}

public CouchbaseBucketTopology requireCouchbaseBucket(ClusterTopology cluster) {
try {
return (CouchbaseBucketTopology) cluster.requireBucket().bucket();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public static NodeIdentifier nodeId(String host, int port) {
}

public static HostAndServicePorts node(String host, Map<ServiceType, Integer> ports) {
return new HostAndServicePorts(host, ports, nodeId(host, ports.getOrDefault(ServiceType.MANAGER, 8091)), null, null);
return new HostAndServicePorts(host, ports, nodeId(host, ports.getOrDefault(ServiceType.MANAGER, 8091)), null, null, null);
}

@Deprecated
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"rev":289,"revEpoch":1,"name":"travel-sample","nodeLocator":"vbucket","bucketType":"membase","storageBackend":"couchstore","uuid":"7aee1f3bde34b9c8ef7514cc28e29180","uri":"/pools/default/buckets/travel-sample?bucket_uuid=7aee1f3bde34b9c8ef7514cc28e29180","streamingUri":"/pools/default/bucketsStreaming/travel-sample?bucket_uuid=7aee1f3bde34b9c8ef7514cc28e29180","numVBuckets":1024,"bucketCapabilitiesVer":"","bucketCapabilities":["collections","durableWrite","tombstonedUserXAttrs","couchapi","subdoc.ReplaceBodyWithXattr","subdoc.DocumentMacroSupport","subdoc.ReviveDocument","dcp.IgnorePurgedTombstones","preserveExpiry","querySystemCollection","mobileSystemCollection","subdoc.ReplicaRead","rangeScan","dcp","cbhello","touch","cccp","xdcrCheckpointing","nodesExt","xattr"],"collectionsManifestUid":"2","ddocs":{"uri":"/pools/default/buckets/travel-sample/ddocs"},"vBucketServerMap":{"hashAlgorithm":"CRC","numReplicas":1,"serverList":["192.168.106.128:11210","192.168.106.129:11210","192.168.106.130:11210"],"vBucketMap":[[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,1],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[0,2],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,0],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[1,2],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,0],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1],[2,1]]},"nodes":[{"couchApiBase":"http://192.168.106.128:8092/travel-sample%2B7aee1f3bde34b9c8ef7514cc28e29180","hostname":"192.168.106.128:8091","ports":{"direct":11210}},{"couchApiBase":"http://192.168.106.129:8092/travel-sample%2B7aee1f3bde34b9c8ef7514cc28e29180","hostname":"192.168.106.129:8091","ports":{"direct":11210}},{"couchApiBase":"http://192.168.106.130:8092/travel-sample%2B7aee1f3bde34b9c8ef7514cc28e29180","hostname":"192.168.106.130:8091","ports":{"direct":11210}}],"nodesExt":[{"services":{"capi":8092,"capiSSL":18092,"fts":8094,"ftsGRPC":9130,"ftsGRPCSSL":19130,"ftsSSL":18094,"indexAdmin":9100,"indexHttp":9102,"indexHttps":19102,"indexScan":9101,"indexStreamCatchup":9104,"indexStreamInit":9103,"indexStreamMaint":9105,"kv":11210,"kvSSL":11207,"mgmt":8091,"mgmtSSL":18091,"n1ql":8093,"n1qlSSL":18093,"projector":9999},"thisNode":true,"hostname":"192.168.106.128","serverGroup":"Group 1","appTelemetryPath":"/foo"},{"services":{"capi":8092,"capiSSL":18092,"fts":8094,"ftsGRPC":9130,"ftsGRPCSSL":19130,"ftsSSL":18094,"indexAdmin":9100,"indexHttp":9102,"indexHttps":19102,"indexScan":9101,"indexStreamCatchup":9104,"indexStreamInit":9103,"indexStreamMaint":9105,"kv":11210,"kvSSL":11207,"mgmt":8091,"mgmtSSL":18091,"n1ql":8093,"n1qlSSL":18093,"projector":9999},"hostname":"192.168.106.129","serverGroup":"Group 1","appTelemetryPath":"/bar"},{"services":{"capi":8092,"capiSSL":18092,"fts":8094,"ftsGRPC":9130,"ftsGRPCSSL":19130,"ftsSSL":18094,"indexAdmin":9100,"indexHttp":9102,"indexHttps":19102,"indexScan":9101,"indexStreamCatchup":9104,"indexStreamInit":9103,"indexStreamMaint":9105,"kv":11210,"kvSSL":11207,"mgmt":8091,"mgmtSSL":18091,"n1ql":8093,"n1qlSSL":18093,"projector":9999},"hostname":"192.168.106.130","serverGroup":"Group 2","appTelemetryPath":"/zot"}],"clusterCapabilitiesVer":[1,0],"clusterCapabilities":{"n1ql":["costBasedOptimizer","indexAdvisor","javaScriptFunctions","inlineFunctions","enhancedPreparedStatements","readFromReplica"],"search":["vectorSearch","scopedSearchIndex"]},"clusterUUID":"f4aff221d68c30ee2f3e6f7e6b2362ef","clusterName":"test-cluster"}

0 comments on commit a5b8368

Please sign in to comment.