aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--RELEASING.md6
-rw-r--r--all/build.gradle1
-rw-r--r--build.gradle2
-rw-r--r--core/src/main/java/io/grpc/internal/IoUtils.java57
-rw-r--r--core/src/test/java/io/grpc/internal/IoUtilsTest.java68
-rw-r--r--examples/settings.gradle1
-rw-r--r--examples/thrift/build.gradle55
-rw-r--r--examples/thrift/src/generated/main/grpc/io/grpc/examples/thrift/helloworld/GreeterGrpc.java1007
-rw-r--r--examples/thrift/src/generated/main/java/io/grpc/examples/thrift/helloworld/HelloRequest.java395
-rw-r--r--examples/thrift/src/generated/main/java/io/grpc/examples/thrift/helloworld/HelloResponse.java395
-rw-r--r--examples/thrift/src/main/java/io/grpc/examples/thrift/helloworld/HelloWorldClient.java89
-rw-r--r--examples/thrift/src/main/java/io/grpc/examples/thrift/helloworld/HelloWorldServer.java93
-rw-r--r--examples/thrift/src/main/thrift/helloworld.thrift13
-rw-r--r--settings.gradle2
-rw-r--r--thrift/build.gradle29
-rw-r--r--thrift/src/generated/test/java/io/grpc/thrift/Message.java744
-rw-r--r--thrift/src/main/java/io/grpc/thrift/MessageFactory.java41
-rw-r--r--thrift/src/main/java/io/grpc/thrift/ThriftInputStream.java122
-rw-r--r--thrift/src/main/java/io/grpc/thrift/ThriftUtils.java111
-rw-r--r--thrift/src/test/java/io/grpc/thrift/ThriftUtilsTest.java183
-rw-r--r--thrift/src/test/thrift/messages.thrift37
21 files changed, 3447 insertions, 4 deletions
diff --git a/RELEASING.md b/RELEASING.md
index 7b362e447..033462161 100644
--- a/RELEASING.md
+++ b/RELEASING.md
@@ -78,7 +78,7 @@ would be used to create all `v0.7` tags (e.g. `v0.7.0`, `v0.7.1`).
$ sed -i 's/[0-9]\+\.[0-9]\+\.[0-9]\+\(.*CURRENT_GRPC_VERSION\)/'$MAJOR.$((MINOR+1)).0'\1/' \
build.gradle android-interop-testing/app/build.gradle \
examples/build.gradle examples/pom.xml \
- examples/android/app/build.gradle
+ examples/android/app/build.gradle examples/thrift/build.gradle
$ ./gradlew build
$ git commit -a -m "Start $MAJOR.$((MINOR+1)).0 development cycle"
```
@@ -98,7 +98,7 @@ would be used to create all `v0.7` tags (e.g. `v0.7.0`, `v0.7.1`).
$ sed -i 's/-SNAPSHOT\(.*CURRENT_GRPC_VERSION\)/\1/' \
build.gradle android-interop-testing/app/build.gradle \
examples/build.gradle examples/pom.xml \
- examples/android/app/build.gradle
+ examples/android/app/build.gradle examples/thrift/build.gradle
$ ./gradlew build
$ git commit -a -m "Bump version to $MAJOR.$MINOR.$PATCH"
$ git tag -a v$MAJOR.$MINOR.$PATCH -m "Version $MAJOR.$MINOR.$PATCH"
@@ -111,7 +111,7 @@ would be used to create all `v0.7` tags (e.g. `v0.7.0`, `v0.7.1`).
$ sed -i 's/[0-9]\+\.[0-9]\+\.[0-9]\+\(.*CURRENT_GRPC_VERSION\)/'$MAJOR.$MINOR.$((PATCH+1))-SNAPSHOT'\1/' \
build.gradle android-interop-testing/app/build.gradle \
examples/build.gradle examples/pom.xml \
- examples/android/app/build.gradle
+ examples/android/app/build.gradle examples/thrift/build.gradle
$ ./gradlew build
$ git commit -a -m "Bump version to $MAJOR.$MINOR.$((PATCH+1))-SNAPSHOT"
```
diff --git a/all/build.gradle b/all/build.gradle
index a84d9eeda..a78d440ec 100644
--- a/all/build.gradle
+++ b/all/build.gradle
@@ -20,6 +20,7 @@ def subprojects = [
project(':grpc-protobuf-lite'),
project(':grpc-protobuf-nano'),
project(':grpc-stub'),
+ project(':grpc-thrift'),
]
for (subproject in rootProject.subprojects) {
diff --git a/build.gradle b/build.gradle
index a6fce8b59..3e2df8ec2 100644
--- a/build.gradle
+++ b/build.gradle
@@ -289,7 +289,7 @@ subprojects {
}
}
if (!(project.name in
- ["grpc-stub", "grpc-protobuf", "grpc-protobuf-lite", "grpc-protobuf-nano"])) {
+ ["grpc-stub", "grpc-protobuf", "grpc-protobuf-lite", "grpc-protobuf-nano", "grpc-thrift"])) {
def core = pom.dependencies.find {dep -> dep.artifactId == 'grpc-core'}
if (core != null) {
// Depend on specific version of grpc-core because internal package is unstable
diff --git a/core/src/main/java/io/grpc/internal/IoUtils.java b/core/src/main/java/io/grpc/internal/IoUtils.java
new file mode 100644
index 000000000..5178c2f4b
--- /dev/null
+++ b/core/src/main/java/io/grpc/internal/IoUtils.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2016, Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package io.grpc.internal;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+
+/** Common IoUtils for thrift and nanopb to convert inputstream to bytes. */
+public final class IoUtils {
+
+ /** maximum buffer to be read is 16 KB. */
+ private static final int MAX_BUFFER_LENGTH = 16384;
+
+ /** Returns the byte array. */
+ public static byte[] toByteArray(InputStream is) throws IOException {
+ ByteArrayOutputStream buffer = new ByteArrayOutputStream();
+ int nRead;
+ byte[] bytes = new byte[MAX_BUFFER_LENGTH];
+
+ while ((nRead = is.read(bytes, 0, bytes.length)) != -1) {
+ buffer.write(bytes, 0, nRead);
+ }
+
+ buffer.flush();
+ return buffer.toByteArray();
+ }
+} \ No newline at end of file
diff --git a/core/src/test/java/io/grpc/internal/IoUtilsTest.java b/core/src/test/java/io/grpc/internal/IoUtilsTest.java
new file mode 100644
index 000000000..43b3bd746
--- /dev/null
+++ b/core/src/test/java/io/grpc/internal/IoUtilsTest.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2016, Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package io.grpc.internal;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotSame;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+
+/** Unit test for IoUtils. */
+@RunWith(JUnit4.class)
+public class IoUtilsTest {
+
+ @Test
+ public void testRoundTrip() throws Exception {
+ byte[] bytes = { 1, 2, 3, -127, 100, 127};
+ InputStream is = new ByteArrayInputStream(bytes);
+ byte[] bytes2 = IoUtils.toByteArray(is);
+
+ assertNotSame(bytes2, bytes);
+ assertEquals(bytes.length, bytes2.length);
+ for (int i = 0; i < bytes.length; ++i) {
+ assertEquals(bytes[i], bytes2[i]);
+ }
+ }
+
+ @Test
+ public void testEmpty() throws Exception {
+ InputStream is = new ByteArrayInputStream(new byte[0]);
+ byte[] bytes = IoUtils.toByteArray(is);
+
+ assertEquals(0, bytes.length);
+ }
+} \ No newline at end of file
diff --git a/examples/settings.gradle b/examples/settings.gradle
index 9512a19f3..091fcf2a3 100644
--- a/examples/settings.gradle
+++ b/examples/settings.gradle
@@ -1 +1,2 @@
rootProject.name = 'examples'
+include 'thrift'
diff --git a/examples/thrift/build.gradle b/examples/thrift/build.gradle
new file mode 100644
index 000000000..4c1760e18
--- /dev/null
+++ b/examples/thrift/build.gradle
@@ -0,0 +1,55 @@
+apply plugin: 'application'
+
+description = "Thrift Examples"
+
+startScripts.enabled = false
+
+def grpcVersion = '1.1.0-SNAPSHOT' // CURRENT_GRPC_VERSION
+
+repositories {
+ mavenCentral()
+ mavenLocal()
+}
+
+dependencies {
+ compile "io.grpc:grpc-stub:${grpcVersion}"
+ compile "io.grpc:grpc-thrift:${grpcVersion}"
+ compile "io.grpc:grpc-netty:${grpcVersion}"
+}
+
+String generatedSourcePath = "${projectDir}/src/generated"
+project.sourceSets {
+ main {
+ java {
+ srcDir "${generatedSourcePath}/main/java"
+ srcDir "${generatedSourcePath}/main/grpc"
+ }
+ }
+}
+
+task thriftHelloWorldServer(type: CreateStartScripts) {
+ mainClassName = "io.grpc.examples.thrift.helloworld.HelloWorldServer"
+ applicationName = "thrift-hello-world-server"
+ outputDir = new File(project.buildDir, 'tmp')
+ classpath = jar.outputs.files + project.configurations.runtime
+}
+
+task thriftHelloWorldClient(type: CreateStartScripts) {
+ mainClassName = "io.grpc.examples.thrift.helloworld.HelloWorldClient"
+ applicationName = "thrift-hello-world-client"
+ outputDir = new File(project.buildDir, 'tmp')
+ classpath = jar.outputs.files + project.configurations.runtime
+}
+
+applicationDistribution.into("bin") {
+ from(thriftHelloWorldServer)
+ from(thriftHelloWorldClient)
+ fileMode = 0755
+}
+
+idea {
+ module {
+ sourceDirs += file("${projectDir}/src/generated/main/java");
+ sourceDirs += file("${projectDir}/src/generated/main/grpc");
+ }
+}
diff --git a/examples/thrift/src/generated/main/grpc/io/grpc/examples/thrift/helloworld/GreeterGrpc.java b/examples/thrift/src/generated/main/grpc/io/grpc/examples/thrift/helloworld/GreeterGrpc.java
new file mode 100644
index 000000000..b4bdeee00
--- /dev/null
+++ b/examples/thrift/src/generated/main/grpc/io/grpc/examples/thrift/helloworld/GreeterGrpc.java
@@ -0,0 +1,1007 @@
+/**
+ * Autogenerated by Thrift Compiler (1.0.0-dev)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ * @generated
+ */
+package io.grpc.examples.thrift.helloworld;
+
+import org.apache.thrift.scheme.IScheme;
+import org.apache.thrift.scheme.SchemeFactory;
+import org.apache.thrift.scheme.StandardScheme;
+
+import org.apache.thrift.scheme.TupleScheme;
+import org.apache.thrift.protocol.TTupleProtocol;
+import org.apache.thrift.protocol.TProtocolException;
+import org.apache.thrift.EncodingUtils;
+import org.apache.thrift.server.AbstractNonblockingServer.*;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.EnumMap;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.EnumSet;
+import java.util.Collections;
+import java.util.BitSet;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import javax.annotation.Generated;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import static io.grpc.stub.ClientCalls.asyncUnaryCall;
+import static io.grpc.stub.ClientCalls.asyncServerStreamingCall;
+import static io.grpc.stub.ClientCalls.asyncClientStreamingCall;
+import static io.grpc.stub.ClientCalls.asyncBidiStreamingCall;
+import static io.grpc.stub.ClientCalls.blockingUnaryCall;
+import static io.grpc.stub.ClientCalls.blockingServerStreamingCall;
+import static io.grpc.stub.ClientCalls.futureUnaryCall;
+import static io.grpc.MethodDescriptor.generateFullMethodName;
+import static io.grpc.stub.ServerCalls.asyncUnaryCall;
+import static io.grpc.stub.ServerCalls.asyncServerStreamingCall;
+import static io.grpc.stub.ServerCalls.asyncClientStreamingCall;
+import static io.grpc.stub.ServerCalls.asyncBidiStreamingCall;
+import static io.grpc.stub.ServerCalls.asyncUnimplementedUnaryCall;
+import static io.grpc.stub.ServerCalls.asyncUnimplementedStreamingCall;
+import io.grpc.thrift.ThriftUtils;
+
+public class GreeterGrpc {
+
+ private GreeterGrpc() {}
+
+ public static final String SERVICE_NAME = "io.grpc.examples.thrift.helloworld.Greeter";
+
+ @java.lang.Deprecated public static interface Greeter {
+ public void sayHello(sayHello_args request,
+ io.grpc.stub.StreamObserver<sayHello_result> responseObserver);
+
+ }
+
+ private static final int ARG_IN_METHOD_sayHello = 1;
+ private static final int ARG_OUT_METHOD_sayHello = 2;
+
+ private static final class ThriftMessageFactory<T extends org.apache.thrift.TBase<T,?>>
+ implements io.grpc.thrift.MessageFactory<T> {
+ private final int id;
+
+
+ ThriftMessageFactory(int id) {
+ this.id = id;
+ }
+ @java.lang.Override
+ public T newInstance() {
+ Object o;
+ switch (id) {
+ case ARG_IN_METHOD_sayHello:
+ o = new sayHello_args();
+ break;
+ case ARG_OUT_METHOD_sayHello:
+ o = new sayHello_result();
+ break;
+ default:
+ throw new AssertionError();
+}
+ @java.lang.SuppressWarnings("unchecked")
+ T t = (T) o;
+return t;
+ }
+ }
+ public static abstract class GreeterImplBase implements Greeter, io.grpc.BindableService {
+ @java.lang.Override
+ public void sayHello(sayHello_args request,
+ io.grpc.stub.StreamObserver<sayHello_result> responseObserver) {
+ asyncUnimplementedUnaryCall(METHOD_sayHello, responseObserver);
+ }
+
+ @java.lang.Override public io.grpc.ServerServiceDefinition bindService() {
+ return GreeterGrpc.bindService(this);
+ }
+
+ }
+
+ @java.lang.Deprecated public static abstract class AbstractGreeter extends GreeterImplBase {}
+
+ public static class sayHello_args implements org.apache.thrift.TBase<sayHello_args, sayHello_args._Fields>, java.io.Serializable, Cloneable, Comparable<sayHello_args> {
+ private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("sayHello_args");
+
+ private static final org.apache.thrift.protocol.TField REQUEST_FIELD_DESC = new org.apache.thrift.protocol.TField("request", org.apache.thrift.protocol.TType.STRUCT, (short)1);
+
+ private static final SchemeFactory STANDARD_SCHEME_FACTORY = new sayHello_argsStandardSchemeFactory();
+ private static final SchemeFactory TUPLE_SCHEME_FACTORY = new sayHello_argsTupleSchemeFactory();
+
+ public HelloRequest request; // required
+
+ /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+ public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+ REQUEST((short)1, "request");
+
+ private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+ static {
+ for (_Fields field : EnumSet.allOf(_Fields.class)) {
+ byName.put(field.getFieldName(), field);
+ }
+ }
+
+ /**
+ * Find the _Fields constant that matches fieldId, or null if its not found.
+ */
+ public static _Fields findByThriftId(int fieldId) {
+ switch(fieldId) {
+ case 1: // REQUEST
+ return REQUEST;
+ default:
+ return null;
+ }
+ }
+
+ /**
+ * Find the _Fields constant that matches fieldId, throwing an exception
+ * if it is not found.
+ */
+ public static _Fields findByThriftIdOrThrow(int fieldId) {
+ _Fields fields = findByThriftId(fieldId);
+ if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+ return fields;
+ }
+
+ /**
+ * Find the _Fields constant that matches name, or null if its not found.
+ */
+ public static _Fields findByName(String name) {
+ return byName.get(name);
+ }
+
+ private final short _thriftId;
+ private final String _fieldName;
+
+ _Fields(short thriftId, String fieldName) {
+ _thriftId = thriftId;
+ _fieldName = fieldName;
+ }
+
+ public short getThriftFieldId() {
+ return _thriftId;
+ }
+
+ public String getFieldName() {
+ return _fieldName;
+ }
+ }
+
+ // isset id assignments
+ public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+ static {
+ Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+ tmpMap.put(_Fields.REQUEST, new org.apache.thrift.meta_data.FieldMetaData("request", org.apache.thrift.TFieldRequirementType.DEFAULT,
+ new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, HelloRequest.class)));
+ metaDataMap = Collections.unmodifiableMap(tmpMap);
+ org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(sayHello_args.class, metaDataMap);
+ }
+
+ public sayHello_args() {
+ }
+
+ public sayHello_args(
+ HelloRequest request)
+ {
+ this();
+ this.request = request;
+ }
+
+ /**
+ * Performs a deep copy on <i>other</i>.
+ */
+ public sayHello_args(sayHello_args other) {
+ if (other.isSetRequest()) {
+ this.request = new HelloRequest(other.request);
+ }
+ }
+
+ public sayHello_args deepCopy() {
+ return new sayHello_args(this);
+ }
+
+ @Override
+ public void clear() {
+ this.request = null;
+ }
+
+ public HelloRequest getRequest() {
+ return this.request;
+ }
+
+ public sayHello_args setRequest(HelloRequest request) {
+ this.request = request;
+ return this;
+ }
+
+ public void unsetRequest() {
+ this.request = null;
+ }
+
+ /** Returns true if field request is set (has been assigned a value) and false otherwise */
+ public boolean isSetRequest() {
+ return this.request != null;
+ }
+
+ public void setRequestIsSet(boolean value) {
+ if (!value) {
+ this.request = null;
+ }
+ }
+
+ public void setFieldValue(_Fields field, Object value) {
+ switch (field) {
+ case REQUEST:
+ if (value == null) {
+ unsetRequest();
+ } else {
+ setRequest((HelloRequest)value);
+ }
+ break;
+
+ }
+ }
+
+ public Object getFieldValue(_Fields field) {
+ switch (field) {
+ case REQUEST:
+ return getRequest();
+
+ }
+ throw new IllegalStateException();
+ }
+
+ /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+ public boolean isSet(_Fields field) {
+ if (field == null) {
+ throw new IllegalArgumentException();
+ }
+
+ switch (field) {
+ case REQUEST:
+ return isSetRequest();
+ }
+ throw new IllegalStateException();
+ }
+
+ @Override
+ public boolean equals(Object that) {
+ if (that == null)
+ return false;
+ if (that instanceof sayHello_args)
+ return this.equals((sayHello_args)that);
+ return false;
+ }
+
+ public boolean equals(sayHello_args that) {
+ if (that == null)
+ return false;
+
+ boolean this_present_request = true && this.isSetRequest();
+ boolean that_present_request = true && that.isSetRequest();
+ if (this_present_request || that_present_request) {
+ if (!(this_present_request && that_present_request))
+ return false;
+ if (!this.request.equals(that.request))
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int hashCode = 1;
+
+ hashCode = hashCode * 8191 + ((isSetRequest()) ? 131071 : 524287);
+ if (isSetRequest())
+ hashCode = hashCode * 8191 + request.hashCode();
+
+ return hashCode;
+ }
+
+ @Override
+ public int compareTo(sayHello_args other) {
+ if (!getClass().equals(other.getClass())) {
+ return getClass().getName().compareTo(other.getClass().getName());
+ }
+
+ int lastComparison = 0;
+
+ lastComparison = Boolean.valueOf(isSetRequest()).compareTo(other.isSetRequest());
+ if (lastComparison != 0) {
+ return lastComparison;
+ }
+ if (isSetRequest()) {
+ lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.request, other.request);
+ if (lastComparison != 0) {
+ return lastComparison;
+ }
+ }
+ return 0;
+ }
+
+ public _Fields fieldForId(int fieldId) {
+ return _Fields.findByThriftId(fieldId);
+ }
+
+ public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+ scheme(iprot).read(iprot, this);
+ }
+
+ public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+ scheme(oprot).write(oprot, this);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder("sayHello_args(");
+ boolean first = true;
+
+ sb.append("request:");
+ if (this.request == null) {
+ sb.append("null");
+ } else {
+ sb.append(this.request);
+ }
+ first = false;
+ sb.append(")");
+ return sb.toString();
+ }
+
+ public void validate() throws org.apache.thrift.TException {
+ // check for required fields
+ // check for sub-struct validity
+ if (request != null) {
+ request.validate();
+ }
+ }
+
+ private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+ try {
+ write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+ } catch (org.apache.thrift.TException te) {
+ throw new java.io.IOException(te);
+ }
+ }
+
+ private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+ try {
+ read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+ } catch (org.apache.thrift.TException te) {
+ throw new java.io.IOException(te);
+ }
+ }
+
+ private static class sayHello_argsStandardSchemeFactory implements SchemeFactory {
+ public sayHello_argsStandardScheme getScheme() {
+ return new sayHello_argsStandardScheme();
+ }
+ }
+
+ private static class sayHello_argsStandardScheme extends StandardScheme<sayHello_args> {
+
+ public void read(org.apache.thrift.protocol.TProtocol iprot, sayHello_args struct) throws org.apache.thrift.TException {
+ org.apache.thrift.protocol.TField schemeField;
+ iprot.readStructBegin();
+ while (true)
+ {
+ schemeField = iprot.readFieldBegin();
+ if (schemeField.type == org.apache.thrift.protocol.TType.STOP) {
+ break;
+ }
+ switch (schemeField.id) {
+ case 1: // REQUEST
+ if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+ struct.request = new HelloRequest();
+ struct.request.read(iprot);
+ struct.setRequestIsSet(true);
+ } else {
+ org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+ }
+ break;
+ default:
+ org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+ }
+ iprot.readFieldEnd();
+ }
+ iprot.readStructEnd();
+
+ // check for required fields of primitive type, which can't be checked in the validate method
+ struct.validate();
+ }
+
+ public void write(org.apache.thrift.protocol.TProtocol oprot, sayHello_args struct) throws org.apache.thrift.TException {
+ struct.validate();
+
+ oprot.writeStructBegin(STRUCT_DESC);
+ if (struct.request != null) {
+ oprot.writeFieldBegin(REQUEST_FIELD_DESC);
+ struct.request.write(oprot);
+ oprot.writeFieldEnd();
+ }
+ oprot.writeFieldStop();
+ oprot.writeStructEnd();
+ }
+
+ }
+
+ private static class sayHello_argsTupleSchemeFactory implements SchemeFactory {
+ public sayHello_argsTupleScheme getScheme() {
+ return new sayHello_argsTupleScheme();
+ }
+ }
+
+ private static class sayHello_argsTupleScheme extends TupleScheme<sayHello_args> {
+
+ @Override
+ public void write(org.apache.thrift.protocol.TProtocol prot, sayHello_args struct) throws org.apache.thrift.TException {
+ TTupleProtocol oprot = (TTupleProtocol) prot;
+ BitSet optionals = new BitSet();
+ if (struct.isSetRequest()) {
+ optionals.set(0);
+ }
+ oprot.writeBitSet(optionals, 1);
+ if (struct.isSetRequest()) {
+ struct.request.write(oprot);
+ }
+ }
+
+ @Override
+ public void read(org.apache.thrift.protocol.TProtocol prot, sayHello_args struct) throws org.apache.thrift.TException {
+ TTupleProtocol iprot = (TTupleProtocol) prot;
+ BitSet incoming = iprot.readBitSet(1);
+ if (incoming.get(0)) {
+ struct.request = new HelloRequest();
+ struct.request.read(iprot);
+ struct.setRequestIsSet(true);
+ }
+ }
+ }
+
+ private static <S extends IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+ return (StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+ }
+ }
+
+ public static class sayHello_result implements org.apache.thrift.TBase<sayHello_result, sayHello_result._Fields>, java.io.Serializable, Cloneable, Comparable<sayHello_result> {
+ private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("sayHello_result");
+
+ private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.STRUCT, (short)0);
+
+ private static final SchemeFactory STANDARD_SCHEME_FACTORY = new sayHello_resultStandardSchemeFactory();
+ private static final SchemeFactory TUPLE_SCHEME_FACTORY = new sayHello_resultTupleSchemeFactory();
+
+ public HelloResponse success; // required
+
+ /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+ public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+ SUCCESS((short)0, "success");
+
+ private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+ static {
+ for (_Fields field : EnumSet.allOf(_Fields.class)) {
+ byName.put(field.getFieldName(), field);
+ }
+ }
+
+ /**
+ * Find the _Fields constant that matches fieldId, or null if its not found.
+ */
+ public static _Fields findByThriftId(int fieldId) {
+ switch(fieldId) {
+ case 0: // SUCCESS
+ return SUCCESS;
+ default:
+ return null;
+ }
+ }
+
+ /**
+ * Find the _Fields constant that matches fieldId, throwing an exception
+ * if it is not found.
+ */
+ public static _Fields findByThriftIdOrThrow(int fieldId) {
+ _Fields fields = findByThriftId(fieldId);
+ if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+ return fields;
+ }
+
+ /**
+ * Find the _Fields constant that matches name, or null if its not found.
+ */
+ public static _Fields findByName(String name) {
+ return byName.get(name);
+ }
+
+ private final short _thriftId;
+ private final String _fieldName;
+
+ _Fields(short thriftId, String fieldName) {
+ _thriftId = thriftId;
+ _fieldName = fieldName;
+ }
+
+ public short getThriftFieldId() {
+ return _thriftId;
+ }
+
+ public String getFieldName() {
+ return _fieldName;
+ }
+ }
+
+ // isset id assignments
+ public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+ static {
+ Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+ tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT,
+ new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, HelloResponse.class)));
+ metaDataMap = Collections.unmodifiableMap(tmpMap);
+ org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(sayHello_result.class, metaDataMap);
+ }
+
+ public sayHello_result() {
+ }
+
+ public sayHello_result(
+ HelloResponse success)
+ {
+ this();
+ this.success = success;
+ }
+
+ /**
+ * Performs a deep copy on <i>other</i>.
+ */
+ public sayHello_result(sayHello_result other) {
+ if (other.isSetSuccess()) {
+ this.success = new HelloResponse(other.success);
+ }
+ }
+
+ public sayHello_result deepCopy() {
+ return new sayHello_result(this);
+ }
+
+ @Override
+ public void clear() {
+ this.success = null;
+ }
+
+ public HelloResponse getSuccess() {
+ return this.success;
+ }
+
+ public sayHello_result setSuccess(HelloResponse success) {
+ this.success = success;
+ return this;
+ }
+
+ public void unsetSuccess() {
+ this.success = null;
+ }
+
+ /** Returns true if field success is set (has been assigned a value) and false otherwise */
+ public boolean isSetSuccess() {
+ return this.success != null;
+ }
+
+ public void setSuccessIsSet(boolean value) {
+ if (!value) {
+ this.success = null;
+ }
+ }
+
+ public void setFieldValue(_Fields field, Object value) {
+ switch (field) {
+ case SUCCESS:
+ if (value == null) {
+ unsetSuccess();
+ } else {
+ setSuccess((HelloResponse)value);
+ }
+ break;
+
+ }
+ }
+
+ public Object getFieldValue(_Fields field) {
+ switch (field) {
+ case SUCCESS:
+ return getSuccess();
+
+ }
+ throw new IllegalStateException();
+ }
+
+ /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+ public boolean isSet(_Fields field) {
+ if (field == null) {
+ throw new IllegalArgumentException();
+ }
+
+ switch (field) {
+ case SUCCESS:
+ return isSetSuccess();
+ }
+ throw new IllegalStateException();
+ }
+
+ @Override
+ public boolean equals(Object that) {
+ if (that == null)
+ return false;
+ if (that instanceof sayHello_result)
+ return this.equals((sayHello_result)that);
+ return false;
+ }
+
+ public boolean equals(sayHello_result that) {
+ if (that == null)
+ return false;
+
+ boolean this_present_success = true && this.isSetSuccess();
+ boolean that_present_success = true && that.isSetSuccess();
+ if (this_present_success || that_present_success) {
+ if (!(this_present_success && that_present_success))
+ return false;
+ if (!this.success.equals(that.success))
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int hashCode = 1;
+
+ hashCode = hashCode * 8191 + ((isSetSuccess()) ? 131071 : 524287);
+ if (isSetSuccess())
+ hashCode = hashCode * 8191 + success.hashCode();
+
+ return hashCode;
+ }
+
+ @Override
+ public int compareTo(sayHello_result other) {
+ if (!getClass().equals(other.getClass())) {
+ return getClass().getName().compareTo(other.getClass().getName());
+ }
+
+ int lastComparison = 0;
+
+ lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(other.isSetSuccess());
+ if (lastComparison != 0) {
+ return lastComparison;
+ }
+ if (isSetSuccess()) {
+ lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, other.success);
+ if (lastComparison != 0) {
+ return lastComparison;
+ }
+ }
+ return 0;
+ }
+
+ public _Fields fieldForId(int fieldId) {
+ return _Fields.findByThriftId(fieldId);
+ }
+
+ public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+ scheme(iprot).read(iprot, this);
+ }
+
+ public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+ scheme(oprot).write(oprot, this);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder("sayHello_result(");
+ boolean first = true;
+
+ sb.append("success:");
+ if (this.success == null) {
+ sb.append("null");
+ } else {
+ sb.append(this.success);
+ }
+ first = false;
+ sb.append(")");
+ return sb.toString();
+ }
+
+ public void validate() throws org.apache.thrift.TException {
+ // check for required fields
+ // check for sub-struct validity
+ if (success != null) {
+ success.validate();
+ }
+ }
+
+ private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+ try {
+ write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+ } catch (org.apache.thrift.TException te) {
+ throw new java.io.IOException(te);
+ }
+ }
+
+ private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+ try {
+ read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+ } catch (org.apache.thrift.TException te) {
+ throw new java.io.IOException(te);
+ }
+ }
+
+ private static class sayHello_resultStandardSchemeFactory implements SchemeFactory {
+ public sayHello_resultStandardScheme getScheme() {
+ return new sayHello_resultStandardScheme();
+ }
+ }
+
+ private static class sayHello_resultStandardScheme extends StandardScheme<sayHello_result> {
+
+ public void read(org.apache.thrift.protocol.TProtocol iprot, sayHello_result struct) throws org.apache.thrift.TException {
+ org.apache.thrift.protocol.TField schemeField;
+ iprot.readStructBegin();
+ while (true)
+ {
+ schemeField = iprot.readFieldBegin();
+ if (schemeField.type == org.apache.thrift.protocol.TType.STOP) {
+ break;
+ }
+ switch (schemeField.id) {
+ case 0: // SUCCESS
+ if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+ struct.success = new HelloResponse();
+ struct.success.read(iprot);
+ struct.setSuccessIsSet(true);
+ } else {
+ org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+ }
+ break;
+ default:
+ org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+ }
+ iprot.readFieldEnd();
+ }
+ iprot.readStructEnd();
+
+ // check for required fields of primitive type, which can't be checked in the validate method
+ struct.validate();
+ }
+
+ public void write(org.apache.thrift.protocol.TProtocol oprot, sayHello_result struct) throws org.apache.thrift.TException {
+ struct.validate();
+
+ oprot.writeStructBegin(STRUCT_DESC);
+ if (struct.success != null) {
+ oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
+ struct.success.write(oprot);
+ oprot.writeFieldEnd();
+ }
+ oprot.writeFieldStop();
+ oprot.writeStructEnd();
+ }
+
+ }
+
+ private static class sayHello_resultTupleSchemeFactory implements SchemeFactory {
+ public sayHello_resultTupleScheme getScheme() {
+ return new sayHello_resultTupleScheme();
+ }
+ }
+
+ private static class sayHello_resultTupleScheme extends TupleScheme<sayHello_result> {
+
+ @Override
+ public void write(org.apache.thrift.protocol.TProtocol prot, sayHello_result struct) throws org.apache.thrift.TException {
+ TTupleProtocol oprot = (TTupleProtocol) prot;
+ BitSet optionals = new BitSet();
+ if (struct.isSetSuccess()) {
+ optionals.set(0);
+ }
+ oprot.writeBitSet(optionals, 1);
+ if (struct.isSetSuccess()) {
+ struct.success.write(oprot);
+ }
+ }
+
+ @Override
+ public void read(org.apache.thrift.protocol.TProtocol prot, sayHello_result struct) throws org.apache.thrift.TException {
+ TTupleProtocol iprot = (TTupleProtocol) prot;
+ BitSet incoming = iprot.readBitSet(1);
+ if (incoming.get(0)) {
+ struct.success = new HelloResponse();
+ struct.success.read(iprot);
+ struct.setSuccessIsSet(true);
+ }
+ }
+ }
+
+ private static <S extends IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+ return (StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+ }
+ }
+
+ public static final io.grpc.MethodDescriptor<sayHello_args,
+ sayHello_result> METHOD_sayHello =
+ io.grpc.MethodDescriptor.create(
+ io.grpc.MethodDescriptor.MethodType.UNARY,
+ generateFullMethodName("io.grpc.examples.thrift.helloworld.Greeter" , "sayHello"),
+ io.grpc.thrift.ThriftUtils.marshaller(
+ new ThriftMessageFactory<sayHello_args>( ARG_IN_METHOD_sayHello)),
+ io.grpc.thrift.ThriftUtils.marshaller(
+ new ThriftMessageFactory<sayHello_result>( ARG_OUT_METHOD_sayHello)));
+
+ public static GreeterStub newStub(io.grpc.Channel channel) {
+ return new GreeterStub(channel);
+ }
+
+ public static class GreeterStub extends io.grpc.stub.AbstractStub<GreeterStub>
+ implements Greeter{
+ private GreeterStub(io.grpc.Channel channel) {
+ super(channel);
+ }
+
+ private GreeterStub(io.grpc.Channel channel,
+ io.grpc.CallOptions callOptions) {
+ super(channel, callOptions);
+ }
+
+ @java.lang.Override
+ protected GreeterStub build(io.grpc.Channel channel,
+ io.grpc.CallOptions callOptions) {
+ return new GreeterStub(channel, callOptions);
+ }
+
+ @java.lang.Override
+ public void sayHello(sayHello_args request,
+ io.grpc.stub.StreamObserver<sayHello_result> responseObserver) {
+ asyncUnaryCall(
+ getChannel().newCall(METHOD_sayHello, getCallOptions()), request, responseObserver);
+ }
+
+ }
+
+ public static GreeterBlockingStub newBlockingStub(
+ io.grpc.Channel channel) {
+ return new GreeterBlockingStub(channel);
+ }
+
+ @java.lang.Deprecated public static interface GreeterBlockingClient {
+ public sayHello_result sayHello(sayHello_args request);
+
+ }
+
+ public static class GreeterBlockingStub extends io.grpc.stub.AbstractStub<GreeterBlockingStub>
+ implements GreeterBlockingClient {
+ private GreeterBlockingStub(io.grpc.Channel channel) {
+ super(channel);
+ }
+
+ private GreeterBlockingStub(io.grpc.Channel channel,
+ io.grpc.CallOptions callOptions) {
+ super(channel, callOptions);
+ }
+
+ @java.lang.Override
+ protected GreeterBlockingStub build(io.grpc.Channel channel,
+ io.grpc.CallOptions callOptions) {
+ return new GreeterBlockingStub(channel, callOptions);
+ }
+
+ @java.lang.Override
+ public sayHello_result sayHello(sayHello_args request) {
+ return blockingUnaryCall(
+ getChannel(), METHOD_sayHello, getCallOptions(), request);
+ }
+
+ }
+
+ public static GreeterFutureStub newFutureStub(
+ io.grpc.Channel channel) {
+ return new GreeterFutureStub(channel);
+ }
+
+ @java.lang.Deprecated public static interface GreeterFutureClient {
+ public com.google.common.util.concurrent.ListenableFuture<sayHello_result> sayHello(
+ sayHello_args request);
+
+ }
+
+ public static class GreeterFutureStub extends io.grpc.stub.AbstractStub<GreeterFutureStub>
+ implements GreeterFutureClient {
+ private GreeterFutureStub(io.grpc.Channel channel) {
+ super(channel);
+ }
+
+ private GreeterFutureStub(io.grpc.Channel channel,
+ io.grpc.CallOptions callOptions) {
+ super(channel, callOptions);
+ }
+
+ @java.lang.Override
+ protected GreeterFutureStub build(io.grpc.Channel channel,
+ io.grpc.CallOptions callOptions) {
+ return new GreeterFutureStub(channel, callOptions);
+ }
+
+ @java.lang.Override
+ public com.google.common.util.concurrent.ListenableFuture<sayHello_result> sayHello(
+ sayHello_args request) {
+ return futureUnaryCall(
+ getChannel().newCall(METHOD_sayHello, getCallOptions()), request);
+ }
+
+ }
+
+ private static final int METHODID_sayHello = 0;
+
+ private static class MethodHandlers<Req, Resp> implements
+ io.grpc.stub.ServerCalls.UnaryMethod<Req, Resp>,
+ io.grpc.stub.ServerCalls.ServerStreamingMethod<Req, Resp>,
+ io.grpc.stub.ServerCalls.ClientStreamingMethod<Req, Resp>,
+ io.grpc.stub.ServerCalls.BidiStreamingMethod<Req, Resp> {
+ private final Greeter serviceImpl;
+ private final int methodId;
+
+ public MethodHandlers(Greeter serviceImpl, int methodId) {
+ this.serviceImpl = serviceImpl;
+ this.methodId = methodId;
+ }
+
+ @java.lang.Override
+ @java.lang.SuppressWarnings("unchecked")
+ public void invoke(Req request, io.grpc.stub.StreamObserver<Resp> responseObserver) {
+ switch (methodId) {
+ case METHODID_sayHello:
+ serviceImpl.sayHello((sayHello_args) request,
+ (io.grpc.stub.StreamObserver<sayHello_result>) responseObserver);
+ break;
+
+ default:
+ throw new AssertionError();
+ }
+ }
+
+ @java.lang.Override
+ @java.lang.SuppressWarnings("unchecked")
+ public io.grpc.stub.StreamObserver<Req> invoke(
+ io.grpc.stub.StreamObserver<Resp> responseObserver) {
+ switch (methodId) {
+ default:
+ throw new AssertionError();
+ }
+ }
+
+ }
+
+ public static io.grpc.ServiceDescriptor getServiceDescriptor() {
+ return new io.grpc.ServiceDescriptor(SERVICE_NAME ,
+ METHOD_sayHello);
+ }
+
+ @java.lang.Deprecated public static io.grpc.ServerServiceDefinition bindService(
+ final Greeter serviceImpl) {
+ return io.grpc.ServerServiceDefinition.builder(getServiceDescriptor())
+ .addMethod(
+ METHOD_sayHello,
+ asyncUnaryCall(
+ new MethodHandlers<
+ sayHello_args,
+ sayHello_result>(
+ serviceImpl, METHODID_sayHello)))
+ .build();
+ }
+
+}
diff --git a/examples/thrift/src/generated/main/java/io/grpc/examples/thrift/helloworld/HelloRequest.java b/examples/thrift/src/generated/main/java/io/grpc/examples/thrift/helloworld/HelloRequest.java
new file mode 100644
index 000000000..8c4646586
--- /dev/null
+++ b/examples/thrift/src/generated/main/java/io/grpc/examples/thrift/helloworld/HelloRequest.java
@@ -0,0 +1,395 @@
+/**
+ * Autogenerated by Thrift Compiler (1.0.0-dev)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ * @generated
+ */
+package io.grpc.examples.thrift.helloworld;
+
+import org.apache.thrift.scheme.IScheme;
+import org.apache.thrift.scheme.SchemeFactory;
+import org.apache.thrift.scheme.StandardScheme;
+
+import org.apache.thrift.scheme.TupleScheme;
+import org.apache.thrift.protocol.TTupleProtocol;
+import org.apache.thrift.protocol.TProtocolException;
+import org.apache.thrift.EncodingUtils;
+import org.apache.thrift.server.AbstractNonblockingServer.*;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.EnumMap;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.EnumSet;
+import java.util.Collections;
+import java.util.BitSet;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import javax.annotation.Generated;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
+@Generated(value = "Autogenerated by Thrift Compiler (1.0.0-dev)", date = "2016-07-21")
+public class HelloRequest implements org.apache.thrift.TBase<HelloRequest, HelloRequest._Fields>, java.io.Serializable, Cloneable, Comparable<HelloRequest> {
+ private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("HelloRequest");
+
+ private static final org.apache.thrift.protocol.TField NAME_FIELD_DESC = new org.apache.thrift.protocol.TField("name", org.apache.thrift.protocol.TType.STRING, (short)1);
+
+ private static final SchemeFactory STANDARD_SCHEME_FACTORY = new HelloRequestStandardSchemeFactory();
+ private static final SchemeFactory TUPLE_SCHEME_FACTORY = new HelloRequestTupleSchemeFactory();
+
+ public String name; // required
+
+ /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+ public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+ NAME((short)1, "name");
+
+ private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+ static {
+ for (_Fields field : EnumSet.allOf(_Fields.class)) {
+ byName.put(field.getFieldName(), field);
+ }
+ }
+
+ /**
+ * Find the _Fields constant that matches fieldId, or null if its not found.
+ */
+ public static _Fields findByThriftId(int fieldId) {
+ switch(fieldId) {
+ case 1: // NAME
+ return NAME;
+ default:
+ return null;
+ }
+ }
+
+ /**
+ * Find the _Fields constant that matches fieldId, throwing an exception
+ * if it is not found.
+ */
+ public static _Fields findByThriftIdOrThrow(int fieldId) {
+ _Fields fields = findByThriftId(fieldId);
+ if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+ return fields;
+ }
+
+ /**
+ * Find the _Fields constant that matches name, or null if its not found.
+ */
+ public static _Fields findByName(String name) {
+ return byName.get(name);
+ }
+
+ private final short _thriftId;
+ private final String _fieldName;
+
+ _Fields(short thriftId, String fieldName) {
+ _thriftId = thriftId;
+ _fieldName = fieldName;
+ }
+
+ public short getThriftFieldId() {
+ return _thriftId;
+ }
+
+ public String getFieldName() {
+ return _fieldName;
+ }
+ }
+
+ // isset id assignments
+ public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+ static {
+ Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+ tmpMap.put(_Fields.NAME, new org.apache.thrift.meta_data.FieldMetaData("name", org.apache.thrift.TFieldRequirementType.DEFAULT,
+ new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
+ metaDataMap = Collections.unmodifiableMap(tmpMap);
+ org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(HelloRequest.class, metaDataMap);
+ }
+
+ public HelloRequest() {
+ }
+
+ public HelloRequest(
+ String name)
+ {
+ this();
+ this.name = name;
+ }
+
+ /**
+ * Performs a deep copy on <i>other</i>.
+ */
+ public HelloRequest(HelloRequest other) {
+ if (other.isSetName()) {
+ this.name = other.name;
+ }
+ }
+
+ public HelloRequest deepCopy() {
+ return new HelloRequest(this);
+ }
+
+ @Override
+ public void clear() {
+ this.name = null;
+ }
+
+ public String getName() {
+ return this.name;
+ }
+
+ public HelloRequest setName(String name) {
+ this.name = name;
+ return this;
+ }
+
+ public void unsetName() {
+ this.name = null;
+ }
+
+ /** Returns true if field name is set (has been assigned a value) and false otherwise */
+ public boolean isSetName() {
+ return this.name != null;
+ }
+
+ public void setNameIsSet(boolean value) {
+ if (!value) {
+ this.name = null;
+ }
+ }
+
+ public void setFieldValue(_Fields field, Object value) {
+ switch (field) {
+ case NAME:
+ if (value == null) {
+ unsetName();
+ } else {
+ setName((String)value);
+ }
+ break;
+
+ }
+ }
+
+ public Object getFieldValue(_Fields field) {
+ switch (field) {
+ case NAME:
+ return getName();
+
+ }
+ throw new IllegalStateException();
+ }
+
+ /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+ public boolean isSet(_Fields field) {
+ if (field == null) {
+ throw new IllegalArgumentException();
+ }
+
+ switch (field) {
+ case NAME:
+ return isSetName();
+ }
+ throw new IllegalStateException();
+ }
+
+ @Override
+ public boolean equals(Object that) {
+ if (that == null)
+ return false;
+ if (that instanceof HelloRequest)
+ return this.equals((HelloRequest)that);
+ return false;
+ }
+
+ public boolean equals(HelloRequest that) {
+ if (that == null)
+ return false;
+
+ boolean this_present_name = true && this.isSetName();
+ boolean that_present_name = true && that.isSetName();
+ if (this_present_name || that_present_name) {
+ if (!(this_present_name && that_present_name))
+ return false;
+ if (!this.name.equals(that.name))
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int hashCode = 1;
+
+ hashCode = hashCode * 8191 + ((isSetName()) ? 131071 : 524287);
+ if (isSetName())
+ hashCode = hashCode * 8191 + name.hashCode();
+
+ return hashCode;
+ }
+
+ @Override
+ public int compareTo(HelloRequest other) {
+ if (!getClass().equals(other.getClass())) {
+ return getClass().getName().compareTo(other.getClass().getName());
+ }
+
+ int lastComparison = 0;
+
+ lastComparison = Boolean.valueOf(isSetName()).compareTo(other.isSetName());
+ if (lastComparison != 0) {
+ return lastComparison;
+ }
+ if (isSetName()) {
+ lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.name, other.name);
+ if (lastComparison != 0) {
+ return lastComparison;
+ }
+ }
+ return 0;
+ }
+
+ public _Fields fieldForId(int fieldId) {
+ return _Fields.findByThriftId(fieldId);
+ }
+
+ public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+ scheme(iprot).read(iprot, this);
+ }
+
+ public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+ scheme(oprot).write(oprot, this);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder("HelloRequest(");
+ boolean first = true;
+
+ sb.append("name:");
+ if (this.name == null) {
+ sb.append("null");
+ } else {
+ sb.append(this.name);
+ }
+ first = false;
+ sb.append(")");
+ return sb.toString();
+ }
+
+ public void validate() throws org.apache.thrift.TException {
+ // check for required fields
+ // check for sub-struct validity
+ }
+
+ private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+ try {
+ write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+ } catch (org.apache.thrift.TException te) {
+ throw new java.io.IOException(te);
+ }
+ }
+
+ private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+ try {
+ read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+ } catch (org.apache.thrift.TException te) {
+ throw new java.io.IOException(te);
+ }
+ }
+
+ private static class HelloRequestStandardSchemeFactory implements SchemeFactory {
+ public HelloRequestStandardScheme getScheme() {
+ return new HelloRequestStandardScheme();
+ }
+ }
+
+ private static class HelloRequestStandardScheme extends StandardScheme<HelloRequest> {
+
+ public void read(org.apache.thrift.protocol.TProtocol iprot, HelloRequest struct) throws org.apache.thrift.TException {
+ org.apache.thrift.protocol.TField schemeField;
+ iprot.readStructBegin();
+ while (true)
+ {
+ schemeField = iprot.readFieldBegin();
+ if (schemeField.type == org.apache.thrift.protocol.TType.STOP) {
+ break;
+ }
+ switch (schemeField.id) {
+ case 1: // NAME
+ if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+ struct.name = iprot.readString();
+ struct.setNameIsSet(true);
+ } else {
+ org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+ }
+ break;
+ default:
+ org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+ }
+ iprot.readFieldEnd();
+ }
+ iprot.readStructEnd();
+
+ // check for required fields of primitive type, which can't be checked in the validate method
+ struct.validate();
+ }
+
+ public void write(org.apache.thrift.protocol.TProtocol oprot, HelloRequest struct) throws org.apache.thrift.TException {
+ struct.validate();
+
+ oprot.writeStructBegin(STRUCT_DESC);
+ if (struct.name != null) {
+ oprot.writeFieldBegin(NAME_FIELD_DESC);
+ oprot.writeString(struct.name);
+ oprot.writeFieldEnd();
+ }
+ oprot.writeFieldStop();
+ oprot.writeStructEnd();
+ }
+
+ }
+
+ private static class HelloRequestTupleSchemeFactory implements SchemeFactory {
+ public HelloRequestTupleScheme getScheme() {
+ return new HelloRequestTupleScheme();
+ }
+ }
+
+ private static class HelloRequestTupleScheme extends TupleScheme<HelloRequest> {
+
+ @Override
+ public void write(org.apache.thrift.protocol.TProtocol prot, HelloRequest struct) throws org.apache.thrift.TException {
+ TTupleProtocol oprot = (TTupleProtocol) prot;
+ BitSet optionals = new BitSet();
+ if (struct.isSetName()) {
+ optionals.set(0);
+ }
+ oprot.writeBitSet(optionals, 1);
+ if (struct.isSetName()) {
+ oprot.writeString(struct.name);
+ }
+ }
+
+ @Override
+ public void read(org.apache.thrift.protocol.TProtocol prot, HelloRequest struct) throws org.apache.thrift.TException {
+ TTupleProtocol iprot = (TTupleProtocol) prot;
+ BitSet incoming = iprot.readBitSet(1);
+ if (incoming.get(0)) {
+ struct.name = iprot.readString();
+ struct.setNameIsSet(true);
+ }
+ }
+ }
+
+ private static <S extends IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+ return (StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+ }
+}
+
diff --git a/examples/thrift/src/generated/main/java/io/grpc/examples/thrift/helloworld/HelloResponse.java b/examples/thrift/src/generated/main/java/io/grpc/examples/thrift/helloworld/HelloResponse.java
new file mode 100644
index 000000000..17c295f3a
--- /dev/null
+++ b/examples/thrift/src/generated/main/java/io/grpc/examples/thrift/helloworld/HelloResponse.java
@@ -0,0 +1,395 @@
+/**
+ * Autogenerated by Thrift Compiler (1.0.0-dev)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ * @generated
+ */
+package io.grpc.examples.thrift.helloworld;
+
+import org.apache.thrift.scheme.IScheme;
+import org.apache.thrift.scheme.SchemeFactory;
+import org.apache.thrift.scheme.StandardScheme;
+
+import org.apache.thrift.scheme.TupleScheme;
+import org.apache.thrift.protocol.TTupleProtocol;
+import org.apache.thrift.protocol.TProtocolException;
+import org.apache.thrift.EncodingUtils;
+import org.apache.thrift.server.AbstractNonblockingServer.*;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.EnumMap;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.EnumSet;
+import java.util.Collections;
+import java.util.BitSet;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import javax.annotation.Generated;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
+@Generated(value = "Autogenerated by Thrift Compiler (1.0.0-dev)", date = "2016-07-21")
+public class HelloResponse implements org.apache.thrift.TBase<HelloResponse, HelloResponse._Fields>, java.io.Serializable, Cloneable, Comparable<HelloResponse> {
+ private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("HelloResponse");
+
+ private static final org.apache.thrift.protocol.TField MESSAGE_FIELD_DESC = new org.apache.thrift.protocol.TField("message", org.apache.thrift.protocol.TType.STRING, (short)1);
+
+ private static final SchemeFactory STANDARD_SCHEME_FACTORY = new HelloResponseStandardSchemeFactory();
+ private static final SchemeFactory TUPLE_SCHEME_FACTORY = new HelloResponseTupleSchemeFactory();
+
+ public String message; // required
+
+ /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+ public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+ MESSAGE((short)1, "message");
+
+ private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+ static {
+ for (_Fields field : EnumSet.allOf(_Fields.class)) {
+ byName.put(field.getFieldName(), field);
+ }
+ }
+
+ /**
+ * Find the _Fields constant that matches fieldId, or null if its not found.
+ */
+ public static _Fields findByThriftId(int fieldId) {
+ switch(fieldId) {
+ case 1: // MESSAGE
+ return MESSAGE;
+ default:
+ return null;
+ }
+ }
+
+ /**
+ * Find the _Fields constant that matches fieldId, throwing an exception
+ * if it is not found.
+ */
+ public static _Fields findByThriftIdOrThrow(int fieldId) {
+ _Fields fields = findByThriftId(fieldId);
+ if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+ return fields;
+ }
+
+ /**
+ * Find the _Fields constant that matches name, or null if its not found.
+ */
+ public static _Fields findByName(String name) {
+ return byName.get(name);
+ }
+
+ private final short _thriftId;
+ private final String _fieldName;
+
+ _Fields(short thriftId, String fieldName) {
+ _thriftId = thriftId;
+ _fieldName = fieldName;
+ }
+
+ public short getThriftFieldId() {
+ return _thriftId;
+ }
+
+ public String getFieldName() {
+ return _fieldName;
+ }
+ }
+
+ // isset id assignments
+ public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+ static {
+ Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+ tmpMap.put(_Fields.MESSAGE, new org.apache.thrift.meta_data.FieldMetaData("message", org.apache.thrift.TFieldRequirementType.DEFAULT,
+ new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
+ metaDataMap = Collections.unmodifiableMap(tmpMap);
+ org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(HelloResponse.class, metaDataMap);
+ }
+
+ public HelloResponse() {
+ }
+
+ public HelloResponse(
+ String message)
+ {
+ this();
+ this.message = message;
+ }
+
+ /**
+ * Performs a deep copy on <i>other</i>.
+ */
+ public HelloResponse(HelloResponse other) {
+ if (other.isSetMessage()) {
+ this.message = other.message;
+ }
+ }
+
+ public HelloResponse deepCopy() {
+ return new HelloResponse(this);
+ }
+
+ @Override
+ public void clear() {
+ this.message = null;
+ }
+
+ public String getMessage() {
+ return this.message;
+ }
+
+ public HelloResponse setMessage(String message) {
+ this.message = message;
+ return this;
+ }
+
+ public void unsetMessage() {
+ this.message = null;
+ }
+
+ /** Returns true if field message is set (has been assigned a value) and false otherwise */
+ public boolean isSetMessage() {
+ return this.message != null;
+ }
+
+ public void setMessageIsSet(boolean value) {
+ if (!value) {
+ this.message = null;
+ }
+ }
+
+ public void setFieldValue(_Fields field, Object value) {
+ switch (field) {
+ case MESSAGE:
+ if (value == null) {
+ unsetMessage();
+ } else {
+ setMessage((String)value);
+ }
+ break;
+
+ }
+ }
+
+ public Object getFieldValue(_Fields field) {
+ switch (field) {
+ case MESSAGE:
+ return getMessage();
+
+ }
+ throw new IllegalStateException();
+ }
+
+ /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+ public boolean isSet(_Fields field) {
+ if (field == null) {
+ throw new IllegalArgumentException();
+ }
+
+ switch (field) {
+ case MESSAGE:
+ return isSetMessage();
+ }
+ throw new IllegalStateException();
+ }
+
+ @Override
+ public boolean equals(Object that) {
+ if (that == null)
+ return false;
+ if (that instanceof HelloResponse)
+ return this.equals((HelloResponse)that);
+ return false;
+ }
+
+ public boolean equals(HelloResponse that) {
+ if (that == null)
+ return false;
+
+ boolean this_present_message = true && this.isSetMessage();
+ boolean that_present_message = true && that.isSetMessage();
+ if (this_present_message || that_present_message) {
+ if (!(this_present_message && that_present_message))
+ return false;
+ if (!this.message.equals(that.message))
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int hashCode = 1;
+
+ hashCode = hashCode * 8191 + ((isSetMessage()) ? 131071 : 524287);
+ if (isSetMessage())
+ hashCode = hashCode * 8191 + message.hashCode();
+
+ return hashCode;
+ }
+
+ @Override
+ public int compareTo(HelloResponse other) {
+ if (!getClass().equals(other.getClass())) {
+ return getClass().getName().compareTo(other.getClass().getName());
+ }
+
+ int lastComparison = 0;
+
+ lastComparison = Boolean.valueOf(isSetMessage()).compareTo(other.isSetMessage());
+ if (lastComparison != 0) {
+ return lastComparison;
+ }
+ if (isSetMessage()) {
+ lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.message, other.message);
+ if (lastComparison != 0) {
+ return lastComparison;
+ }
+ }
+ return 0;
+ }
+
+ public _Fields fieldForId(int fieldId) {
+ return _Fields.findByThriftId(fieldId);
+ }
+
+ public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+ scheme(iprot).read(iprot, this);
+ }
+
+ public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+ scheme(oprot).write(oprot, this);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder("HelloResponse(");
+ boolean first = true;
+
+ sb.append("message:");
+ if (this.message == null) {
+ sb.append("null");
+ } else {
+ sb.append(this.message);
+ }
+ first = false;
+ sb.append(")");
+ return sb.toString();
+ }
+
+ public void validate() throws org.apache.thrift.TException {
+ // check for required fields
+ // check for sub-struct validity
+ }
+
+ private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+ try {
+ write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+ } catch (org.apache.thrift.TException te) {
+ throw new java.io.IOException(te);
+ }
+ }
+
+ private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+ try {
+ read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+ } catch (org.apache.thrift.TException te) {
+ throw new java.io.IOException(te);
+ }
+ }
+
+ private static class HelloResponseStandardSchemeFactory implements SchemeFactory {
+ public HelloResponseStandardScheme getScheme() {
+ return new HelloResponseStandardScheme();
+ }
+ }
+
+ private static class HelloResponseStandardScheme extends StandardScheme<HelloResponse> {
+
+ public void read(org.apache.thrift.protocol.TProtocol iprot, HelloResponse struct) throws org.apache.thrift.TException {
+ org.apache.thrift.protocol.TField schemeField;
+ iprot.readStructBegin();
+ while (true)
+ {
+ schemeField = iprot.readFieldBegin();
+ if (schemeField.type == org.apache.thrift.protocol.TType.STOP) {
+ break;
+ }
+ switch (schemeField.id) {
+ case 1: // MESSAGE
+ if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+ struct.message = iprot.readString();
+ struct.setMessageIsSet(true);
+ } else {
+ org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+ }
+ break;
+ default:
+ org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+ }
+ iprot.readFieldEnd();
+ }
+ iprot.readStructEnd();
+
+ // check for required fields of primitive type, which can't be checked in the validate method
+ struct.validate();
+ }
+
+ public void write(org.apache.thrift.protocol.TProtocol oprot, HelloResponse struct) throws org.apache.thrift.TException {
+ struct.validate();
+
+ oprot.writeStructBegin(STRUCT_DESC);
+ if (struct.message != null) {
+ oprot.writeFieldBegin(MESSAGE_FIELD_DESC);
+ oprot.writeString(struct.message);
+ oprot.writeFieldEnd();
+ }
+ oprot.writeFieldStop();
+ oprot.writeStructEnd();
+ }
+
+ }
+
+ private static class HelloResponseTupleSchemeFactory implements SchemeFactory {
+ public HelloResponseTupleScheme getScheme() {
+ return new HelloResponseTupleScheme();
+ }
+ }
+
+ private static class HelloResponseTupleScheme extends TupleScheme<HelloResponse> {
+
+ @Override
+ public void write(org.apache.thrift.protocol.TProtocol prot, HelloResponse struct) throws org.apache.thrift.TException {
+ TTupleProtocol oprot = (TTupleProtocol) prot;
+ BitSet optionals = new BitSet();
+ if (struct.isSetMessage()) {
+ optionals.set(0);
+ }
+ oprot.writeBitSet(optionals, 1);
+ if (struct.isSetMessage()) {
+ oprot.writeString(struct.message);
+ }
+ }
+
+ @Override
+ public void read(org.apache.thrift.protocol.TProtocol prot, HelloResponse struct) throws org.apache.thrift.TException {
+ TTupleProtocol iprot = (TTupleProtocol) prot;
+ BitSet incoming = iprot.readBitSet(1);
+ if (incoming.get(0)) {
+ struct.message = iprot.readString();
+ struct.setMessageIsSet(true);
+ }
+ }
+ }
+
+ private static <S extends IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+ return (StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+ }
+}
+
diff --git a/examples/thrift/src/main/java/io/grpc/examples/thrift/helloworld/HelloWorldClient.java b/examples/thrift/src/main/java/io/grpc/examples/thrift/helloworld/HelloWorldClient.java
new file mode 100644
index 000000000..5d89c43a7
--- /dev/null
+++ b/examples/thrift/src/main/java/io/grpc/examples/thrift/helloworld/HelloWorldClient.java
@@ -0,0 +1,89 @@
+/*
+ * Copyright 2016, Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package io.grpc.examples.thrift.helloworld;
+
+import io.grpc.ManagedChannel;
+import io.grpc.ManagedChannelBuilder;
+import io.grpc.StatusRuntimeException;
+
+import java.util.concurrent.TimeUnit;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/** Simple client that requests a greeting from {@link HelloWorldServer}. */
+public class HelloWorldClient {
+ private static final Logger logger = Logger.getLogger(HelloWorldClient.class.getName());
+
+ private final ManagedChannel channel;
+ private final GreeterGrpc.GreeterBlockingStub blockingStub;
+
+ public HelloWorldClient(String host, int port) {
+ channel = ManagedChannelBuilder.forAddress(host, port)
+ .usePlaintext(true)
+ .build();
+ blockingStub = GreeterGrpc.newBlockingStub(channel);
+ }
+
+ public void shutdown() throws InterruptedException {
+ channel.shutdown().awaitTermination(5, TimeUnit.SECONDS);
+ }
+
+ /** Say Hello to Server. */
+ public void greet(String name) {
+ logger.info("Will try to greet " + name + " ...");
+ HelloRequest hellorequest = new HelloRequest(name);
+ GreeterGrpc.sayHello_args request = new GreeterGrpc.sayHello_args(hellorequest);
+
+ GreeterGrpc.sayHello_result response;
+ try {
+ response = blockingStub.sayHello(request);
+ } catch (StatusRuntimeException e) {
+ logger.log(Level.WARNING, "RPC failed: {0}", e.getStatus());
+ return;
+ }
+ logger.info("Greeting: " + response.success.message);
+ }
+
+ /** Greet Server. */
+ public static void main(String[] args) throws Exception {
+ HelloWorldClient client = new HelloWorldClient("localhost" , 50051);
+ try {
+ String user = "world";
+ if (args.length > 0) {
+ user = args[0];
+ }
+ client.greet(user);
+ } finally {
+ client.shutdown();
+ }
+ }
+} \ No newline at end of file
diff --git a/examples/thrift/src/main/java/io/grpc/examples/thrift/helloworld/HelloWorldServer.java b/examples/thrift/src/main/java/io/grpc/examples/thrift/helloworld/HelloWorldServer.java
new file mode 100644
index 000000000..48da768ae
--- /dev/null
+++ b/examples/thrift/src/main/java/io/grpc/examples/thrift/helloworld/HelloWorldServer.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2016, Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package io.grpc.examples.thrift.helloworld;
+
+import io.grpc.Server;
+import io.grpc.ServerBuilder;
+import io.grpc.stub.StreamObserver;
+
+import java.io.IOException;
+import java.util.logging.Logger;
+
+/** Server that manages startup/ shutdown of a Greeter server. */
+public class HelloWorldServer {
+ private static final Logger logger = Logger.getLogger(HelloWorldServer.class.getName());
+
+ /** Port on which the server should run. */
+ private int port = 50051;
+ private Server server;
+
+ private void start() throws IOException {
+ server = ServerBuilder.forPort(port)
+ .addService(new GreeterImpl())
+ .build()
+ .start();
+ logger.info("Server started, listening on "+ port);
+ Runtime.getRuntime().addShutdownHook(new Thread() {
+ @Override
+ public void run() {
+ System.err.println("*** Shutting down gRPC server since JVM is shutting down");
+ HelloWorldServer.this.stop();
+ System.err.println("*** Server shut down");
+ }
+ });
+ }
+
+ private void stop() {
+ if (server != null) {
+ server.shutdown();
+ }
+ }
+
+ private void blockUntilShutdown() throws InterruptedException {
+ if (server != null) {
+ server.awaitTermination();
+ }
+ }
+
+ /** Main function to launch server from cmd. */
+ public static void main(String[] args) throws IOException, InterruptedException {
+ final HelloWorldServer server = new HelloWorldServer();
+ server.start();
+ server.blockUntilShutdown();
+ }
+
+ private class GreeterImpl extends GreeterGrpc.GreeterImplBase {
+ @Override
+ public void sayHello(GreeterGrpc.sayHello_args req, StreamObserver<GreeterGrpc.sayHello_result> responseObserver) {
+ GreeterGrpc.sayHello_result reply = new GreeterGrpc.sayHello_result();
+ reply.success = new HelloResponse("Hello " + req.request.name);
+ responseObserver.onNext(reply);
+ responseObserver.onCompleted();
+ }
+ }
+} \ No newline at end of file
diff --git a/examples/thrift/src/main/thrift/helloworld.thrift b/examples/thrift/src/main/thrift/helloworld.thrift
new file mode 100644
index 000000000..a042e563e
--- /dev/null
+++ b/examples/thrift/src/main/thrift/helloworld.thrift
@@ -0,0 +1,13 @@
+namespace java io.grpc.examples.thrift.helloworld
+
+struct HelloRequest {
+ 1:string name
+}
+
+struct HelloResponse {
+ 1:string message
+}
+
+service Greeter {
+ HelloResponse sayHello(1:HelloRequest request);
+}
diff --git a/settings.gradle b/settings.gradle
index 42496c2ee..6c7034ae1 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -13,6 +13,7 @@ include ":grpc-interop-testing"
include ":grpc-all"
include ":grpc-benchmarks"
include ":grpc-services"
+include ":grpc-thrift"
project(':grpc-core').projectDir = "$rootDir/core" as File
project(':grpc-stub').projectDir = "$rootDir/stub" as File
@@ -28,6 +29,7 @@ project(':grpc-interop-testing').projectDir = "$rootDir/interop-testing" as File
project(':grpc-all').projectDir = "$rootDir/all" as File
project(':grpc-benchmarks').projectDir = "$rootDir/benchmarks" as File
project(':grpc-services').projectDir = "$rootDir/services" as File
+project(':grpc-thrift').projectDir = "$rootDir/thrift" as File
if (settings.hasProperty('skipCodegen') && skipCodegen.toBoolean()) {
println '*** Skipping the build of codegen and compilation of proto files because skipCodegen=true'
diff --git a/thrift/build.gradle b/thrift/build.gradle
new file mode 100644
index 000000000..33e509ea9
--- /dev/null
+++ b/thrift/build.gradle
@@ -0,0 +1,29 @@
+description = 'gRPC: Thrift'
+
+dependencies {
+ compile project(':grpc-core'),
+ 'org.apache.thrift:libthrift:0.9.3'
+}
+
+
+String generatedSourcePath = "${projectDir}/src/generated"
+project.sourceSets {
+ main {
+ java {
+ srcDir "${generatedSourcePath}/main/java"
+ srcDir "${generatedSourcePath}/main/grpc"
+ }
+ }
+ test {
+ java {
+ srcDir "${generatedSourcePath}/test/java"
+ srcDir "${generatedSourcePath}/test/grpc"
+ }
+ }
+}
+
+idea {
+ module {
+ sourceDirs += file("${projectDir}/src/generated/test/java");
+ }
+} \ No newline at end of file
diff --git a/thrift/src/generated/test/java/io/grpc/thrift/Message.java b/thrift/src/generated/test/java/io/grpc/thrift/Message.java
new file mode 100644
index 000000000..44c7908bd
--- /dev/null
+++ b/thrift/src/generated/test/java/io/grpc/thrift/Message.java
@@ -0,0 +1,744 @@
+/**
+ * Autogenerated by Thrift Compiler (1.0.0-dev)
+ *
+ * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
+ * @generated
+ */
+package io.grpc.thrift;
+
+import org.apache.thrift.scheme.IScheme;
+import org.apache.thrift.scheme.SchemeFactory;
+import org.apache.thrift.scheme.StandardScheme;
+
+import org.apache.thrift.scheme.TupleScheme;
+import org.apache.thrift.protocol.TTupleProtocol;
+import org.apache.thrift.protocol.TProtocolException;
+import org.apache.thrift.EncodingUtils;
+import org.apache.thrift.server.AbstractNonblockingServer.*;
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.EnumMap;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.EnumSet;
+import java.util.Collections;
+import java.util.BitSet;
+import java.nio.ByteBuffer;
+import java.util.Arrays;
+import javax.annotation.Generated;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+@SuppressWarnings({"cast", "rawtypes", "serial", "unchecked", "unused"})
+@Generated(value = "Autogenerated by Thrift Compiler (1.0.0-dev)", date = "2016-07-11")
+public class Message implements org.apache.thrift.TBase<Message, Message._Fields>, java.io.Serializable, Cloneable, Comparable<Message> {
+ private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("Message");
+
+ private static final org.apache.thrift.protocol.TField I_FIELD_DESC = new org.apache.thrift.protocol.TField("i", org.apache.thrift.protocol.TType.I32, (short)1);
+ private static final org.apache.thrift.protocol.TField B_FIELD_DESC = new org.apache.thrift.protocol.TField("b", org.apache.thrift.protocol.TType.BOOL, (short)2);
+ private static final org.apache.thrift.protocol.TField S_FIELD_DESC = new org.apache.thrift.protocol.TField("s", org.apache.thrift.protocol.TType.STRING, (short)3);
+ private static final org.apache.thrift.protocol.TField L_FIELD_DESC = new org.apache.thrift.protocol.TField("l", org.apache.thrift.protocol.TType.LIST, (short)4);
+
+ private static final SchemeFactory STANDARD_SCHEME_FACTORY = new MessageStandardSchemeFactory();
+ private static final SchemeFactory TUPLE_SCHEME_FACTORY = new MessageTupleSchemeFactory();
+
+ public int i; // required
+ public boolean b; // required
+ public String s; // required
+ public List<Integer> l; // required
+
+ /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+ public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+ I((short)1, "i"),
+ B((short)2, "b"),
+ S((short)3, "s"),
+ L((short)4, "l");
+
+ private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+ static {
+ for (_Fields field : EnumSet.allOf(_Fields.class)) {
+ byName.put(field.getFieldName(), field);
+ }
+ }
+
+ /**
+ * Find the _Fields constant that matches fieldId, or null if its not found.
+ */
+ public static _Fields findByThriftId(int fieldId) {
+ switch(fieldId) {
+ case 1: // I
+ return I;
+ case 2: // B
+ return B;
+ case 3: // S
+ return S;
+ case 4: // L
+ return L;
+ default:
+ return null;
+ }
+ }
+
+ /**
+ * Find the _Fields constant that matches fieldId, throwing an exception
+ * if it is not found.
+ */
+ public static _Fields findByThriftIdOrThrow(int fieldId) {
+ _Fields fields = findByThriftId(fieldId);
+ if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+ return fields;
+ }
+
+ /**
+ * Find the _Fields constant that matches name, or null if its not found.
+ */
+ public static _Fields findByName(String name) {
+ return byName.get(name);
+ }
+
+ private final short _thriftId;
+ private final String _fieldName;
+
+ _Fields(short thriftId, String fieldName) {
+ _thriftId = thriftId;
+ _fieldName = fieldName;
+ }
+
+ public short getThriftFieldId() {
+ return _thriftId;
+ }
+
+ public String getFieldName() {
+ return _fieldName;
+ }
+ }
+
+ // isset id assignments
+ private static final int __I_ISSET_ID = 0;
+ private static final int __B_ISSET_ID = 1;
+ private byte __isset_bitfield = 0;
+ public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+ static {
+ Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+ tmpMap.put(_Fields.I, new org.apache.thrift.meta_data.FieldMetaData("i", org.apache.thrift.TFieldRequirementType.DEFAULT,
+ new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32)));
+ tmpMap.put(_Fields.B, new org.apache.thrift.meta_data.FieldMetaData("b", org.apache.thrift.TFieldRequirementType.DEFAULT,
+ new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.BOOL)));
+ tmpMap.put(_Fields.S, new org.apache.thrift.meta_data.FieldMetaData("s", org.apache.thrift.TFieldRequirementType.DEFAULT,
+ new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
+ tmpMap.put(_Fields.L, new org.apache.thrift.meta_data.FieldMetaData("l", org.apache.thrift.TFieldRequirementType.DEFAULT,
+ new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST,
+ new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I32))));
+ metaDataMap = Collections.unmodifiableMap(tmpMap);
+ org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(Message.class, metaDataMap);
+ }
+
+ public Message() {
+ }
+
+ public Message(
+ int i,
+ boolean b,
+ String s,
+ List<Integer> l)
+ {
+ this();
+ this.i = i;
+ setIIsSet(true);
+ this.b = b;
+ setBIsSet(true);
+ this.s = s;
+ this.l = l;
+ }
+
+ /**
+ * Performs a deep copy on <i>other</i>.
+ */
+ public Message(Message other) {
+ __isset_bitfield = other.__isset_bitfield;
+ this.i = other.i;
+ this.b = other.b;
+ if (other.isSetS()) {
+ this.s = other.s;
+ }
+ if (other.isSetL()) {
+ List<Integer> __this__l = new ArrayList<Integer>(other.l);
+ this.l = __this__l;
+ }
+ }
+
+ public Message deepCopy() {
+ return new Message(this);
+ }
+
+ @Override
+ public void clear() {
+ setIIsSet(false);
+ this.i = 0;
+ setBIsSet(false);
+ this.b = false;
+ this.s = null;
+ this.l = null;
+ }
+
+ public int getI() {
+ return this.i;
+ }
+
+ public Message setI(int i) {
+ this.i = i;
+ setIIsSet(true);
+ return this;
+ }
+
+ public void unsetI() {
+ __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __I_ISSET_ID);
+ }
+
+ /** Returns true if field i is set (has been assigned a value) and false otherwise */
+ public boolean isSetI() {
+ return EncodingUtils.testBit(__isset_bitfield, __I_ISSET_ID);
+ }
+
+ public void setIIsSet(boolean value) {
+ __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __I_ISSET_ID, value);
+ }
+
+ public boolean isB() {
+ return this.b;
+ }
+
+ public Message setB(boolean b) {
+ this.b = b;
+ setBIsSet(true);
+ return this;
+ }
+
+ public void unsetB() {
+ __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __B_ISSET_ID);
+ }
+
+ /** Returns true if field b is set (has been assigned a value) and false otherwise */
+ public boolean isSetB() {
+ return EncodingUtils.testBit(__isset_bitfield, __B_ISSET_ID);
+ }
+
+ public void setBIsSet(boolean value) {
+ __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __B_ISSET_ID, value);
+ }
+
+ public String getS() {
+ return this.s;
+ }
+
+ public Message setS(String s) {
+ this.s = s;
+ return this;
+ }
+
+ public void unsetS() {
+ this.s = null;
+ }
+
+ /** Returns true if field s is set (has been assigned a value) and false otherwise */
+ public boolean isSetS() {
+ return this.s != null;
+ }
+
+ public void setSIsSet(boolean value) {
+ if (!value) {
+ this.s = null;
+ }
+ }
+
+ public int getLSize() {
+ return (this.l == null) ? 0 : this.l.size();
+ }
+
+ public java.util.Iterator<Integer> getLIterator() {
+ return (this.l == null) ? null : this.l.iterator();
+ }
+
+ public void addToL(int elem) {
+ if (this.l == null) {
+ this.l = new ArrayList<Integer>();
+ }
+ this.l.add(elem);
+ }
+
+ public List<Integer> getL() {
+ return this.l;
+ }
+
+ public Message setL(List<Integer> l) {
+ this.l = l;
+ return this;
+ }
+
+ public void unsetL() {
+ this.l = null;
+ }
+
+ /** Returns true if field l is set (has been assigned a value) and false otherwise */
+ public boolean isSetL() {
+ return this.l != null;
+ }
+
+ public void setLIsSet(boolean value) {
+ if (!value) {
+ this.l = null;
+ }
+ }
+
+ public void setFieldValue(_Fields field, Object value) {
+ switch (field) {
+ case I:
+ if (value == null) {
+ unsetI();
+ } else {
+ setI((Integer)value);
+ }
+ break;
+
+ case B:
+ if (value == null) {
+ unsetB();
+ } else {
+ setB((Boolean)value);
+ }
+ break;
+
+ case S:
+ if (value == null) {
+ unsetS();
+ } else {
+ setS((String)value);
+ }
+ break;
+
+ case L:
+ if (value == null) {
+ unsetL();
+ } else {
+ setL((List<Integer>)value);
+ }
+ break;
+
+ }
+ }
+
+ public Object getFieldValue(_Fields field) {
+ switch (field) {
+ case I:
+ return getI();
+
+ case B:
+ return isB();
+
+ case S:
+ return getS();
+
+ case L:
+ return getL();
+
+ }
+ throw new IllegalStateException();
+ }
+
+ /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+ public boolean isSet(_Fields field) {
+ if (field == null) {
+ throw new IllegalArgumentException();
+ }
+
+ switch (field) {
+ case I:
+ return isSetI();
+ case B:
+ return isSetB();
+ case S:
+ return isSetS();
+ case L:
+ return isSetL();
+ }
+ throw new IllegalStateException();
+ }
+
+ @Override
+ public boolean equals(Object that) {
+ if (that == null)
+ return false;
+ if (that instanceof Message)
+ return this.equals((Message)that);
+ return false;
+ }
+
+ public boolean equals(Message that) {
+ if (that == null)
+ return false;
+
+ boolean this_present_i = true;
+ boolean that_present_i = true;
+ if (this_present_i || that_present_i) {
+ if (!(this_present_i && that_present_i))
+ return false;
+ if (this.i != that.i)
+ return false;
+ }
+
+ boolean this_present_b = true;
+ boolean that_present_b = true;
+ if (this_present_b || that_present_b) {
+ if (!(this_present_b && that_present_b))
+ return false;
+ if (this.b != that.b)
+ return false;
+ }
+
+ boolean this_present_s = true && this.isSetS();
+ boolean that_present_s = true && that.isSetS();
+ if (this_present_s || that_present_s) {
+ if (!(this_present_s && that_present_s))
+ return false;
+ if (!this.s.equals(that.s))
+ return false;
+ }
+
+ boolean this_present_l = true && this.isSetL();
+ boolean that_present_l = true && that.isSetL();
+ if (this_present_l || that_present_l) {
+ if (!(this_present_l && that_present_l))
+ return false;
+ if (!this.l.equals(that.l))
+ return false;
+ }
+
+ return true;
+ }
+
+ @Override
+ public int hashCode() {
+ int hashCode = 1;
+
+ hashCode = hashCode * 8191 + i;
+
+ hashCode = hashCode * 8191 + ((b) ? 131071 : 524287);
+
+ hashCode = hashCode * 8191 + ((isSetS()) ? 131071 : 524287);
+ if (isSetS())
+ hashCode = hashCode * 8191 + s.hashCode();
+
+ hashCode = hashCode * 8191 + ((isSetL()) ? 131071 : 524287);
+ if (isSetL())
+ hashCode = hashCode * 8191 + l.hashCode();
+
+ return hashCode;
+ }
+
+ @Override
+ public int compareTo(Message other) {
+ if (!getClass().equals(other.getClass())) {
+ return getClass().getName().compareTo(other.getClass().getName());
+ }
+
+ int lastComparison = 0;
+
+ lastComparison = Boolean.valueOf(isSetI()).compareTo(other.isSetI());
+ if (lastComparison != 0) {
+ return lastComparison;
+ }
+ if (isSetI()) {
+ lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.i, other.i);
+ if (lastComparison != 0) {
+ return lastComparison;
+ }
+ }
+ lastComparison = Boolean.valueOf(isSetB()).compareTo(other.isSetB());
+ if (lastComparison != 0) {
+ return lastComparison;
+ }
+ if (isSetB()) {
+ lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.b, other.b);
+ if (lastComparison != 0) {
+ return lastComparison;
+ }
+ }
+ lastComparison = Boolean.valueOf(isSetS()).compareTo(other.isSetS());
+ if (lastComparison != 0) {
+ return lastComparison;
+ }
+ if (isSetS()) {
+ lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.s, other.s);
+ if (lastComparison != 0) {
+ return lastComparison;
+ }
+ }
+ lastComparison = Boolean.valueOf(isSetL()).compareTo(other.isSetL());
+ if (lastComparison != 0) {
+ return lastComparison;
+ }
+ if (isSetL()) {
+ lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.l, other.l);
+ if (lastComparison != 0) {
+ return lastComparison;
+ }
+ }
+ return 0;
+ }
+
+ public _Fields fieldForId(int fieldId) {
+ return _Fields.findByThriftId(fieldId);
+ }
+
+ public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+ scheme(iprot).read(iprot, this);
+ }
+
+ public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+ scheme(oprot).write(oprot, this);
+ }
+
+ @Override
+ public String toString() {
+ StringBuilder sb = new StringBuilder("Message(");
+ boolean first = true;
+
+ sb.append("i:");
+ sb.append(this.i);
+ first = false;
+ if (!first) sb.append(", ");
+ sb.append("b:");
+ sb.append(this.b);
+ first = false;
+ if (!first) sb.append(", ");
+ sb.append("s:");
+ if (this.s == null) {
+ sb.append("null");
+ } else {
+ sb.append(this.s);
+ }
+ first = false;
+ if (!first) sb.append(", ");
+ sb.append("l:");
+ if (this.l == null) {
+ sb.append("null");
+ } else {
+ sb.append(this.l);
+ }
+ first = false;
+ sb.append(")");
+ return sb.toString();
+ }
+
+ public void validate() throws org.apache.thrift.TException {
+ // check for required fields
+ // check for sub-struct validity
+ }
+
+ private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+ try {
+ write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+ } catch (org.apache.thrift.TException te) {
+ throw new java.io.IOException(te);
+ }
+ }
+
+ private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+ try {
+ // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
+ __isset_bitfield = 0;
+ read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+ } catch (org.apache.thrift.TException te) {
+ throw new java.io.IOException(te);
+ }
+ }
+
+ private static class MessageStandardSchemeFactory implements SchemeFactory {
+ public MessageStandardScheme getScheme() {
+ return new MessageStandardScheme();
+ }
+ }
+
+ private static class MessageStandardScheme extends StandardScheme<Message> {
+
+ public void read(org.apache.thrift.protocol.TProtocol iprot, Message struct) throws org.apache.thrift.TException {
+ org.apache.thrift.protocol.TField schemeField;
+ iprot.readStructBegin();
+ while (true)
+ {
+ schemeField = iprot.readFieldBegin();
+ if (schemeField.type == org.apache.thrift.protocol.TType.STOP) {
+ break;
+ }
+ switch (schemeField.id) {
+ case 1: // I
+ if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
+ struct.i = iprot.readI32();
+ struct.setIIsSet(true);
+ } else {
+ org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+ }
+ break;
+ case 2: // B
+ if (schemeField.type == org.apache.thrift.protocol.TType.BOOL) {
+ struct.b = iprot.readBool();
+ struct.setBIsSet(true);
+ } else {
+ org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+ }
+ break;
+ case 3: // S
+ if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+ struct.s = iprot.readString();
+ struct.setSIsSet(true);
+ } else {
+ org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+ }
+ break;
+ case 4: // L
+ if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
+ {
+ org.apache.thrift.protocol.TList _list0 = iprot.readListBegin();
+ struct.l = new ArrayList<Integer>(_list0.size);
+ int _elem1;
+ for (int _i2 = 0; _i2 < _list0.size; ++_i2)
+ {
+ _elem1 = iprot.readI32();
+ struct.l.add(_elem1);
+ }
+ iprot.readListEnd();
+ }
+ struct.setLIsSet(true);
+ } else {
+ org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+ }
+ break;
+ default:
+ org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+ }
+ iprot.readFieldEnd();
+ }
+ iprot.readStructEnd();
+
+ // check for required fields of primitive type, which can't be checked in the validate method
+ struct.validate();
+ }
+
+ public void write(org.apache.thrift.protocol.TProtocol oprot, Message struct) throws org.apache.thrift.TException {
+ struct.validate();
+
+ oprot.writeStructBegin(STRUCT_DESC);
+ oprot.writeFieldBegin(I_FIELD_DESC);
+ oprot.writeI32(struct.i);
+ oprot.writeFieldEnd();
+ oprot.writeFieldBegin(B_FIELD_DESC);
+ oprot.writeBool(struct.b);
+ oprot.writeFieldEnd();
+ if (struct.s != null) {
+ oprot.writeFieldBegin(S_FIELD_DESC);
+ oprot.writeString(struct.s);
+ oprot.writeFieldEnd();
+ }
+ if (struct.l != null) {
+ oprot.writeFieldBegin(L_FIELD_DESC);
+ {
+ oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.I32, struct.l.size()));
+ for (int _iter3 : struct.l)
+ {
+ oprot.writeI32(_iter3);
+ }
+ oprot.writeListEnd();
+ }
+ oprot.writeFieldEnd();
+ }
+ oprot.writeFieldStop();
+ oprot.writeStructEnd();
+ }
+
+ }
+
+ private static class MessageTupleSchemeFactory implements SchemeFactory {
+ public MessageTupleScheme getScheme() {
+ return new MessageTupleScheme();
+ }
+ }
+
+ private static class MessageTupleScheme extends TupleScheme<Message> {
+
+ @Override
+ public void write(org.apache.thrift.protocol.TProtocol prot, Message struct) throws org.apache.thrift.TException {
+ TTupleProtocol oprot = (TTupleProtocol) prot;
+ BitSet optionals = new BitSet();
+ if (struct.isSetI()) {
+ optionals.set(0);
+ }
+ if (struct.isSetB()) {
+ optionals.set(1);
+ }
+ if (struct.isSetS()) {
+ optionals.set(2);
+ }
+ if (struct.isSetL()) {
+ optionals.set(3);
+ }
+ oprot.writeBitSet(optionals, 4);
+ if (struct.isSetI()) {
+ oprot.writeI32(struct.i);
+ }
+ if (struct.isSetB()) {
+ oprot.writeBool(struct.b);
+ }
+ if (struct.isSetS()) {
+ oprot.writeString(struct.s);
+ }
+ if (struct.isSetL()) {
+ {
+ oprot.writeI32(struct.l.size());
+ for (int _iter4 : struct.l)
+ {
+ oprot.writeI32(_iter4);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void read(org.apache.thrift.protocol.TProtocol prot, Message struct) throws org.apache.thrift.TException {
+ TTupleProtocol iprot = (TTupleProtocol) prot;
+ BitSet incoming = iprot.readBitSet(4);
+ if (incoming.get(0)) {
+ struct.i = iprot.readI32();
+ struct.setIIsSet(true);
+ }
+ if (incoming.get(1)) {
+ struct.b = iprot.readBool();
+ struct.setBIsSet(true);
+ }
+ if (incoming.get(2)) {
+ struct.s = iprot.readString();
+ struct.setSIsSet(true);
+ }
+ if (incoming.get(3)) {
+ {
+ org.apache.thrift.protocol.TList _list5 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.I32, iprot.readI32());
+ struct.l = new ArrayList<Integer>(_list5.size);
+ int _elem6;
+ for (int _i7 = 0; _i7 < _list5.size; ++_i7)
+ {
+ _elem6 = iprot.readI32();
+ struct.l.add(_elem6);
+ }
+ }
+ struct.setLIsSet(true);
+ }
+ }
+ }
+
+ private static <S extends IScheme> S scheme(org.apache.thrift.protocol.TProtocol proto) {
+ return (StandardScheme.class.equals(proto.getScheme()) ? STANDARD_SCHEME_FACTORY : TUPLE_SCHEME_FACTORY).getScheme();
+ }
+}
+
diff --git a/thrift/src/main/java/io/grpc/thrift/MessageFactory.java b/thrift/src/main/java/io/grpc/thrift/MessageFactory.java
new file mode 100644
index 000000000..13c093570
--- /dev/null
+++ b/thrift/src/main/java/io/grpc/thrift/MessageFactory.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2016, Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package io.grpc.thrift;
+
+import org.apache.thrift.TBase;
+
+/**
+ * Produce new Message Instances. Used by Marshaller to deserialize incoming messages.
+ */
+public interface MessageFactory<T extends TBase<T,?>> {
+ T newInstance();
+}
diff --git a/thrift/src/main/java/io/grpc/thrift/ThriftInputStream.java b/thrift/src/main/java/io/grpc/thrift/ThriftInputStream.java
new file mode 100644
index 000000000..bbf8b54a7
--- /dev/null
+++ b/thrift/src/main/java/io/grpc/thrift/ThriftInputStream.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright 2016, Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package io.grpc.thrift;
+
+import com.google.common.io.ByteStreams;
+
+import io.grpc.Drainable;
+import io.grpc.KnownLength;
+import io.grpc.Status;
+import org.apache.thrift.TBase;
+import org.apache.thrift.TException;
+import org.apache.thrift.TSerializer;
+
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import javax.annotation.Nullable;
+
+/** InputStream for Thrift. */
+final class ThriftInputStream extends InputStream implements Drainable, KnownLength {
+
+ /**
+ * ThriftInput stream is initialized with a *message* , *serializer*
+ * *partial* is initially null.
+ */
+ @Nullable private TBase<?,?> message;
+ @Nullable private ByteArrayInputStream partial;
+ private final TSerializer serializer = new TSerializer();
+
+ /** Initialize message with @param message. */
+ public ThriftInputStream(TBase<?,?> message) {
+ this.message = message;
+ }
+
+ @Override
+ public int drainTo(OutputStream target) throws IOException {
+ int written = 0;
+ if (message != null) {
+ try {
+ byte[] bytes = serializer.serialize(message);
+ written = bytes.length;
+ target.write(bytes);
+ message = null;
+ } catch (TException e) {
+ throw Status.INTERNAL.withDescription("failed to serialize thrift message")
+ .withCause(e).asRuntimeException();
+ }
+ } else if (partial != null) {
+ written = (int) ByteStreams.copy(partial, target);
+ partial = null;
+ } else {
+ written = 0;
+ }
+ return written;
+ }
+
+ @Override
+ public int read() throws IOException {
+ if (message != null) {
+ try {
+ partial = new ByteArrayInputStream(serializer.serialize(message));
+ message = null;
+ } catch (TException e) {
+ throw Status.INTERNAL.withDescription("failed to serialize thrift message")
+ .withCause(e).asRuntimeException();
+ }
+ }
+ if (partial != null) {
+ return partial.read();
+ }
+ return -1;
+ }
+
+ @Override
+ public int available() throws IOException {
+ if (message != null) {
+ try {
+ partial = new ByteArrayInputStream(serializer.serialize(message));
+ message = null;
+ return partial.available();
+ } catch (TException e) {
+ throw Status.INTERNAL.withDescription("failed to serialize thrift message")
+ .withCause(e).asRuntimeException();
+ }
+ } else if (partial != null) {
+ return partial.available();
+ }
+ return 0;
+ }
+
+}
diff --git a/thrift/src/main/java/io/grpc/thrift/ThriftUtils.java b/thrift/src/main/java/io/grpc/thrift/ThriftUtils.java
new file mode 100644
index 000000000..e1a94949e
--- /dev/null
+++ b/thrift/src/main/java/io/grpc/thrift/ThriftUtils.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2016, Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package io.grpc.thrift;
+
+import io.grpc.Metadata;
+import io.grpc.MethodDescriptor.Marshaller;
+import io.grpc.Status;
+import io.grpc.internal.IoUtils;
+import org.apache.thrift.TBase;
+import org.apache.thrift.TDeserializer;
+import org.apache.thrift.TException;
+import org.apache.thrift.TSerializer;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+public final class ThriftUtils {
+
+ /** Create a {@code Marshaller} for thrift messages. */
+ public static <T extends TBase<T,?>> Marshaller<T> marshaller(final MessageFactory<T> factory) {
+
+ return new Marshaller<T>() {
+
+ @Override
+ public InputStream stream(T value) {
+ return new ThriftInputStream(value);
+ }
+
+ @Override
+ public T parse(InputStream stream) {
+ try {
+ byte[] bytes = IoUtils.toByteArray(stream);
+ TDeserializer deserializer = new TDeserializer();
+ T message = factory.newInstance();
+ deserializer.deserialize(message, bytes);
+ return message;
+ } catch (TException e) {
+ throw Status.INTERNAL.withDescription("Invalid Stream")
+ .withCause(e).asRuntimeException();
+ } catch (IOException e) {
+ throw Status.INTERNAL.withDescription("failed to read stream")
+ .withCause(e).asRuntimeException();
+ }
+ }
+ };
+ }
+
+ /** Produce a metadata marshaller. */
+ public static <T extends TBase<T,?>> Metadata.BinaryMarshaller<T> metadataMarshaller(
+ final MessageFactory<T> factory) {
+ return new Metadata.BinaryMarshaller<T>() {
+
+ @Override
+ public byte[] toBytes(T value) {
+ try {
+ TSerializer serializer = new TSerializer();
+ return serializer.serialize(value);
+ } catch (TException e) {
+ throw Status.INTERNAL.withDescription("Error in serializing Thrift Message")
+ .withCause(e).asRuntimeException();
+ }
+ }
+
+ @Override
+ public T parseBytes(byte[] serialized) {
+ try {
+ TDeserializer deserializer = new TDeserializer();
+ T message = factory.newInstance();
+ deserializer.deserialize(message, serialized);
+ return message;
+ } catch (TException e) {
+ throw Status.INTERNAL.withDescription("Invalid thrift Byte Sequence")
+ .withCause(e).asRuntimeException();
+ }
+ }
+ };
+ }
+
+ private ThriftUtils() {
+ }
+
+}
diff --git a/thrift/src/test/java/io/grpc/thrift/ThriftUtilsTest.java b/thrift/src/test/java/io/grpc/thrift/ThriftUtilsTest.java
new file mode 100644
index 000000000..7b992ae4d
--- /dev/null
+++ b/thrift/src/test/java/io/grpc/thrift/ThriftUtilsTest.java
@@ -0,0 +1,183 @@
+/*
+ * Copyright 2016, Google Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above
+ * copyright notice, this list of conditions and the following disclaimer
+ * in the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * * Neither the name of Google Inc. nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package io.grpc.thrift;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotSame;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import io.grpc.Drainable;
+import io.grpc.Metadata;
+import io.grpc.MethodDescriptor.Marshaller;
+import io.grpc.Status;
+import io.grpc.StatusRuntimeException;
+import io.grpc.internal.IoUtils;
+import org.apache.thrift.TException;
+import org.apache.thrift.TSerializer;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collections;
+
+/** Unit tests for {@link ThriftUtils}. */
+@RunWith(JUnit4.class)
+public class ThriftUtilsTest {
+ private Marshaller<Message> marshaller = ThriftUtils.marshaller(new MessageFactory<Message>() {
+ @Override
+ public Message newInstance() {
+ return new Message();
+ }
+ });
+
+ private Metadata.BinaryMarshaller<Message> metadataMarshaller = ThriftUtils.metadataMarshaller(
+ new MessageFactory<Message>() {
+ @Override
+ public Message newInstance() {
+ return new Message();
+ }
+ });
+
+ @Test
+ public void testRoundTrip() {
+ Message m = new Message();
+ m.i = 2;
+ m.b = true;
+ m.s = "string";
+ Message m2 = marshaller.parse(marshaller.stream(m));
+ assertNotSame(m, m2);
+ assertTrue(m.equals( m2 ));
+ }
+
+ @Test
+ public void parseInvalid() throws Exception {
+ InputStream is = new ByteArrayInputStream(new byte[] {-127});
+ try {
+ marshaller.parse(is);
+ fail("Expected exception");
+ } catch (StatusRuntimeException ex) {
+ assertEquals(Status.Code.INTERNAL, ex.getStatus().getCode());
+ assertTrue(ex.getCause() instanceof TException);
+ }
+ }
+
+ @Test
+ public void testLarge() throws Exception {
+ Message m = new Message();
+ // list size 80 MB
+ m.l = new ArrayList<Integer>(Collections.nCopies(20 * 1024 * 1024, 1000000007));
+ Message m2 = marshaller.parse(marshaller.stream(m));
+ assertNotSame(m, m2);
+ assertEquals(m.l.size(), m2.l.size());
+ }
+
+ @Test
+ public void metadataMarshaller_roundtrip() {
+ Message m = new Message();
+ m.i = 2;
+ assertEquals(m, metadataMarshaller.parseBytes(metadataMarshaller.toBytes(m)));
+ }
+
+ @Test
+ public void metadataMarshaller_invalid() {
+ try {
+ metadataMarshaller.parseBytes(new byte[] {-127});
+ fail("Expected exception");
+ } catch (Exception ex) {
+ assertTrue(ex.getCause() instanceof TException);
+ }
+ }
+
+ @Test
+ public void testAvailable() throws Exception {
+ Message m = new Message();
+ m.i = 10;
+ InputStream is = marshaller.stream(m);
+ assertEquals(is.available(), new TSerializer().serialize(m).length);
+ is.read();
+ assertEquals(is.available(), new TSerializer().serialize(m).length - 1);
+ while (is.read() != -1) {}
+ assertEquals(-1, is.read());
+ assertEquals(0, is.available());
+ }
+
+ @Test
+ public void testDrainTo_all() throws Exception {
+ Message m = new Message();
+ byte[] bytes = IoUtils.toByteArray(marshaller.stream(m));
+ InputStream is = marshaller.stream(m);
+ Drainable d = (Drainable) is;
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ int drained = d.drainTo(baos);
+ assertEquals(baos.size(), drained);
+ assertArrayEquals(bytes, baos.toByteArray());
+ assertEquals(0, is.available());
+ }
+
+ @Test
+ public void testDrainTo_partial() throws Exception {
+ Message m = new Message();
+ final byte[] bytes;
+ {
+ InputStream is = marshaller.stream(m);
+ is.read();
+ bytes = IoUtils.toByteArray(is);
+ }
+ InputStream is = marshaller.stream(m);
+ is.read();
+ Drainable d = (Drainable) is;
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ int drained = d.drainTo(baos);
+ assertEquals(baos.size(), drained);
+ assertArrayEquals(bytes, baos.toByteArray());
+ assertEquals(0, is.available());
+ }
+
+ @Test
+ public void testDrainTo_none() throws Exception {
+ Message m = new Message();
+ byte[] bytes = IoUtils.toByteArray(marshaller.stream(m));
+ InputStream is = marshaller.stream(m);
+ byte[] unused = IoUtils.toByteArray(is);
+ Drainable d = (Drainable) is;
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ assertEquals(0, d.drainTo(baos));
+ assertArrayEquals(new byte[0], baos.toByteArray());
+ assertEquals(0, is.available());
+ }
+} \ No newline at end of file
diff --git a/thrift/src/test/thrift/messages.thrift b/thrift/src/test/thrift/messages.thrift
new file mode 100644
index 000000000..0f2f4323d
--- /dev/null
+++ b/thrift/src/test/thrift/messages.thrift
@@ -0,0 +1,37 @@
+// Copyright 2016, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+namespace java io.grpc.thrift
+
+struct Message {
+ 1:i32 i,
+ 2:bool b,
+ 3:string s,
+ 4:list<i32> l
+}