Thrift TBinaryProtocol change
Summary: New Thrift TBinaryProtocol with a version identifier
Reviewed By: aditya, eugene
Test Plan: Modify your services to have strictRead_ and strictWrite_ both set to FALSE. Then redeploy your services and test running clients against them. Once you have clients and servers running stably on this new code, you should redploy versions with strictWrite_ set to TRUE. Once that's all good, we can set strictRead_ to TRUE as well, and eventually deprecate the old protocol code entirely.
git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@665138 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/lib/java/src/protocol/TBinaryProtocol.java b/lib/java/src/protocol/TBinaryProtocol.java
index be02a3e..7dff485 100644
--- a/lib/java/src/protocol/TBinaryProtocol.java
+++ b/lib/java/src/protocol/TBinaryProtocol.java
@@ -16,12 +16,30 @@
*/
public class TBinaryProtocol extends TProtocol {
+ protected static final int VERSION_MASK = 0xffff0000;
+ protected static final int VERSION_1 = 0x80010000;
+
+ protected boolean strictRead_ = false;
+ protected boolean strictWrite_ = true;
+
/**
* Factory
*/
public static class Factory implements TProtocolFactory {
+ protected boolean strictRead_ = false;
+ protected boolean strictWrite_ = true;
+
+ public Factory() {
+ this(false, false);
+ }
+
+ public Factory(boolean strictRead, boolean strictWrite) {
+ strictRead_ = strictRead;
+ strictWrite_ = strictWrite;
+ }
+
public TProtocol getProtocol(TTransport trans) {
- return new TBinaryProtocol(trans);
+ return new TBinaryProtocol(trans, strictRead_, strictWrite_);
}
}
@@ -29,13 +47,27 @@
* Constructor
*/
public TBinaryProtocol(TTransport trans) {
- super(trans);
+ this(trans, false, false);
}
+ public TBinaryProtocol(TTransport trans, boolean strictRead, boolean strictWrite) {
+ super(trans);
+ strictRead_ = strictRead;
+ strictWrite_ = strictWrite;
+ }
+
+
public void writeMessageBegin(TMessage message) throws TException {
- writeString(message.name);
- writeByte(message.type);
- writeI32(message.seqid);
+ if (strictWrite_) {
+ int version = VERSION_1 | message.type;
+ writeI32(version);
+ writeString(message.name);
+ writeI32(message.seqid);
+ } else {
+ writeString(message.name);
+ writeByte(message.type);
+ writeI32(message.seqid);
+ }
}
public void writeMessageEnd() {}
@@ -137,9 +169,24 @@
public TMessage readMessageBegin() throws TException {
TMessage message = new TMessage();
- message.name = readString();
- message.type = readByte();
- message.seqid = readI32();
+
+ int size = readI32();
+ if (size < 0) {
+ int version = size & VERSION_MASK;
+ if (version != VERSION_1) {
+ throw new TProtocolException(TProtocolException.BAD_VERSION, "Bad version in readMessageBegin");
+ }
+ message.type = (byte)(version & 0x000000ff);
+ message.name = readString();
+ message.seqid = readI32();
+ } else {
+ if (strictRead_) {
+ throw new TProtocolException(TProtocolException.BAD_VERSION, "Missing version in readMessageBegin, old client?");
+ }
+ message.name = readStringBody(size);
+ message.type = readByte();
+ message.seqid = readI32();
+ }
return message;
}
@@ -239,6 +286,10 @@
public String readString() throws TException {
int size = readI32();
+ return readStringBody(size);
+ }
+
+ public String readStringBody(int size) throws TException {
byte[] buf = new byte[size];
trans_.readAll(buf, 0, size);
return new String(buf);