This is an automated email from the ASF dual-hosted git repository.
tison pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/zookeeper.git
The following commit(s) were added to refs/heads/master by this push:
new 6e746f8e8 ZOOKEEPER-4607. Fix decode problem when sub tnx type is
error (#1915)
6e746f8e8 is described below
commit 6e746f8e881bfeb99cf0f74fa50a3d9c9d679229
Author: Yan Zhao <[email protected]>
AuthorDate: Tue Jul 18 20:04:24 2023 +0800
ZOOKEEPER-4607. Fix decode problem when sub tnx type is error (#1915)
Co-authored-by: tison <[email protected]>
---
.../server/persistence/TxnLogToolkit.java | 21 +++++++++----
.../server/persistence/TxnLogToolkitTest.java | 34 ++++++++++++++++++++++
2 files changed, 49 insertions(+), 6 deletions(-)
diff --git
a/zookeeper-server/src/main/java/org/apache/zookeeper/server/persistence/TxnLogToolkit.java
b/zookeeper-server/src/main/java/org/apache/zookeeper/server/persistence/TxnLogToolkit.java
index 8e5b24bbc..767d64077 100644
---
a/zookeeper-server/src/main/java/org/apache/zookeeper/server/persistence/TxnLogToolkit.java
+++
b/zookeeper-server/src/main/java/org/apache/zookeeper/server/persistence/TxnLogToolkit.java
@@ -30,6 +30,7 @@ import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.text.DateFormat;
import java.util.Date;
@@ -47,6 +48,7 @@ import org.apache.commons.cli.ParseException;
import org.apache.jute.BinaryInputArchive;
import org.apache.jute.BinaryOutputArchive;
import org.apache.jute.Record;
+import org.apache.zookeeper.ZooDefs;
import org.apache.zookeeper.server.ExitCode;
import org.apache.zookeeper.server.Request;
import org.apache.zookeeper.server.TxnLogEntry;
@@ -307,11 +309,13 @@ public class TxnLogToolkit implements Closeable {
}
/**
- * get the formatted string from the txn.
+ * Get the formatted string from the txn.
+ *
* @param txn transaction log data
* @return the formatted string
*/
- private static String getFormattedTxnStr(Record txn) throws IOException {
+ // @VisibleForTesting
+ static String getFormattedTxnStr(Record txn) {
StringBuilder txnData = new StringBuilder();
if (txn == null) {
return txnData.toString();
@@ -340,19 +344,24 @@ public class TxnLogToolkit implements Closeable {
for (int i = 0; i < txnList.size(); i++) {
Txn t = txnList.get(i);
if (i == 0) {
- txnData.append(Request.op2String(t.getType()) + ":" +
checkNullToEmpty(t.getData()));
+ txnData.append(Request.op2String(t.getType())).append(":");
} else {
- txnData.append(";" + Request.op2String(t.getType()) + ":"
+ checkNullToEmpty(t.getData()));
+
txnData.append(";").append(Request.op2String(t.getType())).append(":");
+ }
+ if (t.getType() == ZooDefs.OpCode.error) {
+ txnData.append(ByteBuffer.wrap(t.getData()).getInt());
+ } else {
+ txnData.append(checkNullToEmpty(t.getData()));
}
}
} else {
- txnData.append(txn.toString());
+ txnData.append(txn);
}
return txnData.toString();
}
- private static String checkNullToEmpty(byte[] data) throws IOException {
+ private static String checkNullToEmpty(byte[] data) {
if (data == null || data.length == 0) {
return "";
}
diff --git
a/zookeeper-server/src/test/java/org/apache/zookeeper/server/persistence/TxnLogToolkitTest.java
b/zookeeper-server/src/test/java/org/apache/zookeeper/server/persistence/TxnLogToolkitTest.java
index c65113469..ec02c75b3 100644
---
a/zookeeper-server/src/test/java/org/apache/zookeeper/server/persistence/TxnLogToolkitTest.java
+++
b/zookeeper-server/src/test/java/org/apache/zookeeper/server/persistence/TxnLogToolkitTest.java
@@ -21,6 +21,7 @@ package org.apache.zookeeper.server.persistence;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.core.IsNot.not;
+import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.io.ByteArrayOutputStream;
@@ -28,11 +29,19 @@ import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintStream;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.io.FileUtils;
+import org.apache.jute.BinaryOutputArchive;
+import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.test.ClientBase;
+import org.apache.zookeeper.txn.ErrorTxn;
+import org.apache.zookeeper.txn.MultiTxn;
+import org.apache.zookeeper.txn.Txn;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@@ -84,6 +93,31 @@ public class TxnLogToolkitTest {
});
}
+ @Test
+ public void testMultiTxnDecode() throws IOException {
+ //MultiTxn with four ops, and the first op error.
+ List<Txn> txns = new ArrayList<>();
+ int type = -1;
+ for (int i = 0; i < 4; i++) {
+ ErrorTxn txn;
+ if (i == 0) {
+ txn = new ErrorTxn(KeeperException.Code.NONODE.intValue());
+ } else {
+ txn = new
ErrorTxn(KeeperException.Code.RUNTIMEINCONSISTENCY.intValue());
+ }
+ try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
+ BinaryOutputArchive boa = BinaryOutputArchive.getArchive(baos);
+ txn.serialize(boa, "request");
+ ByteBuffer bb = ByteBuffer.wrap(baos.toByteArray());
+ txns.add(new Txn(type, bb.array()));
+ }
+ }
+ MultiTxn multiTxn = new MultiTxn(txns);
+
+ String formattedTxnStr = TxnLogToolkit.getFormattedTxnStr(multiTxn);
+ assertEquals("error:-101;error:-2;error:-2;error:-2", formattedTxnStr);
+ }
+
@Test
public void testInitWithRecoveryFileExists() {
assertThrows(TxnLogToolkit.TxnLogToolkitException.class, () -> {