Support Thrift Messages

This commit is contained in:
Naveen Reddy Chedeti 2016-07-28 08:48:27 -07:00 committed by Eric Anderson
parent 563baa4a20
commit 2860959d5f
21 changed files with 3447 additions and 4 deletions

View File

@ -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"
```

View File

@ -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) {

View File

@ -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

View File

@ -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();
}
}

View File

@ -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);
}
}

View File

@ -1 +1,2 @@
rootProject.name = 'examples'
include 'thrift'

View File

@ -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");
}
}

View File

@ -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();
}
}

View File

@ -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();
}
}

View File

@ -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();
}
}
}

View File

@ -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();
}
}
}

View File

@ -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);
}

View File

@ -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'

29
thrift/build.gradle Normal file
View File

@ -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");
}
}

View File

@ -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();
}
}

View File

@ -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();
}

View File

@ -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;
}
}

View File

@ -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() {
}
}

View File

@ -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());
}
}

View File

@ -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
}