This is an automated email from the ASF dual-hosted git repository.
andor 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 433cf7e ZOOKEEPER-3410: zkTxnLogToolkit.sh will throw the NPE and
stop the process of formatting txn logs due to the data's content is null
433cf7e is described below
commit 433cf7e2b660fce3c73eb011452814f7084ff196
Author: maoling <[email protected]>
AuthorDate: Tue Jul 9 13:34:06 2019 +0200
ZOOKEEPER-3410: zkTxnLogToolkit.sh will throw the NPE and stop the process
of formatting txn logs due to the data's content is null
- the data can be null,but the other fileds(`acl`,`version`,`ttl`) cannot
be `null`. I also make the `printTxn` method more safer , surrounding it with
`try-catch` in case of other unexpected NPEs.
- some test cases were included in the
[JIRA](https://issues.apache.org/jira/browse/ZOOKEEPER-3410).
- more details in the
[ZOOKEEPER-3410](https://issues.apache.org/jira/browse/ZOOKEEPER-3410)
Author: maoling <[email protected]>
Reviewers: [email protected], [email protected]
Closes #975 from maoling/ZOOKEEPER-3410 and squashes the following commits:
22405c636 [maoling] revert the logic about try-catch the printTxn() method
a84c37406 [maoling] set the charset:UTF8 & e.printStackTrace()
8cc034e2e [maoling] ZOOKEEPER-3410:./zkTxnLogToolkit.sh will throw the NPE
and stop the process of formatting txn logs due to the data's content is null
---
.../server/persistence/TxnLogToolkit.java | 32 ++++++++++++++--------
1 file changed, 20 insertions(+), 12 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 41d71e3..e851199 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
@@ -269,7 +269,7 @@ public class TxnLogToolkit implements Closeable {
private void printTxn(byte[] bytes, String prefix) throws IOException {
TxnHeader hdr = new TxnHeader();
Record txn = SerializeUtils.deserializeTxn(bytes, hdr);
- String txnStr = getDataStrFromTxn(txn);
+ String txnStr = getFormattedTxnStr(txn);
String txns = String.format("%s session 0x%s cxid 0x%s zxid 0x%s %s
%s",
DateFormat.getDateTimeInstance(DateFormat.SHORT,
DateFormat.LONG).format(new Date(hdr.getTime())),
Long.toHexString(hdr.getClientId()),
@@ -288,31 +288,31 @@ public class TxnLogToolkit implements Closeable {
}
/**
- * get transaction log data string with node's data as a string
- * @param txn
- * @return
+ * get the formatted string from the txn.
+ * @param txn transaction log data
+ * @return the formatted string
*/
- private static String getDataStrFromTxn(Record txn) {
+ private static String getFormattedTxnStr(Record txn) throws IOException {
StringBuilder txnData = new StringBuilder();
if (txn == null) {
return txnData.toString();
}
if (txn instanceof CreateTxn) {
CreateTxn createTxn = ((CreateTxn) txn);
- txnData.append(createTxn.getPath() + "," + new
String(createTxn.getData()))
+ txnData.append(createTxn.getPath() + "," +
checkNullToEmpty(createTxn.getData()))
.append("," + createTxn.getAcl() + "," +
createTxn.getEphemeral())
.append("," + createTxn.getParentCVersion());
} else if (txn instanceof SetDataTxn) {
SetDataTxn setDataTxn = ((SetDataTxn) txn);
- txnData.append(setDataTxn.getPath() + "," + new
String(setDataTxn.getData()))
+ txnData.append(setDataTxn.getPath() + "," +
checkNullToEmpty(setDataTxn.getData()))
.append("," + setDataTxn.getVersion());
} else if (txn instanceof CreateContainerTxn) {
CreateContainerTxn createContainerTxn = ((CreateContainerTxn) txn);
- txnData.append(createContainerTxn.getPath() + "," + new
String(createContainerTxn.getData()))
+ txnData.append(createContainerTxn.getPath() + "," +
checkNullToEmpty(createContainerTxn.getData()))
.append("," + createContainerTxn.getAcl() + "," +
createContainerTxn.getParentCVersion());
} else if (txn instanceof CreateTTLTxn) {
CreateTTLTxn createTTLTxn = ((CreateTTLTxn) txn);
- txnData.append(createTTLTxn.getPath() + "," + new
String(createTTLTxn.getData()))
+ txnData.append(createTTLTxn.getPath() + "," +
checkNullToEmpty(createTTLTxn.getData()))
.append("," + createTTLTxn.getAcl() + "," +
createTTLTxn.getParentCVersion())
.append("," + createTTLTxn.getTtl());
} else if (txn instanceof MultiTxn) {
@@ -321,9 +321,9 @@ public class TxnLogToolkit implements Closeable {
for (int i = 0; i < txnList.size(); i++ ) {
Txn t = txnList.get(i);
if (i == 0) {
- txnData.append(TraceFormatter.op2String(t.getType()) + ":"
+ new String(t.getData()));
+ txnData.append(TraceFormatter.op2String(t.getType()) + ":"
+ checkNullToEmpty(t.getData()));
} else {
- txnData.append(";" + TraceFormatter.op2String(t.getType())
+ ":" + new String(t.getData()));
+ txnData.append(";" + TraceFormatter.op2String(t.getType())
+ ":" + checkNullToEmpty(t.getData()));
}
}
} else {
@@ -332,7 +332,15 @@ public class TxnLogToolkit implements Closeable {
return txnData.toString();
}
-
+
+ private static String checkNullToEmpty(byte[] data) throws IOException {
+ if (data == null || data.length == 0) {
+ return "";
+ }
+
+ return new String(data, "UTF8");
+ }
+
private void openTxnLogFile() throws FileNotFoundException {
txnFis = new FileInputStream(txnLogFile);
logStream = BinaryInputArchive.getArchive(txnFis);