diff --git a/.gitignore b/.gitignore
index e263d9723..56389e3fa 100644
--- a/.gitignore
+++ b/.gitignore
@@ -41,11 +41,9 @@ Thumbs.db
.gradle
# Build output directies
-/target
-*/target
-/build
-*/build
-*/bin
+target/
+build/
+bin/
# IntelliJ specific files/directories
out
diff --git a/curator-client/pom.xml b/curator-client/pom.xml
index f3192be95..04ce3fca5 100644
--- a/curator-client/pom.xml
+++ b/curator-client/pom.xml
@@ -26,11 +26,11 @@
org.apache.curator
apache-curator
- 5.5.1-SNAPSHOT
+ 5.6.1-SNAPSHOT
curator-client
- 5.5.1-SNAPSHOT
+ 5.6.1-SNAPSHOT
bundle
Curator Client
diff --git a/curator-client/src/main/java/org/apache/curator/drivers/AdvancedTracerDriver.java b/curator-client/src/main/java/org/apache/curator/drivers/AdvancedTracerDriver.java
index 800dd0cea..ecd7a204c 100644
--- a/curator-client/src/main/java/org/apache/curator/drivers/AdvancedTracerDriver.java
+++ b/curator-client/src/main/java/org/apache/curator/drivers/AdvancedTracerDriver.java
@@ -26,17 +26,43 @@
*/
public abstract class AdvancedTracerDriver implements TracerDriver {
/**
- * Record the given trace event
+ * Records the start of a new operation that will later complete successfully or erroneously via a call to
+ * {@link #endTrace(OperationTrace)}. The call may optionally return driver specific state which can be
+ * accessed in {@link #endTrace(OperationTrace) endTrace} via {@link OperationTrace#getDriverTrace()}. The
+ * driver implementation is responsible for checking that any state returned is valid. Additionally, while it is
+ * expected that all calls to {@code startTrace} will have a corresponding call to
+ * {@link #endTrace(OperationTrace) endTrace}, it is the responsibility of the driver implementation to manage any
+ * leaking of non-terminal {@link OperationTrace OperationTraces}.
*
* @param trace the metrics of the operation
+ * @return The internal trace representation of the driver implementation. Driver dependent, may be {@code null}.
*/
- public abstract void addTrace(OperationTrace trace);
+ public abstract Object startTrace(OperationTrace trace);
/**
- * Add to a named counter
+ * Signals the completion, successful or otherwise, of the specified {@link OperationTrace}.
+ *
+ * @param trace the metrics of the operation
+ */
+ public abstract void endTrace(OperationTrace trace);
+
+ /**
+ * Record the given trace event after the completion of the event. This is equivalent to calling
+ * {@link #startTrace(OperationTrace) startTrace} followed by {@link #endTrace(OperationTrace) endTrace}.
+ *
+ * @param trace the metrics of the operation
+ * @deprecated Prefer the use of {@link #startTrace(OperationTrace)} followed by {@link #endTrace(OperationTrace)}
+ */
+ @Deprecated
+ public void addTrace(OperationTrace trace) {
+ startTrace(trace);
+ endTrace(trace);
+ }
+
+ /**
+ * Record the given trace event
*
- * @param name name of the counter
- * @param increment amount to increment
+ * @param trace name of the counter
*/
public abstract void addEvent(EventTrace trace);
diff --git a/curator-client/src/main/java/org/apache/curator/drivers/OperationTrace.java b/curator-client/src/main/java/org/apache/curator/drivers/OperationTrace.java
index 8ef3de09f..ee86ae002 100644
--- a/curator-client/src/main/java/org/apache/curator/drivers/OperationTrace.java
+++ b/curator-client/src/main/java/org/apache/curator/drivers/OperationTrace.java
@@ -19,28 +19,33 @@
package org.apache.curator.drivers;
-import java.io.UnsupportedEncodingException;
+import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.data.Stat;
+
import java.util.concurrent.TimeUnit;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.data.Stat;
+import static java.nio.charset.StandardCharsets.UTF_8;
+
/**
* Used to trace the metrics of a certain Zookeeper operation.
*/
public class OperationTrace {
private final String name;
private final TracerDriver driver;
-
+ private final long startTimeNanos = System.nanoTime();
+ private final long sessionId;
+ private long endTimeNanos = -1L;
private int returnCode = KeeperException.Code.OK.intValue();
private long latencyMs;
private long requestBytesLength;
private long responseBytesLength;
private String path;
private boolean withWatcher;
- private long sessionId;
private Stat stat;
-
- private final long startTimeNanos = System.nanoTime();
+ // This would ideally be a parameterised type, but we do not wish to break the existing API at this time.
+ private Object driverTrace;
public OperationTrace(String name, TracerDriver driver) {
this(name, driver, -1);
@@ -50,6 +55,9 @@ public OperationTrace(String name, TracerDriver driver, long sessionId) {
this.name = name;
this.driver = driver;
this.sessionId = sessionId;
+ if (this.driver instanceof AdvancedTracerDriver) {
+ driverTrace = ((AdvancedTracerDriver) this.driver).startTrace(this);
+ }
}
public OperationTrace setReturnCode(int returnCode) {
@@ -66,13 +74,7 @@ public OperationTrace setRequestBytesLength(String data) {
if (data == null) {
return this;
}
-
- try {
- this.setRequestBytesLength(data.getBytes("UTF-8").length);
- } catch (UnsupportedEncodingException e) {
- // Ignore the exception.
- }
-
+ this.setRequestBytesLength(data.getBytes(UTF_8).length);
return this;
}
@@ -112,6 +114,10 @@ public OperationTrace setStat(Stat stat) {
return this;
}
+ public Object getDriverTrace() {
+ return driverTrace;
+ }
+
public String getName() {
return this.name;
}
@@ -148,11 +154,23 @@ public Stat getStat() {
return this.stat;
}
+ public long getStartTimeNanos() {
+ return this.startTimeNanos;
+ }
+
+ public long getEndTimeNanos() {
+ if (endTimeNanos < startTimeNanos) {
+ throw new IllegalStateException("End time requested but trace has not yet ended.");
+ }
+ return this.endTimeNanos;
+ }
+
public void commit() {
- long elapsed = System.nanoTime() - startTimeNanos;
+ endTimeNanos = System.nanoTime();
+ long elapsed = endTimeNanos - startTimeNanos;
this.latencyMs = TimeUnit.MILLISECONDS.convert(elapsed, TimeUnit.NANOSECONDS);
if (this.driver instanceof AdvancedTracerDriver) {
- ((AdvancedTracerDriver) this.driver).addTrace(this);
+ ((AdvancedTracerDriver) this.driver).endTrace(this);
} else {
this.driver.addTrace(this.name, elapsed, TimeUnit.NANOSECONDS);
}
diff --git a/curator-client/src/main/java/org/apache/curator/retry/ExponentialBackoffRetry.java b/curator-client/src/main/java/org/apache/curator/retry/ExponentialBackoffRetry.java
index 929b3b372..44aac9bde 100644
--- a/curator-client/src/main/java/org/apache/curator/retry/ExponentialBackoffRetry.java
+++ b/curator-client/src/main/java/org/apache/curator/retry/ExponentialBackoffRetry.java
@@ -64,7 +64,7 @@ public int getBaseSleepTimeMs() {
@Override
protected long getSleepTimeMs(int retryCount, long elapsedTimeMs) {
// copied from Hadoop's RetryPolicies.java
- long sleepMs = baseSleepTimeMs * Math.max(1, random.nextInt(1 << (retryCount + 1)));
+ long sleepMs = (long) baseSleepTimeMs * Math.max(1, random.nextInt(1 << (retryCount + 1)));
if (sleepMs > maxSleepMs) {
log.warn(String.format("Sleep extension too large (%d). Pinning to %d", sleepMs, maxSleepMs));
sleepMs = maxSleepMs;
diff --git a/curator-drivers/open-telemetry/pom.xml b/curator-drivers/open-telemetry/pom.xml
new file mode 100644
index 000000000..28e423b7b
--- /dev/null
+++ b/curator-drivers/open-telemetry/pom.xml
@@ -0,0 +1,79 @@
+
+
+
+
+ 4.0.0
+
+
+ org.apache.curator
+ curator-drivers
+ 5.6.1-SNAPSHOT
+
+
+ curator-drivers-open-telemetry
+ 5.6.1-SNAPSHOT
+
+ Curator OpenTelemetry Tracing Driver
+ A tracing driver driver that emits OpenTelemetry spans.
+ 2023
+
+
+ 1.31.0
+
+
+
+
+ org.apache.curator
+ curator-client
+ ${project.version}
+ provided
+
+
+ io.opentelemetry
+ opentelemetry-api
+ ${opentelemetry.version}
+
+
+ io.opentelemetry
+ opentelemetry-sdk-testing
+ ${opentelemetry.version}
+ test
+
+
+ org.junit.jupiter
+ junit-jupiter-api
+ test
+
+
+ org.slf4j
+ slf4j-log4j12
+ test
+
+
+ org.assertj
+ assertj-core
+ test
+
+
+
\ No newline at end of file
diff --git a/curator-drivers/open-telemetry/src/main/java/org/apache/curator/drivers/opentelemetry/OpenTelemetryTracingDriver.java b/curator-drivers/open-telemetry/src/main/java/org/apache/curator/drivers/opentelemetry/OpenTelemetryTracingDriver.java
new file mode 100644
index 000000000..d4719e85a
--- /dev/null
+++ b/curator-drivers/open-telemetry/src/main/java/org/apache/curator/drivers/opentelemetry/OpenTelemetryTracingDriver.java
@@ -0,0 +1,185 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.curator.drivers.opentelemetry;
+
+import static org.apache.curator.drivers.opentelemetry.OpenTelemetryTracingDriver.AttributeKeys.LATENCY_MS_ATTRIBUTE;
+import static org.apache.curator.drivers.opentelemetry.OpenTelemetryTracingDriver.AttributeKeys.PATH_ATTRIBUTE;
+import static org.apache.curator.drivers.opentelemetry.OpenTelemetryTracingDriver.AttributeKeys.REQUEST_BYTES_LENGTH_ATTRIBUTE;
+import static org.apache.curator.drivers.opentelemetry.OpenTelemetryTracingDriver.AttributeKeys.RESPONSE_BYTES_LENGTH_ATTRIBUTE;
+import static org.apache.curator.drivers.opentelemetry.OpenTelemetryTracingDriver.AttributeKeys.SESSION_ID_ATTRIBUTE;
+import static org.apache.curator.drivers.opentelemetry.OpenTelemetryTracingDriver.AttributeKeys.STAT_AVERSION_ATTRIBUTE;
+import static org.apache.curator.drivers.opentelemetry.OpenTelemetryTracingDriver.AttributeKeys.STAT_CTIME_ATTRIBUTE;
+import static org.apache.curator.drivers.opentelemetry.OpenTelemetryTracingDriver.AttributeKeys.STAT_CVERSION_ATTRIBUTE;
+import static org.apache.curator.drivers.opentelemetry.OpenTelemetryTracingDriver.AttributeKeys.STAT_CZXID_ATTRIBUTE;
+import static org.apache.curator.drivers.opentelemetry.OpenTelemetryTracingDriver.AttributeKeys.STAT_DATA_LENGTH_ATTRIBUTE;
+import static org.apache.curator.drivers.opentelemetry.OpenTelemetryTracingDriver.AttributeKeys.STAT_EPHEMERAL_OWNER_ATTRIBUTE;
+import static org.apache.curator.drivers.opentelemetry.OpenTelemetryTracingDriver.AttributeKeys.STAT_MTIME_ATTRIBUTE;
+import static org.apache.curator.drivers.opentelemetry.OpenTelemetryTracingDriver.AttributeKeys.STAT_MZXID_ATTRIBUTE;
+import static org.apache.curator.drivers.opentelemetry.OpenTelemetryTracingDriver.AttributeKeys.STAT_NUM_CHILDREN_ATTRIBUTE;
+import static org.apache.curator.drivers.opentelemetry.OpenTelemetryTracingDriver.AttributeKeys.STAT_PZXID_ATTRIBUTE;
+import static org.apache.curator.drivers.opentelemetry.OpenTelemetryTracingDriver.AttributeKeys.STAT_VERSION_ATTRIBUTE;
+import static org.apache.curator.drivers.opentelemetry.OpenTelemetryTracingDriver.AttributeKeys.WITH_WATCHER_ATTRIBUTE;
+import static java.util.concurrent.TimeUnit.NANOSECONDS;
+
+import org.apache.curator.drivers.AdvancedTracerDriver;
+import org.apache.curator.drivers.EventTrace;
+import org.apache.curator.drivers.OperationTrace;
+import org.apache.zookeeper.KeeperException;
+
+import com.google.common.base.Preconditions;
+
+import io.opentelemetry.api.common.AttributeKey;
+import io.opentelemetry.api.common.Attributes;
+import io.opentelemetry.api.trace.Span;
+import io.opentelemetry.api.trace.StatusCode;
+import io.opentelemetry.api.trace.Tracer;
+import io.opentelemetry.context.Scope;
+
+/**
+ * Converts Apache Curator traces and events to OpenTelemetry spans, and then publishes these to the supplied OTel
+ * {@link Tracer}. Curator events are added to whatever OTel deems as the {@link Span#current()} current span}. Note
+ * that in the case of attributes, this implementation takes the approach of capturing deviations from the baseline.
+ * For example, it will not register attributes if they have the default value, only if the value has diverged from it.
+ */
+public class OpenTelemetryTracingDriver extends AdvancedTracerDriver {
+
+ interface AttributeKeys {
+ AttributeKey PATH_ATTRIBUTE = AttributeKey.stringKey("path");
+ AttributeKey SESSION_ID_ATTRIBUTE = AttributeKey.longKey("sessionId");
+ AttributeKey LATENCY_MS_ATTRIBUTE = AttributeKey.longKey("latencyMs");
+ AttributeKey REQUEST_BYTES_LENGTH_ATTRIBUTE = AttributeKey.longKey("requestBytesLength");
+ AttributeKey RESPONSE_BYTES_LENGTH_ATTRIBUTE = AttributeKey.longKey("responseBytesLength");
+ AttributeKey WITH_WATCHER_ATTRIBUTE = AttributeKey.booleanKey("withWatcher");
+ AttributeKey STAT_AVERSION_ATTRIBUTE = AttributeKey.longKey("stat.Aversion");
+ AttributeKey STAT_CTIME_ATTRIBUTE = AttributeKey.longKey("stat.Ctime");
+ AttributeKey STAT_CVERSION_ATTRIBUTE = AttributeKey.longKey("stat.Cversion");
+ AttributeKey STAT_CZXID_ATTRIBUTE = AttributeKey.longKey("stat.Czxid");
+ AttributeKey STAT_DATA_LENGTH_ATTRIBUTE = AttributeKey.longKey("stat.DataLength");
+ AttributeKey STAT_EPHEMERAL_OWNER_ATTRIBUTE = AttributeKey.longKey("stat.EphemeralOwner");
+ AttributeKey STAT_MTIME_ATTRIBUTE = AttributeKey.longKey("stat.Mtime");
+ AttributeKey STAT_MZXID_ATTRIBUTE = AttributeKey.longKey("stat.Mzxid");
+ AttributeKey STAT_NUM_CHILDREN_ATTRIBUTE = AttributeKey.longKey("stat.NumChildren");
+ AttributeKey STAT_PZXID_ATTRIBUTE = AttributeKey.longKey("stat.Pzxid");
+ AttributeKey STAT_VERSION_ATTRIBUTE = AttributeKey.longKey("stat.Version");
+ }
+
+ private final Tracer tracer;
+
+ public OpenTelemetryTracingDriver(Tracer tracer) {
+ Preconditions.checkNotNull(tracer);
+ this.tracer = tracer;
+ }
+
+ @Override
+ public Object startTrace(OperationTrace trace) {
+ Preconditions.checkNotNull(trace);
+ Span span = tracer.spanBuilder(trace.getName())
+ .setStartTimestamp(trace.getStartTimeNanos(), NANOSECONDS)
+ .startSpan();
+
+ if (trace.getPath() != null) {
+ span.setAttribute(PATH_ATTRIBUTE, trace.getPath());
+ }
+ if (trace.isWithWatcher()) {
+ span.setAttribute(WITH_WATCHER_ATTRIBUTE, true);
+ }
+ if (trace.getSessionId() >= 0) {
+ span.setAttribute(SESSION_ID_ATTRIBUTE, trace.getSessionId());
+ }
+ if (trace.getRequestBytesLength() > 0) {
+ span.setAttribute(REQUEST_BYTES_LENGTH_ATTRIBUTE, trace.getRequestBytesLength());
+ }
+ // We will close this in endTrace
+ @SuppressWarnings("MustBeClosedChecker")
+ Scope scope = span.makeCurrent();
+ return new SpanScope(span, scope);
+ }
+
+ @Override
+ public void endTrace(OperationTrace trace) {
+ Preconditions.checkNotNull(trace);
+ SpanScope spanScope = (SpanScope) trace.getDriverTrace();
+ Span span = spanScope.getSpan();
+
+ if (trace.getReturnCode() == KeeperException.Code.OK.intValue()) {
+ span.setStatus(StatusCode.OK);
+ } else {
+ span.setStatus(StatusCode.ERROR);
+ span.recordException(
+ KeeperException.create(KeeperException.Code.get(trace.getReturnCode())),
+ Attributes.of(PATH_ATTRIBUTE, trace.getPath())
+ );
+ }
+
+ span.setAttribute(LATENCY_MS_ATTRIBUTE, trace.getRequestBytesLength());
+
+ if (trace.getResponseBytesLength() > 0) {
+ span.setAttribute(RESPONSE_BYTES_LENGTH_ATTRIBUTE, trace.getResponseBytesLength());
+ }
+
+ if (trace.getStat() != null) {
+ span.setAttribute(STAT_AVERSION_ATTRIBUTE, trace.getStat().getAversion());
+ span.setAttribute(STAT_CTIME_ATTRIBUTE, trace.getStat().getCtime());
+ span.setAttribute(STAT_CVERSION_ATTRIBUTE, trace.getStat().getCversion());
+ span.setAttribute(STAT_CZXID_ATTRIBUTE, trace.getStat().getCzxid());
+ span.setAttribute(STAT_DATA_LENGTH_ATTRIBUTE, trace.getStat().getDataLength());
+ span.setAttribute(STAT_EPHEMERAL_OWNER_ATTRIBUTE, trace.getStat().getEphemeralOwner());
+ span.setAttribute(STAT_MTIME_ATTRIBUTE, trace.getStat().getMtime());
+ span.setAttribute(STAT_MZXID_ATTRIBUTE, trace.getStat().getMzxid());
+ span.setAttribute(STAT_NUM_CHILDREN_ATTRIBUTE, trace.getStat().getNumChildren());
+ span.setAttribute(STAT_PZXID_ATTRIBUTE, trace.getStat().getPzxid());
+ span.setAttribute(STAT_VERSION_ATTRIBUTE, trace.getStat().getVersion());
+ }
+
+ span.end(trace.getEndTimeNanos(), NANOSECONDS);
+ spanScope.getScope().close();
+ }
+
+ @Override
+ public void addEvent(EventTrace trace) {
+ Preconditions.checkNotNull(trace);
+ Span span = Span.current();
+ Attributes attrs;
+ if (trace.getSessionId() >= 0) {
+ attrs = Attributes.of(SESSION_ID_ATTRIBUTE, trace.getSessionId());
+ } else {
+ attrs = Attributes.empty();
+ }
+ span.addEvent(trace.getName(), attrs);
+ }
+
+ static final class SpanScope {
+ private final Span span;
+ private final Scope scope;
+
+ SpanScope(Span span, Scope scope) {
+ this.span = span;
+ this.scope = scope;
+ }
+
+ Span getSpan() {
+ return span;
+ }
+
+ Scope getScope() {
+ return scope;
+ }
+ }
+}
diff --git a/curator-drivers/open-telemetry/src/test/java/org/apache/curator/drivers/opentelemetry/OpenTelemetryTracingDriverTest.java b/curator-drivers/open-telemetry/src/test/java/org/apache/curator/drivers/opentelemetry/OpenTelemetryTracingDriverTest.java
new file mode 100644
index 000000000..7f0d432b9
--- /dev/null
+++ b/curator-drivers/open-telemetry/src/test/java/org/apache/curator/drivers/opentelemetry/OpenTelemetryTracingDriverTest.java
@@ -0,0 +1,125 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.curator.drivers.opentelemetry;
+
+import static org.apache.curator.drivers.opentelemetry.OpenTelemetryTracingDriver.AttributeKeys.SESSION_ID_ATTRIBUTE;
+import static org.assertj.core.api.Assertions.assertThat;
+
+import org.apache.curator.drivers.EventTrace;
+import org.apache.curator.drivers.OperationTrace;
+import org.apache.zookeeper.KeeperException;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.extension.RegisterExtension;
+
+import io.opentelemetry.api.trace.Span;
+import io.opentelemetry.api.trace.SpanKind;
+import io.opentelemetry.api.trace.Tracer;
+import io.opentelemetry.context.Scope;
+import io.opentelemetry.sdk.testing.junit5.OpenTelemetryExtension;
+import io.opentelemetry.sdk.trace.data.StatusData;
+
+class OpenTelemetryTracingDriverTest {
+ @RegisterExtension
+ static final OpenTelemetryExtension otel = OpenTelemetryExtension.create();
+
+ private final Tracer tracer = otel.getOpenTelemetry().getTracer("test");
+ private final OpenTelemetryTracingDriver driver = new OpenTelemetryTracingDriver(tracer);
+
+ @Test
+ void testAddTrace_ok() {
+ OperationTrace trace = new OperationTrace("op", driver, 1L);
+ trace.setPath("path");
+ trace.setReturnCode(KeeperException.Code.OK.intValue());
+ trace.commit();
+
+ otel.assertTraces().hasTracesSatisfyingExactly(
+ t -> t.hasSpansSatisfyingExactly(s -> {
+ s.hasName("op");
+ s.hasStatus(StatusData.ok());
+ s.hasAttribute(SESSION_ID_ATTRIBUTE, 1L);
+ s.hasKind(SpanKind.INTERNAL);
+ s.hasEnded();
+ })
+ );
+ }
+
+ @Test
+ void testAddTrace_fail() {
+ OperationTrace trace = new OperationTrace("op", driver);
+ trace.setPath("path");
+ trace.setReturnCode(KeeperException.Code.NOAUTH.intValue());
+ trace.commit();
+
+ otel.assertTraces().hasTracesSatisfyingExactly(
+ t -> t.hasSpansSatisfyingExactly(s -> {
+ s.hasStatus(StatusData.error());
+ s.hasException(new KeeperException.NoAuthException());
+ })
+ );
+ }
+
+ @Test
+ void testAddEvent() {
+ Span span = tracer.spanBuilder("test-span").startSpan();
+ try (Scope ignored = span.makeCurrent()) {
+ new EventTrace("session-expired", driver).commit();
+ span.end();
+
+ otel.assertTraces().hasTracesSatisfyingExactly(
+ t -> t.hasSpansSatisfyingExactly(
+ s -> s.hasEventsSatisfyingExactly(e -> e.hasName("session-expired"))
+ )
+ );
+ }
+ }
+
+ @Test
+ void testAddEvent_noCurrentSpan() {
+ new EventTrace("session-expired", driver).commit();
+ otel.assertTraces().isEmpty();
+ }
+
+ @Test
+ void testAddTraceAndEvent() {
+ OperationTrace trace = new OperationTrace("op", driver, 1L);
+ trace.setPath("path");
+
+ new EventTrace("session-expired", driver, 1L).commit();
+
+ trace.setReturnCode(KeeperException.Code.SESSIONEXPIRED.intValue());
+ trace.commit();
+
+ otel.assertTraces().hasTracesSatisfyingExactly(
+ t -> t.hasSpansSatisfyingExactly(s -> {
+ s.hasStatus(StatusData.error());
+ s.hasEventsSatisfyingExactly(
+ e -> {
+ e.hasName("session-expired");
+ e.hasAttributesSatisfying(a -> {
+ assertThat(a.get(SESSION_ID_ATTRIBUTE)).isEqualTo(1L);
+ assertThat(a.size()).isEqualTo(1L);
+ });
+ },
+ e -> e.hasName("exception")
+ );
+ })
+ );
+ }
+}
diff --git a/curator-drivers/pom.xml b/curator-drivers/pom.xml
new file mode 100644
index 000000000..1ac78cece
--- /dev/null
+++ b/curator-drivers/pom.xml
@@ -0,0 +1,46 @@
+
+
+
+
+ 4.0.0
+
+
+ org.apache.curator
+ apache-curator
+ 5.6.1-SNAPSHOT
+
+
+ curator-drivers
+ 5.6.1-SNAPSHOT
+ pom
+
+ Curator Driver Implementations
+ A collection of Curator driver integrations.
+ 2023
+
+
+ open-telemetry
+
+
+
\ No newline at end of file
diff --git a/curator-examples/pom.xml b/curator-examples/pom.xml
index f5b5c4815..e55fd769b 100644
--- a/curator-examples/pom.xml
+++ b/curator-examples/pom.xml
@@ -26,7 +26,7 @@
org.apache.curator
apache-curator
- 5.5.1-SNAPSHOT
+ 5.6.1-SNAPSHOT
curator-examples
diff --git a/curator-framework/pom.xml b/curator-framework/pom.xml
index 779b0d180..706c00093 100644
--- a/curator-framework/pom.xml
+++ b/curator-framework/pom.xml
@@ -26,11 +26,11 @@
org.apache.curator
apache-curator
- 5.5.1-SNAPSHOT
+ 5.6.1-SNAPSHOT
curator-framework
- 5.5.1-SNAPSHOT
+ 5.6.1-SNAPSHOT
bundle
Curator Framework
diff --git a/curator-recipes/pom.xml b/curator-recipes/pom.xml
index 60a862277..927af0c28 100644
--- a/curator-recipes/pom.xml
+++ b/curator-recipes/pom.xml
@@ -26,11 +26,11 @@
org.apache.curator
apache-curator
- 5.5.1-SNAPSHOT
+ 5.6.1-SNAPSHOT
curator-recipes
- 5.5.1-SNAPSHOT
+ 5.6.1-SNAPSHOT
bundle
Curator Recipes
diff --git a/curator-test-zk35/pom.xml b/curator-test-zk35/pom.xml
index 84cf0df0e..d9bfaf906 100644
--- a/curator-test-zk35/pom.xml
+++ b/curator-test-zk35/pom.xml
@@ -24,7 +24,7 @@
org.apache.curator
apache-curator
- 5.5.1-SNAPSHOT
+ 5.6.1-SNAPSHOT
4.0.0
diff --git a/curator-test-zk36/pom.xml b/curator-test-zk36/pom.xml
index 23f5fd0e4..32261524d 100644
--- a/curator-test-zk36/pom.xml
+++ b/curator-test-zk36/pom.xml
@@ -24,7 +24,7 @@
org.apache.curator
apache-curator
- 5.5.1-SNAPSHOT
+ 5.6.1-SNAPSHOT
4.0.0
diff --git a/curator-test/pom.xml b/curator-test/pom.xml
index 64d99fabf..ad61c1c31 100644
--- a/curator-test/pom.xml
+++ b/curator-test/pom.xml
@@ -26,11 +26,11 @@
org.apache.curator
apache-curator
- 5.5.1-SNAPSHOT
+ 5.6.1-SNAPSHOT
curator-test
- 5.5.1-SNAPSHOT
+ 5.6.1-SNAPSHOT
Curator Testing
Unit testing utilities.
diff --git a/curator-x-async/pom.xml b/curator-x-async/pom.xml
index f9e921a45..297e096ed 100644
--- a/curator-x-async/pom.xml
+++ b/curator-x-async/pom.xml
@@ -24,7 +24,7 @@
org.apache.curator
apache-curator
- 5.5.1-SNAPSHOT
+ 5.6.1-SNAPSHOT
4.0.0
diff --git a/curator-x-discovery-server/pom.xml b/curator-x-discovery-server/pom.xml
index 0695f8881..3f80af0eb 100644
--- a/curator-x-discovery-server/pom.xml
+++ b/curator-x-discovery-server/pom.xml
@@ -26,11 +26,11 @@
org.apache.curator
apache-curator
- 5.5.1-SNAPSHOT
+ 5.6.1-SNAPSHOT
curator-x-discovery-server
- 5.5.1-SNAPSHOT
+ 5.6.1-SNAPSHOT
bundle
Curator Service Discovery Server
diff --git a/curator-x-discovery/pom.xml b/curator-x-discovery/pom.xml
index 229fce2fe..36821852d 100644
--- a/curator-x-discovery/pom.xml
+++ b/curator-x-discovery/pom.xml
@@ -26,11 +26,11 @@
org.apache.curator
apache-curator
- 5.5.1-SNAPSHOT
+ 5.6.1-SNAPSHOT
curator-x-discovery
- 5.5.1-SNAPSHOT
+ 5.6.1-SNAPSHOT
bundle
Curator Service Discovery
diff --git a/pom.xml b/pom.xml
index 67a2f3922..b31cf892c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -26,12 +26,12 @@
org.apache
apache
- 21
+ 31
org.apache.curator
apache-curator
- 5.5.1-SNAPSHOT
+ 5.6.1-SNAPSHOT
pom
Apache Curator
@@ -352,6 +352,7 @@
curator-x-async
curator-test-zk35
curator-test-zk36
+ curator-drivers
@@ -942,9 +943,9 @@
\#|
-
-
-
+
+
+
true
4