fix(zookeeper): handle znodes without data

This commit is contained in:
t8y2
2026-07-13 19:13:18 +08:00
parent 2dec6ebeb8
commit 117b1731f7
2 changed files with 35 additions and 0 deletions
@@ -386,6 +386,11 @@ public final class ZooKeeperAgent {
private static Map<String, Object> valueObject(byte[] bytes) {
Map<String, Object> value = new LinkedHashMap<>();
// ZooKeeper represents znodes created without a data payload as null.
// Expose them as empty UTF-8 values instead of passing null to decoders.
if (bytes == null) {
bytes = new byte[0];
}
String utf8 = strictUtf8(bytes);
if (utf8 != null) {
value.put("encoding", "utf8");
@@ -4,7 +4,12 @@ import com.google.gson.JsonArray;
import com.google.gson.JsonElement;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.curator.test.TestingServer;
import org.apache.zookeeper.CreateMode;
import org.apache.zookeeper.ZooDefs;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
@@ -175,6 +180,31 @@ final class ZooKeeperAgentTest {
}
}
@Test
void kvGetReadsZnodeCreatedWithoutDataAsEmptyUtf8() throws Exception {
try (TestingServer server = new TestingServer();
CuratorFramework curator = CuratorFrameworkFactory.newClient(
server.getConnectString(),
new ExponentialBackoffRetry(100, 3)
)) {
curator.start();
curator.getZookeeperClient().getZooKeeper().create(
"/empty",
null,
ZooDefs.Ids.OPEN_ACL_UNSAFE,
CreateMode.PERSISTENT
);
connect(server);
JsonObject get = result(request(3, "kv_get", "{\"key\":\"/empty\"}"));
Assertions.assertTrue(get.get("found").getAsBoolean());
Assertions.assertEquals("utf8", get.getAsJsonObject("value").get("encoding").getAsString());
Assertions.assertEquals("", get.getAsJsonObject("value").get("data").getAsString());
Assertions.assertEquals(0, get.getAsJsonObject("metadata").get("valueSize").getAsInt());
}
}
@Test
void kvPutUpdatesExistingZnode() throws Exception {
try (TestingServer server = new TestingServer()) {