libthrift-java_0.9.0/0000755000175000017500000000000012075130200015262 5ustar eevanseevans00000000000000libthrift-java_0.9.0/README0000644000175000017500000000310312035665435016162 0ustar eevanseevans00000000000000Thrift Java Software Library License ======= Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Using Thrift with Java ====================== The Thrift Java source is not build using the GNU tools, but rather uses the Apache Ant build system, which tends to be predominant amongst Java developers. To compile the Java Thrift libraries, simply do the following: ant Yep, that's easy. Look for libthrift.jar in the base directory. To include Thrift in your applications simply add libthrift.jar to your classpath, or install if in your default system classpath of choice. Build Thrift behind a proxy: ant -Dproxy.enabled=1 -Dproxy.host=myproxyhost -Dproxy.user=thriftuser -Dproxy.pass=topsecret or via ./configure --with-java ANT_FLAGS='-Dproxy.enabled=1 -Dproxy.host=myproxyhost -Dproxy.user=thriftuser -Dproxy.pass=topsecret' Dependencies ============ Apache Ant http://ant.apache.org/ libthrift-java_0.9.0/build.properties0000644000175000017500000000135612035665435020527 0ustar eevanseevans00000000000000thrift.version=0.9.0 thrift.groupid=org.apache.thrift release=true # Jar Versions mvn.ant.task.version=2.1.3 # Local Install paths install.path=/usr/local/lib install.javadoc.path=${install.path} # Maven dependency download locations mvn.repo=http://repo1.maven.org/maven2 apache.repo=https://repository.apache.org/content/repositories/releases mvn.ant.task.url=${mvn.repo}/org/apache/maven/maven-ant-tasks/${mvn.ant.task.version} mvn.ant.task.jar=maven-ant-tasks-${mvn.ant.task.version}.jar # Apache Maven publish license=http://www.apache.org/licenses/LICENSE-2.0.txt maven-repository-url=https://repository.apache.org/service/local/staging/deploy/maven2 maven-repository-id=apache.releases.https # Jar Versions mvn.ant.task.version=2.1.3 libthrift-java_0.9.0/LICENSE0000644000175000017500000003767312075130200016307 0ustar eevanseevans00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. -------------------------------------------------- SOFTWARE DISTRIBUTED WITH THRIFT: The Apache Thrift software includes a number of subcomponents with separate copyright notices and license terms. Your use of the source code for the these subcomponents is subject to the terms and conditions of the following licenses. -------------------------------------------------- Portions of the following files are licensed under the MIT License: lib/erl/src/Makefile.am Please see doc/otp-base-license.txt for the full terms of this license. -------------------------------------------------- The following files contain some portions of code contributed under the Thrift Software License (see doc/old-thrift-license.txt), and relicensed under the Apache 2.0 License: compiler/cpp/Makefile.am compiler/cpp/src/thrift/generate/t_cocoa_generator.cc compiler/cpp/src/thrift/generate/t_cpp_generator.cc compiler/cpp/src/thrift/generate/t_csharp_generator.cc compiler/cpp/src/thrift/generate/t_erl_generator.cc compiler/cpp/src/thrift/generate/t_hs_generator.cc compiler/cpp/src/thrift/generate/t_java_generator.cc compiler/cpp/src/thrift/generate/t_ocaml_generator.cc compiler/cpp/src/thrift/generate/t_perl_generator.cc compiler/cpp/src/thrift/generate/t_php_generator.cc compiler/cpp/src/thrift/generate/t_py_generator.cc compiler/cpp/src/thrift/generate/t_rb_generator.cc compiler/cpp/src/thrift/generate/t_st_generator.cc compiler/cpp/src/thrift/generate/t_xsd_generator.cc compiler/cpp/src/thrift/main.cc compiler/cpp/src/thrift/parse/t_field.h compiler/cpp/src/thrift/parse/t_program.h compiler/cpp/src/thrift/platform.h compiler/cpp/src/thrift/thriftl.ll compiler/cpp/src/thrift/thrifty.yy lib/csharp/src/Protocol/TBinaryProtocol.cs lib/csharp/src/Protocol/TField.cs lib/csharp/src/Protocol/TList.cs lib/csharp/src/Protocol/TMap.cs lib/csharp/src/Protocol/TMessage.cs lib/csharp/src/Protocol/TMessageType.cs lib/csharp/src/Protocol/TProtocol.cs lib/csharp/src/Protocol/TProtocolException.cs lib/csharp/src/Protocol/TProtocolFactory.cs lib/csharp/src/Protocol/TProtocolUtil.cs lib/csharp/src/Protocol/TSet.cs lib/csharp/src/Protocol/TStruct.cs lib/csharp/src/Protocol/TType.cs lib/csharp/src/Server/TServer.cs lib/csharp/src/Server/TSimpleServer.cs lib/csharp/src/Server/TThreadPoolServer.cs lib/csharp/src/TApplicationException.cs lib/csharp/src/Thrift.csproj lib/csharp/src/Thrift.sln lib/csharp/src/TProcessor.cs lib/csharp/src/Transport/TServerSocket.cs lib/csharp/src/Transport/TServerTransport.cs lib/csharp/src/Transport/TSocket.cs lib/csharp/src/Transport/TStreamTransport.cs lib/csharp/src/Transport/TTransport.cs lib/csharp/src/Transport/TTransportException.cs lib/csharp/src/Transport/TTransportFactory.cs lib/csharp/ThriftMSBuildTask/Properties/AssemblyInfo.cs lib/csharp/ThriftMSBuildTask/ThriftBuild.cs lib/csharp/ThriftMSBuildTask/ThriftMSBuildTask.csproj lib/rb/lib/thrift.rb lib/st/README lib/st/thrift.st test/OptionalRequiredTest.cpp test/OptionalRequiredTest.thrift test/ThriftTest.thrift -------------------------------------------------- For the aclocal/ax_boost_base.m4 and contrib/fb303/aclocal/ax_boost_base.m4 components: # Copyright (c) 2007 Thomas Porschberg # # Copying and distribution of this file, with or without # modification, are permitted in any medium without royalty provided # the copyright notice and this notice are preserved. -------------------------------------------------- For the compiler/cpp/src/thrift/md5.[ch] components: /* Copyright (C) 1999, 2000, 2002 Aladdin Enterprises. All rights reserved. This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software. Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions: 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. L. Peter Deutsch ghost@aladdin.com */ --------------------------------------------------- For the lib/rb/setup.rb: Copyright (c) 2000-2005 Minero Aoki, lib/ocaml/OCamlMakefile and lib/ocaml/README-OCamlMakefile components: Copyright (C) 1999 - 2007 Markus Mottl Licensed under the terms of the GNU Lesser General Public License 2.1 (see doc/lgpl-2.1.txt for the full terms of this license) libthrift-java_0.9.0/CONTRIBUTORS0000644000175000017500000000353512075130200017150 0ustar eevanseevans00000000000000Chad Walters -TJSONProtocol for C++ and Java Nitay -Support for "make check" William Morgan -Miscellaneous Ruby improvements Ben Maurer -Restructuring the way Autoconf is used Patrick Collison -Smalltalk bindings Dave Simpson -Better support for connection tracking in the C++ server -Miscellaneous fixes Igor Afanasyev -Perl HttpClient and bugfixes Todd Berman -MinGW port of the compiler -C# bindings -MS build task ---------------- Release 20070917 ---------------- Dave Engberg -JavaBean/JavaDoc enhancements Andrew McGeachie -Cocoa/Objective-C support Ben Maurer -Python performance enhancements, fastbinary support Andrew Lutomirski -Added optional/required keywords for C++ objects -Added comparison operators for C++ structs Johan Oskarsson -Java findbugs compliance fixes Paul Saab -IPv6 support for TSocket in C++/Python Kevin Clark -Significant overhaul of Ruby code generation and servers Simon Forman -TProcessorFactory abstraction for Java servers Jake Luciani -Perl code generation, libraries, test code David Reiss -strings.h include fix for bzero -endianness fixes on TBinaryProtocol double serialization -improved ntohll,htonll implementation Dan Li -Java TestServer and Tutorial Fixes Kevin Ko -Fix for unnecessary std::string copy construction in Protocol/Exception Paul Querna -Autoconf error message fix for libevent detection -clock_gettime implementation for OSX ---------------- Release 20070401 ---------------- libthrift-java_0.9.0/test/0000755000175000017500000000000012035665714016264 5ustar eevanseevans00000000000000libthrift-java_0.9.0/test/.keystore0000644000175000017500000000260612035665434020135 0ustar eevanseevans00000000000000thrift+t00 +*cww4)>r }7p/AX8 ,@ Ugc*ZEا n\å{WL8sjٞxa" {d^  EY ͭwxTzlNM-Q]F0*.a~W]$1,+sR.&\ڊDe~e0![TJK~¥!6K'Kwc&6hYpR}h)ˋ,HC q"sR5;,I]| b;]NSdexpu{o/0}B:YsTփF.ĸA阁`cy,ӯY tD5$Pʏ{!lcZFK[S(D [><#dr^gM(ԸhkL9lj|!$ޚMurfI68gNL]/#Qޠgc4ʥ[g=nYԎ)dwD=FI+ȫրu 1 ?-a|DU;Y6\0  *H 010UUnknown10UUnknown10UUnknown1#0!U Apache Software Foundation10U  Apache Thrift10 UThrift0 101008155457Z 240616155457Z010UUnknown10UUnknown10UUnknown1#0!U Apache Software Foundation10U  Apache Thrift10 UThrift00  *H 0KĖG6\j k8XXR93^vBW]r кJ~WkWjXvZ$Ǥ8"YWxg彠Ǧq5RH9i&Ii>0-0  *H  +B80x@Al-D[{ҒQuֻ2NS.X\moZ:>L ^ݒX;$/ $ U1 a = new HashSet(); Set b = new HashSet(); assertTrue(TBaseHelper.compareTo(a, b) == 0); a.add("test"); assertTrue(TBaseHelper.compareTo(a, b) > 0); b.add("test"); assertTrue(TBaseHelper.compareTo(a, b) == 0); b.add("aardvark"); assertTrue(TBaseHelper.compareTo(a, b) < 0); a.add("test2"); assertTrue(TBaseHelper.compareTo(a, b) > 0); } public void testNestedStructures() { Set> a = new HashSet>(); Set> b = new HashSet>(); a.add(Arrays.asList(new String[] {"a","b"})); b.add(Arrays.asList(new String[] {"a","b", "c"})); a.add(Arrays.asList(new String[] {"a","b"})); b.add(Arrays.asList(new String[] {"a","b", "c"})); assertTrue(TBaseHelper.compareTo(a, b) < 0); } public void testMapsInSets() { Set> a = new HashSet>(); Set> b = new HashSet>(); assertTrue(TBaseHelper.compareTo(a, b) == 0); Map innerA = new HashMap(); Map innerB = new HashMap(); a.add(innerA); b.add(innerB); innerA.put("a", 1l); innerB.put("a", 2l); assertTrue(TBaseHelper.compareTo(a, b) < 0); } public void testByteArraysInMaps() { Map a = new HashMap(); Map b = new HashMap(); assertTrue(TBaseHelper.compareTo(a, b) == 0); a.put(new byte[]{'a','b'}, 1000L); b.put(new byte[]{'a','b'}, 1000L); a.put(new byte[]{'a','b', 'd'}, 1000L); b.put(new byte[]{'a','b', 'a'}, 1000L); assertTrue(TBaseHelper.compareTo(a, b) > 0); } public void testMapsWithNulls() { Map a = new HashMap(); Map b = new HashMap(); a.put("a", null); a.put("b", null); b.put("a", null); b.put("b", null); assertTrue(TBaseHelper.compareTo(a, b) == 0); } public void testMapKeyComparison() { Map a = new HashMap(); Map b = new HashMap(); a.put("a", "a"); b.put("b", "a"); assertTrue(TBaseHelper.compareTo(a, b) < 0); } public void testMapValueComparison() { Map a = new HashMap(); Map b = new HashMap(); a.put("a", "b"); b.put("a", "a"); assertTrue(TBaseHelper.compareTo(a, b) > 0); } public void testByteArraysInSets() { Set a = new HashSet(); Set b = new HashSet(); if (TBaseHelper.compareTo(a, b) != 0) throw new RuntimeException("Set compare failed:" + a + " vs. " + b); a.add(new byte[]{'a','b'}); b.add(new byte[]{'a','b'}); a.add(new byte[]{'a','b', 'd'}); b.add(new byte[]{'a','b', 'a'}); assertTrue(TBaseHelper.compareTo(a, b) > 0); } public void testByteBufferToByteArray() throws Exception { byte[] b1 = {10,9,8,7,6,5,4,3,2,1,0}; byte[] b2 = TBaseHelper.byteBufferToByteArray(ByteBuffer.wrap(b1)); assertEquals("b1 and b2 should be the exact same array (identity) due to fast path", b1, b2); byte[] b3 = TBaseHelper.byteBufferToByteArray(ByteBuffer.wrap(b1, 1, 3)); assertEquals(3, b3.length); assertEquals(ByteBuffer.wrap(b1, 1, 3), ByteBuffer.wrap(b3)); } public void testRightSize() throws Exception { assertNull(TBaseHelper.rightSize(null)); } public void testByteBufferToString() { byte[] array = new byte[]{1, 2, 3}; ByteBuffer bb = ByteBuffer.wrap(array, 1, 2); StringBuilder sb = new StringBuilder(); TBaseHelper.toString(bb, sb); assertEquals("02 03", sb.toString()); bb = ByteBuffer.wrap(array, 0, array.length); bb.position(1); bb = bb.slice(); assertEquals(1, bb.arrayOffset()); assertEquals(0, bb.position()); assertEquals(2, bb.limit()); sb = new StringBuilder(); TBaseHelper.toString(bb, sb); assertEquals("02 03", sb.toString()); } public void testCopyBinaryWithByteBuffer() throws Exception { byte[] bytes = new byte[]{0, 1, 2, 3, 4, 5}; ByteBuffer b = ByteBuffer.wrap(bytes); ByteBuffer bCopy = TBaseHelper.copyBinary(b); assertEquals(b, bCopy); assertEquals(0, b.position()); b = ByteBuffer.allocateDirect(6); b.put(bytes); b.position(0); bCopy = TBaseHelper.copyBinary(b); assertEquals(6, b.remaining()); assertEquals(0, b.position()); assertEquals(b, bCopy); b.mark(); b.get(); bCopy = TBaseHelper.copyBinary(b); assertEquals(ByteBuffer.wrap(bytes, 1, 5), bCopy); assertEquals(1, b.position()); b.reset(); assertEquals(0, b.position()); assertNull(TBaseHelper.copyBinary((ByteBuffer)null)); } public void testCopyBinaryWithByteArray() throws Exception { byte[] bytes = new byte[]{0, 1, 2, 3, 4, 5}; byte[] copy = TBaseHelper.copyBinary(bytes); assertEquals(ByteBuffer.wrap(bytes), ByteBuffer.wrap(copy)); assertNotSame(bytes, copy); assertNull(TBaseHelper.copyBinary((byte[])null)); } } libthrift-java_0.9.0/test/org/apache/thrift/TestTEnumHelper.java0000644000175000017500000000253712035665434025475 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; import thrift.test.Numberz; import junit.framework.TestCase; public class TestTEnumHelper extends TestCase { public void testGetByValue_ValidValues() { for (Numberz n: Numberz.values()) { int value = n.getValue(); assertEquals(n, TEnumHelper.getByValue(Numberz.class, value)); } } public void testGetByValue_InvalidValue() { assertEquals(null, TEnumHelper.getByValue(Numberz.class, 0)); } public void testGetByValue_InvalidClass() { assertEquals(null, TEnumHelper.getByValue(TEnum.class, 0)); } } libthrift-java_0.9.0/test/org/apache/thrift/TestStruct.java0000644000175000017500000003443212035665434024570 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.nio.ByteBuffer; import java.util.HashMap; import java.util.Map; import junit.framework.TestCase; import org.apache.thrift.meta_data.FieldMetaData; import org.apache.thrift.meta_data.ListMetaData; import org.apache.thrift.meta_data.MapMetaData; import org.apache.thrift.meta_data.SetMetaData; import org.apache.thrift.meta_data.StructMetaData; import org.apache.thrift.protocol.TBinaryProtocol; import org.apache.thrift.protocol.TType; import thrift.test.Bonk; import thrift.test.CrazyNesting; import thrift.test.HolyMoley; import thrift.test.Insanity; import thrift.test.JavaTestHelper; import thrift.test.Nesting; import thrift.test.Numberz; import thrift.test.OneOfEach; import thrift.test.StructA; import thrift.test.StructB; import thrift.test.Xtruct; public class TestStruct extends TestCase { public void testIdentity() throws Exception { TSerializer binarySerializer = new TSerializer(new TBinaryProtocol.Factory()); TDeserializer binaryDeserializer = new TDeserializer(new TBinaryProtocol.Factory()); OneOfEach ooe = Fixtures.oneOfEach; Nesting n = new Nesting(); n.my_ooe = ooe; n.my_ooe.integer16 = 16; n.my_ooe.integer32 = 32; n.my_ooe.integer64 = 64; n.my_ooe.double_precision = (Math.sqrt(5)+1)/2; n.my_ooe.some_characters = ":R (me going \"rrrr\")"; n.my_ooe.zomg_unicode = "\u04c0\u216e\u039d\u0020\u041d\u03bf\u217f"+ "\u043e\u0261\u0433\u0430\u03c1\u210e\u0020"+ "\u0391\u0074\u0074\u03b1\u217d\u03ba\u01c3"+ "\u203c"; n.my_bonk = Fixtures.nesting.my_bonk; HolyMoley hm = Fixtures.holyMoley; OneOfEach ooe2 = new OneOfEach(); binaryDeserializer.deserialize( ooe2, binarySerializer.serialize(ooe)); assertEquals(ooe, ooe2); assertEquals(ooe.hashCode(), ooe2.hashCode()); Nesting n2 = new Nesting(); binaryDeserializer.deserialize( n2, binarySerializer.serialize(n)); assertEquals(n, n2); assertEquals(n.hashCode(), n2.hashCode()); HolyMoley hm2 = new HolyMoley(); binaryDeserializer.deserialize( hm2, binarySerializer.serialize(hm)); assertEquals(hm, hm2); assertEquals(hm.hashCode(), hm2.hashCode()); } public void testDeepCopy() throws Exception { TSerializer binarySerializer = new TSerializer(new TBinaryProtocol.Factory()); TDeserializer binaryDeserializer = new TDeserializer(new TBinaryProtocol.Factory()); HolyMoley hm = Fixtures.holyMoley; byte[] binaryCopy = binarySerializer.serialize(hm); HolyMoley hmCopy = new HolyMoley(); binaryDeserializer.deserialize(hmCopy, binaryCopy); HolyMoley hmCopy2 = new HolyMoley(hm); assertEquals(hm, hmCopy); assertEquals(hmCopy, hmCopy2); // change binary value in original object hm.big.get(0).base64.array()[0]++; // make sure the change didn't propagate to the copied object assertFalse(hm.equals(hmCopy2)); hm.big.get(0).base64.array()[0]--; // undo change hmCopy2.bonks.get("two").get(1).message = "What else?"; assertFalse(hm.equals(hmCopy2)); } public void testCompareTo() throws Exception { Bonk bonk1 = new Bonk(); Bonk bonk2 = new Bonk(); // Compare empty thrift objects. assertEquals(0, bonk1.compareTo(bonk2)); bonk1.setMessage("m"); // Compare one thrift object with a filled in field and another without it. assertTrue(bonk1.compareTo(bonk2) > 0); assertTrue(bonk2.compareTo(bonk1) < 0); // Compare both have filled-in fields. bonk2.setMessage("z"); assertTrue(bonk1.compareTo(bonk2) < 0); assertTrue(bonk2.compareTo(bonk1) > 0); // Compare bonk1 has a field filled in that bonk2 doesn't. bonk1.setType(123); assertTrue(bonk1.compareTo(bonk2) > 0); assertTrue(bonk2.compareTo(bonk1) < 0); // Compare bonk1 and bonk2 equal. bonk2.setType(123); bonk2.setMessage("m"); assertEquals(0, bonk1.compareTo(bonk2)); } public void testCompareToWithDataStructures() { Insanity insanity1 = new Insanity(); Insanity insanity2 = new Insanity(); // Both empty. expectEquals(insanity1, insanity2); insanity1.setUserMap(new HashMap()); // insanity1.map = {}, insanity2.map = null expectGreaterThan(insanity1, insanity2); // insanity1.map = {2:1}, insanity2.map = null insanity1.getUserMap().put(Numberz.TWO, 1l); expectGreaterThan(insanity1, insanity2); // insanity1.map = {2:1}, insanity2.map = {} insanity2.setUserMap(new HashMap()); expectGreaterThan(insanity1, insanity2); // insanity1.map = {2:1}, insanity2.map = {2:2} insanity2.getUserMap().put(Numberz.TWO, 2l); expectLessThan(insanity1, insanity2); // insanity1.map = {2:1, 3:5}, insanity2.map = {2:2} insanity1.getUserMap().put(Numberz.THREE, 5l); expectGreaterThan(insanity1, insanity2); // insanity1.map = {2:1, 3:5}, insanity2.map = {2:1, 4:5} insanity2.getUserMap().put(Numberz.TWO, 1l); insanity2.getUserMap().put(Numberz.FIVE, 5l); expectLessThan(insanity1, insanity2); } private void expectLessThan(Insanity insanity1, Insanity insanity2) { int compareTo = insanity1.compareTo(insanity2); assertTrue(insanity1 + " should be less than " + insanity2 + ", but is: " + compareTo, compareTo < 0); } private void expectGreaterThan(Insanity insanity1, Insanity insanity2) { int compareTo = insanity1.compareTo(insanity2); assertTrue(insanity1 + " should be greater than " + insanity2 + ", but is: " + compareTo, compareTo > 0); } private void expectEquals(Insanity insanity1, Insanity insanity2) { int compareTo = insanity1.compareTo(insanity2); assertEquals(insanity1 + " should be equal to " + insanity2 + ", but is: " + compareTo, 0, compareTo); } public void testMetaData() throws Exception { Map mdMap = CrazyNesting.metaDataMap; // Check for struct fields existence assertEquals(4, mdMap.size()); assertTrue(mdMap.containsKey(CrazyNesting._Fields.SET_FIELD)); assertTrue(mdMap.containsKey(CrazyNesting._Fields.LIST_FIELD)); assertTrue(mdMap.containsKey(CrazyNesting._Fields.STRING_FIELD)); assertTrue(mdMap.containsKey(CrazyNesting._Fields.BINARY_FIELD)); // Check for struct fields contents assertEquals("string_field", mdMap.get(CrazyNesting._Fields.STRING_FIELD).fieldName); assertEquals("list_field", mdMap.get(CrazyNesting._Fields.LIST_FIELD).fieldName); assertEquals("set_field", mdMap.get(CrazyNesting._Fields.SET_FIELD).fieldName); assertEquals("binary_field", mdMap.get(CrazyNesting._Fields.BINARY_FIELD).fieldName); assertEquals(TFieldRequirementType.DEFAULT, mdMap.get(CrazyNesting._Fields.STRING_FIELD).requirementType); assertEquals(TFieldRequirementType.REQUIRED, mdMap.get(CrazyNesting._Fields.LIST_FIELD).requirementType); assertEquals(TFieldRequirementType.OPTIONAL, mdMap.get(CrazyNesting._Fields.SET_FIELD).requirementType); assertEquals(TType.STRING, mdMap.get(CrazyNesting._Fields.STRING_FIELD).valueMetaData.type); assertFalse(mdMap.get(CrazyNesting._Fields.STRING_FIELD).valueMetaData.isBinary()); assertEquals(TType.LIST, mdMap.get(CrazyNesting._Fields.LIST_FIELD).valueMetaData.type); assertEquals(TType.SET, mdMap.get(CrazyNesting._Fields.SET_FIELD).valueMetaData.type); assertEquals(TType.STRING, mdMap.get(CrazyNesting._Fields.BINARY_FIELD).valueMetaData.type); assertTrue(mdMap.get(CrazyNesting._Fields.BINARY_FIELD).valueMetaData.isBinary()); // Check nested structures assertTrue(mdMap.get(CrazyNesting._Fields.LIST_FIELD).valueMetaData.isContainer()); assertFalse(mdMap.get(CrazyNesting._Fields.LIST_FIELD).valueMetaData.isStruct()); assertEquals(TType.STRUCT, ((MapMetaData)((ListMetaData)((SetMetaData)((MapMetaData)((MapMetaData)((ListMetaData)mdMap.get(CrazyNesting._Fields.LIST_FIELD).valueMetaData).elemMetaData).valueMetaData).valueMetaData).elemMetaData).elemMetaData).keyMetaData.type); assertEquals(Insanity.class, ((StructMetaData)((MapMetaData)((ListMetaData)((SetMetaData)((MapMetaData)((MapMetaData)((ListMetaData)mdMap.get(CrazyNesting._Fields.LIST_FIELD).valueMetaData).elemMetaData).valueMetaData).valueMetaData).elemMetaData).elemMetaData).keyMetaData).structClass); // Check that FieldMetaData contains a map with metadata for all generated struct classes assertNotNull(FieldMetaData.getStructMetaDataMap(CrazyNesting.class)); assertNotNull(FieldMetaData.getStructMetaDataMap(Insanity.class)); assertNotNull(FieldMetaData.getStructMetaDataMap(Xtruct.class)); assertEquals(CrazyNesting.metaDataMap, FieldMetaData.getStructMetaDataMap(CrazyNesting.class)); assertEquals(Insanity.metaDataMap, FieldMetaData.getStructMetaDataMap(Insanity.class)); for (Map.Entry mdEntry : mdMap.entrySet()) { assertEquals(mdEntry.getKey(), CrazyNesting._Fields.findByName(mdEntry.getValue().fieldName)); } MapMetaData vmd = (MapMetaData)Insanity.metaDataMap.get(Insanity._Fields.USER_MAP).valueMetaData; assertTrue(vmd.valueMetaData.isTypedef()); assertFalse(vmd.keyMetaData.isTypedef()); } public void testToString() throws Exception { JavaTestHelper object = new JavaTestHelper(); object.req_int = 0; object.req_obj = ""; object.req_bin = ByteBuffer.wrap(new byte[] { 0, -1, 2, -3, 4, -5, 6, -7, 8, -9, 10, -11, 12, -13, 14, -15, 16, -17, 18, -19, 20, -21, 22, -23, 24, -25, 26, -27, 28, -29, 30, -31, 32, -33, 34, -35, 36, -37, 38, -39, 40, -41, 42, -43, 44, -45, 46, -47, 48, -49, 50, -51, 52, -53, 54, -55, 56, -57, 58, -59, 60, -61, 62, -63, 64, -65, 66, -67, 68, -69, 70, -71, 72, -73, 74, -75, 76, -77, 78, -79, 80, -81, 82, -83, 84, -85, 86, -87, 88, -89, 90, -91, 92, -93, 94, -95, 96, -97, 98, -99, 100, -101, 102, -103, 104, -105, 106, -107, 108, -109, 110, -111, 112, -113, 114, -115, 116, -117, 118, -119, 120, -121, 122, -123, 124, -125, 126, -127, }); assertEquals("JavaTestHelper(req_int:0, req_obj:, req_bin:"+ "00 FF 02 FD 04 FB 06 F9 08 F7 0A F5 0C F3 0E F1 10 EF 12 ED 14 "+ "EB 16 E9 18 E7 1A E5 1C E3 1E E1 20 DF 22 DD 24 DB 26 D9 28 D7 "+ "2A D5 2C D3 2E D1 30 CF 32 CD 34 CB 36 C9 38 C7 3A C5 3C C3 3E "+ "C1 40 BF 42 BD 44 BB 46 B9 48 B7 4A B5 4C B3 4E B1 50 AF 52 AD "+ "54 AB 56 A9 58 A7 5A A5 5C A3 5E A1 60 9F 62 9D 64 9B 66 99 68 "+ "97 6A 95 6C 93 6E 91 70 8F 72 8D 74 8B 76 89 78 87 7A 85 7C 83 "+ "7E 81)", object.toString()); object.req_bin = ByteBuffer.wrap(new byte[] { 0, -1, 2, -3, 4, -5, 6, -7, 8, -9, 10, -11, 12, -13, 14, -15, 16, -17, 18, -19, 20, -21, 22, -23, 24, -25, 26, -27, 28, -29, 30, -31, 32, -33, 34, -35, 36, -37, 38, -39, 40, -41, 42, -43, 44, -45, 46, -47, 48, -49, 50, -51, 52, -53, 54, -55, 56, -57, 58, -59, 60, -61, 62, -63, 64, -65, 66, -67, 68, -69, 70, -71, 72, -73, 74, -75, 76, -77, 78, -79, 80, -81, 82, -83, 84, -85, 86, -87, 88, -89, 90, -91, 92, -93, 94, -95, 96, -97, 98, -99, 100, -101, 102, -103, 104, -105, 106, -107, 108, -109, 110, -111, 112, -113, 114, -115, 116, -117, 118, -119, 120, -121, 122, -123, 124, -125, 126, -127, 0, }); assertEquals("JavaTestHelper(req_int:0, req_obj:, req_bin:"+ "00 FF 02 FD 04 FB 06 F9 08 F7 0A F5 0C F3 0E F1 10 EF 12 ED 14 "+ "EB 16 E9 18 E7 1A E5 1C E3 1E E1 20 DF 22 DD 24 DB 26 D9 28 D7 "+ "2A D5 2C D3 2E D1 30 CF 32 CD 34 CB 36 C9 38 C7 3A C5 3C C3 3E "+ "C1 40 BF 42 BD 44 BB 46 B9 48 B7 4A B5 4C B3 4E B1 50 AF 52 AD "+ "54 AB 56 A9 58 A7 5A A5 5C A3 5E A1 60 9F 62 9D 64 9B 66 99 68 "+ "97 6A 95 6C 93 6E 91 70 8F 72 8D 74 8B 76 89 78 87 7A 85 7C 83 "+ "7E 81...)", object.toString()); object.req_bin = ByteBuffer.wrap(new byte[] {}); object.setOpt_binIsSet(true); assertEquals("JavaTestHelper(req_int:0, req_obj:, req_bin:)", object.toString()); } public void testBytesBufferFeatures() throws Exception { JavaTestHelper o = new JavaTestHelper(); o.setReq_bin((ByteBuffer)null); assertNull(o.getReq_bin()); o.setReq_bin((byte[])null); assertNull(o.getReq_bin()); } public void testJavaSerializable() throws Exception { ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(baos); OneOfEach ooe = Fixtures.oneOfEach; // Serialize ooe the Java way... oos.writeObject(ooe); byte[] serialized = baos.toByteArray(); // Attempt to deserialize it ByteArrayInputStream bais = new ByteArrayInputStream(serialized); ObjectInputStream ois = new ObjectInputStream(bais); OneOfEach ooe2 = (OneOfEach) ois.readObject(); assertEquals(ooe, ooe2); } public void testSubStructValidation() throws Exception { StructA valid = new StructA("valid"); StructA invalid = new StructA(); StructB b = new StructB(); try { b.validate(); fail(); } catch (TException e) { // expected } b = new StructB().setAb(valid); b.validate(); b = new StructB().setAb(invalid); try { b.validate(); fail(); } catch (TException e) { // expected } b = new StructB().setAb(valid).setAa(invalid); try { b.validate(); fail(); } catch (TException e) { // expected } } } libthrift-java_0.9.0/test/org/apache/thrift/TestOptionals.java0000644000175000017500000000566112035665434025256 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; import junit.framework.TestCase; import thrift.test.Opt4; import thrift.test.Opt30; import thrift.test.Opt64; import thrift.test.Opt80; // Exercises the isSet methods using structs from from ManyOptionals.thrift public class TestOptionals extends TestCase { public void testEncodingUtils() throws Exception { assertEquals((short)0x8, EncodingUtils.setBit((short)0, 3, true)); assertEquals((short)0, EncodingUtils.setBit((short)0x8, 3, false)); assertEquals(true, EncodingUtils.testBit((short)0x8, 3)); assertEquals(false, EncodingUtils.testBit((short)0x8, 4)); assertEquals((short)Short.MIN_VALUE, EncodingUtils.setBit((short)0, 15, true)); assertEquals((short)0, EncodingUtils.setBit((short)Short.MIN_VALUE, 15, false)); assertEquals(true, EncodingUtils.testBit(Short.MIN_VALUE, 15)); assertEquals(false, EncodingUtils.testBit(Short.MIN_VALUE, 14)); } public void testOpt4() throws Exception { Opt4 x = new Opt4(); assertEquals(false, x.isSetDef1()); x.setDef1(3); assertEquals(true, x.isSetDef1()); assertEquals(false, x.isSetDef2()); Opt4 copy = new Opt4(x); assertEquals(true, copy.isSetDef1()); copy.unsetDef1(); assertEquals(false, copy.isSetDef1()); assertEquals(true, x.isSetDef1()); } public void testOpt30() throws Exception { Opt30 x = new Opt30(); assertEquals(false, x.isSetDef1()); x.setDef1(3); assertEquals(true, x.isSetDef1()); assertEquals(false, x.isSetDef2()); } public void testOpt64() throws Exception { Opt64 x = new Opt64(); assertEquals(false, x.isSetDef1()); x.setDef1(3); assertEquals(true, x.isSetDef1()); assertEquals(false, x.isSetDef2()); x.setDef64(22); assertEquals(true, x.isSetDef64()); assertEquals(false, x.isSetDef63()); } public void testOpt80() throws Exception { Opt80 x = new Opt80(); assertEquals(false, x.isSetDef1()); x.setDef1(3); assertEquals(true, x.isSetDef1()); assertEquals(false, x.isSetDef2()); Opt80 copy = new Opt80(x); copy.unsetDef1(); assertEquals(false, copy.isSetDef1()); assertEquals(true, x.isSetDef1()); } } libthrift-java_0.9.0/test/org/apache/thrift/test/0000755000175000017500000000000012035665714022553 5ustar eevanseevans00000000000000libthrift-java_0.9.0/test/org/apache/thrift/test/TestServer.java0000644000175000017500000001122312035665434025522 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.test; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.thrift.protocol.TBinaryProtocol; import org.apache.thrift.protocol.TProtocol; import org.apache.thrift.protocol.TProtocolFactory; import org.apache.thrift.server.ServerContext; import org.apache.thrift.server.TServer; import org.apache.thrift.server.TServer.Args; import org.apache.thrift.server.TSimpleServer; import org.apache.thrift.server.TThreadPoolServer; import org.apache.thrift.transport.TServerSocket; import org.apache.thrift.server.ServerTestBase.TestHandler; import org.apache.thrift.server.TServerEventHandler; import org.apache.thrift.transport.TTransport; import thrift.test.Insanity; import thrift.test.Numberz; import thrift.test.ThriftTest; import thrift.test.Xception; import thrift.test.Xception2; import thrift.test.Xtruct; import thrift.test.Xtruct2; public class TestServer { static class TestServerContext implements ServerContext { int connectionId; public TestServerContext(int connectionId) { this.connectionId = connectionId; } public int getConnectionId() { return connectionId; } public void setConnectionId(int connectionId) { this.connectionId = connectionId; } } static class TestServerEventHandler implements TServerEventHandler { private int nextConnectionId = 1; public void preServe() { System.out.println("TServerEventHandler.preServe - called only once before server starts accepting connections"); } public ServerContext createContext(TProtocol input, TProtocol output) { //we can create some connection level data which is stored while connection is alive & served TestServerContext ctx = new TestServerContext(nextConnectionId++); System.out.println("TServerEventHandler.createContext - connection #"+ctx.getConnectionId()+" established"); return ctx; } public void deleteContext(ServerContext serverContext, TProtocol input, TProtocol output) { TestServerContext ctx = (TestServerContext)serverContext; System.out.println("TServerEventHandler.deleteContext - connection #"+ctx.getConnectionId()+" terminated"); } public void processContext(ServerContext serverContext, TTransport inputTransport, TTransport outputTransport) { TestServerContext ctx = (TestServerContext)serverContext; System.out.println("TServerEventHandler.processContext - connection #"+ctx.getConnectionId()+" is ready to process next request"); } } public static void main(String [] args) { try { int port = 9090; if (args.length > 1) { port = Integer.valueOf(args[0]); } //@TODO add other protocol and transport types // Processor TestHandler testHandler = new TestHandler(); ThriftTest.Processor testProcessor = new ThriftTest.Processor(testHandler); // Transport TServerSocket tServerSocket = new TServerSocket(port); // Protocol factory TProtocolFactory tProtocolFactory = new TBinaryProtocol.Factory(); TServer serverEngine; // Simple Server //serverEngine = new TSimpleServer(new Args(tServerSocket).processor(testProcessor)); // ThreadPool Server serverEngine = new TThreadPoolServer(new TThreadPoolServer.Args(tServerSocket).processor(testProcessor).protocolFactory(tProtocolFactory)); //Set server event handler serverEngine.setServerEventHandler(new TestServerEventHandler()); // Run it System.out.println("Starting the server on port " + port + "..."); serverEngine.serve(); } catch (Exception x) { x.printStackTrace(); } System.out.println("done."); } } libthrift-java_0.9.0/test/org/apache/thrift/test/SerializationBenchmark.java0000644000175000017500000000572712035665434030060 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.test; import org.apache.thrift.Fixtures; import org.apache.thrift.TBase; import org.apache.thrift.protocol.TBinaryProtocol; import org.apache.thrift.protocol.TProtocol; import org.apache.thrift.protocol.TProtocolFactory; import org.apache.thrift.transport.TMemoryBuffer; import org.apache.thrift.transport.TMemoryInputTransport; import org.apache.thrift.transport.TTransport; import org.apache.thrift.transport.TTransportException; import thrift.test.OneOfEach; public class SerializationBenchmark { private final static int HOW_MANY = 10000000; public static void main(String[] args) throws Exception { TProtocolFactory factory = new TBinaryProtocol.Factory(); testSerialization(factory, Fixtures.oneOfEach); testDeserialization(factory, Fixtures.oneOfEach, OneOfEach.class); } public static void testSerialization(TProtocolFactory factory, TBase object) throws Exception { TTransport trans = new TTransport() { public void write(byte[] bin, int x, int y) throws TTransportException {} public int read(byte[] bin, int x, int y) throws TTransportException {return 0;} public void close() {} public void open() {} public boolean isOpen() {return true;} }; TProtocol proto = factory.getProtocol(trans); long startTime = System.currentTimeMillis(); for (int i = 0; i < HOW_MANY; i++) { object.write(proto); } long endTime = System.currentTimeMillis(); System.out.println("Serialization test time: " + (endTime - startTime) + " ms"); } public static void testDeserialization(TProtocolFactory factory, T object, Class klass) throws Exception { TMemoryBuffer buf = new TMemoryBuffer(0); object.write(factory.getProtocol(buf)); byte[] serialized = new byte[100*1024]; buf.read(serialized, 0, 100*1024); long startTime = System.currentTimeMillis(); for (int i = 0; i < HOW_MANY; i++) { T o2 = klass.newInstance(); o2.read(factory.getProtocol(new TMemoryInputTransport(serialized))); } long endTime = System.currentTimeMillis(); System.out.println("Deserialization test time: " + (endTime - startTime) + " ms"); } }libthrift-java_0.9.0/test/org/apache/thrift/test/WriteStruct.java0000644000175000017500000000351412035665434025717 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.test; import java.io.BufferedOutputStream; import java.io.FileOutputStream; import org.apache.thrift.Fixtures; import org.apache.thrift.protocol.TProtocol; import org.apache.thrift.protocol.TProtocolFactory; import org.apache.thrift.transport.TIOStreamTransport; import org.apache.thrift.transport.TTransport; public class WriteStruct { public static void main(String[] args) throws Exception { if (args.length != 2) { System.out.println("usage: java -cp build/classes org.apache.thrift.test.WriteStruct filename proto_factory_class"); System.out.println("Write out an instance of Fixtures.compactProtocolTestStruct to 'file'. Use a protocol from 'proto_factory_class'."); } TTransport trans = new TIOStreamTransport(new BufferedOutputStream(new FileOutputStream(args[0]))); TProtocolFactory factory = (TProtocolFactory)Class.forName(args[1]).newInstance(); TProtocol proto = factory.getProtocol(trans); Fixtures.compactProtoTestStruct.write(proto); trans.flush(); } } libthrift-java_0.9.0/test/org/apache/thrift/test/EqualityTest.java0000644000175000017500000005015612035665434026061 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ /* This program was generated by the following Python script: #!/usr/bin/python2.5 # Remove this when Python 2.6 hits the streets. from __future__ import with_statement import sys import os.path # Quines the easy way. with open(sys.argv[0], 'r') as handle: source = handle.read() with open(os.path.join(os.path.dirname(sys.argv[0]), 'EqualityTest.java'), 'w') as out: print >> out, ("/""*" r""" * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. """ "*""/") print >> out print >> out, "/""*" print >> out, "This program was generated by the following Python script:" print >> out out.write(source) print >> out, "*""/" print >> out, r''' package org.apache.thrift.test; // Generated code import thrift.test.*; /'''r'''** *'''r'''/ public class EqualityTest { public static void main(String[] args) throws Exception { JavaTestHelper lhs, rhs; ''' vals = { 'int': ("1", "2"), 'obj': ("\"foo\"", "\"bar\""), 'bin': ("new byte[]{1,2}", "new byte[]{3,4}"), } matrix = ( (False,False), (False,True ), (True ,False), (True ,True ), ) for type in ('int', 'obj', 'bin'): for option in ('req', 'opt'): nulls = matrix[0:1] if type == 'int' else matrix[-1::-1] issets = matrix for is_null in nulls: for is_set in issets: # isset is implied for non-primitives, so only consider the case # where isset and non-null match. if type != 'int' and list(is_set) != [ not null for null in is_null ]: continue for equal in (True, False): print >> out print >> out, " lhs = new JavaTestHelper();" print >> out, " rhs = new JavaTestHelper();" print >> out, " lhs." + option + "_" + type, "=", vals[type][0] + ";" print >> out, " rhs." + option + "_" + type, "=", vals[type][0 if equal else 1] + ";" isset_setter = "set" + option[0].upper() + option[1:] + "_" + type + "IsSet" if (type == 'int' and is_set[0]): print >> out, " lhs." + isset_setter + "(true);" if (type == 'int' and is_set[1]): print >> out, " rhs." + isset_setter + "(true);" if (is_null[0]): print >> out, " lhs." + option + "_" + type, "= null;" if (is_null[1]): print >> out, " rhs." + option + "_" + type, "= null;" this_present = not is_null[0] and (option == 'req' or is_set[0]) that_present = not is_null[1] and (option == 'req' or is_set[1]) print >> out, " // this_present = " + repr(this_present) print >> out, " // that_present = " + repr(that_present) is_equal = \ (not this_present and not that_present) or \ (this_present and that_present and equal) eq_str = 'true' if is_equal else 'false' print >> out, " if (lhs.equals(rhs) != "+eq_str+")" print >> out, " throw new RuntimeException(\"Failure\");" if is_equal: print >> out, " if (lhs.hashCode() != rhs.hashCode())" print >> out, " throw new RuntimeException(\"Failure\");" print >> out, r''' } } ''' */ package org.apache.thrift.test; // Generated code import java.nio.ByteBuffer; import thrift.test.JavaTestHelper; /** */ public class EqualityTest { public static void main(String[] args) throws Exception { JavaTestHelper lhs, rhs; lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.req_int = 1; rhs.req_int = 1; // this_present = True // that_present = True if (lhs.equals(rhs) != true) throw new RuntimeException("Failure"); if (lhs.hashCode() != rhs.hashCode()) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.req_int = 1; rhs.req_int = 2; // this_present = True // that_present = True if (lhs.equals(rhs) != false) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.req_int = 1; rhs.req_int = 1; rhs.setReq_intIsSet(true); // this_present = True // that_present = True if (lhs.equals(rhs) != true) throw new RuntimeException("Failure"); if (lhs.hashCode() != rhs.hashCode()) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.req_int = 1; rhs.req_int = 2; rhs.setReq_intIsSet(true); // this_present = True // that_present = True if (lhs.equals(rhs) != false) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.req_int = 1; rhs.req_int = 1; lhs.setReq_intIsSet(true); // this_present = True // that_present = True if (lhs.equals(rhs) != true) throw new RuntimeException("Failure"); if (lhs.hashCode() != rhs.hashCode()) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.req_int = 1; rhs.req_int = 2; lhs.setReq_intIsSet(true); // this_present = True // that_present = True if (lhs.equals(rhs) != false) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.req_int = 1; rhs.req_int = 1; lhs.setReq_intIsSet(true); rhs.setReq_intIsSet(true); // this_present = True // that_present = True if (lhs.equals(rhs) != true) throw new RuntimeException("Failure"); if (lhs.hashCode() != rhs.hashCode()) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.req_int = 1; rhs.req_int = 2; lhs.setReq_intIsSet(true); rhs.setReq_intIsSet(true); // this_present = True // that_present = True if (lhs.equals(rhs) != false) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.opt_int = 1; rhs.opt_int = 1; // this_present = False // that_present = False if (lhs.equals(rhs) != true) throw new RuntimeException("Failure"); if (lhs.hashCode() != rhs.hashCode()) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.opt_int = 1; rhs.opt_int = 2; // this_present = False // that_present = False if (lhs.equals(rhs) != true) throw new RuntimeException("Failure"); if (lhs.hashCode() != rhs.hashCode()) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.opt_int = 1; rhs.opt_int = 1; rhs.setOpt_intIsSet(true); // this_present = False // that_present = True if (lhs.equals(rhs) != false) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.opt_int = 1; rhs.opt_int = 2; rhs.setOpt_intIsSet(true); // this_present = False // that_present = True if (lhs.equals(rhs) != false) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.opt_int = 1; rhs.opt_int = 1; lhs.setOpt_intIsSet(true); // this_present = True // that_present = False if (lhs.equals(rhs) != false) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.opt_int = 1; rhs.opt_int = 2; lhs.setOpt_intIsSet(true); // this_present = True // that_present = False if (lhs.equals(rhs) != false) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.opt_int = 1; rhs.opt_int = 1; lhs.setOpt_intIsSet(true); rhs.setOpt_intIsSet(true); // this_present = True // that_present = True if (lhs.equals(rhs) != true) throw new RuntimeException("Failure"); if (lhs.hashCode() != rhs.hashCode()) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.opt_int = 1; rhs.opt_int = 2; lhs.setOpt_intIsSet(true); rhs.setOpt_intIsSet(true); // this_present = True // that_present = True if (lhs.equals(rhs) != false) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.req_obj = "foo"; rhs.req_obj = "foo"; lhs.req_obj = null; rhs.req_obj = null; // this_present = False // that_present = False if (lhs.equals(rhs) != true) throw new RuntimeException("Failure"); if (lhs.hashCode() != rhs.hashCode()) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.req_obj = "foo"; rhs.req_obj = "bar"; lhs.req_obj = null; rhs.req_obj = null; // this_present = False // that_present = False if (lhs.equals(rhs) != true) throw new RuntimeException("Failure"); if (lhs.hashCode() != rhs.hashCode()) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.req_obj = "foo"; rhs.req_obj = "foo"; lhs.req_obj = null; // this_present = False // that_present = True if (lhs.equals(rhs) != false) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.req_obj = "foo"; rhs.req_obj = "bar"; lhs.req_obj = null; // this_present = False // that_present = True if (lhs.equals(rhs) != false) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.req_obj = "foo"; rhs.req_obj = "foo"; rhs.req_obj = null; // this_present = True // that_present = False if (lhs.equals(rhs) != false) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.req_obj = "foo"; rhs.req_obj = "bar"; rhs.req_obj = null; // this_present = True // that_present = False if (lhs.equals(rhs) != false) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.req_obj = "foo"; rhs.req_obj = "foo"; // this_present = True // that_present = True if (lhs.equals(rhs) != true) throw new RuntimeException("Failure"); if (lhs.hashCode() != rhs.hashCode()) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.req_obj = "foo"; rhs.req_obj = "bar"; // this_present = True // that_present = True if (lhs.equals(rhs) != false) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.opt_obj = "foo"; rhs.opt_obj = "foo"; lhs.opt_obj = null; rhs.opt_obj = null; // this_present = False // that_present = False if (lhs.equals(rhs) != true) throw new RuntimeException("Failure"); if (lhs.hashCode() != rhs.hashCode()) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.opt_obj = "foo"; rhs.opt_obj = "bar"; lhs.opt_obj = null; rhs.opt_obj = null; // this_present = False // that_present = False if (lhs.equals(rhs) != true) throw new RuntimeException("Failure"); if (lhs.hashCode() != rhs.hashCode()) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.opt_obj = "foo"; rhs.opt_obj = "foo"; lhs.opt_obj = null; // this_present = False // that_present = True if (lhs.equals(rhs) != false) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.opt_obj = "foo"; rhs.opt_obj = "bar"; lhs.opt_obj = null; // this_present = False // that_present = True if (lhs.equals(rhs) != false) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.opt_obj = "foo"; rhs.opt_obj = "foo"; rhs.opt_obj = null; // this_present = True // that_present = False if (lhs.equals(rhs) != false) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.opt_obj = "foo"; rhs.opt_obj = "bar"; rhs.opt_obj = null; // this_present = True // that_present = False if (lhs.equals(rhs) != false) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.opt_obj = "foo"; rhs.opt_obj = "foo"; // this_present = True // that_present = True if (lhs.equals(rhs) != true) throw new RuntimeException("Failure"); if (lhs.hashCode() != rhs.hashCode()) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.opt_obj = "foo"; rhs.opt_obj = "bar"; // this_present = True // that_present = True if (lhs.equals(rhs) != false) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.req_bin = ByteBuffer.wrap(new byte[]{1,2}); rhs.req_bin = ByteBuffer.wrap(new byte[]{1,2}); lhs.req_bin = null; rhs.req_bin = null; // this_present = False // that_present = False if (lhs.equals(rhs) != true) throw new RuntimeException("Failure"); if (lhs.hashCode() != rhs.hashCode()) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.req_bin = ByteBuffer.wrap(new byte[]{1,2}); rhs.req_bin = ByteBuffer.wrap(new byte[]{3,4}); lhs.req_bin = null; rhs.req_bin = null; // this_present = False // that_present = False if (lhs.equals(rhs) != true) throw new RuntimeException("Failure"); if (lhs.hashCode() != rhs.hashCode()) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.req_bin = ByteBuffer.wrap(new byte[]{1,2}); rhs.req_bin = ByteBuffer.wrap(new byte[]{1,2}); lhs.req_bin = null; // this_present = False // that_present = True if (lhs.equals(rhs) != false) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.req_bin = ByteBuffer.wrap(new byte[]{1,2}); rhs.req_bin = ByteBuffer.wrap(new byte[]{3,4}); lhs.req_bin = null; // this_present = False // that_present = True if (lhs.equals(rhs) != false) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.req_bin = ByteBuffer.wrap(new byte[]{1,2}); rhs.req_bin = ByteBuffer.wrap(new byte[]{1,2}); rhs.req_bin = null; // this_present = True // that_present = False if (lhs.equals(rhs) != false) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.req_bin = ByteBuffer.wrap(new byte[]{1,2}); rhs.req_bin = ByteBuffer.wrap(new byte[]{3,4}); rhs.req_bin = null; // this_present = True // that_present = False if (lhs.equals(rhs) != false) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.req_bin = ByteBuffer.wrap(new byte[]{1,2}); rhs.req_bin = ByteBuffer.wrap(new byte[]{1,2}); // this_present = True // that_present = True if (lhs.equals(rhs) != true) throw new RuntimeException("Failure"); if (lhs.hashCode() != rhs.hashCode()) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.req_bin = ByteBuffer.wrap(new byte[]{1,2}); rhs.req_bin = ByteBuffer.wrap(new byte[]{3,4}); // this_present = True // that_present = True if (lhs.equals(rhs) != false) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.opt_bin = ByteBuffer.wrap(new byte[]{1,2}); rhs.opt_bin = ByteBuffer.wrap(new byte[]{1,2}); lhs.opt_bin = null; rhs.opt_bin = null; // this_present = False // that_present = False if (lhs.equals(rhs) != true) throw new RuntimeException("Failure"); if (lhs.hashCode() != rhs.hashCode()) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.opt_bin = ByteBuffer.wrap(new byte[]{1,2}); rhs.opt_bin = ByteBuffer.wrap(new byte[]{3,4}); lhs.opt_bin = null; rhs.opt_bin = null; // this_present = False // that_present = False if (lhs.equals(rhs) != true) throw new RuntimeException("Failure"); if (lhs.hashCode() != rhs.hashCode()) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.opt_bin = ByteBuffer.wrap(new byte[]{1,2}); rhs.opt_bin = ByteBuffer.wrap(new byte[]{1,2}); lhs.opt_bin = null; // this_present = False // that_present = True if (lhs.equals(rhs) != false) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.opt_bin = ByteBuffer.wrap(new byte[]{1,2}); rhs.opt_bin = ByteBuffer.wrap(new byte[]{3,4}); lhs.opt_bin = null; // this_present = False // that_present = True if (lhs.equals(rhs) != false) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.opt_bin = ByteBuffer.wrap(new byte[]{1,2}); rhs.opt_bin = ByteBuffer.wrap(new byte[]{1,2}); rhs.opt_bin = null; // this_present = True // that_present = False if (lhs.equals(rhs) != false) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.opt_bin = ByteBuffer.wrap(new byte[]{1,2}); rhs.opt_bin = ByteBuffer.wrap(new byte[]{3,4}); rhs.opt_bin = null; // this_present = True // that_present = False if (lhs.equals(rhs) != false) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.opt_bin = ByteBuffer.wrap(new byte[]{1,2}); rhs.opt_bin = ByteBuffer.wrap(new byte[]{1,2}); // this_present = True // that_present = True if (lhs.equals(rhs) != true) throw new RuntimeException("Failure"); if (lhs.hashCode() != rhs.hashCode()) throw new RuntimeException("Failure"); lhs = new JavaTestHelper(); rhs = new JavaTestHelper(); lhs.opt_bin = ByteBuffer.wrap(new byte[]{1,2}); rhs.opt_bin = ByteBuffer.wrap(new byte[]{3,4}); // this_present = True // that_present = True if (lhs.equals(rhs) != false) throw new RuntimeException("Failure"); } } libthrift-java_0.9.0/test/org/apache/thrift/test/JavaBeansTest.java0000644000175000017500000001150112035665434026105 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.test; import java.nio.ByteBuffer; import java.util.LinkedList; import thrift.test.OneOfEachBeans; public class JavaBeansTest { public static void main(String[] args) throws Exception { // Test isSet methods OneOfEachBeans ooe = new OneOfEachBeans(); // Nothing should be set if (ooe.is_set_a_bite()) throw new RuntimeException("isSet method error: unset field returned as set!"); if (ooe.is_set_base64()) throw new RuntimeException("isSet method error: unset field returned as set!"); if (ooe.is_set_byte_list()) throw new RuntimeException("isSet method error: unset field returned as set!"); if (ooe.is_set_double_precision()) throw new RuntimeException("isSet method error: unset field returned as set!"); if (ooe.is_set_i16_list()) throw new RuntimeException("isSet method error: unset field returned as set!"); if (ooe.is_set_i64_list()) throw new RuntimeException("isSet method error: unset field returned as set!"); if (ooe.is_set_boolean_field()) throw new RuntimeException("isSet method error: unset field returned as set!"); if (ooe.is_set_integer16()) throw new RuntimeException("isSet method error: unset field returned as set!"); if (ooe.is_set_integer32()) throw new RuntimeException("isSet method error: unset field returned as set!"); if (ooe.is_set_integer64()) throw new RuntimeException("isSet method error: unset field returned as set!"); if (ooe.is_set_some_characters()) throw new RuntimeException("isSet method error: unset field returned as set!"); for (int i = 1; i < 12; i++){ if (ooe.isSet(ooe.fieldForId(i))) throw new RuntimeException("isSet method error: unset field " + i + " returned as set!"); } // Everything is set ooe.set_a_bite((byte) 1); ooe.set_base64(ByteBuffer.wrap("bytes".getBytes())); ooe.set_byte_list(new LinkedList()); ooe.set_double_precision(1); ooe.set_i16_list(new LinkedList()); ooe.set_i64_list(new LinkedList()); ooe.set_boolean_field(true); ooe.set_integer16((short) 1); ooe.set_integer32(1); ooe.set_integer64(1); ooe.set_some_characters("string"); if (!ooe.is_set_a_bite()) throw new RuntimeException("isSet method error: set field returned as unset!"); if (!ooe.is_set_base64()) throw new RuntimeException("isSet method error: set field returned as unset!"); if (!ooe.is_set_byte_list()) throw new RuntimeException("isSet method error: set field returned as unset!"); if (!ooe.is_set_double_precision()) throw new RuntimeException("isSet method error: set field returned as unset!"); if (!ooe.is_set_i16_list()) throw new RuntimeException("isSet method error: set field returned as unset!"); if (!ooe.is_set_i64_list()) throw new RuntimeException("isSet method error: set field returned as unset!"); if (!ooe.is_set_boolean_field()) throw new RuntimeException("isSet method error: set field returned as unset!"); if (!ooe.is_set_integer16()) throw new RuntimeException("isSet method error: set field returned as unset!"); if (!ooe.is_set_integer32()) throw new RuntimeException("isSet method error: set field returned as unset!"); if (!ooe.is_set_integer64()) throw new RuntimeException("isSet method error: set field returned as unset!"); if (!ooe.is_set_some_characters()) throw new RuntimeException("isSet method error: set field returned as unset!"); for (int i = 1; i < 12; i++){ if (!ooe.isSet(ooe.fieldForId(i))) throw new RuntimeException("isSet method error: set field " + i + " returned as unset!"); } // Should throw exception when field doesn't exist boolean exceptionThrown = false; try{ if (ooe.isSet(ooe.fieldForId(100))); } catch (IllegalArgumentException e){ exceptionThrown = true; } if (!exceptionThrown) throw new RuntimeException("isSet method error: non-existent field provided as agument but no exception thrown!"); } } libthrift-java_0.9.0/test/org/apache/thrift/test/ReadStruct.java0000644000175000017500000000453112035665434025500 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.test; import java.io.BufferedInputStream; import java.io.FileInputStream; import org.apache.thrift.Fixtures; import org.apache.thrift.protocol.TProtocol; import org.apache.thrift.protocol.TProtocolFactory; import org.apache.thrift.transport.TIOStreamTransport; import org.apache.thrift.transport.TTransport; import thrift.test.CompactProtoTestStruct; public class ReadStruct { public static void main(String[] args) throws Exception { if (args.length != 2) { System.out.println("usage: java -cp build/classes org.apache.thrift.test.ReadStruct filename proto_factory_class"); System.out.println("Read in an instance of CompactProtocolTestStruct from 'file', making sure that it is equivalent to Fixtures.compactProtoTestStruct. Use a protocol from 'proto_factory_class'."); } TTransport trans = new TIOStreamTransport(new BufferedInputStream(new FileInputStream(args[0]))); TProtocolFactory factory = (TProtocolFactory)Class.forName(args[1]).newInstance(); TProtocol proto = factory.getProtocol(trans); CompactProtoTestStruct cpts = new CompactProtoTestStruct(); for (CompactProtoTestStruct._Fields fid : CompactProtoTestStruct.metaDataMap.keySet()) { cpts.setFieldValue(fid, null); } cpts.read(proto); if (cpts.equals(Fixtures.compactProtoTestStruct)) { System.out.println("Object verified successfully!"); } else { System.out.println("Object failed verification!"); System.out.println("Expected: " + Fixtures.compactProtoTestStruct + " but got " + cpts); } } } libthrift-java_0.9.0/test/org/apache/thrift/test/TestClient.java0000644000175000017500000003540712035665434025504 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.test; // Generated code import thrift.test.*; import org.apache.thrift.TApplicationException; import org.apache.thrift.TException; import org.apache.thrift.TSerializer; import org.apache.thrift.transport.TTransport; import org.apache.thrift.transport.TSocket; import org.apache.thrift.transport.THttpClient; import org.apache.thrift.transport.TFramedTransport; import org.apache.thrift.transport.TTransportException; import org.apache.thrift.protocol.TBinaryProtocol; import org.apache.thrift.protocol.TSimpleJSONProtocol; import java.util.Map; import java.util.HashMap; import java.util.Set; import java.util.HashSet; import java.util.List; import java.util.ArrayList; /** * Test Java client for thrift. Essentially just a copy of the C++ version, * this makes a variety of requests to enable testing for both performance and * correctness of the output. * */ public class TestClient { public static void main(String [] args) { try { String host = "localhost"; int port = 9090; String url = null; int numTests = 1; boolean framed = false; int socketTimeout = 1000; try { for (int i = 0; i < args.length; ++i) { if (args[i].equals("-h")) { String[] hostport = (args[++i]).split(":"); host = hostport[0]; port = Integer.valueOf(hostport[1]); } else if (args[i].equals("-f") || args[i].equals("-framed")) { framed = true; } else if (args[i].equals("-u")) { url = args[++i]; } else if (args[i].equals("-n")) { numTests = Integer.valueOf(args[++i]); } else if (args[i].equals("-timeout")) { socketTimeout = Integer.valueOf(args[++i]); } } } catch (Exception x) { x.printStackTrace(); } TTransport transport; if (url != null) { transport = new THttpClient(url); } else { TSocket socket = new TSocket(host, port); socket.setTimeout(socketTimeout); transport = socket; if (framed) { transport = new TFramedTransport(transport); } } TBinaryProtocol binaryProtocol = new TBinaryProtocol(transport); ThriftTest.Client testClient = new ThriftTest.Client(binaryProtocol); Insanity insane = new Insanity(); long timeMin = 0; long timeMax = 0; long timeTot = 0; for (int test = 0; test < numTests; ++test) { /** * CONNECT TEST */ System.out.println("Test #" + (test+1) + ", " + "connect " + host + ":" + port); try { transport.open(); } catch (TTransportException ttx) { System.out.println("Connect failed: " + ttx.getMessage()); continue; } long start = System.nanoTime(); /** * VOID TEST */ try { System.out.print("testVoid()"); testClient.testVoid(); System.out.print(" = void\n"); } catch (TApplicationException tax) { tax.printStackTrace(); } /** * STRING TEST */ System.out.print("testString(\"Test\")"); String s = testClient.testString("Test"); System.out.print(" = \"" + s + "\"\n"); /** * BYTE TEST */ System.out.print("testByte(1)"); byte i8 = testClient.testByte((byte)1); System.out.print(" = " + i8 + "\n"); /** * I32 TEST */ System.out.print("testI32(-1)"); int i32 = testClient.testI32(-1); System.out.print(" = " + i32 + "\n"); /** * I64 TEST */ System.out.print("testI64(-34359738368)"); long i64 = testClient.testI64(-34359738368L); System.out.print(" = " + i64 + "\n"); /** * DOUBLE TEST */ System.out.print("testDouble(5.325098235)"); double dub = testClient.testDouble(5.325098235); System.out.print(" = " + dub + "\n"); /** * STRUCT TEST */ System.out.print("testStruct({\"Zero\", 1, -3, -5})"); Xtruct out = new Xtruct(); out.string_thing = "Zero"; out.byte_thing = (byte) 1; out.i32_thing = -3; out.i64_thing = -5; Xtruct in = testClient.testStruct(out); System.out.print(" = {" + "\"" + in.string_thing + "\", " + in.byte_thing + ", " + in.i32_thing + ", " + in.i64_thing + "}\n"); /** * NESTED STRUCT TEST */ System.out.print("testNest({1, {\"Zero\", 1, -3, -5}), 5}"); Xtruct2 out2 = new Xtruct2(); out2.byte_thing = (short)1; out2.struct_thing = out; out2.i32_thing = 5; Xtruct2 in2 = testClient.testNest(out2); in = in2.struct_thing; System.out.print(" = {" + in2.byte_thing + ", {" + "\"" + in.string_thing + "\", " + in.byte_thing + ", " + in.i32_thing + ", " + in.i64_thing + "}, " + in2.i32_thing + "}\n"); /** * MAP TEST */ Map mapout = new HashMap(); for (int i = 0; i < 5; ++i) { mapout.put(i, i-10); } System.out.print("testMap({"); boolean first = true; for (int key : mapout.keySet()) { if (first) { first = false; } else { System.out.print(", "); } System.out.print(key + " => " + mapout.get(key)); } System.out.print("})"); Map mapin = testClient.testMap(mapout); System.out.print(" = {"); first = true; for (int key : mapin.keySet()) { if (first) { first = false; } else { System.out.print(", "); } System.out.print(key + " => " + mapout.get(key)); } System.out.print("}\n"); /** * SET TEST */ Set setout = new HashSet(); for (int i = -2; i < 3; ++i) { setout.add(i); } System.out.print("testSet({"); first = true; for (int elem : setout) { if (first) { first = false; } else { System.out.print(", "); } System.out.print(elem); } System.out.print("})"); Set setin = testClient.testSet(setout); System.out.print(" = {"); first = true; for (int elem : setin) { if (first) { first = false; } else { System.out.print(", "); } System.out.print(elem); } System.out.print("}\n"); /** * LIST TEST */ List listout = new ArrayList(); for (int i = -2; i < 3; ++i) { listout.add(i); } System.out.print("testList({"); first = true; for (int elem : listout) { if (first) { first = false; } else { System.out.print(", "); } System.out.print(elem); } System.out.print("})"); List listin = testClient.testList(listout); System.out.print(" = {"); first = true; for (int elem : listin) { if (first) { first = false; } else { System.out.print(", "); } System.out.print(elem); } System.out.print("}\n"); /** * ENUM TEST */ System.out.print("testEnum(ONE)"); Numberz ret = testClient.testEnum(Numberz.ONE); System.out.print(" = " + ret + "\n"); System.out.print("testEnum(TWO)"); ret = testClient.testEnum(Numberz.TWO); System.out.print(" = " + ret + "\n"); System.out.print("testEnum(THREE)"); ret = testClient.testEnum(Numberz.THREE); System.out.print(" = " + ret + "\n"); System.out.print("testEnum(FIVE)"); ret = testClient.testEnum(Numberz.FIVE); System.out.print(" = " + ret + "\n"); System.out.print("testEnum(EIGHT)"); ret = testClient.testEnum(Numberz.EIGHT); System.out.print(" = " + ret + "\n"); /** * TYPEDEF TEST */ System.out.print("testTypedef(309858235082523)"); long uid = testClient.testTypedef(309858235082523L); System.out.print(" = " + uid + "\n"); /** * NESTED MAP TEST */ System.out.print("testMapMap(1)"); Map> mm = testClient.testMapMap(1); System.out.print(" = {"); for (int key : mm.keySet()) { System.out.print(key + " => {"); Map m2 = mm.get(key); for (int k2 : m2.keySet()) { System.out.print(k2 + " => " + m2.get(k2) + ", "); } System.out.print("}, "); } System.out.print("}\n"); /** * INSANITY TEST */ insane = new Insanity(); insane.userMap = new HashMap(); insane.userMap.put(Numberz.FIVE, (long)5000); Xtruct truck = new Xtruct(); truck.string_thing = "Truck"; truck.byte_thing = (byte)8; truck.i32_thing = 8; truck.i64_thing = 8; insane.xtructs = new ArrayList(); insane.xtructs.add(truck); System.out.print("testInsanity()"); Map> whoa = testClient.testInsanity(insane); System.out.print(" = {"); for (long key : whoa.keySet()) { Map val = whoa.get(key); System.out.print(key + " => {"); for (Numberz k2 : val.keySet()) { Insanity v2 = val.get(k2); System.out.print(k2 + " => {"); Map userMap = v2.userMap; System.out.print("{"); if (userMap != null) { for (Numberz k3 : userMap.keySet()) { System.out.print(k3 + " => " + userMap.get(k3) + ", "); } } System.out.print("}, "); List xtructs = v2.xtructs; System.out.print("{"); if (xtructs != null) { for (Xtruct x : xtructs) { System.out.print("{" + "\"" + x.string_thing + "\", " + x.byte_thing + ", " + x.i32_thing + ", "+ x.i64_thing + "}, "); } } System.out.print("}"); System.out.print("}, "); } System.out.print("}, "); } System.out.print("}\n"); /** * EXECPTION TEST */ try { System.out.print("testClient.testException(\"Xception\") =>"); testClient.testException("Xception"); System.out.print(" void\nFAILURE\n"); } catch(Xception e) { System.out.printf(" {%u, \"%s\"}\n", e.errorCode, e.message); } try { System.out.print("testClient.testException(\"TException\") =>"); testClient.testException("TException"); System.out.print(" void\nFAILURE\n"); } catch(TException e) { System.out.printf(" {\"%s\"}\n", e.getMessage()); } try { System.out.print("testClient.testException(\"success\") =>"); testClient.testException("success"); System.out.print(" void\n"); }catch(Exception e) { System.out.printf(" exception\nFAILURE\n"); } /** * MULTI EXCEPTION TEST */ try { System.out.printf("testClient.testMultiException(\"Xception\", \"test 1\") =>"); testClient.testMultiException("Xception", "test 1"); System.out.print(" result\nFAILURE\n"); } catch(Xception e) { System.out.printf(" {%u, \"%s\"}\n", e.errorCode, e.message); } try { System.out.printf("testClient.testMultiException(\"Xception2\", \"test 2\") =>"); testClient.testMultiException("Xception2", "test 2"); System.out.print(" result\nFAILURE\n"); } catch(Xception2 e) { System.out.printf(" {%u, {\"%s\"}}\n", e.errorCode, e.struct_thing.string_thing); } try { System.out.print("testClient.testMultiException(\"success\", \"test 3\") =>"); Xtruct result; result = testClient.testMultiException("success", "test 3"); System.out.printf(" {{\"%s\"}}\n", result.string_thing); } catch(Exception e) { System.out.printf(" exception\nFAILURE\n"); } /** * ONEWAY TEST */ System.out.print("testOneway(3)..."); long startOneway = System.nanoTime(); testClient.testOneway(3); long onewayElapsedMillis = (System.nanoTime() - startOneway) / 1000000; if (onewayElapsedMillis > 200) { throw new Exception("Oneway test failed: took " + Long.toString(onewayElapsedMillis) + "ms"); } else { System.out.println("Success - took " + Long.toString(onewayElapsedMillis) + "ms"); } long stop = System.nanoTime(); long tot = stop-start; System.out.println("Total time: " + tot/1000 + "us"); if (timeMin == 0 || tot < timeMin) { timeMin = tot; } if (tot > timeMax) { timeMax = tot; } timeTot += tot; transport.close(); } long timeAvg = timeTot / numTests; System.out.println("Min time: " + timeMin/1000 + "us"); System.out.println("Max time: " + timeMax/1000 + "us"); System.out.println("Avg time: " + timeAvg/1000 + "us"); String json = (new TSerializer(new TSimpleJSONProtocol.Factory())).toString(insane); System.out.println("\nFor good meausre here is some JSON:\n" + json); } catch (Exception x) { x.printStackTrace(); } } } libthrift-java_0.9.0/test/org/apache/thrift/test/TestNonblockingServer.java0000644000175000017500000000456412035665434027720 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.test; import org.apache.thrift.server.THsHaServer; import org.apache.thrift.server.TNonblockingServer; import org.apache.thrift.server.TServer; import org.apache.thrift.server.THsHaServer.Args; import org.apache.thrift.transport.TNonblockingServerSocket; import org.apache.thrift.server.ServerTestBase.TestHandler; import thrift.test.ThriftTest; public class TestNonblockingServer extends TestServer { public static void main(String [] args) { try { int port = 9090; boolean hsha = false; for (int i = 0; i < args.length; i++) { if (args[i].equals("-p")) { port = Integer.valueOf(args[i++]); } else if (args[i].equals("-hsha")) { hsha = true; } } //@TODO add other protocol and transport types // Processor TestHandler testHandler = new TestHandler(); ThriftTest.Processor testProcessor = new ThriftTest.Processor(testHandler); // Transport TNonblockingServerSocket tServerSocket = new TNonblockingServerSocket(port); TServer serverEngine; if (hsha) { // HsHa Server serverEngine = new THsHaServer(new Args(tServerSocket).processor(testProcessor)); } else { // Nonblocking Server serverEngine = new TNonblockingServer(new Args(tServerSocket).processor(testProcessor)); } // Run it System.out.println("Starting the server on port " + port + "..."); serverEngine.serve(); } catch (Exception x) { x.printStackTrace(); } System.out.println("done."); } } libthrift-java_0.9.0/test/org/apache/thrift/TestShortStack.java0000644000175000017500000000651512035665434025372 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; import java.util.Stack; import junit.framework.TestCase; public class TestShortStack extends TestCase { private static final int NUM_TRIALS = 5; private static final int NUM_REPS = 10000000; public void testOps() throws Exception { ShortStack s = new ShortStack(10); s.push((short)10); s.push((short)11); s.push((short)12); assertEquals((short)12, s.peek()); assertEquals((short)12, s.peek()); assertEquals((short)12, s.pop()); assertEquals((short)11, s.pop()); s.push((short)40); assertEquals((short)40, s.peek()); assertEquals((short)40, s.pop()); assertEquals((short)10, s.peek()); assertEquals((short)10, s.pop()); try { s.peek(); fail("should have thrown an exception!"); } catch (Exception e) { // yay } try { s.pop(); fail("should have thrown an exception!"); } catch (Exception e) { // yay } } public void testGrow() throws Exception { ShortStack s = new ShortStack(1); s.push((short)1); s.push((short)1); s.push((short)1); s.push((short)1); s.push((short)1); } public static void main(String[] args) throws Exception { for (int trial = 0; trial < NUM_TRIALS; trial++) { long start = System.currentTimeMillis(); ShortStack s = new ShortStack(10); for (int rep = 0; rep < NUM_REPS; rep++) { s.push((short)1); s.push((short)11); s.push((short)111); s.pop(); s.pop(); s.push((short)12); s.push((short)121); s.push((short)1211); s.push((short)12111); s.pop(); s.pop(); s.pop(); s.pop(); s.push((short)5); s.pop(); s.pop(); } long end = System.currentTimeMillis(); System.out.println("ShortStack: " + (end-start)); start = System.currentTimeMillis(); Stack stdStack = new Stack(); for (int rep = 0; rep < NUM_REPS; rep++) { stdStack.push((short)1); stdStack.push((short)11); stdStack.push((short)111); stdStack.pop(); stdStack.pop(); stdStack.push((short)12); stdStack.push((short)121); stdStack.push((short)1211); stdStack.push((short)12111); stdStack.pop(); stdStack.pop(); stdStack.pop(); stdStack.pop(); stdStack.push((short)5); stdStack.pop(); stdStack.pop(); } end = System.currentTimeMillis(); System.out.println("Built-in stack: " + (end-start)); } } } libthrift-java_0.9.0/test/org/apache/thrift/protocol/0000755000175000017500000000000012035665714023435 5ustar eevanseevans00000000000000libthrift-java_0.9.0/test/org/apache/thrift/protocol/TestTTupleProtocol.java0000644000175000017500000000133312035665434030076 0ustar eevanseevans00000000000000package org.apache.thrift.protocol; import org.apache.thrift.TDeserializer; import org.apache.thrift.TSerializer; import thrift.test.TupleProtocolTestStruct; public class TestTTupleProtocol extends ProtocolTestBase { @Override protected boolean canBeUsedNaked() { return false; } @Override protected TProtocolFactory getFactory() { return new TTupleProtocol.Factory(); } public void testBitsetLengthIssue() throws Exception { final TupleProtocolTestStruct t1 = new TupleProtocolTestStruct(); t1.setField1(0); t1.setField2(12); new TDeserializer(new TTupleProtocol.Factory()).deserialize(new TupleProtocolTestStruct(), new TSerializer(new TTupleProtocol.Factory()).serialize(t1)); } } libthrift-java_0.9.0/test/org/apache/thrift/protocol/TestTJSONProtocol.java0000644000175000017500000000206312035665434027557 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; public class TestTJSONProtocol extends ProtocolTestBase { @Override protected TProtocolFactory getFactory() { return new TJSONProtocol.Factory(); } @Override protected boolean canBeUsedNaked() { return false; } } libthrift-java_0.9.0/test/org/apache/thrift/protocol/TestTBinaryProtocol.java0000644000175000017500000000320712035665434030233 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; import org.apache.thrift.TDeserializer; import org.apache.thrift.TException; import thrift.test.Bonk; public class TestTBinaryProtocol extends ProtocolTestBase { @Override protected TProtocolFactory getFactory() { return new TBinaryProtocol.Factory(); } @Override protected boolean canBeUsedNaked() { return true; } public void testOOMDenialOfService() throws Exception { TDeserializer deser = new TDeserializer(new TBinaryProtocol .Factory(false, false, 1000)); Bonk bonk = new Bonk(); try { // Invalid read length specified here. Would cause an OOM // without the limit on the read length deser.deserialize(bonk, new byte[]{11, 0, 1, 127, -1, -1, -1}); } catch (TException e) { // Ignore as we are only checking for OOM in the failure case } } } libthrift-java_0.9.0/test/org/apache/thrift/protocol/TestTProtocolUtil.java0000644000175000017500000000724512035665434027732 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; import java.nio.ByteBuffer; import java.util.Arrays; import java.util.List; import junit.framework.TestCase; import org.apache.thrift.Fixtures; import org.apache.thrift.TBase; import org.apache.thrift.TDeserializer; import org.apache.thrift.TException; import org.apache.thrift.TSerializer; import org.apache.thrift.transport.TMemoryBuffer; import thrift.test.CompactProtoTestStruct; import thrift.test.HolyMoley; import thrift.test.Nesting; import thrift.test.OneOfEach; import thrift.test.Srv; import thrift.test.GuessProtocolStruct; public class TestTProtocolUtil extends TestCase { public void testGuessProtocolFactory_JSON() throws Exception { byte[] data = "{foo}".getBytes(); TProtocolFactory factory = TProtocolUtil.guessProtocolFactory(data, new TCompactProtocol.Factory()); assertTrue(factory instanceof TJSONProtocol.Factory); // Make sure data serialized with TCompact and which starts with '{' // is not mistakenly guessed as serialized with JSON. GuessProtocolStruct s = new GuessProtocolStruct(); s.putToMap_field("}","}"); byte[] ser = new TSerializer(new TCompactProtocol.Factory()).serialize(s); factory = TProtocolUtil.guessProtocolFactory(ser, new TCompactProtocol.Factory()); assertFalse(factory instanceof TJSONProtocol.Factory); } public void testGuessProtocolFactory_Binary() throws Exception { // Check that a last byte != 0 is correctly reported as Binary byte[] buf = new byte[1]; for (int i = 1; i < 256; i++) { buf[0] = (byte) i; TProtocolFactory factory = TProtocolUtil.guessProtocolFactory(buf, new TCompactProtocol.Factory()); assertTrue(factory instanceof TBinaryProtocol.Factory); } // Check that a second byte set to 0 is reported as Binary buf = new byte[2]; TProtocolFactory factory = TProtocolUtil.guessProtocolFactory(buf, new TCompactProtocol.Factory()); assertTrue(factory instanceof TBinaryProtocol.Factory); } public void testGuessProtocolFactory_Compact() throws Exception { // Check that a first byte > 0x10 is reported as Compact byte[] buf = new byte[3]; buf[0] = 0x11; TProtocolFactory factory = TProtocolUtil.guessProtocolFactory(buf, new TBinaryProtocol.Factory()); assertTrue(factory instanceof TCompactProtocol.Factory); // Check that second byte >= 0x80 is reported as Compact buf[0] = 0; for (int i = 0x80; i < 0x100; i++) { buf[1] = (byte) i; factory = TProtocolUtil.guessProtocolFactory(buf, new TBinaryProtocol.Factory()); assertTrue(factory instanceof TCompactProtocol.Factory); } } public void testGuessProtocolFactory_Undecided() throws Exception { byte[] buf = new byte[3]; buf[1] = 0x7e; TProtocolFactory factory = TProtocolUtil.guessProtocolFactory(buf, new TSimpleJSONProtocol.Factory()); assertTrue(factory instanceof TSimpleJSONProtocol.Factory); } } libthrift-java_0.9.0/test/org/apache/thrift/protocol/ProtocolTestBase.java0000644000175000017500000003313112035665434027534 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; import java.nio.ByteBuffer; import java.util.Arrays; import java.util.List; import junit.framework.TestCase; import org.apache.thrift.Fixtures; import org.apache.thrift.TBase; import org.apache.thrift.TDeserializer; import org.apache.thrift.TException; import org.apache.thrift.TSerializer; import org.apache.thrift.transport.TMemoryBuffer; import thrift.test.CompactProtoTestStruct; import thrift.test.HolyMoley; import thrift.test.Nesting; import thrift.test.OneOfEach; import thrift.test.Srv; public abstract class ProtocolTestBase extends TestCase { /** Does it make sense to call methods like writeI32 directly on your protocol? */ protected abstract boolean canBeUsedNaked(); /** The protocol factory for the protocol being tested. */ protected abstract TProtocolFactory getFactory(); public void testDouble() throws Exception { if (canBeUsedNaked()) { TMemoryBuffer buf = new TMemoryBuffer(1000); TProtocol proto = getFactory().getProtocol(buf); proto.writeDouble(123.456); assertEquals(123.456, proto.readDouble()); } internalTestStructField(new StructFieldTestCase(TType.DOUBLE, (short)15) { @Override public void readMethod(TProtocol proto) throws TException { assertEquals(123.456, proto.readDouble()); } @Override public void writeMethod(TProtocol proto) throws TException { proto.writeDouble(123.456); } }); } public void testSerialization() throws Exception { internalTestSerialization(OneOfEach.class, Fixtures.oneOfEach); internalTestSerialization(Nesting.class, Fixtures.nesting); internalTestSerialization(HolyMoley.class, Fixtures.holyMoley); internalTestSerialization(CompactProtoTestStruct.class, Fixtures.compactProtoTestStruct); } public void testBinary() throws Exception { for (byte[] b : Arrays.asList(new byte[0], new byte[]{0,1,2,3,4,5,6,7,8,9,10}, new byte[]{0,1,2,3,4,5,6,7,8,9,10,11,12,13,14}, new byte[]{0x5D}, new byte[]{(byte)0xD5,(byte)0x5D}, new byte[]{(byte)0xFF,(byte)0xD5,(byte)0x5D}, new byte[128])) { if (canBeUsedNaked()) { internalTestNakedBinary(b); } internalTestBinaryField(b); } if (canBeUsedNaked()) { byte[] data = {1, 2, 3, 4, 5, 6}; TMemoryBuffer buf = new TMemoryBuffer(0); TProtocol proto = getFactory().getProtocol(buf); ByteBuffer bb = ByteBuffer.wrap(data); bb.get(); proto.writeBinary(bb.slice()); assertEquals(ByteBuffer.wrap(data, 1, 5), proto.readBinary()); } } public void testString() throws Exception { for (String s : Arrays.asList("", "short", "borderlinetiny", "a bit longer than the smallest possible")) { if (canBeUsedNaked()) { internalTestNakedString(s); } internalTestStringField(s); } } public void testLong() throws Exception { if (canBeUsedNaked()) { internalTestNakedI64(0); } internalTestI64Field(0); for (int i = 0; i < 62; i++) { if (canBeUsedNaked()) { internalTestNakedI64(1L << i); internalTestNakedI64(-(1L << i)); } internalTestI64Field(1L << i); internalTestI64Field(-(1L << i)); } } public void testInt() throws Exception { for (int i : Arrays.asList(0, 1, 7, 150, 15000, 31337, 0xffff, 0xffffff, -1, -7, -150, -15000, -0xffff, -0xffffff)) { if (canBeUsedNaked()) { internalTestNakedI32(i); } internalTestI32Field(i); } } public void testShort() throws Exception { for (int s : Arrays.asList(0, 1, 7, 150, 15000, 0x7fff, -1, -7, -150, -15000, -0x7fff)) { if (canBeUsedNaked()) { internalTestNakedI16((short)s); } internalTestI16Field((short)s); } } public void testByte() throws Exception { if (canBeUsedNaked()) { internalTestNakedByte(); } for (int i = 0; i < 128; i++) { internalTestByteField((byte)i); internalTestByteField((byte)-i); } } private void internalTestNakedByte() throws Exception { TMemoryBuffer buf = new TMemoryBuffer(1000); TProtocol proto = getFactory().getProtocol(buf); proto.writeByte((byte)123); assertEquals((byte) 123, proto.readByte()); } private void internalTestByteField(final byte b) throws Exception { internalTestStructField(new StructFieldTestCase(TType.BYTE, (short)15) { public void writeMethod(TProtocol proto) throws TException { proto.writeByte(b); } public void readMethod(TProtocol proto) throws TException { assertEquals((byte)b, proto.readByte()); } }); } private void internalTestNakedI16(short n) throws Exception { TMemoryBuffer buf = new TMemoryBuffer(0); TProtocol proto = getFactory().getProtocol(buf); proto.writeI16(n); assertEquals(n, proto.readI16()); } private void internalTestI16Field(final short n) throws Exception { internalTestStructField(new StructFieldTestCase(TType.I16, (short)15) { public void writeMethod(TProtocol proto) throws TException { proto.writeI16(n); } public void readMethod(TProtocol proto) throws TException { assertEquals(n, proto.readI16()); } }); } private void internalTestNakedI32(int n) throws Exception { TMemoryBuffer buf = new TMemoryBuffer(0); TProtocol proto = getFactory().getProtocol(buf); proto.writeI32(n); assertEquals(n, proto.readI32()); } private void internalTestI32Field(final int n) throws Exception { internalTestStructField(new StructFieldTestCase(TType.I32, (short)15) { public void writeMethod(TProtocol proto) throws TException { proto.writeI32(n); } public void readMethod(TProtocol proto) throws TException { assertEquals(n, proto.readI32()); } }); } private void internalTestNakedI64(long n) throws Exception { TMemoryBuffer buf = new TMemoryBuffer(0); TProtocol proto = getFactory().getProtocol(buf); proto.writeI64(n); assertEquals(n, proto.readI64()); } private void internalTestI64Field(final long n) throws Exception { internalTestStructField(new StructFieldTestCase(TType.I64, (short)15) { public void writeMethod(TProtocol proto) throws TException { proto.writeI64(n); } public void readMethod(TProtocol proto) throws TException { assertEquals(n, proto.readI64()); } }); } private void internalTestNakedString(String str) throws Exception { TMemoryBuffer buf = new TMemoryBuffer(0); TProtocol proto = getFactory().getProtocol(buf); proto.writeString(str); assertEquals(str, proto.readString()); } private void internalTestStringField(final String str) throws Exception { internalTestStructField(new StructFieldTestCase(TType.STRING, (short)15) { public void writeMethod(TProtocol proto) throws TException { proto.writeString(str); } public void readMethod(TProtocol proto) throws TException { assertEquals(str, proto.readString()); } }); } private void internalTestNakedBinary(byte[] data) throws Exception { TMemoryBuffer buf = new TMemoryBuffer(0); TProtocol proto = getFactory().getProtocol(buf); proto.writeBinary(ByteBuffer.wrap(data)); assertEquals(ByteBuffer.wrap(data), proto.readBinary()); } private void internalTestBinaryField(final byte[] data) throws Exception { internalTestStructField(new StructFieldTestCase(TType.STRING, (short)15) { public void writeMethod(TProtocol proto) throws TException { proto.writeBinary(ByteBuffer.wrap(data)); } public void readMethod(TProtocol proto) throws TException { assertEquals(ByteBuffer.wrap(data), proto.readBinary()); } }); } private void internalTestSerialization(Class klass, T expected) throws Exception { TMemoryBuffer buf = new TMemoryBuffer(0); TBinaryProtocol binproto = new TBinaryProtocol(buf); expected.write(binproto); buf = new TMemoryBuffer(0); TProtocol proto = getFactory().getProtocol(buf); expected.write(proto); System.out.println("Size in " + proto.getClass().getSimpleName() + ": " + buf.length()); T actual = klass.newInstance(); actual.read(proto); assertEquals(expected, actual); } public void testMessage() throws Exception { List msgs = Arrays.asList(new TMessage[]{ new TMessage("short message name", TMessageType.CALL, 0), new TMessage("1", TMessageType.REPLY, 12345), new TMessage("loooooooooooooooooooooooooooooooooong", TMessageType.EXCEPTION, 1 << 16), new TMessage("Janky", TMessageType.CALL, 0), }); for (TMessage msg : msgs) { TMemoryBuffer buf = new TMemoryBuffer(0); TProtocol proto = getFactory().getProtocol(buf); TMessage output = null; proto.writeMessageBegin(msg); proto.writeMessageEnd(); output = proto.readMessageBegin(); assertEquals(msg, output); } } public void testServerRequest() throws Exception { Srv.Iface handler = new Srv.Iface() { public int Janky(int i32arg) throws TException { return i32arg * 2; } public int primitiveMethod() throws TException { return 0; } public CompactProtoTestStruct structMethod() throws TException { return null; } public void voidMethod() throws TException { } public void methodWithDefaultArgs(int something) throws TException { } @Override public void onewayMethod() throws TException { } }; Srv.Processor testProcessor = new Srv.Processor(handler); TMemoryBuffer clientOutTrans = new TMemoryBuffer(0); TProtocol clientOutProto = getFactory().getProtocol(clientOutTrans); TMemoryBuffer clientInTrans = new TMemoryBuffer(0); TProtocol clientInProto = getFactory().getProtocol(clientInTrans); Srv.Client testClient = new Srv.Client(clientInProto, clientOutProto); testClient.send_Janky(1); // System.out.println(clientOutTrans.inspect()); testProcessor.process(clientOutProto, clientInProto); // System.out.println(clientInTrans.inspect()); assertEquals(2, testClient.recv_Janky()); } public void testTDeserializer() throws TException { TSerializer ser = new TSerializer(getFactory()); byte[] bytes = ser.serialize(Fixtures.compactProtoTestStruct); TDeserializer deser = new TDeserializer(getFactory()); CompactProtoTestStruct cpts = new CompactProtoTestStruct(); deser.deserialize(cpts, bytes); assertEquals(Fixtures.compactProtoTestStruct, cpts); } // // Helper methods // private void internalTestStructField(StructFieldTestCase testCase) throws Exception { TMemoryBuffer buf = new TMemoryBuffer(0); TProtocol proto = getFactory().getProtocol(buf); TField field = new TField("test_field", testCase.type_, testCase.id_); proto.writeStructBegin(new TStruct("test_struct")); proto.writeFieldBegin(field); testCase.writeMethod(proto); proto.writeFieldEnd(); proto.writeStructEnd(); proto.readStructBegin(); TField readField = proto.readFieldBegin(); assertEquals(testCase.id_, readField.id); assertEquals(testCase.type_, readField.type); testCase.readMethod(proto); proto.readStructEnd(); } private static abstract class StructFieldTestCase { byte type_; short id_; public StructFieldTestCase(byte type, short id) { type_ = type; id_ = id; } public abstract void writeMethod(TProtocol proto) throws TException; public abstract void readMethod(TProtocol proto) throws TException; } private static final int NUM_TRIALS = 5; private static final int NUM_REPS = 10000; protected void benchmark() throws Exception { for (int trial = 0; trial < NUM_TRIALS; trial++) { TSerializer ser = new TSerializer(getFactory()); byte[] serialized = null; long serStart = System.currentTimeMillis(); for (int rep = 0; rep < NUM_REPS; rep++) { serialized = ser.serialize(Fixtures.holyMoley); } long serEnd = System.currentTimeMillis(); long serElapsed = serEnd - serStart; System.out.println("Ser:\t" + serElapsed + "ms\t" + ((double)serElapsed / NUM_REPS) + "ms per serialization"); HolyMoley cpts = new HolyMoley(); TDeserializer deser = new TDeserializer(getFactory()); long deserStart = System.currentTimeMillis(); for (int rep = 0; rep < NUM_REPS; rep++) { deser.deserialize(cpts, serialized); } long deserEnd = System.currentTimeMillis(); long deserElapsed = deserEnd - deserStart; System.out.println("Des:\t" + deserElapsed + "ms\t" + ((double)deserElapsed / NUM_REPS) + "ms per deserialization"); } } } libthrift-java_0.9.0/test/org/apache/thrift/protocol/TestTCompactProtocol.java0000644000175000017500000000332612035665434030377 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; import org.apache.thrift.TDeserializer; import org.apache.thrift.TException; import thrift.test.Bonk; public class TestTCompactProtocol extends ProtocolTestBase { @Override protected TProtocolFactory getFactory() { return new TCompactProtocol.Factory(); } @Override protected boolean canBeUsedNaked() { return true; } public void testOOMDenialOfService() throws Exception { // Struct header, Integer.MAX_VALUE length, and only one real // byte of data byte [] bytes = {24, -1, -1, -1, -17, 49}; TDeserializer deser = new TDeserializer(new TCompactProtocol .Factory(1000)); Bonk bonk = new Bonk(); try { deser.deserialize(bonk, bytes); } catch (TException e) { // Ignore as we are only checking for OOM in the failure case } } public static void main(String args[]) throws Exception { new TestTCompactProtocol().benchmark(); } }libthrift-java_0.9.0/test/org/apache/thrift/protocol/BenchmarkProtocols.java0000644000175000017500000000511312035665434030076 0ustar eevanseevans00000000000000package org.apache.thrift.protocol; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.thrift.Fixtures; import org.apache.thrift.TException; import org.apache.thrift.transport.TMemoryBuffer; public class BenchmarkProtocols { private static final Set FACTORIES = new LinkedHashSet(){{ add(new TTupleProtocol.Factory()); add(new TCompactProtocol.Factory()); add(new TBinaryProtocol.Factory()); }}; private static final int NUM_REPS = 100000; private static final int NUM_TRIALS = 10; public static void main(String[] args) throws TException { Map> timesByFactory = new HashMap>(); for (int trial = 0; trial < NUM_TRIALS; trial++) { for (int i = 0; i < 16; i++) { System.gc(); } // TProtocol proto = factory.getProtocol(new TTransport() { // @Override // public void write(byte[] buf, int off, int len) throws TTransportException { // } // // @Override // public int read(byte[] buf, int off, int len) throws TTransportException { // return 0; // } // // @Override // public void open() throws TTransportException { // } // // @Override // public boolean isOpen() { // return true; // } // // @Override // public void close() { // } // }); for (TProtocolFactory factory : FACTORIES) { if (timesByFactory.get(factory) == null) { timesByFactory.put(factory, new ArrayList()); } long start = System.currentTimeMillis(); for (int rep = 0; rep < NUM_REPS; rep++) { TProtocol proto = factory.getProtocol(new TMemoryBuffer(128*1024)); Fixtures.compactProtoTestStruct.write(proto); Fixtures.nesting.write(proto); } long end = System.currentTimeMillis(); timesByFactory.get(factory).add(end-start); } } for (TProtocolFactory factory : FACTORIES) { List times = timesByFactory.get(factory); // System.out.println("raw times pre-drop: " + times ); times.remove(Collections.max(times)); long total = 0; for (long t : times) { total += t; } Collections.sort(times); System.out.println(factory.getClass().getName() + " average time: " + (total / times.size()) + "ms"); System.out.println("raw times: " + times); } } } libthrift-java_0.9.0/test/org/apache/thrift/async/0000755000175000017500000000000012035665714022711 5ustar eevanseevans00000000000000libthrift-java_0.9.0/test/org/apache/thrift/async/TestTAsyncClientManager.java0000644000175000017500000002422412035665434030252 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.async; import java.io.IOException; import java.io.PrintWriter; import java.io.StringWriter; import java.util.ArrayList; import java.util.List; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeoutException; import java.util.concurrent.atomic.AtomicBoolean; import junit.framework.TestCase; import org.apache.thrift.TException; import org.apache.thrift.protocol.TBinaryProtocol; import org.apache.thrift.server.ServerTestBase; import org.apache.thrift.server.THsHaServer; import org.apache.thrift.server.THsHaServer.Args; import org.apache.thrift.transport.TNonblockingServerSocket; import org.apache.thrift.transport.TNonblockingSocket; import thrift.test.CompactProtoTestStruct; import thrift.test.Srv; import thrift.test.Srv.Iface; import thrift.test.Srv.AsyncClient.Janky_call; import thrift.test.Srv.AsyncClient.onewayMethod_call; import thrift.test.Srv.AsyncClient.primitiveMethod_call; import thrift.test.Srv.AsyncClient.voidMethod_call; public class TestTAsyncClientManager extends TestCase { private THsHaServer server_; private Thread serverThread_; private TAsyncClientManager clientManager_; public void setUp() throws Exception { server_ = new THsHaServer(new Args(new TNonblockingServerSocket(ServerTestBase.PORT)).processor(new Srv.Processor(new SrvHandler()))); serverThread_ = new Thread(new Runnable() { public void run() { server_.serve(); } }); serverThread_.start(); clientManager_ = new TAsyncClientManager(); Thread.sleep(500); } public void tearDown() throws Exception { server_.stop(); clientManager_.stop(); serverThread_.join(); } public void testBasicCall() throws Exception { Srv.AsyncClient client = getClient(); basicCall(client); } public void testBasicCallWithTimeout() throws Exception { Srv.AsyncClient client = getClient(); client.setTimeout(5000); basicCall(client); } public void testTimeoutCall() throws Exception { final CountDownLatch latch = new CountDownLatch(1); Srv.AsyncClient client = getClient(); client.setTimeout(100); client.primitiveMethod(new AsyncMethodCallback() { @Override public void onError(Exception exception) { try { if (!(exception instanceof TimeoutException)) { StringWriter sink = new StringWriter(); exception.printStackTrace(new PrintWriter(sink, true)); fail("expected TimeoutException but got " + sink.toString()); } } finally { latch.countDown(); } } @Override public void onComplete(primitiveMethod_call response) { try { fail("Should not have finished timed out call."); } finally { latch.countDown(); } } }); latch.await(2, TimeUnit.SECONDS); assertTrue(client.hasError()); assertTrue(client.getError() instanceof TimeoutException); } public void testVoidCall() throws Exception { final CountDownLatch latch = new CountDownLatch(1); final AtomicBoolean returned = new AtomicBoolean(false); Srv.AsyncClient client = getClient(); client.voidMethod(new FailureLessCallback() { @Override public void onComplete(voidMethod_call response) { try { response.getResult(); returned.set(true); } catch (TException e) { fail(e); } finally { latch.countDown(); } } }); latch.await(1, TimeUnit.SECONDS); assertTrue(returned.get()); } public void testOnewayCall() throws Exception { final CountDownLatch latch = new CountDownLatch(1); final AtomicBoolean returned = new AtomicBoolean(false); Srv.AsyncClient client = getClient(); client.onewayMethod(new FailureLessCallback() { @Override public void onComplete(onewayMethod_call response) { try { response.getResult(); returned.set(true); } catch (TException e) { fail(e); } finally { latch.countDown(); } } }); latch.await(1, TimeUnit.SECONDS); assertTrue(returned.get()); } public void testParallelCalls() throws Exception { // make multiple calls with deserialization in the selector thread (repro Eric's issue) int numThreads = 50; int numCallsPerThread = 100; List runnables = new ArrayList(); List threads = new ArrayList(); for (int i = 0; i < numThreads; i++) { JankyRunnable runnable = new JankyRunnable(numCallsPerThread); Thread thread = new Thread(runnable); thread.start(); threads.add(thread); runnables.add(runnable); } for (Thread thread : threads) { thread.join(); } int numSuccesses = 0; for (JankyRunnable runnable : runnables) { numSuccesses += runnable.getNumSuccesses(); } assertEquals(numThreads * numCallsPerThread, numSuccesses); } private Srv.AsyncClient getClient() throws IOException { TNonblockingSocket clientSocket = new TNonblockingSocket(ServerTestBase.HOST, ServerTestBase.PORT); return new Srv.AsyncClient(new TBinaryProtocol.Factory(), clientManager_, clientSocket); } private void basicCall(Srv.AsyncClient client) throws Exception { final CountDownLatch latch = new CountDownLatch(1); final AtomicBoolean returned = new AtomicBoolean(false); client.Janky(1, new FailureLessCallback() { @Override public void onComplete(Janky_call response) { try { assertEquals(3, response.getResult()); returned.set(true); } catch (TException e) { fail(e); } finally { latch.countDown(); } } @Override public void onError(Exception exception) { try { StringWriter sink = new StringWriter(); exception.printStackTrace(new PrintWriter(sink, true)); fail("unexpected onError with exception " + sink.toString()); } finally { latch.countDown(); } } }); latch.await(100, TimeUnit.SECONDS); assertTrue(returned.get()); } public class SrvHandler implements Iface { // Use this method for a standard call testing @Override public int Janky(int arg) throws TException { assertEquals(1, arg); return 3; } // Using this method for timeout testing - sleeps for 1 second before returning @Override public int primitiveMethod() throws TException { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } return 0; } @Override public void methodWithDefaultArgs(int something) throws TException { } @Override public CompactProtoTestStruct structMethod() throws TException { return null; } @Override public void voidMethod() throws TException { } @Override public void onewayMethod() throws TException { } } private static abstract class FailureLessCallback implements AsyncMethodCallback { @Override public void onError(Exception exception) { fail(exception); } } private static void fail(Exception exception) { StringWriter sink = new StringWriter(); exception.printStackTrace(new PrintWriter(sink, true)); fail("unexpected error " + sink.toString()); } private class JankyRunnable implements Runnable { private int numCalls_; private int numSuccesses_ = 0; private Srv.AsyncClient client_; public JankyRunnable(int numCalls) throws Exception { numCalls_ = numCalls; client_ = getClient(); client_.setTimeout(20000); } public int getNumSuccesses() { return numSuccesses_; } public void run() { for (int i = 0; i < numCalls_ && !client_.hasError(); i++) { final int iteration = i; try { // connect an async client final CountDownLatch latch = new CountDownLatch(1); final AtomicBoolean returned = new AtomicBoolean(false); client_.Janky(1, new AsyncMethodCallback() { @Override public void onComplete(Janky_call response) { try { assertEquals(3, response.getResult()); returned.set(true); latch.countDown(); } catch (TException e) { latch.countDown(); fail(e); } } @Override public void onError(Exception exception) { try { StringWriter sink = new StringWriter(); exception.printStackTrace(new PrintWriter(sink, true)); fail("unexpected onError on iteration " + iteration + ": " + sink.toString()); } finally { latch.countDown(); } } }); boolean calledBack = latch.await(30, TimeUnit.SECONDS); assertTrue("wasn't called back in time on iteration " + iteration, calledBack); assertTrue("onComplete not called on iteration " + iteration, returned.get()); this.numSuccesses_++; } catch (Exception e) { fail(e); } } } } }libthrift-java_0.9.0/test/org/apache/thrift/async/TestTAsyncClient.java0000644000175000017500000000131012035665434026746 0ustar eevanseevans00000000000000package org.apache.thrift.async; import junit.framework.TestCase; import org.apache.thrift.TException; import thrift.test.Srv; import thrift.test.Srv.AsyncClient; public class TestTAsyncClient extends TestCase { public void testRaisesExceptionWhenUsedConcurrently() throws Exception { TAsyncClientManager mockClientManager = new TAsyncClientManager() { @Override public void call(TAsyncMethodCall method) throws TException { // do nothing } }; Srv.AsyncClient c = new AsyncClient(null, mockClientManager, null); c.Janky(0, null); try { c.checkReady(); fail("should have hit an exception"); } catch (Exception e) { // awesome } } } libthrift-java_0.9.0/test/org/apache/thrift/transport/0000755000175000017500000000000012035665714023630 5ustar eevanseevans00000000000000libthrift-java_0.9.0/test/org/apache/thrift/transport/TestAutoExpandingBufferWriteTransport.java0000644000175000017500000000314612035665434034166 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import java.nio.ByteBuffer; import junit.framework.TestCase; public class TestAutoExpandingBufferWriteTransport extends TestCase { public void testIt() throws Exception { AutoExpandingBufferWriteTransport t = new AutoExpandingBufferWriteTransport(1, 1.5); assertEquals(1, t.getBuf().array().length); byte[] b1 = new byte[]{1,2,3}; t.write(b1); assertEquals(3, t.getPos()); assertTrue(t.getBuf().array().length >= 3); assertEquals(ByteBuffer.wrap(b1), ByteBuffer.wrap(t.getBuf().array(), 0, 3)); t.reset(); assertTrue(t.getBuf().array().length >= 3); assertEquals(0, t.getPos()); byte[] b2 = new byte[]{4,5}; t.write(b2); assertEquals(2, t.getPos()); assertEquals(ByteBuffer.wrap(b2), ByteBuffer.wrap(t.getBuf().array(), 0, 2)); } } libthrift-java_0.9.0/test/org/apache/thrift/transport/TestTMemoryInputTransport.java0000644000175000017500000000620512035665434031666 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import java.util.Arrays; import junit.framework.TestCase; public class TestTMemoryInputTransport extends TestCase { public void testFresh() throws Exception { byte[] input_buf = new byte[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; TMemoryInputTransport trans = new TMemoryInputTransport(input_buf); assertEquals(0, trans.getBufferPosition()); assertEquals(input_buf, trans.getBuffer()); assertEquals(10, trans.getBytesRemainingInBuffer()); byte[] buf1 = new byte[4]; trans.readAll(buf1, 0, 4); assertTrue(Arrays.equals(new byte[]{1, 2, 3, 4}, buf1)); assertEquals(4, trans.getBufferPosition()); assertEquals(6, trans.getBytesRemainingInBuffer()); trans.consumeBuffer(2); assertEquals(6, trans.getBufferPosition()); assertEquals(4, trans.getBytesRemainingInBuffer()); trans.readAll(buf1, 0, 4); assertTrue(Arrays.equals(new byte[]{7, 8, 9, 10}, buf1)); assertEquals(10, trans.getBufferPosition()); assertEquals(0, trans.getBytesRemainingInBuffer()); } public void testReused() throws Exception { byte[] input_buf = new byte[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; TMemoryInputTransport trans = new TMemoryInputTransport(input_buf); assertEquals(0, trans.getBufferPosition()); assertEquals(input_buf, trans.getBuffer()); assertEquals(10, trans.getBytesRemainingInBuffer()); byte[] new_buf = new byte[]{10, 9, 8}; trans.reset(new_buf); assertEquals(0, trans.getBufferPosition()); assertEquals(new_buf, trans.getBuffer()); assertEquals(3, trans.getBytesRemainingInBuffer()); } public void testWithOffsetAndLength() throws Exception { byte[] input_buf = new byte[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; TMemoryInputTransport trans = new TMemoryInputTransport(input_buf, 1, 3); assertEquals(1, trans.getBufferPosition()); assertEquals(3, trans.getBytesRemainingInBuffer()); byte[] readBuffer = new byte[3]; trans.readAll(readBuffer, 0, 3); assertTrue(Arrays.equals(new byte[]{2, 3, 4}, readBuffer)); try { assertEquals(0, trans.readAll(readBuffer, 0, 3)); fail("should have thrown an exception"); } catch (Exception e) { // yay } trans.reset(input_buf, 3, 4); readBuffer = new byte[4]; trans.readAll(readBuffer, 0, 4); assertTrue(Arrays.equals(new byte[]{4, 5, 6, 7}, readBuffer)); } } libthrift-java_0.9.0/test/org/apache/thrift/transport/TestTFastFramedTransport.java0000644000175000017500000000204512035665434031410 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; public class TestTFastFramedTransport extends TestTFramedTransport { @Override protected TTransport getTransport(TTransport underlying) { return new TFastFramedTransport(underlying, 50, 10 * 1024 * 1024); } } libthrift-java_0.9.0/test/org/apache/thrift/transport/ReadCountingTransport.java0000644000175000017500000000263712035665434031001 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; public class ReadCountingTransport extends TTransport { public int readCount = 0; private TTransport trans; public ReadCountingTransport(TTransport underlying) { trans = underlying; } @Override public void close() {} @Override public boolean isOpen() {return true;} @Override public void open() throws TTransportException {} @Override public int read(byte[] buf, int off, int len) throws TTransportException { readCount++; return trans.read(buf, off, len); } @Override public void write(byte[] buf, int off, int len) throws TTransportException {} }libthrift-java_0.9.0/test/org/apache/thrift/transport/TestAutoExpandingBuffer.java0000644000175000017500000000246112035665434031235 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import junit.framework.TestCase; public class TestAutoExpandingBuffer extends TestCase { public void testExpands() throws Exception { // has expected initial capacity AutoExpandingBuffer b = new AutoExpandingBuffer(10, 1.5); assertEquals(10, b.array().length); // doesn't shrink b.resizeIfNecessary(8); assertEquals(10, b.array().length); // grows when more capacity is needed b.resizeIfNecessary(100); assertTrue(b.array().length >= 100); } } libthrift-java_0.9.0/test/org/apache/thrift/transport/WriteCountingTransport.java0000644000175000017500000000301412035665434031206 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; public class WriteCountingTransport extends TTransport { public int writeCount = 0; private final TTransport trans; public WriteCountingTransport(TTransport underlying) { trans = underlying; } @Override public void close() {} @Override public boolean isOpen() {return true;} @Override public void open() throws TTransportException {} @Override public int read(byte[] buf, int off, int len) throws TTransportException { return 0; } @Override public void write(byte[] buf, int off, int len) throws TTransportException { writeCount ++; trans.write(buf, off, len); } @Override public void flush() throws TTransportException { trans.flush(); } }libthrift-java_0.9.0/test/org/apache/thrift/transport/TestAutoExpandingBufferReadTransport.java0000644000175000017500000000327312035665434033750 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import java.nio.ByteBuffer; import junit.framework.TestCase; public class TestAutoExpandingBufferReadTransport extends TestCase { private static final byte[] HUNDRED_BYTES = new byte[100]; static { for (byte i = 0; i < 100; i++) { HUNDRED_BYTES[i] = i; } } public void testIt() throws Exception { AutoExpandingBufferReadTransport t = new AutoExpandingBufferReadTransport(150, 1.5); TMemoryInputTransport membuf = new TMemoryInputTransport(HUNDRED_BYTES); t.fill(membuf, 100); assertEquals(100, t.getBytesRemainingInBuffer()); assertEquals(0, t.getBufferPosition()); byte[] target = new byte[10]; assertEquals(10, t.read(target, 0, 10)); assertEquals(ByteBuffer.wrap(HUNDRED_BYTES, 0, 10), ByteBuffer.wrap(target)); assertEquals(90, t.getBytesRemainingInBuffer()); assertEquals(10, t.getBufferPosition()); } } libthrift-java_0.9.0/test/org/apache/thrift/transport/TestTSSLTransportFactory.java0000644000175000017500000000537012035665434031371 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import java.util.ArrayList; import java.util.List; import org.apache.thrift.TProcessor; import org.apache.thrift.protocol.TBinaryProtocol; import org.apache.thrift.protocol.TProtocolFactory; import org.apache.thrift.server.ServerTestBase; import org.apache.thrift.server.TServer; import org.apache.thrift.server.TSimpleServer; import org.apache.thrift.server.TServer.Args; public class TestTSSLTransportFactory extends ServerTestBase { private Thread serverThread; private TServer server; private static final List protocols = new ArrayList(); static { // TODO: Only supported on TBinaryProtocol. Doesn't work for TCompactProtocol protocols.add(new TBinaryProtocol.Factory()); } @Override public TTransport getClientTransport(TTransport underlyingTransport) throws Exception { return TSSLTransportFactory.getClientSocket(HOST, PORT); } @Override public void startServer(final TProcessor processor, final TProtocolFactory protoFactory, final TTransportFactory factory) throws Exception { serverThread = new Thread() { public void run() { try { TServerTransport serverTransport = TSSLTransportFactory.getServerSocket(PORT); final Args args = new Args(serverTransport).processor(processor); server = new TSimpleServer(args); server.serve(); } catch (TTransportException e) { e.printStackTrace(); assert false; } } }; serverThread.start(); Thread.sleep(1000); } @Override public void stopServer() throws Exception { server.stop(); serverThread.join(); } @Override public void open(TTransport transport) throws Exception {} @Override public List getProtocols() { return protocols; } @Override public void testTransportFactory() throws Exception { // this test doesn't really apply to this suite, so let's skip it. } } libthrift-java_0.9.0/test/org/apache/thrift/transport/TestTFramedTransport.java0000644000175000017500000001175012035665434030575 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import java.io.BufferedOutputStream; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; import java.util.Arrays; import junit.framework.TestCase; public class TestTFramedTransport extends TestCase { protected TTransport getTransport(TTransport underlying) { return new TFramedTransport(underlying); } public static byte[] byteSequence(int start, int end) { byte[] result = new byte[end-start+1]; for (int i = 0; i <= (end-start); i++) { result[i] = (byte)(start+i); } return result; } public void testRead() throws IOException, TTransportException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); DataOutputStream dos = new DataOutputStream(baos); dos.writeInt(50); dos.write(byteSequence(0, 49)); dos.writeInt(220); dos.write(byteSequence(0, 219)); TMemoryBuffer membuf = new TMemoryBuffer(0); membuf.write(baos.toByteArray()); ReadCountingTransport countTrans = new ReadCountingTransport(membuf); TTransport trans = getTransport(countTrans); byte[] readBuf = new byte[10]; trans.read(readBuf, 0, 10); assertTrue(Arrays.equals(readBuf, byteSequence(0,9))); assertEquals(2, countTrans.readCount); trans.read(readBuf, 0, 10); assertTrue(Arrays.equals(readBuf, byteSequence(10,19))); assertEquals(2, countTrans.readCount); assertEquals(30, trans.read(new byte[30], 0, 30)); assertEquals(2, countTrans.readCount); readBuf = new byte[220]; assertEquals(220, trans.read(readBuf, 0, 220)); assertTrue(Arrays.equals(readBuf, byteSequence(0, 219))); assertEquals(4, countTrans.readCount); } public void testWrite() throws TTransportException, IOException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); WriteCountingTransport countingTrans = new WriteCountingTransport(new TIOStreamTransport(new BufferedOutputStream(baos))); TTransport trans = getTransport(countingTrans); trans.write(byteSequence(0,100)); assertEquals(0, countingTrans.writeCount); trans.write(byteSequence(101,200)); trans.write(byteSequence(201,255)); assertEquals(0, countingTrans.writeCount); trans.flush(); assertEquals(2, countingTrans.writeCount); trans.write(byteSequence(0, 245)); trans.flush(); assertEquals(4, countingTrans.writeCount); DataInputStream din = new DataInputStream(new ByteArrayInputStream(baos.toByteArray())); assertEquals(256, din.readInt()); byte[] buf = new byte[256]; din.read(buf, 0, 256); assertTrue(Arrays.equals(byteSequence(0,255), buf)); assertEquals(246, din.readInt()); buf = new byte[246]; din.read(buf, 0, 246); assertTrue(Arrays.equals(byteSequence(0,245), buf)); } public void testDirectRead() throws IOException, TTransportException { ByteArrayOutputStream baos = new ByteArrayOutputStream(); DataOutputStream dos = new DataOutputStream(baos); dos.writeInt(50); dos.write(byteSequence(0, 49)); dos.writeInt(75); dos.write(byteSequence(125, 200)); TMemoryBuffer membuf = new TMemoryBuffer(0); membuf.write(baos.toByteArray()); ReadCountingTransport countTrans = new ReadCountingTransport(membuf); TTransport trans = getTransport(countTrans); assertEquals(0, trans.getBytesRemainingInBuffer()); byte[] readBuf = new byte[10]; trans.read(readBuf, 0, 10); assertTrue(Arrays.equals(readBuf, byteSequence(0,9))); assertEquals(40, trans.getBytesRemainingInBuffer()); assertEquals(10, trans.getBufferPosition()); trans.consumeBuffer(5); assertEquals(35, trans.getBytesRemainingInBuffer()); assertEquals(15, trans.getBufferPosition()); assertEquals(2, countTrans.readCount); assertEquals(35, trans.read(new byte[35], 0, 35)); assertEquals(0, trans.getBytesRemainingInBuffer()); assertEquals(50, trans.getBufferPosition()); trans.read(readBuf, 0, 10); assertEquals(4, countTrans.readCount); assertTrue(Arrays.equals(readBuf, byteSequence(125,134))); assertEquals(65, trans.getBytesRemainingInBuffer()); assertEquals(10, trans.getBufferPosition()); } } libthrift-java_0.9.0/test/org/apache/thrift/transport/TestTSaslTransports.java0000644000175000017500000003337712035665434030475 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import java.io.IOException; import java.util.HashMap; import java.util.Map; import javax.security.auth.callback.Callback; import javax.security.auth.callback.CallbackHandler; import javax.security.auth.callback.NameCallback; import javax.security.auth.callback.PasswordCallback; import javax.security.auth.callback.UnsupportedCallbackException; import javax.security.sasl.AuthorizeCallback; import javax.security.sasl.RealmCallback; import javax.security.sasl.Sasl; import javax.security.sasl.SaslClient; import javax.security.sasl.SaslClientFactory; import javax.security.sasl.SaslException; import javax.security.sasl.SaslServer; import javax.security.sasl.SaslServerFactory; import junit.framework.TestCase; import org.apache.thrift.TProcessor; import org.apache.thrift.protocol.TProtocolFactory; import org.apache.thrift.server.ServerTestBase; import org.apache.thrift.server.TServer; import org.apache.thrift.server.TSimpleServer; import org.apache.thrift.server.TServer.Args; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class TestTSaslTransports extends TestCase { private static final Logger LOGGER = LoggerFactory.getLogger(TestTSaslTransports.class); private static final String HOST = "localhost"; private static final String SERVICE = "thrift-test"; private static final String PRINCIPAL = "thrift-test-principal"; private static final String PASSWORD = "super secret password"; private static final String REALM = "thrift-test-realm"; private static final String UNWRAPPED_MECHANISM = "CRAM-MD5"; private static final Map UNWRAPPED_PROPS = null; private static final String WRAPPED_MECHANISM = "DIGEST-MD5"; private static final Map WRAPPED_PROPS = new HashMap(); static { WRAPPED_PROPS.put(Sasl.QOP, "auth-int"); WRAPPED_PROPS.put("com.sun.security.sasl.digest.realm", REALM); } private static final String testMessage1 = "Hello, world! Also, four " + "score and seven years ago our fathers brought forth on this " + "continent a new nation, conceived in liberty, and dedicated to the " + "proposition that all men are created equal."; private static final String testMessage2 = "I have a dream that one day " + "this nation will rise up and live out the true meaning of its creed: " + "'We hold these truths to be self-evident, that all men are created equal.'"; private static class TestSaslCallbackHandler implements CallbackHandler { private final String password; public TestSaslCallbackHandler(String password) { this.password = password; } @Override public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException { for (Callback c : callbacks) { if (c instanceof NameCallback) { ((NameCallback) c).setName(PRINCIPAL); } else if (c instanceof PasswordCallback) { ((PasswordCallback) c).setPassword(password.toCharArray()); } else if (c instanceof AuthorizeCallback) { ((AuthorizeCallback) c).setAuthorized(true); } else if (c instanceof RealmCallback) { ((RealmCallback) c).setText(REALM); } else { throw new UnsupportedCallbackException(c); } } } } private class ServerThread extends Thread { final String mechanism; final Map props; volatile Throwable thrown; public ServerThread(String mechanism, Map props) { this.mechanism = mechanism; this.props = props; } public void run() { try { internalRun(); } catch (Throwable t) { thrown = t; } } private void internalRun() throws Exception { TServerSocket serverSocket = new TServerSocket(ServerTestBase.PORT); try { acceptAndWrite(serverSocket); } finally { serverSocket.close(); } } private void acceptAndWrite(TServerSocket serverSocket) throws Exception { TTransport serverTransport = serverSocket.accept(); TTransport saslServerTransport = new TSaslServerTransport( mechanism, SERVICE, HOST, props, new TestSaslCallbackHandler(PASSWORD), serverTransport); saslServerTransport.open(); byte[] inBuf = new byte[testMessage1.getBytes().length]; // Deliberately read less than the full buffer to ensure // that TSaslTransport is correctly buffering reads. This // will fail for the WRAPPED test, if it doesn't work. saslServerTransport.readAll(inBuf, 0, 5); saslServerTransport.readAll(inBuf, 5, 10); saslServerTransport.readAll(inBuf, 15, inBuf.length - 15); LOGGER.debug("server got: {}", new String(inBuf)); assertEquals(new String(inBuf), testMessage1); LOGGER.debug("server writing: {}", testMessage2); saslServerTransport.write(testMessage2.getBytes()); saslServerTransport.flush(); saslServerTransport.close(); } } private void testSaslOpen(final String mechanism, final Map props) throws Exception { ServerThread serverThread = new ServerThread(mechanism, props); serverThread.start(); try { Thread.sleep(1000); } catch (InterruptedException e) { // Ah well. } try { TSocket clientSocket = new TSocket(HOST, ServerTestBase.PORT); TTransport saslClientTransport = new TSaslClientTransport(mechanism, PRINCIPAL, SERVICE, HOST, props, new TestSaslCallbackHandler(PASSWORD), clientSocket); saslClientTransport.open(); LOGGER.debug("client writing: {}", testMessage1); saslClientTransport.write(testMessage1.getBytes()); saslClientTransport.flush(); byte[] inBuf = new byte[testMessage2.getBytes().length]; saslClientTransport.readAll(inBuf, 0, inBuf.length); LOGGER.debug("client got: {}", new String(inBuf)); assertEquals(new String(inBuf), testMessage2); TTransportException expectedException = null; try { saslClientTransport.open(); } catch (TTransportException e) { expectedException = e; } assertNotNull(expectedException); saslClientTransport.close(); } catch (Exception e) { LOGGER.warn("Exception caught", e); throw e; } finally { serverThread.interrupt(); try { serverThread.join(); } catch (InterruptedException e) { // Ah well. } assertNull(serverThread.thrown); } } public void testUnwrappedOpen() throws Exception { testSaslOpen(UNWRAPPED_MECHANISM, UNWRAPPED_PROPS); } public void testWrappedOpen() throws Exception { testSaslOpen(WRAPPED_MECHANISM, WRAPPED_PROPS); } public void testAnonymousOpen() throws Exception { testSaslOpen("ANONYMOUS", null); } /** * Test that we get the proper exceptions thrown back the server when * the client provides invalid password. */ public void testBadPassword() throws Exception { ServerThread serverThread = new ServerThread(UNWRAPPED_MECHANISM, UNWRAPPED_PROPS); serverThread.start(); try { Thread.sleep(1000); } catch (InterruptedException e) { // Ah well. } boolean clientSidePassed = true; try { TSocket clientSocket = new TSocket(HOST, ServerTestBase.PORT); TTransport saslClientTransport = new TSaslClientTransport( UNWRAPPED_MECHANISM, PRINCIPAL, SERVICE, HOST, UNWRAPPED_PROPS, new TestSaslCallbackHandler("NOT THE PASSWORD"), clientSocket); saslClientTransport.open(); clientSidePassed = false; fail("Was able to open transport with bad password"); } catch (TTransportException tte) { LOGGER.error("Exception for bad password", tte); assertNotNull(tte.getMessage()); assertTrue(tte.getMessage().contains("Invalid response")); } finally { serverThread.interrupt(); serverThread.join(); if (clientSidePassed) { assertNotNull(serverThread.thrown); assertTrue(serverThread.thrown.getMessage().contains("Invalid response")); } } } public void testWithServer() throws Exception { new TestTSaslTransportsWithServer().testIt(); } private static class TestTSaslTransportsWithServer extends ServerTestBase { private Thread serverThread; private TServer server; @Override public TTransport getClientTransport(TTransport underlyingTransport) throws Exception { return new TSaslClientTransport( WRAPPED_MECHANISM, PRINCIPAL, SERVICE, HOST, WRAPPED_PROPS, new TestSaslCallbackHandler(PASSWORD), underlyingTransport); } @Override public void startServer(final TProcessor processor, final TProtocolFactory protoFactory, final TTransportFactory factory) throws Exception { serverThread = new Thread() { public void run() { try { // Transport TServerSocket socket = new TServerSocket(PORT); TTransportFactory factory = new TSaslServerTransport.Factory( WRAPPED_MECHANISM, SERVICE, HOST, WRAPPED_PROPS, new TestSaslCallbackHandler(PASSWORD)); server = new TSimpleServer(new Args(socket).processor(processor).transportFactory(factory).protocolFactory(protoFactory)); // Run it LOGGER.debug("Starting the server on port {}", PORT); server.serve(); } catch (Exception e) { e.printStackTrace(); fail(); } } }; serverThread.start(); Thread.sleep(1000); } @Override public void stopServer() throws Exception { server.stop(); try { serverThread.join(); } catch (InterruptedException e) {} } } /** * Implementation of SASL ANONYMOUS, used for testing client-side * initial responses. */ private static class AnonymousClient implements SaslClient { private final String username; private boolean hasProvidedInitialResponse; public AnonymousClient(String username) { this.username = username; } public String getMechanismName() { return "ANONYMOUS"; } public boolean hasInitialResponse() { return true; } public byte[] evaluateChallenge(byte[] challenge) throws SaslException { if (hasProvidedInitialResponse) { throw new SaslException("Already complete!"); } try { hasProvidedInitialResponse = true; return username.getBytes("UTF-8"); } catch (IOException e) { throw new SaslException(e.toString()); } } public boolean isComplete() { return hasProvidedInitialResponse; } public byte[] unwrap(byte[] incoming, int offset, int len) { throw new UnsupportedOperationException(); } public byte[] wrap(byte[] outgoing, int offset, int len) { throw new UnsupportedOperationException(); } public Object getNegotiatedProperty(String propName) { return null; } public void dispose() {} } private static class AnonymousServer implements SaslServer { private String user; public String getMechanismName() { return "ANONYMOUS"; } public byte[] evaluateResponse(byte[] response) throws SaslException { try { this.user = new String(response, "UTF-8"); } catch (IOException e) { throw new SaslException(e.toString()); } return null; } public boolean isComplete() { return user != null; } public String getAuthorizationID() { return user; } public byte[] unwrap(byte[] incoming, int offset, int len) { throw new UnsupportedOperationException(); } public byte[] wrap(byte[] outgoing, int offset, int len) { throw new UnsupportedOperationException(); } public Object getNegotiatedProperty(String propName) { return null; } public void dispose() {} } public static class SaslAnonymousFactory implements SaslClientFactory, SaslServerFactory { public SaslClient createSaslClient( String[] mechanisms, String authorizationId, String protocol, String serverName, Map props, CallbackHandler cbh) { for (String mech : mechanisms) { if ("ANONYMOUS".equals(mech)) { return new AnonymousClient(authorizationId); } } return null; } public SaslServer createSaslServer( String mechanism, String protocol, String serverName, Map props, CallbackHandler cbh) { if ("ANONYMOUS".equals(mechanism)) { return new AnonymousServer(); } return null; } public String[] getMechanismNames(Map props) { return new String[] { "ANONYMOUS" }; } } static { java.security.Security.addProvider(new SaslAnonymousProvider()); } public static class SaslAnonymousProvider extends java.security.Provider { public SaslAnonymousProvider() { super("ThriftSaslAnonymous", 1.0, "Thrift Anonymous SASL provider"); put("SaslClientFactory.ANONYMOUS", SaslAnonymousFactory.class.getName()); put("SaslServerFactory.ANONYMOUS", SaslAnonymousFactory.class.getName()); } } } libthrift-java_0.9.0/test/org/apache/thrift/scheme/0000755000175000017500000000000012035665714023040 5ustar eevanseevans00000000000000libthrift-java_0.9.0/test/org/apache/thrift/scheme/TestStandardScheme.java0000644000175000017500000000265612035665434027440 0ustar eevanseevans00000000000000package org.apache.thrift.scheme; import junit.framework.TestCase; import org.apache.thrift.Fixtures; import org.apache.thrift.TBase; import org.apache.thrift.TDeserializer; import org.apache.thrift.TException; import org.apache.thrift.TSerializer; import org.apache.thrift.protocol.TBinaryProtocol; import org.apache.thrift.protocol.TProtocol; import org.apache.thrift.transport.TMemoryBuffer; import org.apache.thrift.transport.TTransport; import thrift.test.HolyMoley; import thrift.test.Nesting; import thrift.test.OneOfEach; public class TestStandardScheme extends TestCase { TSerializer serializer = new TSerializer(); TDeserializer deserializer = new TDeserializer(); /** * This tests whether the Standard Scheme properly reads structs serialized * using an older version of thrift. */ public void testPersistentStructs() throws TException { readAndCompare(new OneOfEach(), Fixtures.oneOfEach, Fixtures.persistentBytesOneOfEach); readAndCompare(new HolyMoley(), Fixtures.holyMoley, Fixtures.persistentBytesHolyMoley); readAndCompare(new Nesting(), Fixtures.nesting, Fixtures.persistentBytesNesting); } public void readAndCompare(TBase struct, TBase fixture, byte[] inputBytes) throws TException { TTransport trans = new TMemoryBuffer(0); trans.write(inputBytes, 0, inputBytes.length); TProtocol iprot = new TBinaryProtocol(trans); struct.read(iprot); assertEquals(fixture, struct); } } libthrift-java_0.9.0/test/org/apache/thrift/Fixtures.java0000644000175000017500000004505512035665434024260 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import thrift.test.Bonk; import thrift.test.CompactProtoTestStruct; import thrift.test.HolyMoley; import thrift.test.Nesting; import thrift.test.OneOfEach; public class Fixtures { public static final OneOfEach oneOfEach; public static final Nesting nesting; public static final HolyMoley holyMoley; public static final CompactProtoTestStruct compactProtoTestStruct; // These byte arrays are serialized versions of the above structs. // They were serialized in binary protocol using thrift 0.6.x and are used to // test backwards compatibility with respect to the standard scheme. public static final byte[] persistentBytesOneOfEach = new byte[] { (byte) 0x02, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x00, (byte) 0x02, (byte) 0x00, (byte) 0x03, (byte) 0x00, (byte) 0x03, (byte) 0xD6, (byte) 0x06, (byte) 0x00, (byte) 0x04, (byte) 0x69, (byte) 0x78, (byte) 0x08, (byte) 0x00, (byte) 0x05, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x0A, (byte) 0x00, (byte) 0x06, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x65, (byte) 0xA0, (byte) 0xBC, (byte) 0x00, (byte) 0x04, (byte) 0x00, (byte) 0x07, (byte) 0x40, (byte) 0x09, (byte) 0x21, (byte) 0xFB, (byte) 0x54, (byte) 0x44, (byte) 0x2D, (byte) 0x18, (byte) 0x0B, (byte) 0x00, (byte) 0x08, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x0D, (byte) 0x4A, (byte) 0x53, (byte) 0x4F, (byte) 0x4E, (byte) 0x20, (byte) 0x54, (byte) 0x48, (byte) 0x49, (byte) 0x53, (byte) 0x21, (byte) 0x20, (byte) 0x22, (byte) 0x01, (byte) 0x0B, (byte) 0x00, (byte) 0x09, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x2E, (byte) 0xD3, (byte) 0x80, (byte) 0xE2, (byte) 0x85, (byte) 0xAE, (byte) 0xCE, (byte) 0x9D, (byte) 0x20, (byte) 0xD0, (byte) 0x9D, (byte) 0xCE, (byte) 0xBF, (byte) 0xE2, (byte) 0x85, (byte) 0xBF, (byte) 0xD0, (byte) 0xBE, (byte) 0xC9, (byte) 0xA1, (byte) 0xD0, (byte) 0xB3, (byte) 0xD0, (byte) 0xB0, (byte) 0xCF, (byte) 0x81, (byte) 0xE2, (byte) 0x84, (byte) 0x8E, (byte) 0x20, (byte) 0xCE, (byte) 0x91, (byte) 0x74, (byte) 0x74, (byte) 0xCE, (byte) 0xB1, (byte) 0xE2, (byte) 0x85, (byte) 0xBD, (byte) 0xCE, (byte) 0xBA, (byte) 0xEF, (byte) 0xBF, (byte) 0xBD, (byte) 0xE2, (byte) 0x80, (byte) 0xBC, (byte) 0x02, (byte) 0x00, (byte) 0x0A, (byte) 0x00, (byte) 0x0B, (byte) 0x00, (byte) 0x0B, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x06, (byte) 0x62, (byte) 0x61, (byte) 0x73, (byte) 0x65, (byte) 0x36, (byte) 0x34, (byte) 0x0F, (byte) 0x00, (byte) 0x0C, (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x03, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x0F, (byte) 0x00, (byte) 0x0D, (byte) 0x06, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x03, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x02, (byte) 0x00, (byte) 0x03, (byte) 0x0F, (byte) 0x00, (byte) 0x0E, (byte) 0x0A, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x03, (byte) 0x00 }; public static final byte[] persistentBytesNesting = new byte[] { (byte) 0x0C, (byte) 0x00, (byte) 0x01, (byte) 0x08, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x7A, (byte) 0x69, (byte) 0x0B, (byte) 0x00, (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x13, (byte) 0x49, (byte) 0x20, (byte) 0x61, (byte) 0x6D, (byte) 0x20, (byte) 0x61, (byte) 0x20, (byte) 0x62, (byte) 0x6F, (byte) 0x6E, (byte) 0x6B, (byte) 0x2E, (byte) 0x2E, (byte) 0x2E, (byte) 0x20, (byte) 0x78, (byte) 0x6F, (byte) 0x72, (byte) 0x21, (byte) 0x00, (byte) 0x0C, (byte) 0x00, (byte) 0x02, (byte) 0x02, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x00, (byte) 0x02, (byte) 0x00, (byte) 0x03, (byte) 0x00, (byte) 0x03, (byte) 0xD6, (byte) 0x06, (byte) 0x00, (byte) 0x04, (byte) 0x69, (byte) 0x78, (byte) 0x08, (byte) 0x00, (byte) 0x05, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x0A, (byte) 0x00, (byte) 0x06, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x65, (byte) 0xA0, (byte) 0xBC, (byte) 0x00, (byte) 0x04, (byte) 0x00, (byte) 0x07, (byte) 0x40, (byte) 0x09, (byte) 0x21, (byte) 0xFB, (byte) 0x54, (byte) 0x44, (byte) 0x2D, (byte) 0x18, (byte) 0x0B, (byte) 0x00, (byte) 0x08, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x0D, (byte) 0x4A, (byte) 0x53, (byte) 0x4F, (byte) 0x4E, (byte) 0x20, (byte) 0x54, (byte) 0x48, (byte) 0x49, (byte) 0x53, (byte) 0x21, (byte) 0x20, (byte) 0x22, (byte) 0x01, (byte) 0x0B, (byte) 0x00, (byte) 0x09, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x2E, (byte) 0xD3, (byte) 0x80, (byte) 0xE2, (byte) 0x85, (byte) 0xAE, (byte) 0xCE, (byte) 0x9D, (byte) 0x20, (byte) 0xD0, (byte) 0x9D, (byte) 0xCE, (byte) 0xBF, (byte) 0xE2, (byte) 0x85, (byte) 0xBF, (byte) 0xD0, (byte) 0xBE, (byte) 0xC9, (byte) 0xA1, (byte) 0xD0, (byte) 0xB3, (byte) 0xD0, (byte) 0xB0, (byte) 0xCF, (byte) 0x81, (byte) 0xE2, (byte) 0x84, (byte) 0x8E, (byte) 0x20, (byte) 0xCE, (byte) 0x91, (byte) 0x74, (byte) 0x74, (byte) 0xCE, (byte) 0xB1, (byte) 0xE2, (byte) 0x85, (byte) 0xBD, (byte) 0xCE, (byte) 0xBA, (byte) 0xEF, (byte) 0xBF, (byte) 0xBD, (byte) 0xE2, (byte) 0x80, (byte) 0xBC, (byte) 0x02, (byte) 0x00, (byte) 0x0A, (byte) 0x00, (byte) 0x0B, (byte) 0x00, (byte) 0x0B, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x06, (byte) 0x62, (byte) 0x61, (byte) 0x73, (byte) 0x65, (byte) 0x36, (byte) 0x34, (byte) 0x0F, (byte) 0x00, (byte) 0x0C, (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x03, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x0F, (byte) 0x00, (byte) 0x0D, (byte) 0x06, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x03, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x02, (byte) 0x00, (byte) 0x03, (byte) 0x0F, (byte) 0x00, (byte) 0x0E, (byte) 0x0A, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x03, (byte) 0x00, (byte) 0x00 }; public static final byte[] persistentBytesHolyMoley = new byte[] { (byte) 0x0F, (byte) 0x00, (byte) 0x01, (byte) 0x0C, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x02, (byte) 0x02, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x00, (byte) 0x02, (byte) 0x00, (byte) 0x03, (byte) 0x00, (byte) 0x03, (byte) 0x23, (byte) 0x06, (byte) 0x00, (byte) 0x04, (byte) 0x69, (byte) 0x78, (byte) 0x08, (byte) 0x00, (byte) 0x05, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x0A, (byte) 0x00, (byte) 0x06, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x65, (byte) 0xA0, (byte) 0xBC, (byte) 0x00, (byte) 0x04, (byte) 0x00, (byte) 0x07, (byte) 0x40, (byte) 0x09, (byte) 0x21, (byte) 0xFB, (byte) 0x54, (byte) 0x44, (byte) 0x2D, (byte) 0x18, (byte) 0x0B, (byte) 0x00, (byte) 0x08, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x0D, (byte) 0x4A, (byte) 0x53, (byte) 0x4F, (byte) 0x4E, (byte) 0x20, (byte) 0x54, (byte) 0x48, (byte) 0x49, (byte) 0x53, (byte) 0x21, (byte) 0x20, (byte) 0x22, (byte) 0x01, (byte) 0x0B, (byte) 0x00, (byte) 0x09, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x2E, (byte) 0xD3, (byte) 0x80, (byte) 0xE2, (byte) 0x85, (byte) 0xAE, (byte) 0xCE, (byte) 0x9D, (byte) 0x20, (byte) 0xD0, (byte) 0x9D, (byte) 0xCE, (byte) 0xBF, (byte) 0xE2, (byte) 0x85, (byte) 0xBF, (byte) 0xD0, (byte) 0xBE, (byte) 0xC9, (byte) 0xA1, (byte) 0xD0, (byte) 0xB3, (byte) 0xD0, (byte) 0xB0, (byte) 0xCF, (byte) 0x81, (byte) 0xE2, (byte) 0x84, (byte) 0x8E, (byte) 0x20, (byte) 0xCE, (byte) 0x91, (byte) 0x74, (byte) 0x74, (byte) 0xCE, (byte) 0xB1, (byte) 0xE2, (byte) 0x85, (byte) 0xBD, (byte) 0xCE, (byte) 0xBA, (byte) 0xEF, (byte) 0xBF, (byte) 0xBD, (byte) 0xE2, (byte) 0x80, (byte) 0xBC, (byte) 0x02, (byte) 0x00, (byte) 0x0A, (byte) 0x00, (byte) 0x0B, (byte) 0x00, (byte) 0x0B, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x06, (byte) 0x62, (byte) 0x61, (byte) 0x73, (byte) 0x65, (byte) 0x36, (byte) 0x34, (byte) 0x0F, (byte) 0x00, (byte) 0x0C, (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x03, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x0F, (byte) 0x00, (byte) 0x0D, (byte) 0x06, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x03, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x02, (byte) 0x00, (byte) 0x03, (byte) 0x0F, (byte) 0x00, (byte) 0x0E, (byte) 0x0A, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x03, (byte) 0x00, (byte) 0x02, (byte) 0x00, (byte) 0x01, (byte) 0x01, (byte) 0x02, (byte) 0x00, (byte) 0x02, (byte) 0x00, (byte) 0x03, (byte) 0x00, (byte) 0x03, (byte) 0xD6, (byte) 0x06, (byte) 0x00, (byte) 0x04, (byte) 0x69, (byte) 0x78, (byte) 0x08, (byte) 0x00, (byte) 0x05, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x0A, (byte) 0x00, (byte) 0x06, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x65, (byte) 0xA0, (byte) 0xBC, (byte) 0x00, (byte) 0x04, (byte) 0x00, (byte) 0x07, (byte) 0x40, (byte) 0x09, (byte) 0x21, (byte) 0xFB, (byte) 0x54, (byte) 0x44, (byte) 0x2D, (byte) 0x18, (byte) 0x0B, (byte) 0x00, (byte) 0x08, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x0D, (byte) 0x4A, (byte) 0x53, (byte) 0x4F, (byte) 0x4E, (byte) 0x20, (byte) 0x54, (byte) 0x48, (byte) 0x49, (byte) 0x53, (byte) 0x21, (byte) 0x20, (byte) 0x22, (byte) 0x01, (byte) 0x0B, (byte) 0x00, (byte) 0x09, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x2E, (byte) 0xD3, (byte) 0x80, (byte) 0xE2, (byte) 0x85, (byte) 0xAE, (byte) 0xCE, (byte) 0x9D, (byte) 0x20, (byte) 0xD0, (byte) 0x9D, (byte) 0xCE, (byte) 0xBF, (byte) 0xE2, (byte) 0x85, (byte) 0xBF, (byte) 0xD0, (byte) 0xBE, (byte) 0xC9, (byte) 0xA1, (byte) 0xD0, (byte) 0xB3, (byte) 0xD0, (byte) 0xB0, (byte) 0xCF, (byte) 0x81, (byte) 0xE2, (byte) 0x84, (byte) 0x8E, (byte) 0x20, (byte) 0xCE, (byte) 0x91, (byte) 0x74, (byte) 0x74, (byte) 0xCE, (byte) 0xB1, (byte) 0xE2, (byte) 0x85, (byte) 0xBD, (byte) 0xCE, (byte) 0xBA, (byte) 0xEF, (byte) 0xBF, (byte) 0xBD, (byte) 0xE2, (byte) 0x80, (byte) 0xBC, (byte) 0x02, (byte) 0x00, (byte) 0x0A, (byte) 0x00, (byte) 0x0B, (byte) 0x00, (byte) 0x0B, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x06, (byte) 0x62, (byte) 0x61, (byte) 0x73, (byte) 0x65, (byte) 0x36, (byte) 0x34, (byte) 0x0F, (byte) 0x00, (byte) 0x0C, (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x03, (byte) 0x01, (byte) 0x02, (byte) 0x03, (byte) 0x0F, (byte) 0x00, (byte) 0x0D, (byte) 0x06, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x03, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x02, (byte) 0x00, (byte) 0x03, (byte) 0x0F, (byte) 0x00, (byte) 0x0E, (byte) 0x0A, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x03, (byte) 0x00, (byte) 0x0E, (byte) 0x00, (byte) 0x02, (byte) 0x0F, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x03, (byte) 0x0B, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x0B, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x0F, (byte) 0x74, (byte) 0x68, (byte) 0x65, (byte) 0x6E, (byte) 0x20, (byte) 0x61, (byte) 0x20, (byte) 0x6F, (byte) 0x6E, (byte) 0x65, (byte) 0x2C, (byte) 0x20, (byte) 0x74, (byte) 0x77, (byte) 0x6F, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x06, (byte) 0x74, (byte) 0x68, (byte) 0x72, (byte) 0x65, (byte) 0x65, (byte) 0x21, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x06, (byte) 0x46, (byte) 0x4F, (byte) 0x55, (byte) 0x52, (byte) 0x21, (byte) 0x21, (byte) 0x0B, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x09, (byte) 0x61, (byte) 0x6E, (byte) 0x64, (byte) 0x20, (byte) 0x61, (byte) 0x20, (byte) 0x6F, (byte) 0x6E, (byte) 0x65, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x09, (byte) 0x61, (byte) 0x6E, (byte) 0x64, (byte) 0x20, (byte) 0x61, (byte) 0x20, (byte) 0x74, (byte) 0x77, (byte) 0x6F, (byte) 0x0D, (byte) 0x00, (byte) 0x03, (byte) 0x0B, (byte) 0x0F, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x03, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x03, (byte) 0x74, (byte) 0x77, (byte) 0x6F, (byte) 0x0C, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x02, (byte) 0x08, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x01, (byte) 0x0B, (byte) 0x00, (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x05, (byte) 0x57, (byte) 0x61, (byte) 0x69, (byte) 0x74, (byte) 0x2E, (byte) 0x00, (byte) 0x08, (byte) 0x00, (byte) 0x01, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x02, (byte) 0x0B, (byte) 0x00, (byte) 0x02, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x05, (byte) 0x57, (byte) 0x68, (byte) 0x61, (byte) 0x74, (byte) 0x3F, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x05, (byte) 0x74, (byte) 0x68, (byte) 0x72, (byte) 0x65, (byte) 0x65, (byte) 0x0C, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x04, (byte) 0x7A, (byte) 0x65, (byte) 0x72, (byte) 0x6F, (byte) 0x0C, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00, (byte) 0x00 }; private static final byte[] kUnicodeBytes = { (byte) 0xd3, (byte) 0x80, (byte) 0xe2, (byte) 0x85, (byte) 0xae, (byte) 0xce, (byte) 0x9d, (byte) 0x20, (byte) 0xd0, (byte) 0x9d, (byte) 0xce, (byte) 0xbf, (byte) 0xe2, (byte) 0x85, (byte) 0xbf, (byte) 0xd0, (byte) 0xbe, (byte) 0xc9, (byte) 0xa1, (byte) 0xd0, (byte) 0xb3, (byte) 0xd0, (byte) 0xb0, (byte) 0xcf, (byte) 0x81, (byte) 0xe2, (byte) 0x84, (byte) 0x8e, (byte) 0x20, (byte) 0xce, (byte) 0x91, (byte) 0x74, (byte) 0x74, (byte) 0xce, (byte) 0xb1, (byte) 0xe2, (byte) 0x85, (byte) 0xbd, (byte) 0xce, (byte) 0xba, (byte) 0x83, (byte) 0xe2, (byte) 0x80, (byte) 0xbc }; static { try { oneOfEach = new OneOfEach(); oneOfEach.setIm_true(true); oneOfEach.setIm_false(false); oneOfEach.setA_bite((byte) 0xd6); oneOfEach.setInteger16((short) 27000); oneOfEach.setInteger32(1 << 24); oneOfEach.setInteger64((long) 6000 * 1000 * 1000); oneOfEach.setDouble_precision(Math.PI); oneOfEach.setSome_characters("JSON THIS! \"\1"); oneOfEach.setZomg_unicode(new String(kUnicodeBytes, "UTF-8")); oneOfEach.setBase64(ByteBuffer.wrap("base64".getBytes())); // byte, i16, and i64 lists are populated by default constructor Bonk bonk = new Bonk(); bonk.setType(31337); bonk.setMessage("I am a bonk... xor!"); nesting = new Nesting(bonk, oneOfEach); holyMoley = new HolyMoley(); ArrayList big = new ArrayList(); big.add(new OneOfEach(oneOfEach)); big.add(nesting.my_ooe); holyMoley.setBig(big); holyMoley.getBig().get(0).setA_bite((byte) 0x22); holyMoley.getBig().get(0).setA_bite((byte) 0x23); holyMoley.setContain(new HashSet>()); ArrayList stage1 = new ArrayList(2); stage1.add("and a one"); stage1.add("and a two"); holyMoley.getContain().add(stage1); stage1 = new ArrayList(3); stage1.add("then a one, two"); stage1.add("three!"); stage1.add("FOUR!!"); holyMoley.getContain().add(stage1); stage1 = new ArrayList(0); holyMoley.getContain().add(stage1); ArrayList stage2 = new ArrayList(); holyMoley.setBonks(new HashMap>()); // one empty holyMoley.getBonks().put("zero", stage2); // one with two stage2 = new ArrayList(); Bonk b = new Bonk(); b.setType(1); b.setMessage("Wait."); stage2.add(b); b = new Bonk(); b.setType(2); b.setMessage("What?"); stage2.add(b); holyMoley.getBonks().put("two", stage2); // one with three stage2 = new ArrayList(); b = new Bonk(); b.setType(3); b.setMessage("quoth"); b = new Bonk(); b.setType(4); b.setMessage("the raven"); b = new Bonk(); b.setType(5); b.setMessage("nevermore"); holyMoley.getBonks().put("three", stage2); // superhuge compact proto test struct compactProtoTestStruct = new CompactProtoTestStruct( thrift.test.DebugProtoTestConstants.COMPACT_TEST); compactProtoTestStruct.setA_binary(ByteBuffer.wrap(new byte[] { 0, 1, 2, 3, 4, 5, 6, 7, 8 })); } catch (Exception e) { throw new RuntimeException(e); } } } libthrift-java_0.9.0/test/org/apache/thrift/TestTDeserializer.java0000644000175000017500000001455712035665434026060 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; import java.nio.ByteBuffer; import junit.framework.TestCase; import org.apache.thrift.protocol.TBinaryProtocol; import org.apache.thrift.protocol.TCompactProtocol; import org.apache.thrift.protocol.TJSONProtocol; import org.apache.thrift.protocol.TProtocolFactory; import thrift.test.Backwards; import thrift.test.OneOfEach; import thrift.test.PrimitiveThenStruct; import thrift.test.StructWithAUnion; import thrift.test.TestUnion; public class TestTDeserializer extends TestCase { private static final TProtocolFactory[] PROTOCOLS = new TProtocolFactory[] { new TBinaryProtocol.Factory(), new TCompactProtocol.Factory(), new TJSONProtocol.Factory() }; public void testPartialDeserialize() throws Exception { //Root:StructWithAUnion // 1:Union // 1.3:OneOfEach OneOfEach level3OneOfEach = Fixtures.oneOfEach; TestUnion level2TestUnion = new TestUnion(TestUnion._Fields.STRUCT_FIELD, level3OneOfEach); StructWithAUnion level1SWU = new StructWithAUnion(level2TestUnion); Backwards bw = new Backwards(2, 1); PrimitiveThenStruct pts = new PrimitiveThenStruct(12345, 67890, bw); for (TProtocolFactory factory : PROTOCOLS) { //Level 2 test testPartialDeserialize(factory, level1SWU, new TestUnion(), level2TestUnion, StructWithAUnion._Fields.TEST_UNION); //Level 3 on 3rd field test testPartialDeserialize(factory, level1SWU, new OneOfEach(), level3OneOfEach, StructWithAUnion._Fields.TEST_UNION, TestUnion._Fields.STRUCT_FIELD); //Test early termination when traversed path Field.id exceeds the one being searched for testPartialDeserialize(factory, level1SWU, new OneOfEach(), new OneOfEach(), StructWithAUnion._Fields.TEST_UNION, TestUnion._Fields.I32_FIELD); //Test that readStructBegin isn't called on primitive testPartialDeserialize(factory, pts, new Backwards(), bw, PrimitiveThenStruct._Fields.BW); //Test primitive types TDeserializer deserializer = new TDeserializer(factory); Boolean expectedBool = level3OneOfEach.isIm_true(); Boolean resultBool = deserializer.partialDeserializeBool(serialize(level1SWU, factory), StructWithAUnion._Fields.TEST_UNION, TestUnion._Fields.STRUCT_FIELD, OneOfEach._Fields.IM_TRUE); assertEquals(expectedBool, resultBool); Byte expectedByte = level3OneOfEach.getA_bite(); Byte resultByte = deserializer.partialDeserializeByte(serialize(level1SWU, factory), StructWithAUnion._Fields.TEST_UNION, TestUnion._Fields.STRUCT_FIELD, OneOfEach._Fields.A_BITE); assertEquals(expectedByte, resultByte); Double expectedDouble = level3OneOfEach.getDouble_precision(); Double resultDouble = deserializer.partialDeserializeDouble(serialize(level1SWU, factory), StructWithAUnion._Fields.TEST_UNION, TestUnion._Fields.STRUCT_FIELD, OneOfEach._Fields.DOUBLE_PRECISION); assertEquals(expectedDouble, resultDouble); Short expectedI16 = level3OneOfEach.getInteger16(); Short resultI16 = deserializer.partialDeserializeI16(serialize(level1SWU, factory), StructWithAUnion._Fields.TEST_UNION, TestUnion._Fields.STRUCT_FIELD, OneOfEach._Fields.INTEGER16); assertEquals(expectedI16, resultI16); Integer expectedI32 = level3OneOfEach.getInteger32(); Integer resultI32 = deserializer.partialDeserializeI32(serialize(level1SWU, factory), StructWithAUnion._Fields.TEST_UNION, TestUnion._Fields.STRUCT_FIELD, OneOfEach._Fields.INTEGER32); assertEquals(expectedI32, resultI32); Long expectedI64 = level3OneOfEach.getInteger64(); Long resultI64= deserializer.partialDeserializeI64(serialize(level1SWU, factory), StructWithAUnion._Fields.TEST_UNION, TestUnion._Fields.STRUCT_FIELD, OneOfEach._Fields.INTEGER64); assertEquals(expectedI64, resultI64); String expectedString = level3OneOfEach.getSome_characters(); String resultString = deserializer.partialDeserializeString(serialize(level1SWU, factory), StructWithAUnion._Fields.TEST_UNION, TestUnion._Fields.STRUCT_FIELD, OneOfEach._Fields.SOME_CHARACTERS); assertEquals(expectedString, resultString); byte[] expectedBinary = level3OneOfEach.getBase64(); ByteBuffer resultBinary = deserializer.partialDeserializeByteArray(serialize(level1SWU, factory), StructWithAUnion._Fields.TEST_UNION, TestUnion._Fields.STRUCT_FIELD, OneOfEach._Fields.BASE64); assertEquals(expectedBinary.length, resultBinary.limit() - resultBinary.position() - resultBinary.arrayOffset()); assertEquals(ByteBuffer.wrap(expectedBinary), resultBinary); // Test field id in Union short id = deserializer.partialDeserializeSetFieldIdInUnion(serialize(level1SWU, factory), StructWithAUnion._Fields.TEST_UNION); assertEquals(level2TestUnion.getSetField().getThriftFieldId(), id); } } public static void testPartialDeserialize(TProtocolFactory protocolFactory, TBase input, TBase output, TBase expected, TFieldIdEnum fieldIdPathFirst, TFieldIdEnum ... fieldIdPathRest) throws TException { byte[] record = serialize(input, protocolFactory); TDeserializer deserializer = new TDeserializer(protocolFactory); for (int i = 0; i < 2; i++) { TBase outputCopy = output.deepCopy(); deserializer.partialDeserialize(outputCopy, record, fieldIdPathFirst, fieldIdPathRest); assertEquals("on attempt " + i + ", with " + protocolFactory.toString() + ", expected " + expected + " but got " + outputCopy, expected, outputCopy); } } private static byte[] serialize(TBase input, TProtocolFactory protocolFactory) throws TException{ return new TSerializer(protocolFactory).serialize(input); } } libthrift-java_0.9.0/test/org/apache/thrift/TestTUnion.java0000644000175000017500000002003612035665434024513 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import junit.framework.TestCase; import org.apache.thrift.protocol.TBinaryProtocol; import org.apache.thrift.protocol.TProtocol; import org.apache.thrift.protocol.TTupleProtocol; import org.apache.thrift.transport.TMemoryBuffer; import thrift.test.ComparableUnion; import thrift.test.Empty; import thrift.test.RandomStuff; import thrift.test.SomeEnum; import thrift.test.StructWithAUnion; import thrift.test.TestUnion; import thrift.test.TestUnionMinusStringField; public class TestTUnion extends TestCase { public void testBasic() throws Exception { TestUnion union = new TestUnion(); assertFalse(union.isSet()); assertFalse(union.isSetI32_field()); assertNull(union.getFieldValue()); union = new TestUnion(TestUnion._Fields.I32_FIELD, 25); assertEquals(Integer.valueOf(25), union.getFieldValue()); assertEquals(Integer.valueOf(25), union.getFieldValue(TestUnion._Fields.I32_FIELD)); assertTrue(union.isSetI32_field()); try { union.getFieldValue(TestUnion._Fields.STRING_FIELD); fail("should have thrown an exception"); } catch (IllegalArgumentException e) { // cool! } union = new TestUnion(); // should not throw an exception here union.hashCode(); union.setI32_field(1); assertEquals(1, union.getI32_field()); union.hashCode(); assertFalse(union.isSetString_field()); try { union.getString_field(); fail("should have thrown an exception"); } catch (Exception e) { // sweet } union = TestUnion.i32_field(1); assertFalse(union.equals((TestUnion)null)); union = TestUnion.enum_field(SomeEnum.ONE); union.hashCode(); union = new TestUnion(); // should not throw an exception union.toString(); } public void testCompareTo() throws Exception { ComparableUnion cu = ComparableUnion.string_field("a"); ComparableUnion cu2 = ComparableUnion.string_field("b"); assertTrue(cu.compareTo(cu) == 0); assertTrue(cu2.compareTo(cu2) == 0); assertTrue(cu.compareTo(cu2) < 0); assertTrue(cu2.compareTo(cu) > 0); cu2 = ComparableUnion.binary_field(ByteBuffer.wrap(new byte[]{2})); assertTrue(cu.compareTo(cu2) < 0); assertTrue(cu2.compareTo(cu) > 0); cu = ComparableUnion.binary_field(ByteBuffer.wrap(new byte[]{1})); assertTrue(cu.compareTo(cu2) < 0); assertTrue(cu2.compareTo(cu) > 0); TestUnion union1 = new TestUnion(TestUnion._Fields.STRUCT_LIST, new ArrayList()); TestUnion union2 = new TestUnion(TestUnion._Fields.STRUCT_LIST, new ArrayList()); assertTrue(union1.compareTo(union2) == 0); TestUnion union3 = new TestUnion(TestUnion._Fields.I32_SET, new HashSet()); Set i32_set = new HashSet(); i32_set.add(1); TestUnion union4 = new TestUnion(TestUnion._Fields.I32_SET, i32_set); assertTrue(union3.compareTo(union4) < 0); Map i32_map = new HashMap(); i32_map.put(1,1); TestUnion union5 = new TestUnion(TestUnion._Fields.I32_MAP, i32_map); TestUnion union6 = new TestUnion(TestUnion._Fields.I32_MAP, new HashMap()); assertTrue(union5.compareTo(union6) > 0); } public void testEquality() throws Exception { TestUnion union = new TestUnion(TestUnion._Fields.I32_FIELD, 25); TestUnion otherUnion = new TestUnion(TestUnion._Fields.STRING_FIELD, "blah!!!"); assertFalse(union.equals(otherUnion)); otherUnion = new TestUnion(TestUnion._Fields.I32_FIELD, 400); assertFalse(union.equals(otherUnion)); otherUnion = new TestUnion(TestUnion._Fields.OTHER_I32_FIELD, 25); assertFalse(union.equals(otherUnion)); } public void testSerialization() throws Exception { TestUnion union = new TestUnion(TestUnion._Fields.I32_FIELD, 25); union.setI32_set(Collections.singleton(42)); TMemoryBuffer buf = new TMemoryBuffer(0); TProtocol proto = new TBinaryProtocol(buf); union.write(proto); TestUnion u2 = new TestUnion(); u2.read(proto); assertEquals(u2, union); StructWithAUnion swau = new StructWithAUnion(u2); buf = new TMemoryBuffer(0); proto = new TBinaryProtocol(buf); swau.write(proto); StructWithAUnion swau2 = new StructWithAUnion(); assertFalse(swau2.equals(swau)); swau2.read(proto); assertEquals(swau2, swau); // this should NOT throw an exception. buf = new TMemoryBuffer(0); proto = new TBinaryProtocol(buf); swau.write(proto); new Empty().read(proto); } public void testTupleProtocolSerialization () throws Exception { TestUnion union = new TestUnion(TestUnion._Fields.I32_FIELD, 25); union.setI32_set(Collections.singleton(42)); TMemoryBuffer buf = new TMemoryBuffer(0); TProtocol proto = new TTupleProtocol(buf); union.write(proto); TestUnion u2 = new TestUnion(); u2.read(proto); assertEquals(u2, union); StructWithAUnion swau = new StructWithAUnion(u2); buf = new TMemoryBuffer(0); proto = new TBinaryProtocol(buf); swau.write(proto); StructWithAUnion swau2 = new StructWithAUnion(); assertFalse(swau2.equals(swau)); swau2.read(proto); assertEquals(swau2, swau); // this should NOT throw an exception. buf = new TMemoryBuffer(0); proto = new TTupleProtocol(buf); swau.write(proto); new Empty().read(proto); } public void testSkip() throws Exception { TestUnion tu = TestUnion.string_field("string"); byte[] tuSerialized = new TSerializer().serialize(tu); TestUnionMinusStringField tums = new TestUnionMinusStringField(); new TDeserializer().deserialize(tums, tuSerialized); assertNull(tums.getSetField()); assertNull(tums.getFieldValue()); } public void testDeepCopy() throws Exception { byte[] bytes = {1, 2, 3}; ByteBuffer value = ByteBuffer.wrap(bytes); ComparableUnion cu = ComparableUnion.binary_field(value); ComparableUnion copy = cu.deepCopy(); assertEquals(cu, copy); assertNotSame(cu.bufferForBinary_field().array(), copy.bufferForBinary_field().array()); } public void testToString() throws Exception { byte[] bytes = {1, 2, 3}; ByteBuffer value = ByteBuffer.wrap(bytes); ComparableUnion cu = ComparableUnion.binary_field(value); String expectedString = ""; assertEquals(expectedString, cu.toString()); } public void testJavaSerializable() throws Exception { ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(baos); TestUnion tu = TestUnion.string_field("string"); // Serialize tu the Java way... oos.writeObject(tu); byte[] serialized = baos.toByteArray(); // Attempt to deserialize it ByteArrayInputStream bais = new ByteArrayInputStream(serialized); ObjectInputStream ois = new ObjectInputStream(bais); TestUnion tu2 = (TestUnion) ois.readObject(); assertEquals(tu, tu2); } } libthrift-java_0.9.0/test/org/apache/thrift/server/0000755000175000017500000000000012035665714023102 5ustar eevanseevans00000000000000libthrift-java_0.9.0/test/org/apache/thrift/server/ServerTestBase.java0000644000175000017500000004263212035665434026654 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.server; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import junit.framework.TestCase; import org.apache.thrift.TException; import org.apache.thrift.TProcessor; import org.apache.thrift.protocol.TBinaryProtocol; import org.apache.thrift.protocol.TCompactProtocol; import org.apache.thrift.protocol.TProtocol; import org.apache.thrift.protocol.TProtocolFactory; import org.apache.thrift.transport.TFramedTransport; import org.apache.thrift.transport.TSocket; import org.apache.thrift.transport.TTransport; import org.apache.thrift.transport.TTransportFactory; import org.apache.thrift.transport.TFramedTransport.Factory; import thrift.test.Insanity; import thrift.test.Numberz; import thrift.test.ThriftTest; import thrift.test.Xception; import thrift.test.Xception2; import thrift.test.Xtruct; import thrift.test.Xtruct2; public abstract class ServerTestBase extends TestCase { public static class TestHandler implements ThriftTest.Iface { public TestHandler() {} public void testVoid() { System.out.print("testVoid()\n"); } public String testString(String thing) { System.out.print("testString(\"" + thing + "\")\n"); return thing; } public byte testByte(byte thing) { System.out.print("testByte(" + thing + ")\n"); return thing; } public int testI32(int thing) { System.out.print("testI32(" + thing + ")\n"); return thing; } public long testI64(long thing) { System.out.print("testI64(" + thing + ")\n"); return thing; } public double testDouble(double thing) { System.out.print("testDouble(" + thing + ")\n"); return thing; } public Xtruct testStruct(Xtruct thing) { System.out.print("testStruct({" + "\"" + thing.string_thing + "\", " + thing.byte_thing + ", " + thing.i32_thing + ", " + thing.i64_thing + "})\n"); return thing; } public Xtruct2 testNest(Xtruct2 nest) { Xtruct thing = nest.struct_thing; System.out.print("testNest({" + nest.byte_thing + ", {" + "\"" + thing.string_thing + "\", " + thing.byte_thing + ", " + thing.i32_thing + ", " + thing.i64_thing + "}, " + nest.i32_thing + "})\n"); return nest; } public Map testMap(Map thing) { System.out.print("testMap({"); System.out.print(thing); System.out.print("})\n"); return thing; } public Map testStringMap(Map thing) { System.out.print("testStringMap({"); System.out.print(thing); System.out.print("})\n"); return thing; } public Set testSet(Set thing) { System.out.print("testSet({"); boolean first = true; for (int elem : thing) { if (first) { first = false; } else { System.out.print(", "); } System.out.print(elem); } System.out.print("})\n"); return thing; } public List testList(List thing) { System.out.print("testList({"); boolean first = true; for (int elem : thing) { if (first) { first = false; } else { System.out.print(", "); } System.out.print(elem); } System.out.print("})\n"); return thing; } public Numberz testEnum(Numberz thing) { System.out.print("testEnum(" + thing + ")\n"); return thing; } public long testTypedef(long thing) { System.out.print("testTypedef(" + thing + ")\n"); return thing; } public Map> testMapMap(int hello) { System.out.print("testMapMap(" + hello + ")\n"); Map> mapmap = new HashMap>(); HashMap pos = new HashMap(); HashMap neg = new HashMap(); for (int i = 1; i < 5; i++) { pos.put(i, i); neg.put(-i, -i); } mapmap.put(4, pos); mapmap.put(-4, neg); return mapmap; } public Map> testInsanity(Insanity argument) { System.out.print("testInsanity()\n"); Xtruct hello = new Xtruct(); hello.string_thing = "Hello2"; hello.byte_thing = 2; hello.i32_thing = 2; hello.i64_thing = 2; Xtruct goodbye = new Xtruct(); goodbye.string_thing = "Goodbye4"; goodbye.byte_thing = (byte)4; goodbye.i32_thing = 4; goodbye.i64_thing = (long)4; Insanity crazy = new Insanity(); crazy.userMap = new HashMap(); crazy.userMap.put(Numberz.EIGHT, (long)8); crazy.userMap.put(Numberz.FIVE, (long)5); crazy.xtructs = new ArrayList(); crazy.xtructs.add(goodbye); crazy.xtructs.add(hello); HashMap first_map = new HashMap(); HashMap second_map = new HashMap();; first_map.put(Numberz.TWO, crazy); first_map.put(Numberz.THREE, crazy); Insanity looney = new Insanity(); second_map.put(Numberz.SIX, looney); Map> insane = new HashMap>(); insane.put((long)1, first_map); insane.put((long)2, second_map); return insane; } public Xtruct testMulti(byte arg0, int arg1, long arg2, Map arg3, Numberz arg4, long arg5) { System.out.print("testMulti()\n"); Xtruct hello = new Xtruct();; hello.string_thing = "Hello2"; hello.byte_thing = arg0; hello.i32_thing = arg1; hello.i64_thing = arg2; return hello; } public void testException(String arg) throws Xception, TException { System.out.print("testException("+arg+")\n"); if (arg.equals("Xception")) { Xception x = new Xception(); x.errorCode = 1001; x.message = arg; throw x; } else if (arg.equals("ApplicationException")) { throw new TException(arg); } else { Xtruct result = new Xtruct(); result.string_thing = arg; } return; } public Xtruct testMultiException(String arg0, String arg1) throws Xception, Xception2 { System.out.print("testMultiException(" + arg0 + ", " + arg1 + ")\n"); if (arg0.equals("Xception")) { Xception x = new Xception(); x.errorCode = 1001; x.message = "This is an Xception"; throw x; } else if (arg0.equals("Xception2")) { Xception2 x = new Xception2(); x.errorCode = 2002; x.struct_thing = new Xtruct(); x.struct_thing.string_thing = "This is an Xception2"; throw x; } Xtruct result = new Xtruct(); result.string_thing = arg1; return result; } public void testOneway(int sleepFor) { System.out.println("testOneway(" + Integer.toString(sleepFor) + ") => sleeping..."); try { Thread.sleep(sleepFor * 1000); System.out.println("Done sleeping!"); } catch (InterruptedException ie) { throw new RuntimeException(ie); } } } // class TestHandler private static final List PROTOCOLS = Arrays.asList( new TBinaryProtocol.Factory(), new TCompactProtocol.Factory()); public static final String HOST = "localhost"; public static final int PORT = Integer.valueOf( System.getProperty("test.port", "9090")); protected static final int SOCKET_TIMEOUT = 1000; private static final Xtruct XSTRUCT = new Xtruct("Zero", (byte) 1, -3, -5); private static final Xtruct2 XSTRUCT2 = new Xtruct2((byte)1, XSTRUCT, 5); public void startServer(TProcessor processor, TProtocolFactory protoFactory) throws Exception{ startServer(processor, protoFactory, null); } public abstract void startServer(TProcessor processor, TProtocolFactory protoFactory, TTransportFactory factory) throws Exception; public abstract void stopServer() throws Exception; public abstract TTransport getClientTransport(TTransport underlyingTransport) throws Exception; private void testByte(ThriftTest.Client testClient) throws TException { byte i8 = testClient.testByte((byte)1); assertEquals(1, i8); } private void testDouble(ThriftTest.Client testClient) throws TException { double dub = testClient.testDouble(5.325098235); assertEquals(5.325098235, dub); } private void testEnum(ThriftTest.Client testClient) throws TException { assertEquals(Numberz.ONE, testClient.testEnum(Numberz.ONE)); assertEquals(Numberz.TWO, testClient.testEnum(Numberz.TWO)); assertEquals(Numberz.THREE, testClient.testEnum(Numberz.THREE)); assertEquals(Numberz.FIVE, testClient.testEnum(Numberz.FIVE)); assertEquals(Numberz.EIGHT, testClient.testEnum(Numberz.EIGHT)); } private void testI32(ThriftTest.Client testClient) throws TException { int i32 = testClient.testI32(-1); assertEquals(i32, -1); } private void testI64(ThriftTest.Client testClient) throws TException { long i64 = testClient.testI64(-34359738368L); assertEquals(i64, -34359738368L); } // todo: add assertions private void testInsanity(ThriftTest.Client testClient) throws TException { Insanity insane; insane = new Insanity(); insane.userMap = new HashMap(); insane.userMap.put(Numberz.FIVE, (long)5000); Xtruct truck = new Xtruct(); truck.string_thing = "Truck"; truck.byte_thing = (byte)8; truck.i32_thing = 8; truck.i64_thing = 8; insane.xtructs = new ArrayList(); insane.xtructs.add(truck); System.out.print("testInsanity()"); Map> whoa = testClient.testInsanity(insane); System.out.print(" = {"); for (long key : whoa.keySet()) { Map val = whoa.get(key); System.out.print(key + " => {"); for (Numberz k2 : val.keySet()) { Insanity v2 = val.get(k2); System.out.print(k2 + " => {"); Map userMap = v2.userMap; System.out.print("{"); if (userMap != null) { for (Numberz k3 : userMap.keySet()) { System.out.print(k3 + " => " + userMap.get(k3) + ", "); } } System.out.print("}, "); List xtructs = v2.xtructs; System.out.print("{"); if (xtructs != null) { for (Xtruct x : xtructs) { System.out.print("{" + "\"" + x.string_thing + "\", " + x.byte_thing + ", " + x.i32_thing + ", "+ x.i64_thing + "}, "); } } System.out.print("}"); System.out.print("}, "); } System.out.print("}, "); } System.out.print("}\n"); } public void testIt() throws Exception { for (TProtocolFactory protoFactory : getProtocols()) { TestHandler handler = new TestHandler(); ThriftTest.Processor processor = new ThriftTest.Processor(handler); startServer(processor, protoFactory); TSocket socket = new TSocket(HOST, PORT); socket.setTimeout(SOCKET_TIMEOUT); TTransport transport = getClientTransport(socket); TProtocol protocol = protoFactory.getProtocol(transport); ThriftTest.Client testClient = new ThriftTest.Client(protocol); open(transport); testVoid(testClient); testString(testClient); testByte(testClient); testI32(testClient); testI64(testClient); testDouble(testClient); testStruct(testClient); testNestedStruct(testClient); testMap(testClient); testStringMap(testClient); testSet(testClient); testList(testClient); testEnum(testClient); testTypedef(testClient); testNestedMap(testClient); testInsanity(testClient); testOneway(testClient); testException(testClient); transport.close(); stopServer(); } } public void open(TTransport transport) throws Exception { transport.open(); } public List getProtocols() { return PROTOCOLS; } private void testList(ThriftTest.Client testClient) throws TException { List listout = new ArrayList(); for (int i = -2; i < 3; ++i) { listout.add(i); } List listin = testClient.testList(listout); assertEquals(listout, listin); } private void testMap(ThriftTest.Client testClient) throws TException { Map mapout = new HashMap(); for (int i = 0; i < 5; ++i) { mapout.put(i, i-10); } Map mapin = testClient.testMap(mapout); assertEquals(mapout, mapin); } private void testStringMap(ThriftTest.Client testClient) throws TException { Map mapout = new HashMap(); mapout.put("a", "123"); mapout.put(" x y ", " with spaces "); mapout.put("same", "same"); mapout.put("0", "numeric key"); Map mapin = testClient.testStringMap(mapout); assertEquals(mapout, mapin); } private void testNestedMap(ThriftTest.Client testClient) throws TException { Map> mm = testClient.testMapMap(1); Map> mapmap = new HashMap>(); HashMap pos = new HashMap(); HashMap neg = new HashMap(); for (int i = 1; i < 5; i++) { pos.put(i, i); neg.put(-i, -i); } mapmap.put(4, pos); mapmap.put(-4, neg); assertEquals(mapmap, mm); } private void testNestedStruct(ThriftTest.Client testClient) throws TException { Xtruct2 in2 = testClient.testNest(XSTRUCT2); assertEquals(XSTRUCT2, in2); } private void testOneway(ThriftTest.Client testClient) throws Exception { testClient.testOneway(3); } private void testSet(ThriftTest.Client testClient) throws TException { Set setout = new HashSet(); for (int i = -2; i < 3; ++i) { setout.add(i); } Set setin = testClient.testSet(setout); assertEquals(setout, setin); } private void testString(ThriftTest.Client testClient) throws TException { String s = testClient.testString("Test"); assertEquals("Test", s); } private void testStruct(ThriftTest.Client testClient) throws TException { assertEquals(XSTRUCT, testClient.testStruct(XSTRUCT)); } private void testTypedef(ThriftTest.Client testClient) throws TException { assertEquals(309858235082523L, testClient.testTypedef(309858235082523L)); } private void testVoid(ThriftTest.Client testClient) throws TException { testClient.testVoid(); } private static class CallCountingTransportFactory extends TTransportFactory { public int count = 0; private final Factory factory; public CallCountingTransportFactory(Factory factory) { this.factory = factory; } @Override public TTransport getTransport(TTransport trans) { count++; return factory.getTransport(trans); } } public void testTransportFactory() throws Exception { for (TProtocolFactory protoFactory : getProtocols()) { TestHandler handler = new TestHandler(); ThriftTest.Processor processor = new ThriftTest.Processor(handler); final CallCountingTransportFactory factory = new CallCountingTransportFactory(new TFramedTransport.Factory()); startServer(processor, protoFactory, factory); assertEquals(0, factory.count); TSocket socket = new TSocket(HOST, PORT); socket.setTimeout(SOCKET_TIMEOUT); TTransport transport = getClientTransport(socket); open(transport); TProtocol protocol = protoFactory.getProtocol(transport); ThriftTest.Client testClient = new ThriftTest.Client(protocol); assertEquals(0, testClient.testByte((byte) 0)); assertEquals(2, factory.count); stopServer(); } } private void testException(ThriftTest.Client testClient) throws TException, Xception { //@TODO testException //testClient.testException("no Exception"); /*try { testClient.testException("Xception"); } catch(Xception e) { assertEquals(e.message, "Xception"); }*/ /*try { testClient.testException("ApplicationException"); } catch(TException e) { assertEquals(e.message, "ApplicationException"); }*/ } } libthrift-java_0.9.0/test/org/apache/thrift/server/TestThreadedSelectorServer.java0000644000175000017500000000251512035665434031217 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.server; import org.apache.thrift.TProcessor; import org.apache.thrift.protocol.TProtocolFactory; import org.apache.thrift.server.TThreadedSelectorServer.Args; import org.apache.thrift.transport.TNonblockingServerSocket; public class TestThreadedSelectorServer extends TestNonblockingServer { protected TServer getServer(TProcessor processor, TNonblockingServerSocket socket, TProtocolFactory protoFactory) { return new TThreadedSelectorServer(new Args(socket).processor(processor).protocolFactory(protoFactory)); } } libthrift-java_0.9.0/test/org/apache/thrift/server/TestHsHaServer.java0000644000175000017500000000245112035665434026620 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.server; import org.apache.thrift.TProcessor; import org.apache.thrift.protocol.TProtocolFactory; import org.apache.thrift.server.THsHaServer.Args; import org.apache.thrift.transport.TNonblockingServerSocket; public class TestHsHaServer extends TestNonblockingServer { protected TServer getServer(TProcessor processor, TNonblockingServerSocket socket, TProtocolFactory protoFactory) { return new THsHaServer(new Args(socket).processor(processor).protocolFactory(protoFactory)); } } libthrift-java_0.9.0/test/org/apache/thrift/server/TestNonblockingServer.java0000644000175000017500000000775412035665434030253 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.server; import org.apache.thrift.TProcessor; import org.apache.thrift.protocol.TProtocol; import org.apache.thrift.protocol.TProtocolFactory; import org.apache.thrift.server.TNonblockingServer.Args; import org.apache.thrift.transport.TFramedTransport; import org.apache.thrift.transport.TNonblockingServerSocket; import org.apache.thrift.transport.TSocket; import org.apache.thrift.transport.TTransport; import org.apache.thrift.transport.TTransportException; import org.apache.thrift.transport.TTransportFactory; import thrift.test.ThriftTest; public class TestNonblockingServer extends ServerTestBase { private Thread serverThread; private TServer server; private static final int NUM_QUERIES = 1000; protected TServer getServer(TProcessor processor, TNonblockingServerSocket socket, TProtocolFactory protoFactory, TTransportFactory factory) { final Args args = new Args(socket).processor(processor).protocolFactory(protoFactory); if (factory != null) { args.transportFactory(factory); } return new TNonblockingServer(args); } @Override public void startServer(final TProcessor processor, final TProtocolFactory protoFactory, final TTransportFactory factory) throws Exception { serverThread = new Thread() { public void run() { try { // Transport TNonblockingServerSocket tServerSocket = new TNonblockingServerSocket(PORT); server = getServer(processor, tServerSocket, protoFactory, factory); // Run it System.out.println("Starting the server on port " + PORT + "..."); server.serve(); } catch (Exception e) { e.printStackTrace(); fail(); } } }; serverThread.start(); Thread.sleep(1000); } @Override public void stopServer() throws Exception { server.stop(); try { serverThread.join(); } catch (InterruptedException e) {} } @Override public TTransport getClientTransport(TTransport underlyingTransport) throws Exception { return new TFramedTransport(underlyingTransport); } public void testCleanupAllSelectionKeys() throws Exception { for (TProtocolFactory protoFactory : getProtocols()) { TestHandler handler = new TestHandler(); ThriftTest.Processor processor = new ThriftTest.Processor(handler); startServer(processor, protoFactory); TSocket socket = new TSocket(HOST, PORT); socket.setTimeout(SOCKET_TIMEOUT); TTransport transport = getClientTransport(socket); TProtocol protocol = protoFactory.getProtocol(transport); ThriftTest.Client testClient = new ThriftTest.Client(protocol); open(transport); for (int i = 0; i < NUM_QUERIES; ++i) { testClient.testI32(1); } server.stop(); for (int i = 0; i < NUM_QUERIES; ++i) { try { testClient.testI32(1); } catch(TTransportException e) { System.err.println(e); e.printStackTrace(); if (e.getCause() instanceof java.net.SocketTimeoutException) { fail("timed out when it should have thrown another kind of error!"); } } } transport.close(); stopServer(); } } } libthrift-java_0.9.0/test/log4j.properties0000644000175000017500000000046612035665434021426 0ustar eevanseevans00000000000000# log4j configuration used during build and unit tests log4j.rootLogger=debug,stdout log4j.threshhold=ALL log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d{ISO8601} %-5p %c{2} (%F:%M(%L)) - %m%n libthrift-java_0.9.0/test/.truststore0000644000175000017500000000130412035665434020520 0ustar eevanseevans00000000000000thrift+(X.50900L>0  *H 010UUnknown10UUnknown10UUnknown1#0!U Apache Software Foundation10U  Apache Thrift10 UThrift0 101008155457Z 240616155457Z010UUnknown10UUnknown10UUnknown1#0!U Apache Software Foundation10U  Apache Thrift10 UThrift00  *H 0KĖG6\j k8XXR93^vBW]r кJ~WkWjXvZ$Ǥ8"YWxg彠Ǧq5RH9i&Ii>0-0  *H  +B80x@Al-D[{ҒQuֻ2NS.X\moZ:>L ^ݒX;$/ $ U1 Thrift Build File Tests failed! libthrift-java_0.9.0/src/0000755000175000017500000000000012035665714016074 5ustar eevanseevans00000000000000libthrift-java_0.9.0/src/org/0000755000175000017500000000000012035665714016663 5ustar eevanseevans00000000000000libthrift-java_0.9.0/src/org/apache/0000755000175000017500000000000012035665714020104 5ustar eevanseevans00000000000000libthrift-java_0.9.0/src/org/apache/thrift/0000755000175000017500000000000012035665714021404 5ustar eevanseevans00000000000000libthrift-java_0.9.0/src/org/apache/thrift/TBaseHelper.java0000644000175000017500000002026312035665435024410 0ustar eevanseevans00000000000000/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.thrift; import java.nio.ByteBuffer; import java.util.Comparator; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; import java.util.SortedMap; import java.util.SortedSet; import java.util.TreeMap; import java.util.TreeSet; public final class TBaseHelper { private TBaseHelper(){} private static final Comparator comparator = new NestedStructureComparator(); public static int compareTo(Object o1, Object o2) { if (o1 instanceof Comparable) { return compareTo((Comparable)o1, (Comparable)o2); } else if (o1 instanceof List) { return compareTo((List)o1, (List)o2); } else if (o1 instanceof Set) { return compareTo((Set)o1, (Set)o2); } else if (o1 instanceof Map) { return compareTo((Map)o1, (Map)o2); } else if (o1 instanceof byte[]) { return compareTo((byte[])o1, (byte[])o2); } else { throw new IllegalArgumentException("Cannot compare objects of type " + o1.getClass()); } } public static int compareTo(boolean a, boolean b) { return Boolean.valueOf(a).compareTo(b); } public static int compareTo(byte a, byte b) { if (a < b) { return -1; } else if (b < a) { return 1; } else { return 0; } } public static int compareTo(short a, short b) { if (a < b) { return -1; } else if (b < a) { return 1; } else { return 0; } } public static int compareTo(int a, int b) { if (a < b) { return -1; } else if (b < a) { return 1; } else { return 0; } } public static int compareTo(long a, long b) { if (a < b) { return -1; } else if (b < a) { return 1; } else { return 0; } } public static int compareTo(double a, double b) { if (a < b) { return -1; } else if (b < a) { return 1; } else { return 0; } } public static int compareTo(String a, String b) { return a.compareTo(b); } public static int compareTo(byte[] a, byte[] b) { int sizeCompare = compareTo(a.length, b.length); if (sizeCompare != 0) { return sizeCompare; } for (int i = 0; i < a.length; i++) { int byteCompare = compareTo(a[i], b[i]); if (byteCompare != 0) { return byteCompare; } } return 0; } public static int compareTo(Comparable a, Comparable b) { return a.compareTo(b); } public static int compareTo(List a, List b) { int lastComparison = compareTo(a.size(), b.size()); if (lastComparison != 0) { return lastComparison; } for (int i = 0; i < a.size(); i++) { lastComparison = comparator.compare(a.get(i), b.get(i)); if (lastComparison != 0) { return lastComparison; } } return 0; } public static int compareTo(Set a, Set b) { int lastComparison = compareTo(a.size(), b.size()); if (lastComparison != 0) { return lastComparison; } SortedSet sortedA = new TreeSet(comparator); sortedA.addAll(a); SortedSet sortedB = new TreeSet(comparator); sortedB.addAll(b); Iterator iterA = sortedA.iterator(); Iterator iterB = sortedB.iterator(); // Compare each item. while (iterA.hasNext() && iterB.hasNext()) { lastComparison = comparator.compare(iterA.next(), iterB.next()); if (lastComparison != 0) { return lastComparison; } } return 0; } public static int compareTo(Map a, Map b) { int lastComparison = compareTo(a.size(), b.size()); if (lastComparison != 0) { return lastComparison; } // Sort a and b so we can compare them. SortedMap sortedA = new TreeMap(comparator); sortedA.putAll(a); Iterator iterA = sortedA.entrySet().iterator(); SortedMap sortedB = new TreeMap(comparator); sortedB.putAll(b); Iterator iterB = sortedB.entrySet().iterator(); // Compare each item. while (iterA.hasNext() && iterB.hasNext()) { Map.Entry entryA = iterA.next(); Map.Entry entryB = iterB.next(); lastComparison = comparator.compare(entryA.getKey(), entryB.getKey()); if (lastComparison != 0) { return lastComparison; } lastComparison = comparator.compare(entryA.getValue(), entryB.getValue()); if (lastComparison != 0) { return lastComparison; } } return 0; } /** * Comparator to compare items inside a structure (e.g. a list, set, or map). */ private static class NestedStructureComparator implements Comparator { public int compare(Object oA, Object oB) { if (oA == null && oB == null) { return 0; } else if (oA == null) { return -1; } else if (oB == null) { return 1; } else if (oA instanceof List) { return compareTo((List)oA, (List)oB); } else if (oA instanceof Set) { return compareTo((Set)oA, (Set)oB); } else if (oA instanceof Map) { return compareTo((Map)oA, (Map)oB); } else if (oA instanceof byte[]) { return compareTo((byte[])oA, (byte[])oB); } else { return compareTo((Comparable)oA, (Comparable)oB); } } } public static void toString(ByteBuffer bb, StringBuilder sb) { byte[] buf = bb.array(); int arrayOffset = bb.arrayOffset(); int offset = arrayOffset + bb.position(); int origLimit = arrayOffset + bb.limit(); int limit = (origLimit - offset > 128) ? offset + 128 : origLimit; for (int i = offset; i < limit; i++) { if (i > offset) { sb.append(" "); } sb.append(paddedByteString(buf[i])); } if (origLimit != limit) { sb.append("..."); } } public static String paddedByteString(byte b) { int extended = (b | 0x100) & 0x1ff; return Integer.toHexString(extended).toUpperCase().substring(1); } public static byte[] byteBufferToByteArray(ByteBuffer byteBuffer) { if (wrapsFullArray(byteBuffer)) { return byteBuffer.array(); } byte[] target = new byte[byteBuffer.remaining()]; byteBufferToByteArray(byteBuffer, target, 0); return target; } public static boolean wrapsFullArray(ByteBuffer byteBuffer) { return byteBuffer.hasArray() && byteBuffer.position() == 0 && byteBuffer.arrayOffset() == 0 && byteBuffer.remaining() == byteBuffer.capacity(); } public static int byteBufferToByteArray(ByteBuffer byteBuffer, byte[] target, int offset) { int remaining = byteBuffer.remaining(); System.arraycopy(byteBuffer.array(), byteBuffer.arrayOffset() + byteBuffer.position(), target, offset, remaining); return remaining; } public static ByteBuffer rightSize(ByteBuffer in) { if (in == null) { return null; } if (wrapsFullArray(in)) { return in; } return ByteBuffer.wrap(byteBufferToByteArray(in)); } public static ByteBuffer copyBinary(final ByteBuffer orig) { if (orig == null) { return null; } ByteBuffer copy = ByteBuffer.wrap(new byte[orig.remaining()]); if (orig.hasArray()) { System.arraycopy(orig.array(), orig.arrayOffset() + orig.position(), copy.array(), 0, orig.remaining()); } else { orig.slice().get(copy.array()); } return copy; } public static byte[] copyBinary(final byte[] orig) { if (orig == null) { return null; } byte[] copy = new byte[orig.length]; System.arraycopy(orig, 0, copy, 0, orig.length); return copy; } } libthrift-java_0.9.0/src/org/apache/thrift/TBaseProcessor.java0000644000175000017500000000266312035665435025154 0ustar eevanseevans00000000000000package org.apache.thrift; import java.util.Collections; import java.util.Map; import org.apache.thrift.protocol.TMessage; import org.apache.thrift.protocol.TMessageType; import org.apache.thrift.protocol.TProtocol; import org.apache.thrift.protocol.TProtocolUtil; import org.apache.thrift.protocol.TType; public abstract class TBaseProcessor implements TProcessor { private final I iface; private final Map> processMap; protected TBaseProcessor(I iface, Map> processFunctionMap) { this.iface = iface; this.processMap = processFunctionMap; } public Map> getProcessMapView() { return Collections.unmodifiableMap(processMap); } @Override public boolean process(TProtocol in, TProtocol out) throws TException { TMessage msg = in.readMessageBegin(); ProcessFunction fn = processMap.get(msg.name); if (fn == null) { TProtocolUtil.skip(in, TType.STRUCT); in.readMessageEnd(); TApplicationException x = new TApplicationException(TApplicationException.UNKNOWN_METHOD, "Invalid method name: '"+msg.name+"'"); out.writeMessageBegin(new TMessage(msg.name, TMessageType.EXCEPTION, msg.seqid)); x.write(out); out.writeMessageEnd(); out.getTransport().flush(); return true; } fn.process(msg.seqid, in, out, iface); return true; } } libthrift-java_0.9.0/src/org/apache/thrift/ProcessFunction.java0000644000175000017500000000411012035665435025367 0ustar eevanseevans00000000000000/** * */ package org.apache.thrift; import org.apache.thrift.protocol.TMessage; import org.apache.thrift.protocol.TMessageType; import org.apache.thrift.protocol.TProtocol; import org.apache.thrift.protocol.TProtocolException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public abstract class ProcessFunction { private final String methodName; private static final Logger LOGGER = LoggerFactory.getLogger(ProcessFunction.class.getName()); public ProcessFunction(String methodName) { this.methodName = methodName; } public final void process(int seqid, TProtocol iprot, TProtocol oprot, I iface) throws TException { T args = getEmptyArgsInstance(); try { args.read(iprot); } catch (TProtocolException e) { iprot.readMessageEnd(); TApplicationException x = new TApplicationException(TApplicationException.PROTOCOL_ERROR, e.getMessage()); oprot.writeMessageBegin(new TMessage(getMethodName(), TMessageType.EXCEPTION, seqid)); x.write(oprot); oprot.writeMessageEnd(); oprot.getTransport().flush(); return; } iprot.readMessageEnd(); TBase result = null; try { result = getResult(iface, args); } catch(Throwable th) { LOGGER.error("Internal error processing " + getMethodName(), th); TApplicationException x = new TApplicationException(TApplicationException.INTERNAL_ERROR, "Internal error processing " + getMethodName()); oprot.writeMessageBegin(new TMessage(getMethodName(), TMessageType.EXCEPTION, seqid)); x.write(oprot); oprot.writeMessageEnd(); oprot.getTransport().flush(); return; } if(!isOneway()) { oprot.writeMessageBegin(new TMessage(getMethodName(), TMessageType.REPLY, seqid)); result.write(oprot); oprot.writeMessageEnd(); oprot.getTransport().flush(); } } protected abstract boolean isOneway(); public abstract TBase getResult(I iface, T args) throws TException; public abstract T getEmptyArgsInstance(); public String getMethodName() { return methodName; } } libthrift-java_0.9.0/src/org/apache/thrift/TFieldIdEnum.java0000644000175000017500000000214012035665435024515 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; /** * Interface for all generated struct Fields objects. */ public interface TFieldIdEnum { /** * Get the Thrift field id for the named field. */ public short getThriftFieldId(); /** * Get the field's name, exactly as in the IDL. */ public String getFieldName(); } libthrift-java_0.9.0/src/org/apache/thrift/TBase.java0000644000175000017500000000423712035665435023253 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; import java.io.Serializable; import org.apache.thrift.protocol.TProtocol; /** * Generic base interface for generated Thrift objects. * */ public interface TBase, F extends TFieldIdEnum> extends Comparable, Serializable { /** * Reads the TObject from the given input protocol. * * @param iprot Input protocol */ public void read(TProtocol iprot) throws TException; /** * Writes the objects out to the protocol * * @param oprot Output protocol */ public void write(TProtocol oprot) throws TException; /** * Get the F instance that corresponds to fieldId. */ public F fieldForId(int fieldId); /** * Check if a field is currently set or unset. * * @param field */ public boolean isSet(F field); /** * Get a field's value by field variable. Primitive types will be wrapped in * the appropriate "boxed" types. * * @param field */ public Object getFieldValue(F field); /** * Set a field's value by field variable. Primitive types must be "boxed" in * the appropriate object wrapper type. * * @param field */ public void setFieldValue(F field, Object value); public TBase deepCopy(); /** * Return to the state of having just been initialized, as though you had just * called the default constructor. */ public void clear(); } libthrift-java_0.9.0/src/org/apache/thrift/EncodingUtils.java0000644000175000017500000001073412035665435025023 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; /** * Utility methods for use when encoding/decoding raw data as byte arrays. */ public class EncodingUtils { /** * Encode integer as a series of 4 bytes into buf * starting at position 0 within that buffer. * * @param integer * The integer to encode. * @param buf * The buffer to write to. */ public static final void encodeBigEndian(final int integer, final byte[] buf) { encodeBigEndian(integer, buf, 0); } /** * Encode integer as a series of 4 bytes into buf * starting at position offset. * * @param integer * The integer to encode. * @param buf * The buffer to write to. * @param offset * The offset within buf to start the encoding. */ public static final void encodeBigEndian(final int integer, final byte[] buf, int offset) { buf[offset] = (byte) (0xff & (integer >> 24)); buf[offset + 1] = (byte) (0xff & (integer >> 16)); buf[offset + 2] = (byte) (0xff & (integer >> 8)); buf[offset + 3] = (byte) (0xff & (integer)); } /** * Decode a series of 4 bytes from buf, starting at position 0, * and interpret them as an integer. * * @param buf * The buffer to read from. * @return An integer, as read from the buffer. */ public static final int decodeBigEndian(final byte[] buf) { return decodeBigEndian(buf, 0); } /** * Decode a series of 4 bytes from buf, start at * offset, and interpret them as an integer. * * @param buf * The buffer to read from. * @param offset * The offset with buf to start the decoding. * @return An integer, as read from the buffer. */ public static final int decodeBigEndian(final byte[] buf, int offset) { return ((buf[offset] & 0xff) << 24) | ((buf[offset + 1] & 0xff) << 16) | ((buf[offset + 2] & 0xff) << 8) | ((buf[offset + 3] & 0xff)); } /** * Bitfield utilities. * Returns true if the bit at position is set in v. */ public static final boolean testBit(byte v, int position) { return testBit((int)v, position); } public static final boolean testBit(short v, int position) { return testBit((int)v, position); } public static final boolean testBit(int v, int position) { return (v & (1 << position)) != 0; } public static final boolean testBit(long v, int position) { return (v & (1L << position)) != 0L; } /** * Returns v, with the bit at position set to zero. */ public static final byte clearBit(byte v, int position) { return (byte)clearBit((int)v, position); } public static final short clearBit(short v, int position) { return (short)clearBit((int)v, position); } public static final int clearBit(int v, int position) { return v & ~(1 << position); } public static final long clearBit(long v, int position) { return v & ~(1L << position); } /** * Returns v, with the bit at position set to 1 or 0 depending on value. */ public static final byte setBit(byte v, int position, boolean value) { return (byte)setBit((int)v, position, value); } public static final short setBit(short v, int position, boolean value) { return (short)setBit((int)v, position, value); } public static final int setBit(int v, int position, boolean value) { if(value) return v | (1 << position); else return clearBit(v, position); } public static final long setBit(long v, int position, boolean value) { if(value) return v | (1L << position); else return clearBit(v, position); } } libthrift-java_0.9.0/src/org/apache/thrift/TServiceClient.java0000644000175000017500000000504212035665435025133 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; import org.apache.thrift.protocol.TMessage; import org.apache.thrift.protocol.TMessageType; import org.apache.thrift.protocol.TProtocol; /** * A TServiceClient is used to communicate with a TService implementation * across protocols and transports. */ public abstract class TServiceClient { public TServiceClient(TProtocol prot) { this(prot, prot); } public TServiceClient(TProtocol iprot, TProtocol oprot) { iprot_ = iprot; oprot_ = oprot; } protected TProtocol iprot_; protected TProtocol oprot_; protected int seqid_; /** * Get the TProtocol being used as the input (read) protocol. * @return the TProtocol being used as the input (read) protocol. */ public TProtocol getInputProtocol() { return this.iprot_; } /** * Get the TProtocol being used as the output (write) protocol. * @return the TProtocol being used as the output (write) protocol. */ public TProtocol getOutputProtocol() { return this.oprot_; } protected void sendBase(String methodName, TBase args) throws TException { oprot_.writeMessageBegin(new TMessage(methodName, TMessageType.CALL, ++seqid_)); args.write(oprot_); oprot_.writeMessageEnd(); oprot_.getTransport().flush(); } protected void receiveBase(TBase result, String methodName) throws TException { TMessage msg = iprot_.readMessageBegin(); if (msg.type == TMessageType.EXCEPTION) { TApplicationException x = TApplicationException.read(iprot_); iprot_.readMessageEnd(); throw x; } if (msg.seqid != seqid_) { throw new TApplicationException(TApplicationException.BAD_SEQUENCE_ID, methodName + " failed: out of sequence response"); } result.read(iprot_); iprot_.readMessageEnd(); } } libthrift-java_0.9.0/src/org/apache/thrift/TApplicationException.java0000644000175000017500000000675112035665435026526 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; import org.apache.thrift.protocol.TField; import org.apache.thrift.protocol.TProtocol; import org.apache.thrift.protocol.TProtocolUtil; import org.apache.thrift.protocol.TStruct; import org.apache.thrift.protocol.TType; /** * Application level exception * */ public class TApplicationException extends TException { private static final TStruct TAPPLICATION_EXCEPTION_STRUCT = new TStruct("TApplicationException"); private static final TField MESSAGE_FIELD = new TField("message", TType.STRING, (short)1); private static final TField TYPE_FIELD = new TField("type", TType.I32, (short)2); private static final long serialVersionUID = 1L; public static final int UNKNOWN = 0; public static final int UNKNOWN_METHOD = 1; public static final int INVALID_MESSAGE_TYPE = 2; public static final int WRONG_METHOD_NAME = 3; public static final int BAD_SEQUENCE_ID = 4; public static final int MISSING_RESULT = 5; public static final int INTERNAL_ERROR = 6; public static final int PROTOCOL_ERROR = 7; protected int type_ = UNKNOWN; public TApplicationException() { super(); } public TApplicationException(int type) { super(); type_ = type; } public TApplicationException(int type, String message) { super(message); type_ = type; } public TApplicationException(String message) { super(message); } public int getType() { return type_; } public static TApplicationException read(TProtocol iprot) throws TException { TField field; iprot.readStructBegin(); String message = null; int type = UNKNOWN; while (true) { field = iprot.readFieldBegin(); if (field.type == TType.STOP) { break; } switch (field.id) { case 1: if (field.type == TType.STRING) { message = iprot.readString(); } else { TProtocolUtil.skip(iprot, field.type); } break; case 2: if (field.type == TType.I32) { type = iprot.readI32(); } else { TProtocolUtil.skip(iprot, field.type); } break; default: TProtocolUtil.skip(iprot, field.type); break; } iprot.readFieldEnd(); } iprot.readStructEnd(); return new TApplicationException(type, message); } public void write(TProtocol oprot) throws TException { oprot.writeStructBegin(TAPPLICATION_EXCEPTION_STRUCT); if (getMessage() != null) { oprot.writeFieldBegin(MESSAGE_FIELD); oprot.writeString(getMessage()); oprot.writeFieldEnd(); } oprot.writeFieldBegin(TYPE_FIELD); oprot.writeI32(type_); oprot.writeFieldEnd(); oprot.writeFieldStop(); oprot.writeStructEnd(); } } libthrift-java_0.9.0/src/org/apache/thrift/protocol/0000755000175000017500000000000012035665714023245 5ustar eevanseevans00000000000000libthrift-java_0.9.0/src/org/apache/thrift/protocol/TJSONProtocol.java0000644000175000017500000006211712035665435026536 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; import java.io.UnsupportedEncodingException; import java.nio.ByteBuffer; import java.util.Stack; import org.apache.thrift.TByteArrayOutputStream; import org.apache.thrift.TException; import org.apache.thrift.transport.TTransport; /** * JSON protocol implementation for thrift. * * This is a full-featured protocol supporting write and read. * * Please see the C++ class header for a detailed description of the * protocol's wire format. * */ public class TJSONProtocol extends TProtocol { /** * Factory for JSON protocol objects */ public static class Factory implements TProtocolFactory { public TProtocol getProtocol(TTransport trans) { return new TJSONProtocol(trans); } } private static final byte[] COMMA = new byte[] {','}; private static final byte[] COLON = new byte[] {':'}; private static final byte[] LBRACE = new byte[] {'{'}; private static final byte[] RBRACE = new byte[] {'}'}; private static final byte[] LBRACKET = new byte[] {'['}; private static final byte[] RBRACKET = new byte[] {']'}; private static final byte[] QUOTE = new byte[] {'"'}; private static final byte[] BACKSLASH = new byte[] {'\\'}; private static final byte[] ZERO = new byte[] {'0'}; private static final byte[] ESCSEQ = new byte[] {'\\','u','0','0'}; private static final long VERSION = 1; private static final byte[] JSON_CHAR_TABLE = { /* 0 1 2 3 4 5 6 7 8 9 A B C D E F */ 0, 0, 0, 0, 0, 0, 0, 0,'b','t','n', 0,'f','r', 0, 0, // 0 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 1 1, 1,'"', 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, // 2 }; private static final String ESCAPE_CHARS = "\"\\bfnrt"; private static final byte[] ESCAPE_CHAR_VALS = { '"', '\\', '\b', '\f', '\n', '\r', '\t', }; private static final int DEF_STRING_SIZE = 16; private static final byte[] NAME_BOOL = new byte[] {'t', 'f'}; private static final byte[] NAME_BYTE = new byte[] {'i','8'}; private static final byte[] NAME_I16 = new byte[] {'i','1','6'}; private static final byte[] NAME_I32 = new byte[] {'i','3','2'}; private static final byte[] NAME_I64 = new byte[] {'i','6','4'}; private static final byte[] NAME_DOUBLE = new byte[] {'d','b','l'}; private static final byte[] NAME_STRUCT = new byte[] {'r','e','c'}; private static final byte[] NAME_STRING = new byte[] {'s','t','r'}; private static final byte[] NAME_MAP = new byte[] {'m','a','p'}; private static final byte[] NAME_LIST = new byte[] {'l','s','t'}; private static final byte[] NAME_SET = new byte[] {'s','e','t'}; private static final TStruct ANONYMOUS_STRUCT = new TStruct(); private static final byte[] getTypeNameForTypeID(byte typeID) throws TException { switch (typeID) { case TType.BOOL: return NAME_BOOL; case TType.BYTE: return NAME_BYTE; case TType.I16: return NAME_I16; case TType.I32: return NAME_I32; case TType.I64: return NAME_I64; case TType.DOUBLE: return NAME_DOUBLE; case TType.STRING: return NAME_STRING; case TType.STRUCT: return NAME_STRUCT; case TType.MAP: return NAME_MAP; case TType.SET: return NAME_SET; case TType.LIST: return NAME_LIST; default: throw new TProtocolException(TProtocolException.NOT_IMPLEMENTED, "Unrecognized type"); } } private static final byte getTypeIDForTypeName(byte[] name) throws TException { byte result = TType.STOP; if (name.length > 1) { switch (name[0]) { case 'd': result = TType.DOUBLE; break; case 'i': switch (name[1]) { case '8': result = TType.BYTE; break; case '1': result = TType.I16; break; case '3': result = TType.I32; break; case '6': result = TType.I64; break; } break; case 'l': result = TType.LIST; break; case 'm': result = TType.MAP; break; case 'r': result = TType.STRUCT; break; case 's': if (name[1] == 't') { result = TType.STRING; } else if (name[1] == 'e') { result = TType.SET; } break; case 't': result = TType.BOOL; break; } } if (result == TType.STOP) { throw new TProtocolException(TProtocolException.NOT_IMPLEMENTED, "Unrecognized type"); } return result; } // Base class for tracking JSON contexts that may require inserting/reading // additional JSON syntax characters // This base context does nothing. protected class JSONBaseContext { protected void write() throws TException {} protected void read() throws TException {} protected boolean escapeNum() { return false; } } // Context for JSON lists. Will insert/read commas before each item except // for the first one protected class JSONListContext extends JSONBaseContext { private boolean first_ = true; @Override protected void write() throws TException { if (first_) { first_ = false; } else { trans_.write(COMMA); } } @Override protected void read() throws TException { if (first_) { first_ = false; } else { readJSONSyntaxChar(COMMA); } } } // Context for JSON records. Will insert/read colons before the value portion // of each record pair, and commas before each key except the first. In // addition, will indicate that numbers in the key position need to be // escaped in quotes (since JSON keys must be strings). protected class JSONPairContext extends JSONBaseContext { private boolean first_ = true; private boolean colon_ = true; @Override protected void write() throws TException { if (first_) { first_ = false; colon_ = true; } else { trans_.write(colon_ ? COLON : COMMA); colon_ = !colon_; } } @Override protected void read() throws TException { if (first_) { first_ = false; colon_ = true; } else { readJSONSyntaxChar(colon_ ? COLON : COMMA); colon_ = !colon_; } } @Override protected boolean escapeNum() { return colon_; } } // Holds up to one byte from the transport protected class LookaheadReader { private boolean hasData_; private byte[] data_ = new byte[1]; // Return and consume the next byte to be read, either taking it from the // data buffer if present or getting it from the transport otherwise. protected byte read() throws TException { if (hasData_) { hasData_ = false; } else { trans_.readAll(data_, 0, 1); } return data_[0]; } // Return the next byte to be read without consuming, filling the data // buffer if it has not been filled already. protected byte peek() throws TException { if (!hasData_) { trans_.readAll(data_, 0, 1); } hasData_ = true; return data_[0]; } } // Stack of nested contexts that we may be in private Stack contextStack_ = new Stack(); // Current context that we are in private JSONBaseContext context_ = new JSONBaseContext(); // Reader that manages a 1-byte buffer private LookaheadReader reader_ = new LookaheadReader(); // Push a new JSON context onto the stack. private void pushContext(JSONBaseContext c) { contextStack_.push(context_); context_ = c; } // Pop the last JSON context off the stack private void popContext() { context_ = contextStack_.pop(); } /** * Constructor */ public TJSONProtocol(TTransport trans) { super(trans); } @Override public void reset() { contextStack_.clear(); context_ = new JSONBaseContext(); reader_ = new LookaheadReader(); } // Temporary buffer used by several methods private byte[] tmpbuf_ = new byte[4]; // Read a byte that must match b[0]; otherwise an exception is thrown. // Marked protected to avoid synthetic accessor in JSONListContext.read // and JSONPairContext.read protected void readJSONSyntaxChar(byte[] b) throws TException { byte ch = reader_.read(); if (ch != b[0]) { throw new TProtocolException(TProtocolException.INVALID_DATA, "Unexpected character:" + (char)ch); } } // Convert a byte containing a hex char ('0'-'9' or 'a'-'f') into its // corresponding hex value private static final byte hexVal(byte ch) throws TException { if ((ch >= '0') && (ch <= '9')) { return (byte)((char)ch - '0'); } else if ((ch >= 'a') && (ch <= 'f')) { return (byte)((char)ch - 'a' + 10); } else { throw new TProtocolException(TProtocolException.INVALID_DATA, "Expected hex character"); } } // Convert a byte containing a hex value to its corresponding hex character private static final byte hexChar(byte val) { val &= 0x0F; if (val < 10) { return (byte)((char)val + '0'); } else { return (byte)((char)(val - 10) + 'a'); } } // Write the bytes in array buf as a JSON characters, escaping as needed private void writeJSONString(byte[] b) throws TException { context_.write(); trans_.write(QUOTE); int len = b.length; for (int i = 0; i < len; i++) { if ((b[i] & 0x00FF) >= 0x30) { if (b[i] == BACKSLASH[0]) { trans_.write(BACKSLASH); trans_.write(BACKSLASH); } else { trans_.write(b, i, 1); } } else { tmpbuf_[0] = JSON_CHAR_TABLE[b[i]]; if (tmpbuf_[0] == 1) { trans_.write(b, i, 1); } else if (tmpbuf_[0] > 1) { trans_.write(BACKSLASH); trans_.write(tmpbuf_, 0, 1); } else { trans_.write(ESCSEQ); tmpbuf_[0] = hexChar((byte)(b[i] >> 4)); tmpbuf_[1] = hexChar(b[i]); trans_.write(tmpbuf_, 0, 2); } } } trans_.write(QUOTE); } // Write out number as a JSON value. If the context dictates so, it will be // wrapped in quotes to output as a JSON string. private void writeJSONInteger(long num) throws TException { context_.write(); String str = Long.toString(num); boolean escapeNum = context_.escapeNum(); if (escapeNum) { trans_.write(QUOTE); } try { byte[] buf = str.getBytes("UTF-8"); trans_.write(buf); } catch (UnsupportedEncodingException uex) { throw new TException("JVM DOES NOT SUPPORT UTF-8"); } if (escapeNum) { trans_.write(QUOTE); } } // Write out a double as a JSON value. If it is NaN or infinity or if the // context dictates escaping, write out as JSON string. private void writeJSONDouble(double num) throws TException { context_.write(); String str = Double.toString(num); boolean special = false; switch (str.charAt(0)) { case 'N': // NaN case 'I': // Infinity special = true; break; case '-': if (str.charAt(1) == 'I') { // -Infinity special = true; } break; } boolean escapeNum = special || context_.escapeNum(); if (escapeNum) { trans_.write(QUOTE); } try { byte[] b = str.getBytes("UTF-8"); trans_.write(b, 0, b.length); } catch (UnsupportedEncodingException uex) { throw new TException("JVM DOES NOT SUPPORT UTF-8"); } if (escapeNum) { trans_.write(QUOTE); } } // Write out contents of byte array b as a JSON string with base-64 encoded // data private void writeJSONBase64(byte[] b, int offset, int length) throws TException { context_.write(); trans_.write(QUOTE); int len = length; int off = offset; while (len >= 3) { // Encode 3 bytes at a time TBase64Utils.encode(b, off, 3, tmpbuf_, 0); trans_.write(tmpbuf_, 0, 4); off += 3; len -= 3; } if (len > 0) { // Encode remainder TBase64Utils.encode(b, off, len, tmpbuf_, 0); trans_.write(tmpbuf_, 0, len + 1); } trans_.write(QUOTE); } private void writeJSONObjectStart() throws TException { context_.write(); trans_.write(LBRACE); pushContext(new JSONPairContext()); } private void writeJSONObjectEnd() throws TException { popContext(); trans_.write(RBRACE); } private void writeJSONArrayStart() throws TException { context_.write(); trans_.write(LBRACKET); pushContext(new JSONListContext()); } private void writeJSONArrayEnd() throws TException { popContext(); trans_.write(RBRACKET); } @Override public void writeMessageBegin(TMessage message) throws TException { writeJSONArrayStart(); writeJSONInteger(VERSION); try { byte[] b = message.name.getBytes("UTF-8"); writeJSONString(b); } catch (UnsupportedEncodingException uex) { throw new TException("JVM DOES NOT SUPPORT UTF-8"); } writeJSONInteger(message.type); writeJSONInteger(message.seqid); } @Override public void writeMessageEnd() throws TException { writeJSONArrayEnd(); } @Override public void writeStructBegin(TStruct struct) throws TException { writeJSONObjectStart(); } @Override public void writeStructEnd() throws TException { writeJSONObjectEnd(); } @Override public void writeFieldBegin(TField field) throws TException { writeJSONInteger(field.id); writeJSONObjectStart(); writeJSONString(getTypeNameForTypeID(field.type)); } @Override public void writeFieldEnd() throws TException { writeJSONObjectEnd(); } @Override public void writeFieldStop() {} @Override public void writeMapBegin(TMap map) throws TException { writeJSONArrayStart(); writeJSONString(getTypeNameForTypeID(map.keyType)); writeJSONString(getTypeNameForTypeID(map.valueType)); writeJSONInteger(map.size); writeJSONObjectStart(); } @Override public void writeMapEnd() throws TException { writeJSONObjectEnd(); writeJSONArrayEnd(); } @Override public void writeListBegin(TList list) throws TException { writeJSONArrayStart(); writeJSONString(getTypeNameForTypeID(list.elemType)); writeJSONInteger(list.size); } @Override public void writeListEnd() throws TException { writeJSONArrayEnd(); } @Override public void writeSetBegin(TSet set) throws TException { writeJSONArrayStart(); writeJSONString(getTypeNameForTypeID(set.elemType)); writeJSONInteger(set.size); } @Override public void writeSetEnd() throws TException { writeJSONArrayEnd(); } @Override public void writeBool(boolean b) throws TException { writeJSONInteger(b ? (long)1 : (long)0); } @Override public void writeByte(byte b) throws TException { writeJSONInteger((long)b); } @Override public void writeI16(short i16) throws TException { writeJSONInteger((long)i16); } @Override public void writeI32(int i32) throws TException { writeJSONInteger((long)i32); } @Override public void writeI64(long i64) throws TException { writeJSONInteger(i64); } @Override public void writeDouble(double dub) throws TException { writeJSONDouble(dub); } @Override public void writeString(String str) throws TException { try { byte[] b = str.getBytes("UTF-8"); writeJSONString(b); } catch (UnsupportedEncodingException uex) { throw new TException("JVM DOES NOT SUPPORT UTF-8"); } } @Override public void writeBinary(ByteBuffer bin) throws TException { writeJSONBase64(bin.array(), bin.position() + bin.arrayOffset(), bin.limit() - bin.position() - bin.arrayOffset()); } /** * Reading methods. */ // Read in a JSON string, unescaping as appropriate.. Skip reading from the // context if skipContext is true. private TByteArrayOutputStream readJSONString(boolean skipContext) throws TException { TByteArrayOutputStream arr = new TByteArrayOutputStream(DEF_STRING_SIZE); if (!skipContext) { context_.read(); } readJSONSyntaxChar(QUOTE); while (true) { byte ch = reader_.read(); if (ch == QUOTE[0]) { break; } if (ch == ESCSEQ[0]) { ch = reader_.read(); if (ch == ESCSEQ[1]) { readJSONSyntaxChar(ZERO); readJSONSyntaxChar(ZERO); trans_.readAll(tmpbuf_, 0, 2); ch = (byte)((hexVal((byte)tmpbuf_[0]) << 4) + hexVal(tmpbuf_[1])); } else { int off = ESCAPE_CHARS.indexOf(ch); if (off == -1) { throw new TProtocolException(TProtocolException.INVALID_DATA, "Expected control char"); } ch = ESCAPE_CHAR_VALS[off]; } } arr.write(ch); } return arr; } // Return true if the given byte could be a valid part of a JSON number. private boolean isJSONNumeric(byte b) { switch (b) { case '+': case '-': case '.': case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case 'E': case 'e': return true; } return false; } // Read in a sequence of characters that are all valid in JSON numbers. Does // not do a complete regex check to validate that this is actually a number. private String readJSONNumericChars() throws TException { StringBuilder strbld = new StringBuilder(); while (true) { byte ch = reader_.peek(); if (!isJSONNumeric(ch)) { break; } strbld.append((char)reader_.read()); } return strbld.toString(); } // Read in a JSON number. If the context dictates, read in enclosing quotes. private long readJSONInteger() throws TException { context_.read(); if (context_.escapeNum()) { readJSONSyntaxChar(QUOTE); } String str = readJSONNumericChars(); if (context_.escapeNum()) { readJSONSyntaxChar(QUOTE); } try { return Long.valueOf(str); } catch (NumberFormatException ex) { throw new TProtocolException(TProtocolException.INVALID_DATA, "Bad data encounted in numeric data"); } } // Read in a JSON double value. Throw if the value is not wrapped in quotes // when expected or if wrapped in quotes when not expected. private double readJSONDouble() throws TException { context_.read(); if (reader_.peek() == QUOTE[0]) { TByteArrayOutputStream arr = readJSONString(true); try { double dub = Double.valueOf(arr.toString("UTF-8")); if (!context_.escapeNum() && !Double.isNaN(dub) && !Double.isInfinite(dub)) { // Throw exception -- we should not be in a string in this case throw new TProtocolException(TProtocolException.INVALID_DATA, "Numeric data unexpectedly quoted"); } return dub; } catch (UnsupportedEncodingException ex) { throw new TException("JVM DOES NOT SUPPORT UTF-8"); } } else { if (context_.escapeNum()) { // This will throw - we should have had a quote if escapeNum == true readJSONSyntaxChar(QUOTE); } try { return Double.valueOf(readJSONNumericChars()); } catch (NumberFormatException ex) { throw new TProtocolException(TProtocolException.INVALID_DATA, "Bad data encounted in numeric data"); } } } // Read in a JSON string containing base-64 encoded data and decode it. private byte[] readJSONBase64() throws TException { TByteArrayOutputStream arr = readJSONString(false); byte[] b = arr.get(); int len = arr.len(); int off = 0; int size = 0; while (len >= 4) { // Decode 4 bytes at a time TBase64Utils.decode(b, off, 4, b, size); // NB: decoded in place off += 4; len -= 4; size += 3; } // Don't decode if we hit the end or got a single leftover byte (invalid // base64 but legal for skip of regular string type) if (len > 1) { // Decode remainder TBase64Utils.decode(b, off, len, b, size); // NB: decoded in place size += len - 1; } // Sadly we must copy the byte[] (any way around this?) byte [] result = new byte[size]; System.arraycopy(b, 0, result, 0, size); return result; } private void readJSONObjectStart() throws TException { context_.read(); readJSONSyntaxChar(LBRACE); pushContext(new JSONPairContext()); } private void readJSONObjectEnd() throws TException { readJSONSyntaxChar(RBRACE); popContext(); } private void readJSONArrayStart() throws TException { context_.read(); readJSONSyntaxChar(LBRACKET); pushContext(new JSONListContext()); } private void readJSONArrayEnd() throws TException { readJSONSyntaxChar(RBRACKET); popContext(); } @Override public TMessage readMessageBegin() throws TException { readJSONArrayStart(); if (readJSONInteger() != VERSION) { throw new TProtocolException(TProtocolException.BAD_VERSION, "Message contained bad version."); } String name; try { name = readJSONString(false).toString("UTF-8"); } catch (UnsupportedEncodingException ex) { throw new TException("JVM DOES NOT SUPPORT UTF-8"); } byte type = (byte) readJSONInteger(); int seqid = (int) readJSONInteger(); return new TMessage(name, type, seqid); } @Override public void readMessageEnd() throws TException { readJSONArrayEnd(); } @Override public TStruct readStructBegin() throws TException { readJSONObjectStart(); return ANONYMOUS_STRUCT; } @Override public void readStructEnd() throws TException { readJSONObjectEnd(); } @Override public TField readFieldBegin() throws TException { byte ch = reader_.peek(); byte type; short id = 0; if (ch == RBRACE[0]) { type = TType.STOP; } else { id = (short) readJSONInteger(); readJSONObjectStart(); type = getTypeIDForTypeName(readJSONString(false).get()); } return new TField("", type, id); } @Override public void readFieldEnd() throws TException { readJSONObjectEnd(); } @Override public TMap readMapBegin() throws TException { readJSONArrayStart(); byte keyType = getTypeIDForTypeName(readJSONString(false).get()); byte valueType = getTypeIDForTypeName(readJSONString(false).get()); int size = (int)readJSONInteger(); readJSONObjectStart(); return new TMap(keyType, valueType, size); } @Override public void readMapEnd() throws TException { readJSONObjectEnd(); readJSONArrayEnd(); } @Override public TList readListBegin() throws TException { readJSONArrayStart(); byte elemType = getTypeIDForTypeName(readJSONString(false).get()); int size = (int)readJSONInteger(); return new TList(elemType, size); } @Override public void readListEnd() throws TException { readJSONArrayEnd(); } @Override public TSet readSetBegin() throws TException { readJSONArrayStart(); byte elemType = getTypeIDForTypeName(readJSONString(false).get()); int size = (int)readJSONInteger(); return new TSet(elemType, size); } @Override public void readSetEnd() throws TException { readJSONArrayEnd(); } @Override public boolean readBool() throws TException { return (readJSONInteger() == 0 ? false : true); } @Override public byte readByte() throws TException { return (byte) readJSONInteger(); } @Override public short readI16() throws TException { return (short) readJSONInteger(); } @Override public int readI32() throws TException { return (int) readJSONInteger(); } @Override public long readI64() throws TException { return (long) readJSONInteger(); } @Override public double readDouble() throws TException { return readJSONDouble(); } @Override public String readString() throws TException { try { return readJSONString(false).toString("UTF-8"); } catch (UnsupportedEncodingException ex) { throw new TException("JVM DOES NOT SUPPORT UTF-8"); } } @Override public ByteBuffer readBinary() throws TException { return ByteBuffer.wrap(readJSONBase64()); } } libthrift-java_0.9.0/src/org/apache/thrift/protocol/TMessageType.java0000644000175000017500000000211012035665435026454 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; /** * Message type constants in the Thrift protocol. * */ public final class TMessageType { public static final byte CALL = 1; public static final byte REPLY = 2; public static final byte EXCEPTION = 3; public static final byte ONEWAY = 4; } libthrift-java_0.9.0/src/org/apache/thrift/protocol/TProtocolUtil.java0000644000175000017500000001533412035665435026701 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; import org.apache.thrift.TException; /** * Utility class with static methods for interacting with protocol data * streams. * */ public class TProtocolUtil { /** * The maximum recursive depth the skip() function will traverse before * throwing a TException. */ private static int maxSkipDepth = Integer.MAX_VALUE; /** * Specifies the maximum recursive depth that the skip function will * traverse before throwing a TException. This is a global setting, so * any call to skip in this JVM will enforce this value. * * @param depth the maximum recursive depth. A value of 2 would allow * the skip function to skip a structure or collection with basic children, * but it would not permit skipping a struct that had a field containing * a child struct. A value of 1 would only allow skipping of simple * types and empty structs/collections. */ public static void setMaxSkipDepth(int depth) { maxSkipDepth = depth; } /** * Skips over the next data element from the provided input TProtocol object. * * @param prot the protocol object to read from * @param type the next value will be interpreted as this TType value. */ public static void skip(TProtocol prot, byte type) throws TException { skip(prot, type, maxSkipDepth); } /** * Skips over the next data element from the provided input TProtocol object. * * @param prot the protocol object to read from * @param type the next value will be interpreted as this TType value. * @param maxDepth this function will only skip complex objects to this * recursive depth, to prevent Java stack overflow. */ public static void skip(TProtocol prot, byte type, int maxDepth) throws TException { if (maxDepth <= 0) { throw new TException("Maximum skip depth exceeded"); } switch (type) { case TType.BOOL: prot.readBool(); break; case TType.BYTE: prot.readByte(); break; case TType.I16: prot.readI16(); break; case TType.I32: prot.readI32(); break; case TType.I64: prot.readI64(); break; case TType.DOUBLE: prot.readDouble(); break; case TType.STRING: prot.readBinary(); break; case TType.STRUCT: prot.readStructBegin(); while (true) { TField field = prot.readFieldBegin(); if (field.type == TType.STOP) { break; } skip(prot, field.type, maxDepth - 1); prot.readFieldEnd(); } prot.readStructEnd(); break; case TType.MAP: TMap map = prot.readMapBegin(); for (int i = 0; i < map.size; i++) { skip(prot, map.keyType, maxDepth - 1); skip(prot, map.valueType, maxDepth - 1); } prot.readMapEnd(); break; case TType.SET: TSet set = prot.readSetBegin(); for (int i = 0; i < set.size; i++) { skip(prot, set.elemType, maxDepth - 1); } prot.readSetEnd(); break; case TType.LIST: TList list = prot.readListBegin(); for (int i = 0; i < list.size; i++) { skip(prot, list.elemType, maxDepth - 1); } prot.readListEnd(); break; default: break; } } /** * Attempt to determine the protocol used to serialize some data. * * The guess is based on known specificities of supported protocols. * In some cases, no guess can be done, in that case we return the * fallback TProtocolFactory. * To be certain to correctly detect the protocol, the first encoded * field should have a field id < 256 * * @param data The serialized data to guess the protocol for. * @param fallback The TProtocol to return if no guess can be made. * @return a Class implementing TProtocolFactory which can be used to create a deserializer. */ public static TProtocolFactory guessProtocolFactory(byte[] data, TProtocolFactory fallback) { // // If the first and last bytes are opening/closing curly braces we guess the protocol as // being TJSONProtocol. // It could not be a TCompactBinary encoding for a field of type 0xb (Map) // with delta id 7 as the last byte for TCompactBinary is always 0. // if ('{' == data[0] && '}' == data[data.length - 1]) { return new TJSONProtocol.Factory(); } // // If the last byte is not 0, then it cannot be TCompactProtocol, it must be // TBinaryProtocol. // if (data[data.length - 1] != 0) { return new TBinaryProtocol.Factory(); } // // A first byte of value > 16 indicates TCompactProtocol was used, and the first byte // encodes a delta field id (id <= 15) and a field type. // if (data[0] > 0x10) { return new TCompactProtocol.Factory(); } // // If the second byte is 0 then it is a field id < 256 encoded by TBinaryProtocol. // It cannot possibly be TCompactProtocol since a value of 0 would imply a field id // of 0 as the zig zag varint encoding would end. // if (data.length > 1 && 0 == data[1]) { return new TBinaryProtocol.Factory(); } // // If bit 7 of the first byte of the field id is set then we have two choices: // 1. A field id > 63 was encoded with TCompactProtocol. // 2. A field id > 0x7fff (32767) was encoded with TBinaryProtocol and the last byte of the // serialized data is 0. // Option 2 is impossible since field ids are short and thus limited to 32767. // if (data.length > 1 && (data[1] & 0x80) != 0) { return new TCompactProtocol.Factory(); } // // The remaining case is either a field id <= 63 encoded as TCompactProtocol, // one >= 256 encoded with TBinaryProtocol with a last byte at 0, or an empty structure. // As we cannot really decide, we return the fallback protocol. // return fallback; } } libthrift-java_0.9.0/src/org/apache/thrift/protocol/TCompactProtocol.java0000644000175000017500000006150412035665435027352 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; import java.io.UnsupportedEncodingException; import java.nio.ByteBuffer; import org.apache.thrift.ShortStack; import org.apache.thrift.TException; import org.apache.thrift.transport.TTransport; /** * TCompactProtocol2 is the Java implementation of the compact protocol specified * in THRIFT-110. The fundamental approach to reducing the overhead of * structures is a) use variable-length integers all over the place and b) make * use of unused bits wherever possible. Your savings will obviously vary * based on the specific makeup of your structs, but in general, the more * fields, nested structures, short strings and collections, and low-value i32 * and i64 fields you have, the more benefit you'll see. */ public class TCompactProtocol extends TProtocol { private final static TStruct ANONYMOUS_STRUCT = new TStruct(""); private final static TField TSTOP = new TField("", TType.STOP, (short)0); private final static byte[] ttypeToCompactType = new byte[16]; static { ttypeToCompactType[TType.STOP] = TType.STOP; ttypeToCompactType[TType.BOOL] = Types.BOOLEAN_TRUE; ttypeToCompactType[TType.BYTE] = Types.BYTE; ttypeToCompactType[TType.I16] = Types.I16; ttypeToCompactType[TType.I32] = Types.I32; ttypeToCompactType[TType.I64] = Types.I64; ttypeToCompactType[TType.DOUBLE] = Types.DOUBLE; ttypeToCompactType[TType.STRING] = Types.BINARY; ttypeToCompactType[TType.LIST] = Types.LIST; ttypeToCompactType[TType.SET] = Types.SET; ttypeToCompactType[TType.MAP] = Types.MAP; ttypeToCompactType[TType.STRUCT] = Types.STRUCT; } /** * TProtocolFactory that produces TCompactProtocols. */ public static class Factory implements TProtocolFactory { private final long maxNetworkBytes_; public Factory() { maxNetworkBytes_ = -1; } public Factory(int maxNetworkBytes) { maxNetworkBytes_ = maxNetworkBytes; } public TProtocol getProtocol(TTransport trans) { return new TCompactProtocol(trans, maxNetworkBytes_); } } private static final byte PROTOCOL_ID = (byte)0x82; private static final byte VERSION = 1; private static final byte VERSION_MASK = 0x1f; // 0001 1111 private static final byte TYPE_MASK = (byte)0xE0; // 1110 0000 private static final int TYPE_SHIFT_AMOUNT = 5; /** * All of the on-wire type codes. */ private static class Types { public static final byte BOOLEAN_TRUE = 0x01; public static final byte BOOLEAN_FALSE = 0x02; public static final byte BYTE = 0x03; public static final byte I16 = 0x04; public static final byte I32 = 0x05; public static final byte I64 = 0x06; public static final byte DOUBLE = 0x07; public static final byte BINARY = 0x08; public static final byte LIST = 0x09; public static final byte SET = 0x0A; public static final byte MAP = 0x0B; public static final byte STRUCT = 0x0C; } /** * Used to keep track of the last field for the current and previous structs, * so we can do the delta stuff. */ private ShortStack lastField_ = new ShortStack(15); private short lastFieldId_ = 0; /** * If we encounter a boolean field begin, save the TField here so it can * have the value incorporated. */ private TField booleanField_ = null; /** * If we read a field header, and it's a boolean field, save the boolean * value here so that readBool can use it. */ private Boolean boolValue_ = null; /** * The maximum number of bytes to read from the network for * variable-length fields (such as strings or binary) or -1 for * unlimited. */ private final long maxNetworkBytes_; /** * Create a TCompactProtocol. * * @param transport the TTransport object to read from or write to. * @param maxNetworkBytes the maximum number of bytes to read for * variable-length fields. */ public TCompactProtocol(TTransport transport, long maxNetworkBytes) { super(transport); maxNetworkBytes_ = maxNetworkBytes; } /** * Create a TCompactProtocol. * * @param transport the TTransport object to read from or write to. */ public TCompactProtocol(TTransport transport) { this(transport, -1); } @Override public void reset() { lastField_.clear(); lastFieldId_ = 0; } // // Public Writing methods. // /** * Write a message header to the wire. Compact Protocol messages contain the * protocol version so we can migrate forwards in the future if need be. */ public void writeMessageBegin(TMessage message) throws TException { writeByteDirect(PROTOCOL_ID); writeByteDirect((VERSION & VERSION_MASK) | ((message.type << TYPE_SHIFT_AMOUNT) & TYPE_MASK)); writeVarint32(message.seqid); writeString(message.name); } /** * Write a struct begin. This doesn't actually put anything on the wire. We * use it as an opportunity to put special placeholder markers on the field * stack so we can get the field id deltas correct. */ public void writeStructBegin(TStruct struct) throws TException { lastField_.push(lastFieldId_); lastFieldId_ = 0; } /** * Write a struct end. This doesn't actually put anything on the wire. We use * this as an opportunity to pop the last field from the current struct off * of the field stack. */ public void writeStructEnd() throws TException { lastFieldId_ = lastField_.pop(); } /** * Write a field header containing the field id and field type. If the * difference between the current field id and the last one is small (< 15), * then the field id will be encoded in the 4 MSB as a delta. Otherwise, the * field id will follow the type header as a zigzag varint. */ public void writeFieldBegin(TField field) throws TException { if (field.type == TType.BOOL) { // we want to possibly include the value, so we'll wait. booleanField_ = field; } else { writeFieldBeginInternal(field, (byte)-1); } } /** * The workhorse of writeFieldBegin. It has the option of doing a * 'type override' of the type header. This is used specifically in the * boolean field case. */ private void writeFieldBeginInternal(TField field, byte typeOverride) throws TException { // short lastField = lastField_.pop(); // if there's a type override, use that. byte typeToWrite = typeOverride == -1 ? getCompactType(field.type) : typeOverride; // check if we can use delta encoding for the field id if (field.id > lastFieldId_ && field.id - lastFieldId_ <= 15) { // write them together writeByteDirect((field.id - lastFieldId_) << 4 | typeToWrite); } else { // write them separate writeByteDirect(typeToWrite); writeI16(field.id); } lastFieldId_ = field.id; // lastField_.push(field.id); } /** * Write the STOP symbol so we know there are no more fields in this struct. */ public void writeFieldStop() throws TException { writeByteDirect(TType.STOP); } /** * Write a map header. If the map is empty, omit the key and value type * headers, as we don't need any additional information to skip it. */ public void writeMapBegin(TMap map) throws TException { if (map.size == 0) { writeByteDirect(0); } else { writeVarint32(map.size); writeByteDirect(getCompactType(map.keyType) << 4 | getCompactType(map.valueType)); } } /** * Write a list header. */ public void writeListBegin(TList list) throws TException { writeCollectionBegin(list.elemType, list.size); } /** * Write a set header. */ public void writeSetBegin(TSet set) throws TException { writeCollectionBegin(set.elemType, set.size); } /** * Write a boolean value. Potentially, this could be a boolean field, in * which case the field header info isn't written yet. If so, decide what the * right type header is for the value and then write the field header. * Otherwise, write a single byte. */ public void writeBool(boolean b) throws TException { if (booleanField_ != null) { // we haven't written the field header yet writeFieldBeginInternal(booleanField_, b ? Types.BOOLEAN_TRUE : Types.BOOLEAN_FALSE); booleanField_ = null; } else { // we're not part of a field, so just write the value. writeByteDirect(b ? Types.BOOLEAN_TRUE : Types.BOOLEAN_FALSE); } } /** * Write a byte. Nothing to see here! */ public void writeByte(byte b) throws TException { writeByteDirect(b); } /** * Write an I16 as a zigzag varint. */ public void writeI16(short i16) throws TException { writeVarint32(intToZigZag(i16)); } /** * Write an i32 as a zigzag varint. */ public void writeI32(int i32) throws TException { writeVarint32(intToZigZag(i32)); } /** * Write an i64 as a zigzag varint. */ public void writeI64(long i64) throws TException { writeVarint64(longToZigzag(i64)); } /** * Write a double to the wire as 8 bytes. */ public void writeDouble(double dub) throws TException { byte[] data = new byte[]{0, 0, 0, 0, 0, 0, 0, 0}; fixedLongToBytes(Double.doubleToLongBits(dub), data, 0); trans_.write(data); } /** * Write a string to the wire with a varint size preceding. */ public void writeString(String str) throws TException { try { byte[] bytes = str.getBytes("UTF-8"); writeBinary(bytes, 0, bytes.length); } catch (UnsupportedEncodingException e) { throw new TException("UTF-8 not supported!"); } } /** * Write a byte array, using a varint for the size. */ public void writeBinary(ByteBuffer bin) throws TException { int length = bin.limit() - bin.position(); writeBinary(bin.array(), bin.position() + bin.arrayOffset(), length); } private void writeBinary(byte[] buf, int offset, int length) throws TException { writeVarint32(length); trans_.write(buf, offset, length); } // // These methods are called by structs, but don't actually have any wire // output or purpose. // public void writeMessageEnd() throws TException {} public void writeMapEnd() throws TException {} public void writeListEnd() throws TException {} public void writeSetEnd() throws TException {} public void writeFieldEnd() throws TException {} // // Internal writing methods // /** * Abstract method for writing the start of lists and sets. List and sets on * the wire differ only by the type indicator. */ protected void writeCollectionBegin(byte elemType, int size) throws TException { if (size <= 14) { writeByteDirect(size << 4 | getCompactType(elemType)); } else { writeByteDirect(0xf0 | getCompactType(elemType)); writeVarint32(size); } } /** * Write an i32 as a varint. Results in 1-5 bytes on the wire. * TODO: make a permanent buffer like writeVarint64? */ byte[] i32buf = new byte[5]; private void writeVarint32(int n) throws TException { int idx = 0; while (true) { if ((n & ~0x7F) == 0) { i32buf[idx++] = (byte)n; // writeByteDirect((byte)n); break; // return; } else { i32buf[idx++] = (byte)((n & 0x7F) | 0x80); // writeByteDirect((byte)((n & 0x7F) | 0x80)); n >>>= 7; } } trans_.write(i32buf, 0, idx); } /** * Write an i64 as a varint. Results in 1-10 bytes on the wire. */ byte[] varint64out = new byte[10]; private void writeVarint64(long n) throws TException { int idx = 0; while (true) { if ((n & ~0x7FL) == 0) { varint64out[idx++] = (byte)n; break; } else { varint64out[idx++] = ((byte)((n & 0x7F) | 0x80)); n >>>= 7; } } trans_.write(varint64out, 0, idx); } /** * Convert l into a zigzag long. This allows negative numbers to be * represented compactly as a varint. */ private long longToZigzag(long l) { return (l << 1) ^ (l >> 63); } /** * Convert n into a zigzag int. This allows negative numbers to be * represented compactly as a varint. */ private int intToZigZag(int n) { return (n << 1) ^ (n >> 31); } /** * Convert a long into little-endian bytes in buf starting at off and going * until off+7. */ private void fixedLongToBytes(long n, byte[] buf, int off) { buf[off+0] = (byte)( n & 0xff); buf[off+1] = (byte)((n >> 8 ) & 0xff); buf[off+2] = (byte)((n >> 16) & 0xff); buf[off+3] = (byte)((n >> 24) & 0xff); buf[off+4] = (byte)((n >> 32) & 0xff); buf[off+5] = (byte)((n >> 40) & 0xff); buf[off+6] = (byte)((n >> 48) & 0xff); buf[off+7] = (byte)((n >> 56) & 0xff); } /** * Writes a byte without any possibility of all that field header nonsense. * Used internally by other writing methods that know they need to write a byte. */ private byte[] byteDirectBuffer = new byte[1]; private void writeByteDirect(byte b) throws TException { byteDirectBuffer[0] = b; trans_.write(byteDirectBuffer); } /** * Writes a byte without any possibility of all that field header nonsense. */ private void writeByteDirect(int n) throws TException { writeByteDirect((byte)n); } // // Reading methods. // /** * Read a message header. */ public TMessage readMessageBegin() throws TException { byte protocolId = readByte(); if (protocolId != PROTOCOL_ID) { throw new TProtocolException("Expected protocol id " + Integer.toHexString(PROTOCOL_ID) + " but got " + Integer.toHexString(protocolId)); } byte versionAndType = readByte(); byte version = (byte)(versionAndType & VERSION_MASK); if (version != VERSION) { throw new TProtocolException("Expected version " + VERSION + " but got " + version); } byte type = (byte)((versionAndType >> TYPE_SHIFT_AMOUNT) & 0x03); int seqid = readVarint32(); String messageName = readString(); return new TMessage(messageName, type, seqid); } /** * Read a struct begin. There's nothing on the wire for this, but it is our * opportunity to push a new struct begin marker onto the field stack. */ public TStruct readStructBegin() throws TException { lastField_.push(lastFieldId_); lastFieldId_ = 0; return ANONYMOUS_STRUCT; } /** * Doesn't actually consume any wire data, just removes the last field for * this struct from the field stack. */ public void readStructEnd() throws TException { // consume the last field we read off the wire. lastFieldId_ = lastField_.pop(); } /** * Read a field header off the wire. */ public TField readFieldBegin() throws TException { byte type = readByte(); // if it's a stop, then we can return immediately, as the struct is over. if (type == TType.STOP) { return TSTOP; } short fieldId; // mask off the 4 MSB of the type header. it could contain a field id delta. short modifier = (short)((type & 0xf0) >> 4); if (modifier == 0) { // not a delta. look ahead for the zigzag varint field id. fieldId = readI16(); } else { // has a delta. add the delta to the last read field id. fieldId = (short)(lastFieldId_ + modifier); } TField field = new TField("", getTType((byte)(type & 0x0f)), fieldId); // if this happens to be a boolean field, the value is encoded in the type if (isBoolType(type)) { // save the boolean value in a special instance variable. boolValue_ = (byte)(type & 0x0f) == Types.BOOLEAN_TRUE ? Boolean.TRUE : Boolean.FALSE; } // push the new field onto the field stack so we can keep the deltas going. lastFieldId_ = field.id; return field; } /** * Read a map header off the wire. If the size is zero, skip reading the key * and value type. This means that 0-length maps will yield TMaps without the * "correct" types. */ public TMap readMapBegin() throws TException { int size = readVarint32(); byte keyAndValueType = size == 0 ? 0 : readByte(); return new TMap(getTType((byte)(keyAndValueType >> 4)), getTType((byte)(keyAndValueType & 0xf)), size); } /** * Read a list header off the wire. If the list size is 0-14, the size will * be packed into the element type header. If it's a longer list, the 4 MSB * of the element type header will be 0xF, and a varint will follow with the * true size. */ public TList readListBegin() throws TException { byte size_and_type = readByte(); int size = (size_and_type >> 4) & 0x0f; if (size == 15) { size = readVarint32(); } byte type = getTType(size_and_type); return new TList(type, size); } /** * Read a set header off the wire. If the set size is 0-14, the size will * be packed into the element type header. If it's a longer set, the 4 MSB * of the element type header will be 0xF, and a varint will follow with the * true size. */ public TSet readSetBegin() throws TException { return new TSet(readListBegin()); } /** * Read a boolean off the wire. If this is a boolean field, the value should * already have been read during readFieldBegin, so we'll just consume the * pre-stored value. Otherwise, read a byte. */ public boolean readBool() throws TException { if (boolValue_ != null) { boolean result = boolValue_.booleanValue(); boolValue_ = null; return result; } return readByte() == Types.BOOLEAN_TRUE; } byte[] byteRawBuf = new byte[1]; /** * Read a single byte off the wire. Nothing interesting here. */ public byte readByte() throws TException { byte b; if (trans_.getBytesRemainingInBuffer() > 0) { b = trans_.getBuffer()[trans_.getBufferPosition()]; trans_.consumeBuffer(1); } else { trans_.readAll(byteRawBuf, 0, 1); b = byteRawBuf[0]; } return b; } /** * Read an i16 from the wire as a zigzag varint. */ public short readI16() throws TException { return (short)zigzagToInt(readVarint32()); } /** * Read an i32 from the wire as a zigzag varint. */ public int readI32() throws TException { return zigzagToInt(readVarint32()); } /** * Read an i64 from the wire as a zigzag varint. */ public long readI64() throws TException { return zigzagToLong(readVarint64()); } /** * No magic here - just read a double off the wire. */ public double readDouble() throws TException { byte[] longBits = new byte[8]; trans_.readAll(longBits, 0, 8); return Double.longBitsToDouble(bytesToLong(longBits)); } /** * Reads a byte[] (via readBinary), and then UTF-8 decodes it. */ public String readString() throws TException { int length = readVarint32(); checkReadLength(length); if (length == 0) { return ""; } try { if (trans_.getBytesRemainingInBuffer() >= length) { String str = new String(trans_.getBuffer(), trans_.getBufferPosition(), length, "UTF-8"); trans_.consumeBuffer(length); return str; } else { return new String(readBinary(length), "UTF-8"); } } catch (UnsupportedEncodingException e) { throw new TException("UTF-8 not supported!"); } } /** * Read a byte[] from the wire. */ public ByteBuffer readBinary() throws TException { int length = readVarint32(); checkReadLength(length); if (length == 0) return ByteBuffer.wrap(new byte[0]); byte[] buf = new byte[length]; trans_.readAll(buf, 0, length); return ByteBuffer.wrap(buf); } /** * Read a byte[] of a known length from the wire. */ private byte[] readBinary(int length) throws TException { if (length == 0) return new byte[0]; byte[] buf = new byte[length]; trans_.readAll(buf, 0, length); return buf; } private void checkReadLength(int length) throws TProtocolException { if (length < 0) { throw new TProtocolException("Negative length: " + length); } if (maxNetworkBytes_ != -1 && length > maxNetworkBytes_) { throw new TProtocolException("Length exceeded max allowed: " + length); } } // // These methods are here for the struct to call, but don't have any wire // encoding. // public void readMessageEnd() throws TException {} public void readFieldEnd() throws TException {} public void readMapEnd() throws TException {} public void readListEnd() throws TException {} public void readSetEnd() throws TException {} // // Internal reading methods // /** * Read an i32 from the wire as a varint. The MSB of each byte is set * if there is another byte to follow. This can read up to 5 bytes. */ private int readVarint32() throws TException { int result = 0; int shift = 0; if (trans_.getBytesRemainingInBuffer() >= 5) { byte[] buf = trans_.getBuffer(); int pos = trans_.getBufferPosition(); int off = 0; while (true) { byte b = buf[pos+off]; result |= (int) (b & 0x7f) << shift; if ((b & 0x80) != 0x80) break; shift += 7; off++; } trans_.consumeBuffer(off+1); } else { while (true) { byte b = readByte(); result |= (int) (b & 0x7f) << shift; if ((b & 0x80) != 0x80) break; shift += 7; } } return result; } /** * Read an i64 from the wire as a proper varint. The MSB of each byte is set * if there is another byte to follow. This can read up to 10 bytes. */ private long readVarint64() throws TException { int shift = 0; long result = 0; if (trans_.getBytesRemainingInBuffer() >= 10) { byte[] buf = trans_.getBuffer(); int pos = trans_.getBufferPosition(); int off = 0; while (true) { byte b = buf[pos+off]; result |= (long) (b & 0x7f) << shift; if ((b & 0x80) != 0x80) break; shift += 7; off++; } trans_.consumeBuffer(off+1); } else { while (true) { byte b = readByte(); result |= (long) (b & 0x7f) << shift; if ((b & 0x80) != 0x80) break; shift +=7; } } return result; } // // encoding helpers // /** * Convert from zigzag int to int. */ private int zigzagToInt(int n) { return (n >>> 1) ^ -(n & 1); } /** * Convert from zigzag long to long. */ private long zigzagToLong(long n) { return (n >>> 1) ^ -(n & 1); } /** * Note that it's important that the mask bytes are long literals, * otherwise they'll default to ints, and when you shift an int left 56 bits, * you just get a messed up int. */ private long bytesToLong(byte[] bytes) { return ((bytes[7] & 0xffL) << 56) | ((bytes[6] & 0xffL) << 48) | ((bytes[5] & 0xffL) << 40) | ((bytes[4] & 0xffL) << 32) | ((bytes[3] & 0xffL) << 24) | ((bytes[2] & 0xffL) << 16) | ((bytes[1] & 0xffL) << 8) | ((bytes[0] & 0xffL)); } // // type testing and converting // private boolean isBoolType(byte b) { int lowerNibble = b & 0x0f; return lowerNibble == Types.BOOLEAN_TRUE || lowerNibble == Types.BOOLEAN_FALSE; } /** * Given a TCompactProtocol.Types constant, convert it to its corresponding * TType value. */ private byte getTType(byte type) throws TProtocolException { switch ((byte)(type & 0x0f)) { case TType.STOP: return TType.STOP; case Types.BOOLEAN_FALSE: case Types.BOOLEAN_TRUE: return TType.BOOL; case Types.BYTE: return TType.BYTE; case Types.I16: return TType.I16; case Types.I32: return TType.I32; case Types.I64: return TType.I64; case Types.DOUBLE: return TType.DOUBLE; case Types.BINARY: return TType.STRING; case Types.LIST: return TType.LIST; case Types.SET: return TType.SET; case Types.MAP: return TType.MAP; case Types.STRUCT: return TType.STRUCT; default: throw new TProtocolException("don't know what type: " + (byte)(type & 0x0f)); } } /** * Given a TType value, find the appropriate TCompactProtocol.Types constant. */ private byte getCompactType(byte ttype) { return ttypeToCompactType[ttype]; } } libthrift-java_0.9.0/src/org/apache/thrift/protocol/TList.java0000644000175000017500000000212112035665435025143 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; /** * Helper class that encapsulates list metadata. * */ public final class TList { public TList() { this(TType.STOP, 0); } public TList(byte t, int s) { elemType = t; size = s; } public final byte elemType; public final int size; } libthrift-java_0.9.0/src/org/apache/thrift/protocol/TTupleProtocol.java0000644000175000017500000000573412035665435027060 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; import java.util.BitSet; import org.apache.thrift.TException; import org.apache.thrift.scheme.IScheme; import org.apache.thrift.scheme.TupleScheme; import org.apache.thrift.transport.TTransport; public final class TTupleProtocol extends TCompactProtocol { public static class Factory implements TProtocolFactory { public Factory() {} public TProtocol getProtocol(TTransport trans) { return new TTupleProtocol(trans); } } public TTupleProtocol(TTransport transport) { super(transport); } @Override public Class getScheme() { return TupleScheme.class; } public void writeBitSet(BitSet bs, int vectorWidth) throws TException { byte[] bytes = toByteArray(bs, vectorWidth); for (byte b : bytes) { writeByte(b); } } public BitSet readBitSet(int i) throws TException { int length = (int) Math.ceil(i/8.0); byte[] bytes = new byte[length]; for (int j = 0; j < length; j++) { bytes[j] = readByte(); } BitSet bs = fromByteArray(bytes); return bs; } /** * Returns a bitset containing the values in bytes. The byte-ordering must be * big-endian. */ public static BitSet fromByteArray(byte[] bytes) { BitSet bits = new BitSet(); for (int i = 0; i < bytes.length * 8; i++) { if ((bytes[bytes.length - i / 8 - 1] & (1 << (i % 8))) > 0) { bits.set(i); } } return bits; } /** * Returns a byte array of at least length 1. The most significant bit in the * result is guaranteed not to be a 1 (since BitSet does not support sign * extension). The byte-ordering of the result is big-endian which means the * most significant bit is in element 0. The bit at index 0 of the bit set is * assumed to be the least significant bit. * * @param bits * @param vectorWidth * @return a byte array of at least length 1 */ public static byte[] toByteArray(BitSet bits, int vectorWidth) { byte[] bytes = new byte[(int) Math.ceil(vectorWidth/8.0)]; for (int i = 0; i < bits.length(); i++) { if (bits.get(i)) { bytes[bytes.length - i / 8 - 1] |= 1 << (i % 8); } } return bytes; } } libthrift-java_0.9.0/src/org/apache/thrift/protocol/TProtocol.java0000644000175000017500000001040212035665435026032 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; import java.nio.ByteBuffer; import org.apache.thrift.TException; import org.apache.thrift.scheme.IScheme; import org.apache.thrift.scheme.StandardScheme; import org.apache.thrift.transport.TTransport; /** * Protocol interface definition. * */ public abstract class TProtocol { /** * Prevent direct instantiation */ @SuppressWarnings("unused") private TProtocol() {} /** * Transport */ protected TTransport trans_; /** * Constructor */ protected TProtocol(TTransport trans) { trans_ = trans; } /** * Transport accessor */ public TTransport getTransport() { return trans_; } /** * Writing methods. */ public abstract void writeMessageBegin(TMessage message) throws TException; public abstract void writeMessageEnd() throws TException; public abstract void writeStructBegin(TStruct struct) throws TException; public abstract void writeStructEnd() throws TException; public abstract void writeFieldBegin(TField field) throws TException; public abstract void writeFieldEnd() throws TException; public abstract void writeFieldStop() throws TException; public abstract void writeMapBegin(TMap map) throws TException; public abstract void writeMapEnd() throws TException; public abstract void writeListBegin(TList list) throws TException; public abstract void writeListEnd() throws TException; public abstract void writeSetBegin(TSet set) throws TException; public abstract void writeSetEnd() throws TException; public abstract void writeBool(boolean b) throws TException; public abstract void writeByte(byte b) throws TException; public abstract void writeI16(short i16) throws TException; public abstract void writeI32(int i32) throws TException; public abstract void writeI64(long i64) throws TException; public abstract void writeDouble(double dub) throws TException; public abstract void writeString(String str) throws TException; public abstract void writeBinary(ByteBuffer buf) throws TException; /** * Reading methods. */ public abstract TMessage readMessageBegin() throws TException; public abstract void readMessageEnd() throws TException; public abstract TStruct readStructBegin() throws TException; public abstract void readStructEnd() throws TException; public abstract TField readFieldBegin() throws TException; public abstract void readFieldEnd() throws TException; public abstract TMap readMapBegin() throws TException; public abstract void readMapEnd() throws TException; public abstract TList readListBegin() throws TException; public abstract void readListEnd() throws TException; public abstract TSet readSetBegin() throws TException; public abstract void readSetEnd() throws TException; public abstract boolean readBool() throws TException; public abstract byte readByte() throws TException; public abstract short readI16() throws TException; public abstract int readI32() throws TException; public abstract long readI64() throws TException; public abstract double readDouble() throws TException; public abstract String readString() throws TException; public abstract ByteBuffer readBinary() throws TException; /** * Reset any internal state back to a blank slate. This method only needs to * be implemented for stateful protocols. */ public void reset() {} /** * Scheme accessor */ public Class getScheme() { return StandardScheme.class; } } libthrift-java_0.9.0/src/org/apache/thrift/protocol/TStruct.java0000644000175000017500000000203312035665435025516 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; /** * Helper class that encapsulates struct metadata. * */ public final class TStruct { public TStruct() { this(""); } public TStruct(String n) { name = n; } public final String name; } libthrift-java_0.9.0/src/org/apache/thrift/protocol/TProtocolFactory.java0000644000175000017500000000210712035665435027365 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; import java.io.Serializable; import org.apache.thrift.transport.TTransport; /** * Factory interface for constructing protocol instances. */ public interface TProtocolFactory extends Serializable { public TProtocol getProtocol(TTransport trans); } libthrift-java_0.9.0/src/org/apache/thrift/protocol/TType.java0000644000175000017500000000270212035665435025156 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; /** * Type constants in the Thrift protocol. */ public final class TType { public static final byte STOP = 0; public static final byte VOID = 1; public static final byte BOOL = 2; public static final byte BYTE = 3; public static final byte DOUBLE = 4; public static final byte I16 = 6; public static final byte I32 = 8; public static final byte I64 = 10; public static final byte STRING = 11; public static final byte STRUCT = 12; public static final byte MAP = 13; public static final byte SET = 14; public static final byte LIST = 15; public static final byte ENUM = 16; } libthrift-java_0.9.0/src/org/apache/thrift/protocol/TProtocolException.java0000644000175000017500000000400012035665435027706 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; import org.apache.thrift.TException; /** * Protocol exceptions. * */ public class TProtocolException extends TException { private static final long serialVersionUID = 1L; public static final int UNKNOWN = 0; public static final int INVALID_DATA = 1; public static final int NEGATIVE_SIZE = 2; public static final int SIZE_LIMIT = 3; public static final int BAD_VERSION = 4; public static final int NOT_IMPLEMENTED = 5; protected int type_ = UNKNOWN; public TProtocolException() { super(); } public TProtocolException(int type) { super(); type_ = type; } public TProtocolException(int type, String message) { super(message); type_ = type; } public TProtocolException(String message) { super(message); } public TProtocolException(int type, Throwable cause) { super(cause); type_ = type; } public TProtocolException(Throwable cause) { super(cause); } public TProtocolException(String message, Throwable cause) { super(message, cause); } public TProtocolException(int type, String message, Throwable cause) { super(message, cause); type_ = type; } public int getType() { return type_; } } libthrift-java_0.9.0/src/org/apache/thrift/protocol/TBinaryProtocol.java0000644000175000017500000002504712035665435027212 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; import java.io.UnsupportedEncodingException; import java.nio.ByteBuffer; import org.apache.thrift.TException; import org.apache.thrift.transport.TTransport; /** * Binary protocol implementation for thrift. * */ public class TBinaryProtocol extends TProtocol { private static final TStruct ANONYMOUS_STRUCT = new TStruct(); protected static final int VERSION_MASK = 0xffff0000; protected static final int VERSION_1 = 0x80010000; protected boolean strictRead_ = false; protected boolean strictWrite_ = true; protected int readLength_; protected boolean checkReadLength_ = false; /** * Factory */ public static class Factory implements TProtocolFactory { protected boolean strictRead_ = false; protected boolean strictWrite_ = true; protected int readLength_; public Factory() { this(false, true); } public Factory(boolean strictRead, boolean strictWrite) { this(strictRead, strictWrite, 0); } public Factory(boolean strictRead, boolean strictWrite, int readLength) { strictRead_ = strictRead; strictWrite_ = strictWrite; readLength_ = readLength; } public TProtocol getProtocol(TTransport trans) { TBinaryProtocol proto = new TBinaryProtocol(trans, strictRead_, strictWrite_); if (readLength_ != 0) { proto.setReadLength(readLength_); } return proto; } } /** * Constructor */ public TBinaryProtocol(TTransport trans) { this(trans, false, true); } public TBinaryProtocol(TTransport trans, boolean strictRead, boolean strictWrite) { super(trans); strictRead_ = strictRead; strictWrite_ = strictWrite; } public void writeMessageBegin(TMessage message) throws TException { if (strictWrite_) { int version = VERSION_1 | message.type; writeI32(version); writeString(message.name); writeI32(message.seqid); } else { writeString(message.name); writeByte(message.type); writeI32(message.seqid); } } public void writeMessageEnd() {} public void writeStructBegin(TStruct struct) {} public void writeStructEnd() {} public void writeFieldBegin(TField field) throws TException { writeByte(field.type); writeI16(field.id); } public void writeFieldEnd() {} public void writeFieldStop() throws TException { writeByte(TType.STOP); } public void writeMapBegin(TMap map) throws TException { writeByte(map.keyType); writeByte(map.valueType); writeI32(map.size); } public void writeMapEnd() {} public void writeListBegin(TList list) throws TException { writeByte(list.elemType); writeI32(list.size); } public void writeListEnd() {} public void writeSetBegin(TSet set) throws TException { writeByte(set.elemType); writeI32(set.size); } public void writeSetEnd() {} public void writeBool(boolean b) throws TException { writeByte(b ? (byte)1 : (byte)0); } private byte [] bout = new byte[1]; public void writeByte(byte b) throws TException { bout[0] = b; trans_.write(bout, 0, 1); } private byte[] i16out = new byte[2]; public void writeI16(short i16) throws TException { i16out[0] = (byte)(0xff & (i16 >> 8)); i16out[1] = (byte)(0xff & (i16)); trans_.write(i16out, 0, 2); } private byte[] i32out = new byte[4]; public void writeI32(int i32) throws TException { i32out[0] = (byte)(0xff & (i32 >> 24)); i32out[1] = (byte)(0xff & (i32 >> 16)); i32out[2] = (byte)(0xff & (i32 >> 8)); i32out[3] = (byte)(0xff & (i32)); trans_.write(i32out, 0, 4); } private byte[] i64out = new byte[8]; public void writeI64(long i64) throws TException { i64out[0] = (byte)(0xff & (i64 >> 56)); i64out[1] = (byte)(0xff & (i64 >> 48)); i64out[2] = (byte)(0xff & (i64 >> 40)); i64out[3] = (byte)(0xff & (i64 >> 32)); i64out[4] = (byte)(0xff & (i64 >> 24)); i64out[5] = (byte)(0xff & (i64 >> 16)); i64out[6] = (byte)(0xff & (i64 >> 8)); i64out[7] = (byte)(0xff & (i64)); trans_.write(i64out, 0, 8); } public void writeDouble(double dub) throws TException { writeI64(Double.doubleToLongBits(dub)); } public void writeString(String str) throws TException { try { byte[] dat = str.getBytes("UTF-8"); writeI32(dat.length); trans_.write(dat, 0, dat.length); } catch (UnsupportedEncodingException uex) { throw new TException("JVM DOES NOT SUPPORT UTF-8"); } } public void writeBinary(ByteBuffer bin) throws TException { int length = bin.limit() - bin.position(); writeI32(length); trans_.write(bin.array(), bin.position() + bin.arrayOffset(), length); } /** * Reading methods. */ public TMessage readMessageBegin() throws TException { int size = readI32(); if (size < 0) { int version = size & VERSION_MASK; if (version != VERSION_1) { throw new TProtocolException(TProtocolException.BAD_VERSION, "Bad version in readMessageBegin"); } return new TMessage(readString(), (byte)(size & 0x000000ff), readI32()); } else { if (strictRead_) { throw new TProtocolException(TProtocolException.BAD_VERSION, "Missing version in readMessageBegin, old client?"); } return new TMessage(readStringBody(size), readByte(), readI32()); } } public void readMessageEnd() {} public TStruct readStructBegin() { return ANONYMOUS_STRUCT; } public void readStructEnd() {} public TField readFieldBegin() throws TException { byte type = readByte(); short id = type == TType.STOP ? 0 : readI16(); return new TField("", type, id); } public void readFieldEnd() {} public TMap readMapBegin() throws TException { return new TMap(readByte(), readByte(), readI32()); } public void readMapEnd() {} public TList readListBegin() throws TException { return new TList(readByte(), readI32()); } public void readListEnd() {} public TSet readSetBegin() throws TException { return new TSet(readByte(), readI32()); } public void readSetEnd() {} public boolean readBool() throws TException { return (readByte() == 1); } private byte[] bin = new byte[1]; public byte readByte() throws TException { if (trans_.getBytesRemainingInBuffer() >= 1) { byte b = trans_.getBuffer()[trans_.getBufferPosition()]; trans_.consumeBuffer(1); return b; } readAll(bin, 0, 1); return bin[0]; } private byte[] i16rd = new byte[2]; public short readI16() throws TException { byte[] buf = i16rd; int off = 0; if (trans_.getBytesRemainingInBuffer() >= 2) { buf = trans_.getBuffer(); off = trans_.getBufferPosition(); trans_.consumeBuffer(2); } else { readAll(i16rd, 0, 2); } return (short) (((buf[off] & 0xff) << 8) | ((buf[off+1] & 0xff))); } private byte[] i32rd = new byte[4]; public int readI32() throws TException { byte[] buf = i32rd; int off = 0; if (trans_.getBytesRemainingInBuffer() >= 4) { buf = trans_.getBuffer(); off = trans_.getBufferPosition(); trans_.consumeBuffer(4); } else { readAll(i32rd, 0, 4); } return ((buf[off] & 0xff) << 24) | ((buf[off+1] & 0xff) << 16) | ((buf[off+2] & 0xff) << 8) | ((buf[off+3] & 0xff)); } private byte[] i64rd = new byte[8]; public long readI64() throws TException { byte[] buf = i64rd; int off = 0; if (trans_.getBytesRemainingInBuffer() >= 8) { buf = trans_.getBuffer(); off = trans_.getBufferPosition(); trans_.consumeBuffer(8); } else { readAll(i64rd, 0, 8); } return ((long)(buf[off] & 0xff) << 56) | ((long)(buf[off+1] & 0xff) << 48) | ((long)(buf[off+2] & 0xff) << 40) | ((long)(buf[off+3] & 0xff) << 32) | ((long)(buf[off+4] & 0xff) << 24) | ((long)(buf[off+5] & 0xff) << 16) | ((long)(buf[off+6] & 0xff) << 8) | ((long)(buf[off+7] & 0xff)); } public double readDouble() throws TException { return Double.longBitsToDouble(readI64()); } public String readString() throws TException { int size = readI32(); if (trans_.getBytesRemainingInBuffer() >= size) { try { String s = new String(trans_.getBuffer(), trans_.getBufferPosition(), size, "UTF-8"); trans_.consumeBuffer(size); return s; } catch (UnsupportedEncodingException e) { throw new TException("JVM DOES NOT SUPPORT UTF-8"); } } return readStringBody(size); } public String readStringBody(int size) throws TException { try { checkReadLength(size); byte[] buf = new byte[size]; trans_.readAll(buf, 0, size); return new String(buf, "UTF-8"); } catch (UnsupportedEncodingException uex) { throw new TException("JVM DOES NOT SUPPORT UTF-8"); } } public ByteBuffer readBinary() throws TException { int size = readI32(); checkReadLength(size); if (trans_.getBytesRemainingInBuffer() >= size) { ByteBuffer bb = ByteBuffer.wrap(trans_.getBuffer(), trans_.getBufferPosition(), size); trans_.consumeBuffer(size); return bb; } byte[] buf = new byte[size]; trans_.readAll(buf, 0, size); return ByteBuffer.wrap(buf); } private int readAll(byte[] buf, int off, int len) throws TException { checkReadLength(len); return trans_.readAll(buf, off, len); } public void setReadLength(int readLength) { readLength_ = readLength; checkReadLength_ = true; } protected void checkReadLength(int length) throws TException { if (length < 0) { throw new TProtocolException("Negative length: " + length); } if (checkReadLength_) { readLength_ -= length; if (readLength_ < 0) { throw new TProtocolException("Message length exceeded: " + length); } } } } libthrift-java_0.9.0/src/org/apache/thrift/protocol/TMessage.java0000644000175000017500000000305512035665435025623 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; /** * Helper class that encapsulates struct metadata. * */ public final class TMessage { public TMessage() { this("", TType.STOP, 0); } public TMessage(String n, byte t, int s) { name = n; type = t; seqid = s; } public final String name; public final byte type; public final int seqid; @Override public String toString() { return ""; } @Override public boolean equals(Object other) { if (other instanceof TMessage) { return equals((TMessage) other); } return false; } public boolean equals(TMessage other) { return name.equals(other.name) && type == other.type && seqid == other.seqid; } } libthrift-java_0.9.0/src/org/apache/thrift/protocol/TSet.java0000644000175000017500000000222212035665435024765 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; /** * Helper class that encapsulates set metadata. * */ public final class TSet { public TSet() { this(TType.STOP, 0); } public TSet(byte t, int s) { elemType = t; size = s; } public TSet(TList list) { this(list.elemType, list.size); } public final byte elemType; public final int size; } libthrift-java_0.9.0/src/org/apache/thrift/protocol/TField.java0000644000175000017500000000255012035665435025261 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; /** * Helper class that encapsulates field metadata. * */ public class TField { public TField() { this("", TType.STOP, (short)0); } public TField(String n, byte t, short i) { name = n; type = t; id = i; } public final String name; public final byte type; public final short id; public String toString() { return ""; } public boolean equals(TField otherField) { return type == otherField.type && id == otherField.id; } } libthrift-java_0.9.0/src/org/apache/thrift/protocol/TBase64Utils.java0000644000175000017500000001236012035665435026303 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; /** * Class for encoding and decoding Base64 data. * * This class is kept at package level because the interface does no input * validation and is therefore too low-level for generalized reuse. * * Note also that the encoding does not pad with equal signs , as discussed in * section 2.2 of the RFC (http://www.faqs.org/rfcs/rfc3548.html). Furthermore, * bad data encountered when decoding is neither rejected or ignored but simply * results in bad decoded data -- this is not in compliance with the RFC but is * done in the interest of performance. * */ class TBase64Utils { private static final String ENCODE_TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; /** * Encode len bytes of data in src at offset srcOff, storing the result into * dst at offset dstOff. len must be 1, 2, or 3. dst must have at least len+1 * bytes of space at dstOff. src and dst should not be the same object. This * method does no validation of the input values in the interest of * performance. * * @param src the source of bytes to encode * @param srcOff the offset into the source to read the unencoded bytes * @param len the number of bytes to encode (must be 1, 2, or 3). * @param dst the destination for the encoding * @param dstOff the offset into the destination to place the encoded bytes */ static final void encode(byte[] src, int srcOff, int len, byte[] dst, int dstOff) { dst[dstOff] = (byte)ENCODE_TABLE.charAt((src[srcOff] >> 2) & 0x3F); if (len == 3) { dst[dstOff + 1] = (byte)ENCODE_TABLE.charAt( ((src[srcOff] << 4) & 0x30) | ((src[srcOff+1] >> 4) & 0x0F)); dst[dstOff + 2] = (byte)ENCODE_TABLE.charAt( ((src[srcOff+1] << 2) & 0x3C) | ((src[srcOff+2] >> 6) & 0x03)); dst[dstOff + 3] = (byte)ENCODE_TABLE.charAt(src[srcOff+2] & 0x3F); } else if (len == 2) { dst[dstOff+1] = (byte)ENCODE_TABLE.charAt( ((src[srcOff] << 4) & 0x30) | ((src[srcOff+1] >> 4) & 0x0F)); dst[dstOff + 2] = (byte)ENCODE_TABLE.charAt((src[srcOff+1] << 2) & 0x3C); } else { // len == 1) { dst[dstOff + 1] = (byte)ENCODE_TABLE.charAt((src[srcOff] << 4) & 0x30); } } private static final byte[] DECODE_TABLE = { -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,62,-1,-1,-1,63, 52,53,54,55,56,57,58,59,60,61,-1,-1,-1,-1,-1,-1, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10,11,12,13,14, 15,16,17,18,19,20,21,22,23,24,25,-1,-1,-1,-1,-1, -1,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40, 41,42,43,44,45,46,47,48,49,50,51,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, }; /** * Decode len bytes of data in src at offset srcOff, storing the result into * dst at offset dstOff. len must be 2, 3, or 4. dst must have at least len-1 * bytes of space at dstOff. src and dst may be the same object as long as * dstoff <= srcOff. This method does no validation of the input values in * the interest of performance. * * @param src the source of bytes to decode * @param srcOff the offset into the source to read the encoded bytes * @param len the number of bytes to decode (must be 2, 3, or 4) * @param dst the destination for the decoding * @param dstOff the offset into the destination to place the decoded bytes */ static final void decode(byte[] src, int srcOff, int len, byte[] dst, int dstOff) { dst[dstOff] = (byte) ((DECODE_TABLE[src[srcOff] & 0x0FF] << 2) | (DECODE_TABLE[src[srcOff+1] & 0x0FF] >> 4)); if (len > 2) { dst[dstOff+1] = (byte) (((DECODE_TABLE[src[srcOff+1] & 0x0FF] << 4) & 0xF0) | (DECODE_TABLE[src[srcOff+2] & 0x0FF] >> 2)); if (len > 3) { dst[dstOff+2] = (byte) (((DECODE_TABLE[src[srcOff+2] & 0x0FF] << 6) & 0xC0) | DECODE_TABLE[src[srcOff+3] & 0x0FF]); } } } } libthrift-java_0.9.0/src/org/apache/thrift/protocol/TSimpleJSONProtocol.java0000644000175000017500000002273212035665435027707 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; import java.io.UnsupportedEncodingException; import java.nio.ByteBuffer; import java.util.Stack; import org.apache.thrift.TException; import org.apache.thrift.transport.TTransport; /** * JSON protocol implementation for thrift. * * This protocol is write-only and produces a simple output format * suitable for parsing by scripting languages. It should not be * confused with the full-featured TJSONProtocol. * */ public class TSimpleJSONProtocol extends TProtocol { /** * Factory */ public static class Factory implements TProtocolFactory { public TProtocol getProtocol(TTransport trans) { return new TSimpleJSONProtocol(trans); } } public static final byte[] COMMA = new byte[] {','}; public static final byte[] COLON = new byte[] {':'}; public static final byte[] LBRACE = new byte[] {'{'}; public static final byte[] RBRACE = new byte[] {'}'}; public static final byte[] LBRACKET = new byte[] {'['}; public static final byte[] RBRACKET = new byte[] {']'}; public static final char QUOTE = '"'; private static final TStruct ANONYMOUS_STRUCT = new TStruct(); private static final TField ANONYMOUS_FIELD = new TField(); private static final TMessage EMPTY_MESSAGE = new TMessage(); private static final TSet EMPTY_SET = new TSet(); private static final TList EMPTY_LIST = new TList(); private static final TMap EMPTY_MAP = new TMap(); protected class Context { protected void write() throws TException {} } protected class ListContext extends Context { protected boolean first_ = true; protected void write() throws TException { if (first_) { first_ = false; } else { trans_.write(COMMA); } } } protected class StructContext extends Context { protected boolean first_ = true; protected boolean colon_ = true; protected void write() throws TException { if (first_) { first_ = false; colon_ = true; } else { trans_.write(colon_ ? COLON : COMMA); colon_ = !colon_; } } } protected final Context BASE_CONTEXT = new Context(); /** * Stack of nested contexts that we may be in. */ protected Stack writeContextStack_ = new Stack(); /** * Current context that we are in */ protected Context writeContext_ = BASE_CONTEXT; /** * Push a new write context onto the stack. */ protected void pushWriteContext(Context c) { writeContextStack_.push(writeContext_); writeContext_ = c; } /** * Pop the last write context off the stack */ protected void popWriteContext() { writeContext_ = writeContextStack_.pop(); } /** * Constructor */ public TSimpleJSONProtocol(TTransport trans) { super(trans); } public void writeMessageBegin(TMessage message) throws TException { trans_.write(LBRACKET); pushWriteContext(new ListContext()); writeString(message.name); writeByte(message.type); writeI32(message.seqid); } public void writeMessageEnd() throws TException { popWriteContext(); trans_.write(RBRACKET); } public void writeStructBegin(TStruct struct) throws TException { writeContext_.write(); trans_.write(LBRACE); pushWriteContext(new StructContext()); } public void writeStructEnd() throws TException { popWriteContext(); trans_.write(RBRACE); } public void writeFieldBegin(TField field) throws TException { // Note that extra type information is omitted in JSON! writeString(field.name); } public void writeFieldEnd() {} public void writeFieldStop() {} public void writeMapBegin(TMap map) throws TException { writeContext_.write(); trans_.write(LBRACE); pushWriteContext(new StructContext()); // No metadata! } public void writeMapEnd() throws TException { popWriteContext(); trans_.write(RBRACE); } public void writeListBegin(TList list) throws TException { writeContext_.write(); trans_.write(LBRACKET); pushWriteContext(new ListContext()); // No metadata! } public void writeListEnd() throws TException { popWriteContext(); trans_.write(RBRACKET); } public void writeSetBegin(TSet set) throws TException { writeContext_.write(); trans_.write(LBRACKET); pushWriteContext(new ListContext()); // No metadata! } public void writeSetEnd() throws TException { popWriteContext(); trans_.write(RBRACKET); } public void writeBool(boolean b) throws TException { writeByte(b ? (byte)1 : (byte)0); } public void writeByte(byte b) throws TException { writeI32(b); } public void writeI16(short i16) throws TException { writeI32(i16); } public void writeI32(int i32) throws TException { writeContext_.write(); _writeStringData(Integer.toString(i32)); } public void _writeStringData(String s) throws TException { try { byte[] b = s.getBytes("UTF-8"); trans_.write(b); } catch (UnsupportedEncodingException uex) { throw new TException("JVM DOES NOT SUPPORT UTF-8"); } } public void writeI64(long i64) throws TException { writeContext_.write(); _writeStringData(Long.toString(i64)); } public void writeDouble(double dub) throws TException { writeContext_.write(); _writeStringData(Double.toString(dub)); } public void writeString(String str) throws TException { writeContext_.write(); int length = str.length(); StringBuffer escape = new StringBuffer(length + 16); escape.append(QUOTE); for (int i = 0; i < length; ++i) { char c = str.charAt(i); switch (c) { case '"': case '\\': escape.append('\\'); escape.append(c); break; case '\b': escape.append('\\'); escape.append('b'); break; case '\f': escape.append('\\'); escape.append('f'); break; case '\n': escape.append('\\'); escape.append('n'); break; case '\r': escape.append('\\'); escape.append('r'); break; case '\t': escape.append('\\'); escape.append('t'); break; default: // Control characters! According to JSON RFC u0020 (space) if (c < ' ') { String hex = Integer.toHexString(c); escape.append('\\'); escape.append('u'); for (int j = 4; j > hex.length(); --j) { escape.append('0'); } escape.append(hex); } else { escape.append(c); } break; } } escape.append(QUOTE); _writeStringData(escape.toString()); } public void writeBinary(ByteBuffer bin) throws TException { try { // TODO(mcslee): Fix this writeString(new String(bin.array(), bin.position() + bin.arrayOffset(), bin.limit() - bin.position() - bin.arrayOffset(), "UTF-8")); } catch (UnsupportedEncodingException uex) { throw new TException("JVM DOES NOT SUPPORT UTF-8"); } } /** * Reading methods. */ public TMessage readMessageBegin() throws TException { // TODO(mcslee): implement return EMPTY_MESSAGE; } public void readMessageEnd() {} public TStruct readStructBegin() { // TODO(mcslee): implement return ANONYMOUS_STRUCT; } public void readStructEnd() {} public TField readFieldBegin() throws TException { // TODO(mcslee): implement return ANONYMOUS_FIELD; } public void readFieldEnd() {} public TMap readMapBegin() throws TException { // TODO(mcslee): implement return EMPTY_MAP; } public void readMapEnd() {} public TList readListBegin() throws TException { // TODO(mcslee): implement return EMPTY_LIST; } public void readListEnd() {} public TSet readSetBegin() throws TException { // TODO(mcslee): implement return EMPTY_SET; } public void readSetEnd() {} public boolean readBool() throws TException { return (readByte() == 1); } public byte readByte() throws TException { // TODO(mcslee): implement return 0; } public short readI16() throws TException { // TODO(mcslee): implement return 0; } public int readI32() throws TException { // TODO(mcslee): implement return 0; } public long readI64() throws TException { // TODO(mcslee): implement return 0; } public double readDouble() throws TException { // TODO(mcslee): implement return 0; } public String readString() throws TException { // TODO(mcslee): implement return ""; } public String readStringBody(int size) throws TException { // TODO(mcslee): implement return ""; } public ByteBuffer readBinary() throws TException { // TODO(mcslee): implement return ByteBuffer.wrap(new byte[0]); } } libthrift-java_0.9.0/src/org/apache/thrift/protocol/TMap.java0000644000175000017500000000222412035665435024751 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.protocol; /** * Helper class that encapsulates map metadata. * */ public final class TMap { public TMap() { this(TType.STOP, TType.STOP, 0); } public TMap(byte k, byte v, int s) { keyType = k; valueType = v; size = s; } public final byte keyType; public final byte valueType; public final int size; } libthrift-java_0.9.0/src/org/apache/thrift/async/0000755000175000017500000000000012035665714022521 5ustar eevanseevans00000000000000libthrift-java_0.9.0/src/org/apache/thrift/async/TAsyncMethodCall.java0000644000175000017500000002003512035665435026522 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.async; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.util.concurrent.atomic.AtomicLong; import org.apache.thrift.TException; import org.apache.thrift.protocol.TProtocol; import org.apache.thrift.protocol.TProtocolFactory; import org.apache.thrift.transport.TFramedTransport; import org.apache.thrift.transport.TMemoryBuffer; import org.apache.thrift.transport.TNonblockingTransport; import org.apache.thrift.transport.TTransportException; /** * Encapsulates an async method call * Need to generate: * - private void write_args(TProtocol protocol) * - public T getResult() throws , , ... * @param */ public abstract class TAsyncMethodCall { private static final int INITIAL_MEMORY_BUFFER_SIZE = 128; private static AtomicLong sequenceIdCounter = new AtomicLong(0); public static enum State { CONNECTING, WRITING_REQUEST_SIZE, WRITING_REQUEST_BODY, READING_RESPONSE_SIZE, READING_RESPONSE_BODY, RESPONSE_READ, ERROR; } /** * Next step in the call, initialized by start() */ private State state = null; protected final TNonblockingTransport transport; private final TProtocolFactory protocolFactory; protected final TAsyncClient client; private final AsyncMethodCallback callback; private final boolean isOneway; private long sequenceId; private ByteBuffer sizeBuffer; private final byte[] sizeBufferArray = new byte[4]; private ByteBuffer frameBuffer; private long startTime = System.currentTimeMillis(); protected TAsyncMethodCall(TAsyncClient client, TProtocolFactory protocolFactory, TNonblockingTransport transport, AsyncMethodCallback callback, boolean isOneway) { this.transport = transport; this.callback = callback; this.protocolFactory = protocolFactory; this.client = client; this.isOneway = isOneway; this.sequenceId = TAsyncMethodCall.sequenceIdCounter.getAndIncrement(); } protected State getState() { return state; } protected boolean isFinished() { return state == State.RESPONSE_READ; } protected long getStartTime() { return startTime; } protected long getSequenceId() { return sequenceId; } public TAsyncClient getClient() { return client; } public boolean hasTimeout() { return client.hasTimeout(); } public long getTimeoutTimestamp() { return client.getTimeout() + startTime; } protected abstract void write_args(TProtocol protocol) throws TException; /** * Initialize buffers. * @throws TException if buffer initialization fails */ protected void prepareMethodCall() throws TException { TMemoryBuffer memoryBuffer = new TMemoryBuffer(INITIAL_MEMORY_BUFFER_SIZE); TProtocol protocol = protocolFactory.getProtocol(memoryBuffer); write_args(protocol); int length = memoryBuffer.length(); frameBuffer = ByteBuffer.wrap(memoryBuffer.getArray(), 0, length); TFramedTransport.encodeFrameSize(length, sizeBufferArray); sizeBuffer = ByteBuffer.wrap(sizeBufferArray); } /** * Register with selector and start first state, which could be either connecting or writing. * @throws IOException if register or starting fails */ void start(Selector sel) throws IOException { SelectionKey key; if (transport.isOpen()) { state = State.WRITING_REQUEST_SIZE; key = transport.registerSelector(sel, SelectionKey.OP_WRITE); } else { state = State.CONNECTING; key = transport.registerSelector(sel, SelectionKey.OP_CONNECT); // non-blocking connect can complete immediately, // in which case we should not expect the OP_CONNECT if (transport.startConnect()) { registerForFirstWrite(key); } } key.attach(this); } void registerForFirstWrite(SelectionKey key) throws IOException { state = State.WRITING_REQUEST_SIZE; key.interestOps(SelectionKey.OP_WRITE); } protected ByteBuffer getFrameBuffer() { return frameBuffer; } /** * Transition to next state, doing whatever work is required. Since this * method is only called by the selector thread, we can make changes to our * select interests without worrying about concurrency. * @param key */ protected void transition(SelectionKey key) { // Ensure key is valid if (!key.isValid()) { key.cancel(); Exception e = new TTransportException("Selection key not valid!"); onError(e); return; } // Transition function try { switch (state) { case CONNECTING: doConnecting(key); break; case WRITING_REQUEST_SIZE: doWritingRequestSize(); break; case WRITING_REQUEST_BODY: doWritingRequestBody(key); break; case READING_RESPONSE_SIZE: doReadingResponseSize(); break; case READING_RESPONSE_BODY: doReadingResponseBody(key); break; default: // RESPONSE_READ, ERROR, or bug throw new IllegalStateException("Method call in state " + state + " but selector called transition method. Seems like a bug..."); } } catch (Exception e) { key.cancel(); key.attach(null); onError(e); } } protected void onError(Exception e) { client.onError(e); callback.onError(e); state = State.ERROR; } private void doReadingResponseBody(SelectionKey key) throws IOException { if (transport.read(frameBuffer) < 0) { throw new IOException("Read call frame failed"); } if (frameBuffer.remaining() == 0) { cleanUpAndFireCallback(key); } } private void cleanUpAndFireCallback(SelectionKey key) { state = State.RESPONSE_READ; key.interestOps(0); // this ensures that the TAsyncMethod instance doesn't hang around key.attach(null); client.onComplete(); callback.onComplete((T)this); } private void doReadingResponseSize() throws IOException { if (transport.read(sizeBuffer) < 0) { throw new IOException("Read call frame size failed"); } if (sizeBuffer.remaining() == 0) { state = State.READING_RESPONSE_BODY; frameBuffer = ByteBuffer.allocate(TFramedTransport.decodeFrameSize(sizeBufferArray)); } } private void doWritingRequestBody(SelectionKey key) throws IOException { if (transport.write(frameBuffer) < 0) { throw new IOException("Write call frame failed"); } if (frameBuffer.remaining() == 0) { if (isOneway) { cleanUpAndFireCallback(key); } else { state = State.READING_RESPONSE_SIZE; sizeBuffer.rewind(); // Prepare to read incoming frame size key.interestOps(SelectionKey.OP_READ); } } } private void doWritingRequestSize() throws IOException { if (transport.write(sizeBuffer) < 0) { throw new IOException("Write call frame size failed"); } if (sizeBuffer.remaining() == 0) { state = State.WRITING_REQUEST_BODY; } } private void doConnecting(SelectionKey key) throws IOException { if (!key.isConnectable() || !transport.finishConnect()) { throw new IOException("not connectable or finishConnect returned false after we got an OP_CONNECT"); } registerForFirstWrite(key); } } libthrift-java_0.9.0/src/org/apache/thrift/async/TAsyncClientFactory.java0000644000175000017500000000177612035665435027267 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.async; import org.apache.thrift.transport.TNonblockingTransport; public interface TAsyncClientFactory { public T getAsyncClient(TNonblockingTransport transport); } libthrift-java_0.9.0/src/org/apache/thrift/async/TAsyncClient.java0000644000175000017500000000576712035665435025743 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.async; import org.apache.thrift.protocol.TProtocolFactory; import org.apache.thrift.transport.TNonblockingTransport; public abstract class TAsyncClient { protected final TProtocolFactory ___protocolFactory; protected final TNonblockingTransport ___transport; protected final TAsyncClientManager ___manager; protected TAsyncMethodCall ___currentMethod; private Exception ___error; private long ___timeout; public TAsyncClient(TProtocolFactory protocolFactory, TAsyncClientManager manager, TNonblockingTransport transport) { this(protocolFactory, manager, transport, 0); } public TAsyncClient(TProtocolFactory protocolFactory, TAsyncClientManager manager, TNonblockingTransport transport, long timeout) { this.___protocolFactory = protocolFactory; this.___manager = manager; this.___transport = transport; this.___timeout = timeout; } public TProtocolFactory getProtocolFactory() { return ___protocolFactory; } public long getTimeout() { return ___timeout; } public boolean hasTimeout() { return ___timeout > 0; } public void setTimeout(long timeout) { this.___timeout = timeout; } /** * Is the client in an error state? * @return If client in an error state? */ public boolean hasError() { return ___error != null; } /** * Get the client's error - returns null if no error * @return Get the client's error.
returns null if no error */ public Exception getError() { return ___error; } protected void checkReady() { // Ensure we are not currently executing a method if (___currentMethod != null) { throw new IllegalStateException("Client is currently executing another method: " + ___currentMethod.getClass().getName()); } // Ensure we're not in an error state if (___error != null) { throw new IllegalStateException("Client has an error!", ___error); } } /** * Called by delegate method when finished */ protected void onComplete() { ___currentMethod = null; } /** * Called by delegate method on error */ protected void onError(Exception exception) { ___transport.close(); ___currentMethod = null; ___error = exception; } } libthrift-java_0.9.0/src/org/apache/thrift/async/TAsyncClientManager.java0000644000175000017500000001545212035665435027226 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.async; import java.io.IOException; import java.nio.channels.ClosedSelectorException; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.spi.SelectorProvider; import java.util.Comparator; import java.util.Iterator; import java.util.TreeSet; import java.util.concurrent.ConcurrentLinkedQueue; import java.util.concurrent.TimeoutException; import org.apache.thrift.TException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Contains selector thread which transitions method call objects */ public class TAsyncClientManager { private static final Logger LOGGER = LoggerFactory.getLogger(TAsyncClientManager.class.getName()); private final SelectThread selectThread; private final ConcurrentLinkedQueue pendingCalls = new ConcurrentLinkedQueue(); public TAsyncClientManager() throws IOException { this.selectThread = new SelectThread(); selectThread.start(); } public void call(TAsyncMethodCall method) throws TException { if (!isRunning()) { throw new TException("SelectThread is not running"); } method.prepareMethodCall(); pendingCalls.add(method); selectThread.getSelector().wakeup(); } public void stop() { selectThread.finish(); } public boolean isRunning() { return selectThread.isAlive(); } private class SelectThread extends Thread { private final Selector selector; private volatile boolean running; private final TreeSet timeoutWatchSet = new TreeSet(new TAsyncMethodCallTimeoutComparator()); public SelectThread() throws IOException { this.selector = SelectorProvider.provider().openSelector(); this.running = true; this.setName("TAsyncClientManager#SelectorThread " + this.getId()); // We don't want to hold up the JVM when shutting down setDaemon(true); } public Selector getSelector() { return selector; } public void finish() { running = false; selector.wakeup(); } public void run() { while (running) { try { try { if (timeoutWatchSet.size() == 0) { // No timeouts, so select indefinitely selector.select(); } else { // We have a timeout pending, so calculate the time until then and select appropriately long nextTimeout = timeoutWatchSet.first().getTimeoutTimestamp(); long selectTime = nextTimeout - System.currentTimeMillis(); if (selectTime > 0) { // Next timeout is in the future, select and wake up then selector.select(selectTime); } else { // Next timeout is now or in past, select immediately so we can time out selector.selectNow(); } } } catch (IOException e) { LOGGER.error("Caught IOException in TAsyncClientManager!", e); } transitionMethods(); timeoutMethods(); startPendingMethods(); } catch (Exception exception) { LOGGER.error("Ignoring uncaught exception in SelectThread", exception); } } } // Transition methods for ready keys private void transitionMethods() { try { Iterator keys = selector.selectedKeys().iterator(); while (keys.hasNext()) { SelectionKey key = keys.next(); keys.remove(); if (!key.isValid()) { // this can happen if the method call experienced an error and the // key was cancelled. can also happen if we timeout a method, which // results in a channel close. // just skip continue; } TAsyncMethodCall methodCall = (TAsyncMethodCall)key.attachment(); methodCall.transition(key); // If done or error occurred, remove from timeout watch set if (methodCall.isFinished() || methodCall.getClient().hasError()) { timeoutWatchSet.remove(methodCall); } } } catch (ClosedSelectorException e) { LOGGER.error("Caught ClosedSelectorException in TAsyncClientManager!", e); } } // Timeout any existing method calls private void timeoutMethods() { Iterator iterator = timeoutWatchSet.iterator(); long currentTime = System.currentTimeMillis(); while (iterator.hasNext()) { TAsyncMethodCall methodCall = iterator.next(); if (currentTime >= methodCall.getTimeoutTimestamp()) { iterator.remove(); methodCall.onError(new TimeoutException("Operation " + methodCall.getClass() + " timed out after " + (currentTime - methodCall.getStartTime()) + " ms.")); } else { break; } } } // Start any new calls private void startPendingMethods() { TAsyncMethodCall methodCall; while ((methodCall = pendingCalls.poll()) != null) { // Catch registration errors. method will catch transition errors and cleanup. try { methodCall.start(selector); // If timeout specified and first transition went smoothly, add to timeout watch set TAsyncClient client = methodCall.getClient(); if (client.hasTimeout() && !client.hasError()) { timeoutWatchSet.add(methodCall); } } catch (Exception exception) { LOGGER.warn("Caught exception in TAsyncClientManager!", exception); methodCall.onError(exception); } } } } /** Comparator used in TreeSet */ private static class TAsyncMethodCallTimeoutComparator implements Comparator { public int compare(TAsyncMethodCall left, TAsyncMethodCall right) { if (left.getTimeoutTimestamp() == right.getTimeoutTimestamp()) { return (int)(left.getSequenceId() - right.getSequenceId()); } else { return (int)(left.getTimeoutTimestamp() - right.getTimeoutTimestamp()); } } } } libthrift-java_0.9.0/src/org/apache/thrift/async/AsyncMethodCallback.java0000644000175000017500000000271312035665435027222 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.async; public interface AsyncMethodCallback { /** * This method will be called when the remote side has completed invoking * your method call and the result is fully read. For oneway method calls, * this method will be called as soon as we have completed writing out the * request. * @param response */ public void onComplete(T response); /** * This method will be called when there is an unexpected clientside * exception. This does not include application-defined exceptions that * appear in the IDL, but rather things like IOExceptions. * @param exception */ public void onError(Exception exception); } libthrift-java_0.9.0/src/org/apache/thrift/TFieldRequirementType.java0000644000175000017500000000202312035665435026476 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; /** * Requirement type constants. * */ public final class TFieldRequirementType { public static final byte REQUIRED = 1; public static final byte OPTIONAL = 2; public static final byte DEFAULT = 3; } libthrift-java_0.9.0/src/org/apache/thrift/TEnumHelper.java0000644000175000017500000000375212035665435024446 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; import java.lang.InstantiationException; import java.lang.NoSuchMethodException; import java.lang.IllegalAccessException; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; /** * Utility class with static methods for interacting with TEnum */ public class TEnumHelper { /** * Given a TEnum class and integer value, this method will return * the associated constant from the given TEnum class. * This method MUST be modified should the name of the 'findByValue' method * change. * * @param enumClass TEnum from which to return a matching constant. * @param value Value for which to return the constant. * * @return The constant in 'enumClass' whose value is 'value' or null if * something went wrong. */ public static TEnum getByValue(Class enumClass, int value) { try { Method method = enumClass.getMethod("findByValue", int.class); return (TEnum) method.invoke(null, value); } catch (NoSuchMethodException nsme) { return null; } catch (IllegalAccessException iae) { return null; } catch (InvocationTargetException ite) { return null; } } } libthrift-java_0.9.0/src/org/apache/thrift/TDeserializer.java0000644000175000017500000003150412035665435025020 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; import java.io.UnsupportedEncodingException; import java.nio.ByteBuffer; import org.apache.thrift.protocol.TBinaryProtocol; import org.apache.thrift.protocol.TField; import org.apache.thrift.protocol.TProtocol; import org.apache.thrift.protocol.TProtocolFactory; import org.apache.thrift.protocol.TProtocolUtil; import org.apache.thrift.protocol.TType; import org.apache.thrift.transport.TMemoryInputTransport; /** * Generic utility for easily deserializing objects from a byte array or Java * String. * */ public class TDeserializer { private final TProtocol protocol_; private final TMemoryInputTransport trans_; /** * Create a new TDeserializer that uses the TBinaryProtocol by default. */ public TDeserializer() { this(new TBinaryProtocol.Factory()); } /** * Create a new TDeserializer. It will use the TProtocol specified by the * factory that is passed in. * * @param protocolFactory Factory to create a protocol */ public TDeserializer(TProtocolFactory protocolFactory) { trans_ = new TMemoryInputTransport(); protocol_ = protocolFactory.getProtocol(trans_); } /** * Deserialize the Thrift object from a byte array. * * @param base The object to read into * @param bytes The array to read from */ public void deserialize(TBase base, byte[] bytes) throws TException { try { trans_.reset(bytes); base.read(protocol_); } finally { trans_.clear(); protocol_.reset(); } } /** * Deserialize the Thrift object from a Java string, using a specified * character set for decoding. * * @param base The object to read into * @param data The string to read from * @param charset Valid JVM charset */ public void deserialize(TBase base, String data, String charset) throws TException { try { deserialize(base, data.getBytes(charset)); } catch (UnsupportedEncodingException uex) { throw new TException("JVM DOES NOT SUPPORT ENCODING: " + charset); } finally { protocol_.reset(); } } /** * Deserialize only a single Thrift object (addressed by recursively using field id) * from a byte record. * @param tb The object to read into * @param bytes The serialized object to read from * @param fieldIdPathFirst First of the FieldId's that define a path tb * @param fieldIdPathRest The rest FieldId's that define a path tb * @throws TException */ public void partialDeserialize(TBase tb, byte[] bytes, TFieldIdEnum fieldIdPathFirst, TFieldIdEnum ... fieldIdPathRest) throws TException { try { if (locateField(bytes, fieldIdPathFirst, fieldIdPathRest) != null) { // if this line is reached, iprot will be positioned at the start of tb. tb.read(protocol_); } } catch (Exception e) { throw new TException(e); } finally { trans_.clear(); protocol_.reset(); } } /** * Deserialize only a boolean field (addressed by recursively using field id) * from a byte record. * @param bytes The serialized object to read from * @param fieldIdPathFirst First of the FieldId's that define a path to a boolean field * @param fieldIdPathRest The rest FieldId's that define a path to a boolean field * @throws TException */ public Boolean partialDeserializeBool(byte[] bytes, TFieldIdEnum fieldIdPathFirst, TFieldIdEnum ... fieldIdPathRest) throws TException { return (Boolean) partialDeserializeField(TType.BOOL, bytes, fieldIdPathFirst, fieldIdPathRest); } /** * Deserialize only a byte field (addressed by recursively using field id) * from a byte record. * @param bytes The serialized object to read from * @param fieldIdPathFirst First of the FieldId's that define a path to a byte field * @param fieldIdPathRest The rest FieldId's that define a path to a byte field * @throws TException */ public Byte partialDeserializeByte(byte[] bytes, TFieldIdEnum fieldIdPathFirst, TFieldIdEnum ... fieldIdPathRest) throws TException { return (Byte) partialDeserializeField(TType.BYTE, bytes, fieldIdPathFirst, fieldIdPathRest); } /** * Deserialize only a double field (addressed by recursively using field id) * from a byte record. * @param bytes The serialized object to read from * @param fieldIdPathFirst First of the FieldId's that define a path to a double field * @param fieldIdPathRest The rest FieldId's that define a path to a double field * @throws TException */ public Double partialDeserializeDouble(byte[] bytes, TFieldIdEnum fieldIdPathFirst, TFieldIdEnum ... fieldIdPathRest) throws TException { return (Double) partialDeserializeField(TType.DOUBLE, bytes, fieldIdPathFirst, fieldIdPathRest); } /** * Deserialize only an i16 field (addressed by recursively using field id) * from a byte record. * @param bytes The serialized object to read from * @param fieldIdPathFirst First of the FieldId's that define a path to an i16 field * @param fieldIdPathRest The rest FieldId's that define a path to an i16 field * @throws TException */ public Short partialDeserializeI16(byte[] bytes, TFieldIdEnum fieldIdPathFirst, TFieldIdEnum ... fieldIdPathRest) throws TException { return (Short) partialDeserializeField(TType.I16, bytes, fieldIdPathFirst, fieldIdPathRest); } /** * Deserialize only an i32 field (addressed by recursively using field id) * from a byte record. * @param bytes The serialized object to read from * @param fieldIdPathFirst First of the FieldId's that define a path to an i32 field * @param fieldIdPathRest The rest FieldId's that define a path to an i32 field * @throws TException */ public Integer partialDeserializeI32(byte[] bytes, TFieldIdEnum fieldIdPathFirst, TFieldIdEnum ... fieldIdPathRest) throws TException { return (Integer) partialDeserializeField(TType.I32, bytes, fieldIdPathFirst, fieldIdPathRest); } /** * Deserialize only an i64 field (addressed by recursively using field id) * from a byte record. * @param bytes The serialized object to read from * @param fieldIdPathFirst First of the FieldId's that define a path to an i64 field * @param fieldIdPathRest The rest FieldId's that define a path to an i64 field * @throws TException */ public Long partialDeserializeI64(byte[] bytes, TFieldIdEnum fieldIdPathFirst, TFieldIdEnum ... fieldIdPathRest) throws TException { return (Long) partialDeserializeField(TType.I64, bytes, fieldIdPathFirst, fieldIdPathRest); } /** * Deserialize only a string field (addressed by recursively using field id) * from a byte record. * @param bytes The serialized object to read from * @param fieldIdPathFirst First of the FieldId's that define a path to a string field * @param fieldIdPathRest The rest FieldId's that define a path to a string field * @throws TException */ public String partialDeserializeString(byte[] bytes, TFieldIdEnum fieldIdPathFirst, TFieldIdEnum ... fieldIdPathRest) throws TException { return (String) partialDeserializeField(TType.STRING, bytes, fieldIdPathFirst, fieldIdPathRest); } /** * Deserialize only a binary field (addressed by recursively using field id) * from a byte record. * @param bytes The serialized object to read from * @param fieldIdPathFirst First of the FieldId's that define a path to a binary field * @param fieldIdPathRest The rest FieldId's that define a path to a binary field * @throws TException */ public ByteBuffer partialDeserializeByteArray(byte[] bytes, TFieldIdEnum fieldIdPathFirst, TFieldIdEnum ... fieldIdPathRest) throws TException { // TType does not have binary, so we use the arbitrary num 100 return (ByteBuffer) partialDeserializeField((byte)100, bytes, fieldIdPathFirst, fieldIdPathRest); } /** * Deserialize only the id of the field set in a TUnion (addressed by recursively using field id) * from a byte record. * @param bytes The serialized object to read from * @param fieldIdPathFirst First of the FieldId's that define a path to a TUnion * @param fieldIdPathRest The rest FieldId's that define a path to a TUnion * @throws TException */ public Short partialDeserializeSetFieldIdInUnion(byte[] bytes, TFieldIdEnum fieldIdPathFirst, TFieldIdEnum ... fieldIdPathRest) throws TException { try { TField field = locateField(bytes, fieldIdPathFirst, fieldIdPathRest); if (field != null){ protocol_.readStructBegin(); // The Union return protocol_.readFieldBegin().id; // The field set in the union } return null; } catch (Exception e) { throw new TException(e); } finally { trans_.clear(); protocol_.reset(); } } private Object partialDeserializeField(byte ttype, byte[] bytes, TFieldIdEnum fieldIdPathFirst, TFieldIdEnum ... fieldIdPathRest) throws TException { try { TField field = locateField(bytes, fieldIdPathFirst, fieldIdPathRest); if (field != null) { // if this point is reached, iprot will be positioned at the start of the field. switch(ttype){ case TType.BOOL: if (field.type == TType.BOOL){ return protocol_.readBool(); } break; case TType.BYTE: if (field.type == TType.BYTE) { return protocol_.readByte(); } break; case TType.DOUBLE: if (field.type == TType.DOUBLE) { return protocol_.readDouble(); } break; case TType.I16: if (field.type == TType.I16) { return protocol_.readI16(); } break; case TType.I32: if (field.type == TType.I32) { return protocol_.readI32(); } break; case TType.I64: if (field.type == TType.I64) { return protocol_.readI64(); } break; case TType.STRING: if (field.type == TType.STRING) { return protocol_.readString(); } break; case 100: // hack to differentiate between string and binary if (field.type == TType.STRING) { return protocol_.readBinary(); } break; } } return null; } catch (Exception e) { throw new TException(e); } finally { trans_.clear(); protocol_.reset(); } } private TField locateField(byte[] bytes, TFieldIdEnum fieldIdPathFirst, TFieldIdEnum ... fieldIdPathRest) throws TException { trans_.reset(bytes); TFieldIdEnum[] fieldIdPath= new TFieldIdEnum[fieldIdPathRest.length + 1]; fieldIdPath[0] = fieldIdPathFirst; for (int i = 0; i < fieldIdPathRest.length; i++){ fieldIdPath[i + 1] = fieldIdPathRest[i]; } // index into field ID path being currently searched for int curPathIndex = 0; // this will be the located field, or null if it is not located TField field = null; protocol_.readStructBegin(); while (curPathIndex < fieldIdPath.length) { field = protocol_.readFieldBegin(); // we can stop searching if we either see a stop or we go past the field // id we're looking for (since fields should now be serialized in asc // order). if (field.type == TType.STOP || field.id > fieldIdPath[curPathIndex].getThriftFieldId()) { return null; } if (field.id != fieldIdPath[curPathIndex].getThriftFieldId()) { // Not the field we're looking for. Skip field. TProtocolUtil.skip(protocol_, field.type); protocol_.readFieldEnd(); } else { // This field is the next step in the path. Step into field. curPathIndex++; if (curPathIndex < fieldIdPath.length) { protocol_.readStructBegin(); } } } return field; } /** * Deserialize the Thrift object from a Java string, using the default JVM * charset encoding. * * @param base The object to read into * @param data The string to read from */ public void fromString(TBase base, String data) throws TException { deserialize(base, data.getBytes()); } } libthrift-java_0.9.0/src/org/apache/thrift/TProcessor.java0000644000175000017500000000212312035665435024350 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; import org.apache.thrift.protocol.TProtocol; /** * A processor is a generic object which operates upon an input stream and * writes to some output stream. * */ public interface TProcessor { public boolean process(TProtocol in, TProtocol out) throws TException; } libthrift-java_0.9.0/src/org/apache/thrift/meta_data/0000755000175000017500000000000012035665714023323 5ustar eevanseevans00000000000000libthrift-java_0.9.0/src/org/apache/thrift/meta_data/EnumMetaData.java0000644000175000017500000000212012035665434026465 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.meta_data; import org.apache.thrift.TEnum; public class EnumMetaData extends FieldValueMetaData { public final Class enumClass; public EnumMetaData(byte type, Class sClass){ super(type); this.enumClass = sClass; } } libthrift-java_0.9.0/src/org/apache/thrift/meta_data/StructMetaData.java0000644000175000017500000000213012035665434027046 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.meta_data; import org.apache.thrift.TBase; public class StructMetaData extends FieldValueMetaData { public final Class structClass; public StructMetaData(byte type, Class sClass){ super(type); this.structClass = sClass; } } libthrift-java_0.9.0/src/org/apache/thrift/meta_data/FieldMetaData.java0000644000175000017500000000523112035665434026612 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.meta_data; import java.util.HashMap; import java.util.Map; import org.apache.thrift.TBase; import org.apache.thrift.TFieldIdEnum; /** * This class is used to store meta data about thrift fields. Every field in a * a struct should have a corresponding instance of this class describing it. * */ public class FieldMetaData implements java.io.Serializable { public final String fieldName; public final byte requirementType; public final FieldValueMetaData valueMetaData; private static Map, Map> structMap; static { structMap = new HashMap, Map>(); } public FieldMetaData(String name, byte req, FieldValueMetaData vMetaData){ this.fieldName = name; this.requirementType = req; this.valueMetaData = vMetaData; } public static void addStructMetaDataMap(Class sClass, Map map){ structMap.put(sClass, map); } /** * Returns a map with metadata (i.e. instances of FieldMetaData) that * describe the fields of the given class. * * @param sClass The TBase class for which the metadata map is requested */ public static Map getStructMetaDataMap(Class sClass){ if (!structMap.containsKey(sClass)){ // Load class if it hasn't been loaded try{ sClass.newInstance(); } catch (InstantiationException e){ throw new RuntimeException("InstantiationException for TBase class: " + sClass.getName() + ", message: " + e.getMessage()); } catch (IllegalAccessException e){ throw new RuntimeException("IllegalAccessException for TBase class: " + sClass.getName() + ", message: " + e.getMessage()); } } return structMap.get(sClass); } } libthrift-java_0.9.0/src/org/apache/thrift/meta_data/ListMetaData.java0000644000175000017500000000206312035665434026502 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.meta_data; public class ListMetaData extends FieldValueMetaData { public final FieldValueMetaData elemMetaData; public ListMetaData(byte type, FieldValueMetaData eMetaData){ super(type); this.elemMetaData = eMetaData; } } libthrift-java_0.9.0/src/org/apache/thrift/meta_data/SetMetaData.java0000644000175000017500000000206112035665434026320 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.meta_data; public class SetMetaData extends FieldValueMetaData { public final FieldValueMetaData elemMetaData; public SetMetaData(byte type, FieldValueMetaData eMetaData){ super(type); this.elemMetaData = eMetaData; } } libthrift-java_0.9.0/src/org/apache/thrift/meta_data/MapMetaData.java0000644000175000017500000000224212035665434026303 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.meta_data; public class MapMetaData extends FieldValueMetaData { public final FieldValueMetaData keyMetaData; public final FieldValueMetaData valueMetaData; public MapMetaData(byte type, FieldValueMetaData kMetaData, FieldValueMetaData vMetaData){ super(type); this.keyMetaData = kMetaData; this.valueMetaData = vMetaData; } } libthrift-java_0.9.0/src/org/apache/thrift/meta_data/FieldValueMetaData.java0000644000175000017500000000370312035665434027611 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.meta_data; import org.apache.thrift.protocol.TType; /** * FieldValueMetaData and collection of subclasses to store metadata about * the value(s) of a field */ public class FieldValueMetaData implements java.io.Serializable { public final byte type; private final boolean isTypedefType; private final String typedefName; private final boolean isBinary; public FieldValueMetaData(byte type, boolean binary) { this.type = type; this.isTypedefType = false; this.typedefName = null; this.isBinary = binary; } public FieldValueMetaData(byte type) { this(type, false); } public FieldValueMetaData(byte type, String typedefName) { this.type = type; this.isTypedefType = true; this.typedefName = typedefName; this.isBinary = false; } public boolean isTypedef() { return isTypedefType; } public String getTypedefName() { return typedefName; } public boolean isStruct() { return type == TType.STRUCT; } public boolean isContainer() { return type == TType.LIST || type == TType.MAP || type == TType.SET; } public boolean isBinary() { return isBinary; } } libthrift-java_0.9.0/src/org/apache/thrift/transport/0000755000175000017500000000000012035665714023440 5ustar eevanseevans00000000000000libthrift-java_0.9.0/src/org/apache/thrift/transport/TStandardFile.java0000644000175000017500000000337512035665435026777 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import java.io.InputStream; import java.io.OutputStream; import java.io.IOException; import java.io.RandomAccessFile; import java.io.FileInputStream; import java.io.FileOutputStream; public class TStandardFile implements TSeekableFile { protected String path_ = null; protected RandomAccessFile inputFile_ = null; public TStandardFile(String path) throws IOException { path_ = path; inputFile_ = new RandomAccessFile(path_, "r"); } public InputStream getInputStream() throws IOException { return new FileInputStream(inputFile_.getFD()); } public OutputStream getOutputStream() throws IOException { return new FileOutputStream(path_); } public void close() throws IOException { if(inputFile_ != null) { inputFile_.close(); } } public long length() throws IOException { return inputFile_.length(); } public void seek(long pos) throws IOException { inputFile_.seek(pos); } } libthrift-java_0.9.0/src/org/apache/thrift/transport/TMemoryInputTransport.java0000644000175000017500000000450512035665435030640 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; public final class TMemoryInputTransport extends TTransport { private byte[] buf_; private int pos_; private int endPos_; public TMemoryInputTransport() { } public TMemoryInputTransport(byte[] buf) { reset(buf); } public TMemoryInputTransport(byte[] buf, int offset, int length) { reset(buf, offset, length); } public void reset(byte[] buf) { reset(buf, 0, buf.length); } public void reset(byte[] buf, int offset, int length) { buf_ = buf; pos_ = offset; endPos_ = offset + length; } public void clear() { buf_ = null; } @Override public void close() {} @Override public boolean isOpen() { return true; } @Override public void open() throws TTransportException {} @Override public int read(byte[] buf, int off, int len) throws TTransportException { int bytesRemaining = getBytesRemainingInBuffer(); int amtToRead = (len > bytesRemaining ? bytesRemaining : len); if (amtToRead > 0) { System.arraycopy(buf_, pos_, buf, off, amtToRead); consumeBuffer(amtToRead); } return amtToRead; } @Override public void write(byte[] buf, int off, int len) throws TTransportException { throw new UnsupportedOperationException("No writing allowed!"); } @Override public byte[] getBuffer() { return buf_; } public int getBufferPosition() { return pos_; } public int getBytesRemainingInBuffer() { return endPos_ - pos_; } public void consumeBuffer(int len) { pos_ += len; } } libthrift-java_0.9.0/src/org/apache/thrift/transport/TFileProcessor.java0000644000175000017500000001027412035665435027212 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import org.apache.thrift.TProcessor; import org.apache.thrift.TException; import org.apache.thrift.protocol.TProtocol; import org.apache.thrift.protocol.TProtocolFactory; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.RandomAccessFile; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.InputStream; import java.io.OutputStream; import java.io.IOException; /** * FileProcessor: helps in processing files generated by TFileTransport. * Port of original cpp implementation * * @author Joydeep Sen Sarma */ public class TFileProcessor { private TProcessor processor_; private TProtocolFactory inputProtocolFactory_; private TProtocolFactory outputProtocolFactory_; private TFileTransport inputTransport_; private TTransport outputTransport_; public TFileProcessor(TProcessor processor, TProtocolFactory protocolFactory, TFileTransport inputTransport, TTransport outputTransport) { processor_ = processor; inputProtocolFactory_ = outputProtocolFactory_ = protocolFactory; inputTransport_ = inputTransport; outputTransport_ = outputTransport; } public TFileProcessor(TProcessor processor, TProtocolFactory inputProtocolFactory, TProtocolFactory outputProtocolFactory, TFileTransport inputTransport, TTransport outputTransport) { processor_ = processor; inputProtocolFactory_ = inputProtocolFactory; outputProtocolFactory_ = outputProtocolFactory; inputTransport_ = inputTransport; outputTransport_ = outputTransport; } private void processUntil(int lastChunk) throws TException { TProtocol ip = inputProtocolFactory_.getProtocol(inputTransport_); TProtocol op = outputProtocolFactory_.getProtocol(outputTransport_); int curChunk = inputTransport_.getCurChunk(); try { while (lastChunk >= curChunk) { processor_.process(ip, op); int newChunk = inputTransport_.getCurChunk(); curChunk = newChunk; } } catch (TTransportException e) { // if we are processing the last chunk - we could have just hit EOF // on EOF - trap the error and stop processing. if(e.getType() != TTransportException.END_OF_FILE) throw e; else { return; } } } /** * Process from start to last chunk both inclusive where chunks begin from 0 * @param startChunkNum first chunk to be processed * @param endChunkNum last chunk to be processed */ public void processChunk(int startChunkNum, int endChunkNum) throws TException { int numChunks = inputTransport_.getNumChunks(); if(endChunkNum < 0) endChunkNum += numChunks; if(startChunkNum < 0) startChunkNum += numChunks; if(endChunkNum < startChunkNum) throw new TException("endChunkNum " + endChunkNum + " is less than " + startChunkNum); inputTransport_.seekToChunk(startChunkNum); processUntil(endChunkNum); } /** * Process a single chunk * * @param chunkNum chunk to be processed */ public void processChunk(int chunkNum) throws TException { processChunk(chunkNum, chunkNum); } /** * Process a current chunk */ public void processChunk() throws TException { processChunk(inputTransport_.getCurChunk()); } } libthrift-java_0.9.0/src/org/apache/thrift/transport/TFileTransport.java0000644000175000017500000004111512035665435027225 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.InputStream; import java.io.OutputStream; import java.io.IOException; import java.util.Random; /** * FileTransport implementation of the TTransport interface. * Currently this is a straightforward port of the cpp implementation * * It may make better sense to provide a basic stream access on top of the framed file format * The FileTransport can then be a user of this framed file format with some additional logic * for chunking. * * @author Joydeep Sen Sarma */ public class TFileTransport extends TTransport { public static class truncableBufferedInputStream extends BufferedInputStream { public void trunc() { pos = count = 0; } public truncableBufferedInputStream(InputStream in) { super(in); } public truncableBufferedInputStream(InputStream in, int size) { super(in, size); } } public static class Event { private byte[] buf_; private int nread_; private int navailable_; /** * Initialize an event. Initially, it has no valid contents * * @param buf byte array buffer to store event */ public Event(byte[] buf) { buf_ = buf; nread_ = navailable_ = 0; } public byte[] getBuf() { return buf_;} public int getSize() { return buf_.length; } public void setAvailable(int sz) { nread_ = 0; navailable_=sz;} public int getRemaining() { return (navailable_ - nread_); } public int emit(byte[] buf, int offset, int ndesired) { if((ndesired == 0) || (ndesired > getRemaining())) ndesired = getRemaining(); if(ndesired <= 0) return (ndesired); System.arraycopy(buf_, nread_, buf, offset, ndesired); nread_ += ndesired; return(ndesired); } }; public static class chunkState { /** * Chunk Size. Must be same across all implementations */ public static final int DEFAULT_CHUNK_SIZE = 16 * 1024 * 1024; private int chunk_size_ = DEFAULT_CHUNK_SIZE; private long offset_ = 0; public chunkState() {} public chunkState(int chunk_size) { chunk_size_ = chunk_size; } public void skip(int size) {offset_ += size; } public void seek(long offset) {offset_ = offset;} public int getChunkSize() { return chunk_size_;} public int getChunkNum() { return ((int)(offset_/chunk_size_));} public int getRemaining() { return (chunk_size_ - ((int)(offset_ % chunk_size_)));} public long getOffset() { return (offset_);} } public static enum tailPolicy { NOWAIT(0, 0), WAIT_FOREVER(500, -1); /** * Time in milliseconds to sleep before next read * If 0, no sleep */ public final int timeout_; /** * Number of retries before giving up * if 0, no retries * if -1, retry forever */ public final int retries_; /** * ctor for policy * * @param timeout sleep time for this particular policy * @param retries number of retries */ tailPolicy(int timeout, int retries) { timeout_ = timeout; retries_ = retries; } } /** * Current tailing policy */ tailPolicy currentPolicy_ = tailPolicy.NOWAIT; /** * Underlying file being read */ protected TSeekableFile inputFile_ = null; /** * Underlying outputStream */ protected OutputStream outputStream_ = null; /** * Event currently read in */ Event currentEvent_ = null; /** * InputStream currently being used for reading */ InputStream inputStream_ = null; /** * current Chunk state */ chunkState cs = null; /** * Read timeout */ private int readTimeout_ = 0; /** * is read only? */ private boolean readOnly_ = false; /** * Get File Tailing Policy * * @return current read policy */ public tailPolicy getTailPolicy() { return (currentPolicy_); } /** * Set file Tailing Policy * * @param policy New policy to set * @return Old policy */ public tailPolicy setTailPolicy(tailPolicy policy) { tailPolicy old = currentPolicy_; currentPolicy_ = policy; return (old); } /** * Initialize read input stream * * @return input stream to read from file */ private InputStream createInputStream() throws TTransportException { InputStream is; try { if(inputStream_ != null) { ((truncableBufferedInputStream)inputStream_).trunc(); is = inputStream_; } else { is = new truncableBufferedInputStream(inputFile_.getInputStream()); } } catch (IOException iox) { System.err.println("createInputStream: "+iox.getMessage()); throw new TTransportException(iox.getMessage(), iox); } return(is); } /** * Read (potentially tailing) an input stream * * @param is InputStream to read from * @param buf Buffer to read into * @param off Offset in buffer to read into * @param len Number of bytes to read * @param tp policy to use if we hit EOF * * @return number of bytes read */ private int tailRead(InputStream is, byte[] buf, int off, int len, tailPolicy tp) throws TTransportException { int orig_len = len; try { int retries = 0; while(len > 0) { int cnt = is.read(buf, off, len); if(cnt > 0) { off += cnt; len -= cnt; retries = 0; cs.skip(cnt); // remember that we read so many bytes } else if (cnt == -1) { // EOF retries++; if((tp.retries_ != -1) && tp.retries_ < retries) return (orig_len - len); if(tp.timeout_ > 0) { try {Thread.sleep(tp.timeout_);} catch(InterruptedException e) {} } } else { // either non-zero or -1 is what the contract says! throw new TTransportException("Unexpected return from InputStream.read = " + cnt); } } } catch (IOException iox) { throw new TTransportException(iox.getMessage(), iox); } return(orig_len - len); } /** * Event is corrupted. Do recovery * * @return true if recovery could be performed and we can read more data * false is returned only when nothing more can be read */ private boolean performRecovery() throws TTransportException { int numChunks = getNumChunks(); int curChunk = cs.getChunkNum(); if(curChunk >= (numChunks-1)) { return false; } seekToChunk(curChunk+1); return true; } /** * Read event from underlying file * * @return true if event could be read, false otherwise (on EOF) */ private boolean readEvent() throws TTransportException { byte[] ebytes = new byte[4]; int esize; int nread; int nrequested; retry: do { // corner case. read to end of chunk nrequested = cs.getRemaining(); if(nrequested < 4) { nread = tailRead(inputStream_, ebytes, 0, nrequested, currentPolicy_); if(nread != nrequested) { return(false); } } // assuming serialized on little endian machine nread = tailRead(inputStream_, ebytes, 0, 4, currentPolicy_); if(nread != 4) { return(false); } esize=0; for(int i=3; i>=0; i--) { int val = (0x000000ff & (int)ebytes[i]); esize |= (val << (i*8)); } // check if event is corrupted and do recovery as required if(esize > cs.getRemaining()) { throw new TTransportException("FileTransport error: bad event size"); /* if(performRecovery()) { esize=0; } else { return false; } */ } } while (esize == 0); // reset existing event or get a larger one if(currentEvent_.getSize() < esize) currentEvent_ = new Event(new byte [esize]); // populate the event byte[] buf = currentEvent_.getBuf(); nread = tailRead(inputStream_, buf, 0, esize, currentPolicy_); if(nread != esize) { return(false); } currentEvent_.setAvailable(esize); return(true); } /** * open if both input/output open unless readonly * * @return true */ public boolean isOpen() { return ((inputStream_ != null) && (readOnly_ || (outputStream_ != null))); } /** * Diverging from the cpp model and sticking to the TSocket model * Files are not opened in ctor - but in explicit open call */ public void open() throws TTransportException { if (isOpen()) throw new TTransportException(TTransportException.ALREADY_OPEN); try { inputStream_ = createInputStream(); cs = new chunkState(); currentEvent_ = new Event(new byte [256]); if(!readOnly_) outputStream_ = new BufferedOutputStream(inputFile_.getOutputStream(), 8192); } catch (IOException iox) { throw new TTransportException(TTransportException.NOT_OPEN, iox); } } /** * Closes the transport. */ public void close() { if (inputFile_ != null) { try { inputFile_.close(); } catch (IOException iox) { System.err.println("WARNING: Error closing input file: " + iox.getMessage()); } inputFile_ = null; } if (outputStream_ != null) { try { outputStream_.close(); } catch (IOException iox) { System.err.println("WARNING: Error closing output stream: " + iox.getMessage()); } outputStream_ = null; } } /** * File Transport ctor * * @param path File path to read and write from * @param readOnly Whether this is a read-only transport */ public TFileTransport(final String path, boolean readOnly) throws IOException { inputFile_ = new TStandardFile(path); readOnly_ = readOnly; } /** * File Transport ctor * * @param inputFile open TSeekableFile to read/write from * @param readOnly Whether this is a read-only transport */ public TFileTransport(TSeekableFile inputFile, boolean readOnly) { inputFile_ = inputFile; readOnly_ = readOnly; } /** * Cloned from TTransport.java:readAll(). Only difference is throwing an EOF exception * where one is detected. */ public int readAll(byte[] buf, int off, int len) throws TTransportException { int got = 0; int ret = 0; while (got < len) { ret = read(buf, off+got, len-got); if (ret < 0) { throw new TTransportException("Error in reading from file"); } if(ret == 0) { throw new TTransportException(TTransportException.END_OF_FILE, "End of File reached"); } got += ret; } return got; } /** * Reads up to len bytes into buffer buf, starting at offset off. * * @param buf Array to read into * @param off Index to start reading at * @param len Maximum number of bytes to read * @return The number of bytes actually read * @throws TTransportException if there was an error reading data */ public int read(byte[] buf, int off, int len) throws TTransportException { if(!isOpen()) throw new TTransportException(TTransportException.NOT_OPEN, "Must open before reading"); if(currentEvent_.getRemaining() == 0) { if(!readEvent()) return(0); } int nread = currentEvent_.emit(buf, off, len); return nread; } public int getNumChunks() throws TTransportException { if(!isOpen()) throw new TTransportException(TTransportException.NOT_OPEN, "Must open before getNumChunks"); try { long len = inputFile_.length(); if(len == 0) return 0; else return (((int)(len/cs.getChunkSize())) + 1); } catch (IOException iox) { throw new TTransportException(iox.getMessage(), iox); } } public int getCurChunk() throws TTransportException { if(!isOpen()) throw new TTransportException(TTransportException.NOT_OPEN, "Must open before getCurChunk"); return (cs.getChunkNum()); } public void seekToChunk(int chunk) throws TTransportException { if(!isOpen()) throw new TTransportException(TTransportException.NOT_OPEN, "Must open before seeking"); int numChunks = getNumChunks(); // file is empty, seeking to chunk is pointless if (numChunks == 0) { return; } // negative indicates reverse seek (from the end) if (chunk < 0) { chunk += numChunks; } // too large a value for reverse seek, just seek to beginning if (chunk < 0) { chunk = 0; } long eofOffset=0; boolean seekToEnd = (chunk >= numChunks); if(seekToEnd) { chunk = chunk - 1; try { eofOffset = inputFile_.length(); } catch (IOException iox) {throw new TTransportException(iox.getMessage(), iox);} } if(chunk*cs.getChunkSize() != cs.getOffset()) { try { inputFile_.seek((long)chunk*cs.getChunkSize()); } catch (IOException iox) { System.err.println("createInputStream: "+iox.getMessage()); throw new TTransportException("Seek to chunk " + chunk + " " +iox.getMessage(), iox); } cs.seek((long)chunk*cs.getChunkSize()); currentEvent_.setAvailable(0); inputStream_ = createInputStream(); } if(seekToEnd) { // waiting forever here - otherwise we can hit EOF and end up // having consumed partial data from the data stream. tailPolicy old = setTailPolicy(tailPolicy.WAIT_FOREVER); while(cs.getOffset() < eofOffset) { readEvent(); } currentEvent_.setAvailable(0); setTailPolicy(old); } } public void seekToEnd() throws TTransportException { if(!isOpen()) throw new TTransportException(TTransportException.NOT_OPEN, "Must open before seeking"); seekToChunk(getNumChunks()); } /** * Writes up to len bytes from the buffer. * * @param buf The output data buffer * @param off The offset to start writing from * @param len The number of bytes to write * @throws TTransportException if there was an error writing data */ public void write(byte[] buf, int off, int len) throws TTransportException { throw new TTransportException("Not Supported"); } /** * Flush any pending data out of a transport buffer. * * @throws TTransportException if there was an error writing out data. */ public void flush() throws TTransportException { throw new TTransportException("Not Supported"); } /** * test program * */ public static void main(String[] args) throws Exception { int num_chunks = 10; if((args.length < 1) || args[0].equals("--help") || args[0].equals("-h") || args[0].equals("-?")) { printUsage(); } if(args.length > 1) { try { num_chunks = Integer.parseInt(args[1]); } catch (Exception e) { System.err.println("Cannot parse " + args[1]); printUsage(); } } TFileTransport t = new TFileTransport(args[0], true); t.open(); System.out.println("NumChunks="+t.getNumChunks()); Random r = new Random(); for(int j=0; j [num_chunks]"); System.err.println(" (Opens and reads num_chunks chunks from file randomly)"); System.exit(1); } } libthrift-java_0.9.0/src/org/apache/thrift/transport/TTransportFactory.java0000644000175000017500000000251712035665435027760 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; /** * Factory class used to create wrapped instance of Transports. * This is used primarily in servers, which get Transports from * a ServerTransport and then may want to mutate them (i.e. create * a BufferedTransport from the underlying base transport) * */ public class TTransportFactory { /** * Return a wrapped instance of the base Transport. * * @param trans The base transport * @return Wrapped Transport */ public TTransport getTransport(TTransport trans) { return trans; } } libthrift-java_0.9.0/src/org/apache/thrift/transport/TMemoryBuffer.java0000644000175000017500000000524612035665435027040 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import org.apache.thrift.TByteArrayOutputStream; import java.io.UnsupportedEncodingException; /** * Memory buffer-based implementation of the TTransport interface. */ public class TMemoryBuffer extends TTransport { /** * Create a TMemoryBuffer with an initial buffer size of size. The * internal buffer will grow as necessary to accommodate the size of the data * being written to it. */ public TMemoryBuffer(int size) { arr_ = new TByteArrayOutputStream(size); } @Override public boolean isOpen() { return true; } @Override public void open() { /* Do nothing */ } @Override public void close() { /* Do nothing */ } @Override public int read(byte[] buf, int off, int len) { byte[] src = arr_.get(); int amtToRead = (len > arr_.len() - pos_ ? arr_.len() - pos_ : len); if (amtToRead > 0) { System.arraycopy(src, pos_, buf, off, amtToRead); pos_ += amtToRead; } return amtToRead; } @Override public void write(byte[] buf, int off, int len) { arr_.write(buf, off, len); } /** * Output the contents of the memory buffer as a String, using the supplied * encoding * @param enc the encoding to use * @return the contents of the memory buffer as a String */ public String toString(String enc) throws UnsupportedEncodingException { return arr_.toString(enc); } public String inspect() { String buf = ""; byte[] bytes = arr_.toByteArray(); for (int i = 0; i < bytes.length; i++) { buf += (pos_ == i ? "==>" : "" ) + Integer.toHexString(bytes[i] & 0xff) + " "; } return buf; } // The contents of the buffer private TByteArrayOutputStream arr_; // Position to read next byte from private int pos_; public int length() { return arr_.size(); } public byte[] getArray() { return arr_.get(); } } libthrift-java_0.9.0/src/org/apache/thrift/transport/TSSLTransportFactory.java0000644000175000017500000002703512035665435030344 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import java.io.FileInputStream; import java.net.InetAddress; import java.security.KeyStore; import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.SSLContext; import javax.net.ssl.SSLServerSocket; import javax.net.ssl.SSLServerSocketFactory; import javax.net.ssl.SSLSocket; import javax.net.ssl.SSLSocketFactory; import javax.net.ssl.TrustManagerFactory; /** * A Factory for providing and setting up Client and Server SSL wrapped * TSocket and TServerSocket */ public class TSSLTransportFactory { /** * Get a SSL wrapped TServerSocket bound to the specified port. In this * configuration the default settings are used. Default settings are retrieved * from System properties that are set. * * Example system properties: * -Djavax.net.ssl.trustStore= * -Djavax.net.ssl.trustStorePassword=password * -Djavax.net.ssl.keyStore= * -Djavax.net.ssl.keyStorePassword=password * * @param port * @return A SSL wrapped TServerSocket * @throws TTransportException */ public static TServerSocket getServerSocket(int port) throws TTransportException { return getServerSocket(port, 0); } /** * Get a default SSL wrapped TServerSocket bound to the specified port * * @param port * @param clientTimeout * @return A SSL wrapped TServerSocket * @throws TTransportException */ public static TServerSocket getServerSocket(int port, int clientTimeout) throws TTransportException { return getServerSocket(port, clientTimeout, false, null); } /** * Get a default SSL wrapped TServerSocket bound to the specified port and interface * * @param port * @param clientTimeout * @param ifAddress * @return A SSL wrapped TServerSocket * @throws TTransportException */ public static TServerSocket getServerSocket(int port, int clientTimeout, boolean clientAuth, InetAddress ifAddress) throws TTransportException { SSLServerSocketFactory factory = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault(); return createServer(factory, port, clientTimeout, clientAuth, ifAddress, null); } /** * Get a configured SSL wrapped TServerSocket bound to the specified port and interface. * Here the TSSLTransportParameters are used to set the values for the algorithms, keystore, * truststore and other settings * * @param port * @param clientTimeout * @param ifAddress * @param params * @return A SSL wrapped TServerSocket * @throws TTransportException */ public static TServerSocket getServerSocket(int port, int clientTimeout, InetAddress ifAddress, TSSLTransportParameters params) throws TTransportException { if (params == null || !(params.isKeyStoreSet || params.isTrustStoreSet)) { throw new TTransportException("Either one of the KeyStore or TrustStore must be set for SSLTransportParameters"); } SSLContext ctx = createSSLContext(params); return createServer(ctx.getServerSocketFactory(), port, clientTimeout, params.clientAuth, ifAddress, params); } private static TServerSocket createServer(SSLServerSocketFactory factory, int port, int timeout, boolean clientAuth, InetAddress ifAddress, TSSLTransportParameters params) throws TTransportException { try { SSLServerSocket serverSocket = (SSLServerSocket) factory.createServerSocket(port, 100, ifAddress); serverSocket.setSoTimeout(timeout); serverSocket.setNeedClientAuth(clientAuth); if (params != null && params.cipherSuites != null) { serverSocket.setEnabledCipherSuites(params.cipherSuites); } return new TServerSocket(serverSocket, timeout); } catch (Exception e) { throw new TTransportException("Could not bind to port " + port, e); } } /** * Get a default SSL wrapped TSocket connected to the specified host and port. All * the client methods return a bound connection. So there is no need to call open() on the * TTransport. * * @param host * @param port * @param timeout * @return A SSL wrapped TSocket * @throws TTransportException */ public static TSocket getClientSocket(String host, int port, int timeout) throws TTransportException { SSLSocketFactory factory = (SSLSocketFactory) SSLSocketFactory.getDefault(); return createClient(factory, host, port, timeout); } /** * Get a default SSL wrapped TSocket connected to the specified host and port. * * @param host * @param port * @return A SSL wrapped TSocket * @throws TTransportException */ public static TSocket getClientSocket(String host, int port) throws TTransportException { return getClientSocket(host, port, 0); } /** * Get a custom configured SSL wrapped TSocket. The SSL settings are obtained from the * passed in TSSLTransportParameters. * * @param host * @param port * @param timeout * @param params * @return A SSL wrapped TSocket * @throws TTransportException */ public static TSocket getClientSocket(String host, int port, int timeout, TSSLTransportParameters params) throws TTransportException { if (params == null || !(params.isKeyStoreSet || params.isTrustStoreSet)) { throw new TTransportException("Either one of the KeyStore or TrustStore must be set for SSLTransportParameters"); } SSLContext ctx = createSSLContext(params); return createClient(ctx.getSocketFactory(), host, port, timeout); } private static SSLContext createSSLContext(TSSLTransportParameters params) throws TTransportException { SSLContext ctx; try { ctx = SSLContext.getInstance(params.protocol); TrustManagerFactory tmf = null; KeyManagerFactory kmf = null; if (params.isTrustStoreSet) { tmf = TrustManagerFactory.getInstance(params.trustManagerType); KeyStore ts = KeyStore.getInstance(params.trustStoreType); ts.load(new FileInputStream(params.trustStore), params.trustPass.toCharArray()); tmf.init(ts); } if (params.isKeyStoreSet) { kmf = KeyManagerFactory.getInstance(params.keyManagerType); KeyStore ks = KeyStore.getInstance(params.keyStoreType); ks.load(new FileInputStream(params.keyStore), params.keyPass.toCharArray()); kmf.init(ks, params.keyPass.toCharArray()); } if (params.isKeyStoreSet && params.isTrustStoreSet) { ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null); } else if (params.isKeyStoreSet) { ctx.init(kmf.getKeyManagers(), null, null); } else { ctx.init(null, tmf.getTrustManagers(), null); } } catch (Exception e) { throw new TTransportException("Error creating the transport", e); } return ctx; } private static TSocket createClient(SSLSocketFactory factory, String host, int port, int timeout) throws TTransportException { try { SSLSocket socket = (SSLSocket) factory.createSocket(host, port); socket.setSoTimeout(timeout); return new TSocket(socket); } catch (Exception e) { throw new TTransportException("Could not connect to " + host + " on port " + port, e); } } /** * A Class to hold all the SSL parameters */ public static class TSSLTransportParameters { protected String protocol = "TLS"; protected String keyStore; protected String keyPass; protected String keyManagerType = KeyManagerFactory.getDefaultAlgorithm(); protected String keyStoreType = "JKS"; protected String trustStore; protected String trustPass; protected String trustManagerType = TrustManagerFactory.getDefaultAlgorithm(); protected String trustStoreType = "JKS"; protected String[] cipherSuites; protected boolean clientAuth = false; protected boolean isKeyStoreSet = false; protected boolean isTrustStoreSet = false; public TSSLTransportParameters() {} /** * Create parameters specifying the protocol and cipher suites * * @param protocol The specific protocol (TLS/SSL) can be specified with versions * @param cipherSuites */ public TSSLTransportParameters(String protocol, String[] cipherSuites) { this(protocol, cipherSuites, false); } /** * Create parameters specifying the protocol, cipher suites and if client authentication * is required * * @param protocol The specific protocol (TLS/SSL) can be specified with versions * @param cipherSuites * @param clientAuth */ public TSSLTransportParameters(String protocol, String[] cipherSuites, boolean clientAuth) { if (protocol != null) { this.protocol = protocol; } this.cipherSuites = cipherSuites; this.clientAuth = clientAuth; } /** * Set the keystore, password, certificate type and the store type * * @param keyStore Location of the Keystore on disk * @param keyPass Keystore password * @param keyManagerType The default is X509 * @param keyStoreType The default is JKS */ public void setKeyStore(String keyStore, String keyPass, String keyManagerType, String keyStoreType) { this.keyStore = keyStore; this.keyPass = keyPass; if (keyManagerType != null) { this.keyManagerType = keyManagerType; } if (keyStoreType != null) { this.keyStoreType = keyStoreType; } isKeyStoreSet = true; } /** * Set the keystore and password * * @param keyStore Location of the Keystore on disk * @param keyPass Keystore password */ public void setKeyStore(String keyStore, String keyPass) { setKeyStore(keyStore, keyPass, null, null); } /** * Set the truststore, password, certificate type and the store type * * @param trustStore Location of the Truststore on disk * @param trustPass Truststore password * @param trustManagerType The default is X509 * @param trustStoreType The default is JKS */ public void setTrustStore(String trustStore, String trustPass, String trustManagerType, String trustStoreType) { this.trustStore = trustStore; this.trustPass = trustPass; if (trustManagerType != null) { this.trustManagerType = trustManagerType; } if (trustStoreType != null) { this.trustStoreType = trustStoreType; } isTrustStoreSet = true; } /** * Set the truststore and password * * @param trustStore Location of the Truststore on disk * @param trustPass Truststore password */ public void setTrustStore(String trustStore, String trustPass) { setTrustStore(trustStore, trustPass, null, null); } /** * Set if client authentication is required * * @param clientAuth */ public void requireClientAuth(boolean clientAuth) { this.clientAuth = clientAuth; } } } libthrift-java_0.9.0/src/org/apache/thrift/transport/THttpClient.java0000644000175000017500000002445512035665435026517 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.io.IOException; import java.net.URL; import java.net.HttpURLConnection; import java.util.HashMap; import java.util.Map; import org.apache.http.HttpHost; import org.apache.http.HttpResponse; import org.apache.http.HttpStatus; import org.apache.http.client.HttpClient; import org.apache.http.client.methods.HttpPost; import org.apache.http.entity.ByteArrayEntity; import org.apache.http.params.CoreConnectionPNames; import org.apache.http.util.EntityUtils; /** * HTTP implementation of the TTransport interface. Used for working with a * Thrift web services implementation (using for example TServlet). * * This class offers two implementations of the HTTP transport. * One uses HttpURLConnection instances, the other HttpClient from Apache * Http Components. * The chosen implementation depends on the constructor used to * create the THttpClient instance. * Using the THttpClient(String url) constructor or passing null as the * HttpClient to THttpClient(String url, HttpClient client) will create an * instance which will use HttpURLConnection. * * When using HttpClient, the following configuration leads to 5-15% * better performance than the HttpURLConnection implementation: * * http.protocol.version=HttpVersion.HTTP_1_1 * http.protocol.content-charset=UTF-8 * http.protocol.expect-continue=false * http.connection.stalecheck=false * * Also note that under high load, the HttpURLConnection implementation * may exhaust the open file descriptor limit. * * @see THRIFT-970 */ public class THttpClient extends TTransport { private URL url_ = null; private final ByteArrayOutputStream requestBuffer_ = new ByteArrayOutputStream(); private InputStream inputStream_ = null; private int connectTimeout_ = 0; private int readTimeout_ = 0; private Map customHeaders_ = null; private final HttpHost host; private final HttpClient client; public static class Factory extends TTransportFactory { private final String url; private final HttpClient client; public Factory(String url) { this.url = url; this.client = null; } public Factory(String url, HttpClient client) { this.url = url; this.client = client; } @Override public TTransport getTransport(TTransport trans) { try { if (null != client) { return new THttpClient(url, client); } else { return new THttpClient(url); } } catch (TTransportException tte) { return null; } } } public THttpClient(String url) throws TTransportException { try { url_ = new URL(url); this.client = null; this.host = null; } catch (IOException iox) { throw new TTransportException(iox); } } public THttpClient(String url, HttpClient client) throws TTransportException { try { url_ = new URL(url); this.client = client; this.host = new HttpHost(url_.getHost(), -1 == url_.getPort() ? url_.getDefaultPort() : url_.getPort(), url_.getProtocol()); } catch (IOException iox) { throw new TTransportException(iox); } } public void setConnectTimeout(int timeout) { connectTimeout_ = timeout; if (null != this.client) { // WARNING, this modifies the HttpClient params, this might have an impact elsewhere if the // same HttpClient is used for something else. client.getParams().setParameter(CoreConnectionPNames.CONNECTION_TIMEOUT, connectTimeout_); } } public void setReadTimeout(int timeout) { readTimeout_ = timeout; if (null != this.client) { // WARNING, this modifies the HttpClient params, this might have an impact elsewhere if the // same HttpClient is used for something else. client.getParams().setParameter(CoreConnectionPNames.SO_TIMEOUT, readTimeout_); } } public void setCustomHeaders(Map headers) { customHeaders_ = headers; } public void setCustomHeader(String key, String value) { if (customHeaders_ == null) { customHeaders_ = new HashMap(); } customHeaders_.put(key, value); } public void open() {} public void close() { if (null != inputStream_) { try { inputStream_.close(); } catch (IOException ioe) { ; } inputStream_ = null; } } public boolean isOpen() { return true; } public int read(byte[] buf, int off, int len) throws TTransportException { if (inputStream_ == null) { throw new TTransportException("Response buffer is empty, no request."); } try { int ret = inputStream_.read(buf, off, len); if (ret == -1) { throw new TTransportException("No more data available."); } return ret; } catch (IOException iox) { throw new TTransportException(iox); } } public void write(byte[] buf, int off, int len) { requestBuffer_.write(buf, off, len); } private void flushUsingHttpClient() throws TTransportException { if (null == this.client) { throw new TTransportException("Null HttpClient, aborting."); } // Extract request and reset buffer byte[] data = requestBuffer_.toByteArray(); requestBuffer_.reset(); HttpPost post = null; InputStream is = null; try { // Set request to path + query string post = new HttpPost(this.url_.getFile()); // // Headers are added to the HttpPost instance, not // to HttpClient. // post.setHeader("Content-Type", "application/x-thrift"); post.setHeader("Accept", "application/x-thrift"); post.setHeader("User-Agent", "Java/THttpClient/HC"); if (null != customHeaders_) { for (Map.Entry header : customHeaders_.entrySet()) { post.setHeader(header.getKey(), header.getValue()); } } post.setEntity(new ByteArrayEntity(data)); HttpResponse response = this.client.execute(this.host, post); int responseCode = response.getStatusLine().getStatusCode(); // // Retrieve the inputstream BEFORE checking the status code so // resources get freed in the finally clause. // is = response.getEntity().getContent(); if (responseCode != HttpStatus.SC_OK) { throw new TTransportException("HTTP Response code: " + responseCode); } // Read the responses into a byte array so we can release the connection // early. This implies that the whole content will have to be read in // memory, and that momentarily we might use up twice the memory (while the // thrift struct is being read up the chain). // Proceeding differently might lead to exhaustion of connections and thus // to app failure. byte[] buf = new byte[1024]; ByteArrayOutputStream baos = new ByteArrayOutputStream(); int len = 0; do { len = is.read(buf); if (len > 0) { baos.write(buf, 0, len); } } while (-1 != len); try { // Indicate we're done with the content. EntityUtils.consume(response.getEntity()); } catch (IOException ioe) { // We ignore this exception, it might only mean the server has no // keep-alive capability. } inputStream_ = new ByteArrayInputStream(baos.toByteArray()); } catch (IOException ioe) { // Abort method so the connection gets released back to the connection manager if (null != post) { post.abort(); } throw new TTransportException(ioe); } finally { if (null != is) { // Close the entity's input stream, this will release the underlying connection try { is.close(); } catch (IOException ioe) { throw new TTransportException(ioe); } } } } public void flush() throws TTransportException { if (null != this.client) { flushUsingHttpClient(); return; } // Extract request and reset buffer byte[] data = requestBuffer_.toByteArray(); requestBuffer_.reset(); try { // Create connection object HttpURLConnection connection = (HttpURLConnection)url_.openConnection(); // Timeouts, only if explicitly set if (connectTimeout_ > 0) { connection.setConnectTimeout(connectTimeout_); } if (readTimeout_ > 0) { connection.setReadTimeout(readTimeout_); } // Make the request connection.setRequestMethod("POST"); connection.setRequestProperty("Content-Type", "application/x-thrift"); connection.setRequestProperty("Accept", "application/x-thrift"); connection.setRequestProperty("User-Agent", "Java/THttpClient"); if (customHeaders_ != null) { for (Map.Entry header : customHeaders_.entrySet()) { connection.setRequestProperty(header.getKey(), header.getValue()); } } connection.setDoOutput(true); connection.connect(); connection.getOutputStream().write(data); int responseCode = connection.getResponseCode(); if (responseCode != HttpURLConnection.HTTP_OK) { throw new TTransportException("HTTP Response code: " + responseCode); } // Read the responses inputStream_ = connection.getInputStream(); } catch (IOException iox) { throw new TTransportException(iox); } } } libthrift-java_0.9.0/src/org/apache/thrift/transport/AutoExpandingBufferReadTransport.java0000644000175000017500000000453712035665435032725 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import org.apache.commons.lang.NotImplementedException; /** * TTransport for reading from an AutoExpandingBuffer. */ public class AutoExpandingBufferReadTransport extends TTransport { private final AutoExpandingBuffer buf; private int pos = 0; private int limit = 0; public AutoExpandingBufferReadTransport(int initialCapacity, double overgrowthCoefficient) { this.buf = new AutoExpandingBuffer(initialCapacity, overgrowthCoefficient); } public void fill(TTransport inTrans, int length) throws TTransportException { buf.resizeIfNecessary(length); inTrans.readAll(buf.array(), 0, length); pos = 0; limit = length; } @Override public void close() {} @Override public boolean isOpen() { return true; } @Override public void open() throws TTransportException {} @Override public final int read(byte[] target, int off, int len) throws TTransportException { int amtToRead = Math.min(len, getBytesRemainingInBuffer()); System.arraycopy(buf.array(), pos, target, off, amtToRead); consumeBuffer(amtToRead); return amtToRead; } @Override public void write(byte[] buf, int off, int len) throws TTransportException { throw new NotImplementedException(); } @Override public final void consumeBuffer(int len) { pos += len; } @Override public final byte[] getBuffer() { return buf.array(); } @Override public final int getBufferPosition() { return pos; } @Override public final int getBytesRemainingInBuffer() { return limit - pos; } } libthrift-java_0.9.0/src/org/apache/thrift/transport/TSaslClientTransport.java0000644000175000017500000000723112035665435030410 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import java.util.Map; import javax.security.auth.callback.CallbackHandler; import javax.security.sasl.Sasl; import javax.security.sasl.SaslClient; import javax.security.sasl.SaslException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Wraps another Thrift TTransport, but performs SASL client * negotiation on the call to open(). This class will wrap ensuing * communication over it, if a SASL QOP is negotiated with the other party. */ public class TSaslClientTransport extends TSaslTransport { private static final Logger LOGGER = LoggerFactory.getLogger(TSaslClientTransport.class); /** * The name of the mechanism this client supports. */ private final String mechanism; /** * Uses the given SaslClient. * * @param saslClient * The SaslClient to use for the subsequent SASL * negotiation. * @param transport * Transport underlying this one. */ public TSaslClientTransport(SaslClient saslClient, TTransport transport) { super(saslClient, transport); mechanism = saslClient.getMechanismName(); } /** * Creates a SaslClient using the given SASL-specific parameters. * See the Java documentation for Sasl.createSaslClient for the * details of the parameters. * * @param transport * The underlying Thrift transport. * @throws SaslException */ public TSaslClientTransport(String mechanism, String authorizationId, String protocol, String serverName, Map props, CallbackHandler cbh, TTransport transport) throws SaslException { super(Sasl.createSaslClient(new String[] { mechanism }, authorizationId, protocol, serverName, props, cbh), transport); this.mechanism = mechanism; } @Override protected SaslRole getRole() { return SaslRole.CLIENT; } /** * Performs the client side of the initial portion of the Thrift SASL * protocol. Generates and sends the initial response to the server, including * which mechanism this client wants to use. */ @Override protected void handleSaslStartMessage() throws TTransportException, SaslException { SaslClient saslClient = getSaslClient(); byte[] initialResponse = new byte[0]; if (saslClient.hasInitialResponse()) initialResponse = saslClient.evaluateChallenge(initialResponse); LOGGER.debug("Sending mechanism name {} and initial response of length {}", mechanism, initialResponse.length); byte[] mechanismBytes = mechanism.getBytes(); sendSaslMessage(NegotiationStatus.START, mechanismBytes); // Send initial response sendSaslMessage(saslClient.isComplete() ? NegotiationStatus.COMPLETE : NegotiationStatus.OK, initialResponse); underlyingTransport.flush(); } } libthrift-java_0.9.0/src/org/apache/thrift/transport/AutoExpandingBufferWriteTransport.java0000644000175000017500000000362412035665435033140 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import org.apache.commons.lang.NotImplementedException; /** * TTransport for writing to an AutoExpandingBuffer. */ public final class AutoExpandingBufferWriteTransport extends TTransport { private final AutoExpandingBuffer buf; private int pos; public AutoExpandingBufferWriteTransport(int initialCapacity, double growthCoefficient) { this.buf = new AutoExpandingBuffer(initialCapacity, growthCoefficient); this.pos = 0; } @Override public void close() {} @Override public boolean isOpen() {return true;} @Override public void open() throws TTransportException {} @Override public int read(byte[] buf, int off, int len) throws TTransportException { throw new NotImplementedException(); } @Override public void write(byte[] toWrite, int off, int len) throws TTransportException { buf.resizeIfNecessary(pos + len); System.arraycopy(toWrite, off, buf.array(), pos, len); pos += len; } public AutoExpandingBuffer getBuf() { return buf; } public int getPos() { return pos; } public void reset() { pos = 0; } } libthrift-java_0.9.0/src/org/apache/thrift/transport/TFramedTransport.java0000644000175000017500000001067212035665435027550 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import org.apache.thrift.TByteArrayOutputStream; /** * TFramedTransport is a buffered TTransport that ensures a fully read message * every time by preceding messages with a 4-byte frame size. */ public class TFramedTransport extends TTransport { protected static final int DEFAULT_MAX_LENGTH = 16384000; private int maxLength_; /** * Underlying transport */ private TTransport transport_ = null; /** * Buffer for output */ private final TByteArrayOutputStream writeBuffer_ = new TByteArrayOutputStream(1024); /** * Buffer for input */ private TMemoryInputTransport readBuffer_ = new TMemoryInputTransport(new byte[0]); public static class Factory extends TTransportFactory { private int maxLength_; public Factory() { maxLength_ = TFramedTransport.DEFAULT_MAX_LENGTH; } public Factory(int maxLength) { maxLength_ = maxLength; } @Override public TTransport getTransport(TTransport base) { return new TFramedTransport(base, maxLength_); } } /** * Constructor wraps around another transport */ public TFramedTransport(TTransport transport, int maxLength) { transport_ = transport; maxLength_ = maxLength; } public TFramedTransport(TTransport transport) { transport_ = transport; maxLength_ = TFramedTransport.DEFAULT_MAX_LENGTH; } public void open() throws TTransportException { transport_.open(); } public boolean isOpen() { return transport_.isOpen(); } public void close() { transport_.close(); } public int read(byte[] buf, int off, int len) throws TTransportException { if (readBuffer_ != null) { int got = readBuffer_.read(buf, off, len); if (got > 0) { return got; } } // Read another frame of data readFrame(); return readBuffer_.read(buf, off, len); } @Override public byte[] getBuffer() { return readBuffer_.getBuffer(); } @Override public int getBufferPosition() { return readBuffer_.getBufferPosition(); } @Override public int getBytesRemainingInBuffer() { return readBuffer_.getBytesRemainingInBuffer(); } @Override public void consumeBuffer(int len) { readBuffer_.consumeBuffer(len); } private final byte[] i32buf = new byte[4]; private void readFrame() throws TTransportException { transport_.readAll(i32buf, 0, 4); int size = decodeFrameSize(i32buf); if (size < 0) { throw new TTransportException("Read a negative frame size (" + size + ")!"); } if (size > maxLength_) { throw new TTransportException("Frame size (" + size + ") larger than max length (" + maxLength_ + ")!"); } byte[] buff = new byte[size]; transport_.readAll(buff, 0, size); readBuffer_.reset(buff); } public void write(byte[] buf, int off, int len) throws TTransportException { writeBuffer_.write(buf, off, len); } @Override public void flush() throws TTransportException { byte[] buf = writeBuffer_.get(); int len = writeBuffer_.len(); writeBuffer_.reset(); encodeFrameSize(len, i32buf); transport_.write(i32buf, 0, 4); transport_.write(buf, 0, len); transport_.flush(); } public static final void encodeFrameSize(final int frameSize, final byte[] buf) { buf[0] = (byte)(0xff & (frameSize >> 24)); buf[1] = (byte)(0xff & (frameSize >> 16)); buf[2] = (byte)(0xff & (frameSize >> 8)); buf[3] = (byte)(0xff & (frameSize)); } public static final int decodeFrameSize(final byte[] buf) { return ((buf[0] & 0xff) << 24) | ((buf[1] & 0xff) << 16) | ((buf[2] & 0xff) << 8) | ((buf[3] & 0xff)); } } libthrift-java_0.9.0/src/org/apache/thrift/transport/TTransportException.java0000644000175000017500000000372612035665435030312 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import org.apache.thrift.TException; /** * Transport exceptions. * */ public class TTransportException extends TException { private static final long serialVersionUID = 1L; public static final int UNKNOWN = 0; public static final int NOT_OPEN = 1; public static final int ALREADY_OPEN = 2; public static final int TIMED_OUT = 3; public static final int END_OF_FILE = 4; protected int type_ = UNKNOWN; public TTransportException() { super(); } public TTransportException(int type) { super(); type_ = type; } public TTransportException(int type, String message) { super(message); type_ = type; } public TTransportException(String message) { super(message); } public TTransportException(int type, Throwable cause) { super(cause); type_ = type; } public TTransportException(Throwable cause) { super(cause); } public TTransportException(String message, Throwable cause) { super(message, cause); } public TTransportException(int type, String message, Throwable cause) { super(message, cause); type_ = type; } public int getType() { return type_; } } libthrift-java_0.9.0/src/org/apache/thrift/transport/TNonblockingTransport.java0000644000175000017500000000321312035665435030606 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import java.io.IOException; import java.net.SocketAddress; import java.nio.ByteBuffer; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; public abstract class TNonblockingTransport extends TTransport { /** * Non-blocking connection initialization. * @see java.nio.channels.SocketChannel#connect(SocketAddress remote) */ public abstract boolean startConnect() throws IOException; /** * Non-blocking connection completion. * @see java.nio.channels.SocketChannel#finishConnect() */ public abstract boolean finishConnect() throws IOException; public abstract SelectionKey registerSelector(Selector selector, int interests) throws IOException; public abstract int read(ByteBuffer buffer) throws IOException; public abstract int write(ByteBuffer buffer) throws IOException; } libthrift-java_0.9.0/src/org/apache/thrift/transport/TServerTransport.java0000644000175000017500000000330112035665435027607 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; /** * Server transport. Object which provides client transports. * */ public abstract class TServerTransport { public abstract void listen() throws TTransportException; public final TTransport accept() throws TTransportException { TTransport transport = acceptImpl(); if (transport == null) { throw new TTransportException("accept() may not return NULL"); } return transport; } public abstract void close(); protected abstract TTransport acceptImpl() throws TTransportException; /** * Optional method implementation. This signals to the server transport * that it should break out of any accept() or listen() that it is currently * blocked on. This method, if implemented, MUST be thread safe, as it may * be called from a different thread context than the other TServerTransport * methods. */ public void interrupt() {} } libthrift-java_0.9.0/src/org/apache/thrift/transport/TSaslTransport.java0000644000175000017500000004175612035665435027263 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import java.io.UnsupportedEncodingException; import java.util.HashMap; import java.util.Map; import javax.security.sasl.Sasl; import javax.security.sasl.SaslClient; import javax.security.sasl.SaslException; import javax.security.sasl.SaslServer; import org.apache.thrift.EncodingUtils; import org.apache.thrift.TByteArrayOutputStream; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * A superclass for SASL client/server thrift transports. A subclass need only * implement the open method. */ abstract class TSaslTransport extends TTransport { private static final Logger LOGGER = LoggerFactory.getLogger(TSaslTransport.class); protected static final int DEFAULT_MAX_LENGTH = 0x7FFFFFFF; protected static final int MECHANISM_NAME_BYTES = 1; protected static final int STATUS_BYTES = 1; protected static final int PAYLOAD_LENGTH_BYTES = 4; protected static enum SaslRole { SERVER, CLIENT; } /** * Status bytes used during the initial Thrift SASL handshake. */ protected static enum NegotiationStatus { START((byte)0x01), OK((byte)0x02), BAD((byte)0x03), ERROR((byte)0x04), COMPLETE((byte)0x05); private final byte value; private static final Map reverseMap = new HashMap(); static { for (NegotiationStatus s : NegotiationStatus.class.getEnumConstants()) { reverseMap.put(s.getValue(), s); } } private NegotiationStatus(byte val) { this.value = val; } public byte getValue() { return value; } public static NegotiationStatus byValue(byte val) { return reverseMap.get(val); } } /** * Transport underlying this one. */ protected TTransport underlyingTransport; /** * Either a SASL client or a SASL server. */ private SaslParticipant sasl; /** * Whether or not we should wrap/unwrap reads/writes. Determined by whether or * not a QOP is negotiated during the SASL handshake. */ private boolean shouldWrap = false; /** * Buffer for input. */ private TMemoryInputTransport readBuffer = new TMemoryInputTransport(); /** * Buffer for output. */ private final TByteArrayOutputStream writeBuffer = new TByteArrayOutputStream(1024); /** * Create a TSaslTransport. It's assumed that setSaslServer will be called * later to initialize the SASL endpoint underlying this transport. * * @param underlyingTransport * The thrift transport which this transport is wrapping. */ protected TSaslTransport(TTransport underlyingTransport) { this.underlyingTransport = underlyingTransport; } /** * Create a TSaslTransport which acts as a client. * * @param saslClient * The SaslClient which this transport will use for SASL * negotiation. * @param underlyingTransport * The thrift transport which this transport is wrapping. */ protected TSaslTransport(SaslClient saslClient, TTransport underlyingTransport) { sasl = new SaslParticipant(saslClient); this.underlyingTransport = underlyingTransport; } protected void setSaslServer(SaslServer saslServer) { sasl = new SaslParticipant(saslServer); } // Used to read the status byte and payload length. private final byte[] messageHeader = new byte[STATUS_BYTES + PAYLOAD_LENGTH_BYTES]; /** * Send a complete Thrift SASL message. * * @param status * The status to send. * @param payload * The data to send as the payload of this message. * @throws TTransportException */ protected void sendSaslMessage(NegotiationStatus status, byte[] payload) throws TTransportException { if (payload == null) payload = new byte[0]; messageHeader[0] = status.getValue(); EncodingUtils.encodeBigEndian(payload.length, messageHeader, STATUS_BYTES); if (LOGGER.isDebugEnabled()) LOGGER.debug(getRole() + ": Writing message with status {} and payload length {}", status, payload.length); underlyingTransport.write(messageHeader); underlyingTransport.write(payload); underlyingTransport.flush(); } /** * Read a complete Thrift SASL message. * * @return The SASL status and payload from this message. * @throws TTransportException * Thrown if there is a failure reading from the underlying * transport, or if a status code of BAD or ERROR is encountered. */ protected SaslResponse receiveSaslMessage() throws TTransportException { underlyingTransport.readAll(messageHeader, 0, messageHeader.length); byte statusByte = messageHeader[0]; byte[] payload = new byte[EncodingUtils.decodeBigEndian(messageHeader, STATUS_BYTES)]; underlyingTransport.readAll(payload, 0, payload.length); NegotiationStatus status = NegotiationStatus.byValue(statusByte); if (status == null) { sendAndThrowMessage(NegotiationStatus.ERROR, "Invalid status " + statusByte); } else if (status == NegotiationStatus.BAD || status == NegotiationStatus.ERROR) { try { String remoteMessage = new String(payload, "UTF-8"); throw new TTransportException("Peer indicated failure: " + remoteMessage); } catch (UnsupportedEncodingException e) { throw new TTransportException(e); } } if (LOGGER.isDebugEnabled()) LOGGER.debug(getRole() + ": Received message with status {} and payload length {}", status, payload.length); return new SaslResponse(status, payload); } /** * Send a Thrift SASL message with the given status (usually BAD or ERROR) and * string message, and then throw a TTransportException with the given * message. * * @param status * The Thrift SASL status code to send. Usually BAD or ERROR. * @param message * The optional message to send to the other side. * @throws TTransportException * Always thrown with the message provided. */ protected void sendAndThrowMessage(NegotiationStatus status, String message) throws TTransportException { try { sendSaslMessage(status, message.getBytes()); } catch (Exception e) { LOGGER.warn("Could not send failure response", e); message += "\nAlso, could not send response: " + e.toString(); } throw new TTransportException(message); } /** * Implemented by subclasses to start the Thrift SASL handshake process. When * this method completes, the SaslParticipant in this class is * assumed to be initialized. * * @throws TTransportException * @throws SaslException */ abstract protected void handleSaslStartMessage() throws TTransportException, SaslException; protected abstract SaslRole getRole(); /** * Opens the underlying transport if it's not already open and then performs * SASL negotiation. If a QOP is negotiated during this SASL handshake, it used * for all communication on this transport after this call is complete. */ @Override public void open() throws TTransportException { LOGGER.debug("opening transport {}", this); if (sasl != null && sasl.isComplete()) throw new TTransportException("SASL transport already open"); if (!underlyingTransport.isOpen()) underlyingTransport.open(); try { // Negotiate a SASL mechanism. The client also sends its // initial response, or an empty one. handleSaslStartMessage(); LOGGER.debug("{}: Start message handled", getRole()); SaslResponse message = null; while (!sasl.isComplete()) { message = receiveSaslMessage(); if (message.status != NegotiationStatus.COMPLETE && message.status != NegotiationStatus.OK) { throw new TTransportException("Expected COMPLETE or OK, got " + message.status); } byte[] challenge = sasl.evaluateChallengeOrResponse(message.payload); // If we are the client, and the server indicates COMPLETE, we don't need to // send back any further response. if (message.status == NegotiationStatus.COMPLETE && getRole() == SaslRole.CLIENT) { LOGGER.debug("{}: All done!", getRole()); break; } sendSaslMessage(sasl.isComplete() ? NegotiationStatus.COMPLETE : NegotiationStatus.OK, challenge); } LOGGER.debug("{}: Main negotiation loop complete", getRole()); assert sasl.isComplete(); // If we're the client, and we're complete, but the server isn't // complete yet, we need to wait for its response. This will occur // with ANONYMOUS auth, for example, where we send an initial response // and are immediately complete. if (getRole() == SaslRole.CLIENT && (message == null || message.status == NegotiationStatus.OK)) { LOGGER.debug("{}: SASL Client receiving last message", getRole()); message = receiveSaslMessage(); if (message.status != NegotiationStatus.COMPLETE) { throw new TTransportException( "Expected SASL COMPLETE, but got " + message.status); } } } catch (SaslException e) { try { LOGGER.error("SASL negotiation failure", e); sendAndThrowMessage(NegotiationStatus.BAD, e.getMessage()); } finally { underlyingTransport.close(); } } String qop = (String) sasl.getNegotiatedProperty(Sasl.QOP); if (qop != null && !qop.equalsIgnoreCase("auth")) shouldWrap = true; } /** * Get the underlying SaslClient. * * @return The SaslClient, or null if this transport * is backed by a SaslServer. */ public SaslClient getSaslClient() { return sasl.saslClient; } /** * Get the underlying transport that Sasl is using. * @return The TTransport transport */ public TTransport getUnderlyingTransport() { return underlyingTransport; } /** * Get the underlying SaslServer. * * @return The SaslServer, or null if this transport * is backed by a SaslClient. */ public SaslServer getSaslServer() { return sasl.saslServer; } /** * Read a 4-byte word from the underlying transport and interpret it as an * integer. * * @return The length prefix of the next SASL message to read. * @throws TTransportException * Thrown if reading from the underlying transport fails. */ protected int readLength() throws TTransportException { byte[] lenBuf = new byte[4]; underlyingTransport.readAll(lenBuf, 0, lenBuf.length); return EncodingUtils.decodeBigEndian(lenBuf); } /** * Write the given integer as 4 bytes to the underlying transport. * * @param length * The length prefix of the next SASL message to write. * @throws TTransportException * Thrown if writing to the underlying transport fails. */ protected void writeLength(int length) throws TTransportException { byte[] lenBuf = new byte[4]; TFramedTransport.encodeFrameSize(length, lenBuf); underlyingTransport.write(lenBuf); } // Below is the SASL implementation of the TTransport interface. /** * Closes the underlying transport and disposes of the SASL implementation * underlying this transport. */ @Override public void close() { underlyingTransport.close(); try { sasl.dispose(); } catch (SaslException e) { // Not much we can do here. } } /** * True if the underlying transport is open and the SASL handshake is * complete. */ @Override public boolean isOpen() { return underlyingTransport.isOpen() && sasl != null && sasl.isComplete(); } /** * Read from the underlying transport. Unwraps the contents if a QOP was * negotiated during the SASL handshake. */ @Override public int read(byte[] buf, int off, int len) throws TTransportException { if (!isOpen()) throw new TTransportException("SASL authentication not complete"); int got = readBuffer.read(buf, off, len); if (got > 0) { return got; } // Read another frame of data try { readFrame(); } catch (SaslException e) { throw new TTransportException(e); } return readBuffer.read(buf, off, len); } /** * Read a single frame of data from the underlying transport, unwrapping if * necessary. * * @throws TTransportException * Thrown if there's an error reading from the underlying transport. * @throws SaslException * Thrown if there's an error unwrapping the data. */ private void readFrame() throws TTransportException, SaslException { int dataLength = readLength(); if (dataLength < 0) throw new TTransportException("Read a negative frame size (" + dataLength + ")!"); byte[] buff = new byte[dataLength]; LOGGER.debug("{}: reading data length: {}", getRole(), dataLength); underlyingTransport.readAll(buff, 0, dataLength); if (shouldWrap) { buff = sasl.unwrap(buff, 0, buff.length); LOGGER.debug("data length after unwrap: {}", buff.length); } readBuffer.reset(buff); } /** * Write to the underlying transport. */ @Override public void write(byte[] buf, int off, int len) throws TTransportException { if (!isOpen()) throw new TTransportException("SASL authentication not complete"); writeBuffer.write(buf, off, len); } /** * Flushes to the underlying transport. Wraps the contents if a QOP was * negotiated during the SASL handshake. */ @Override public void flush() throws TTransportException { byte[] buf = writeBuffer.get(); int dataLength = writeBuffer.len(); writeBuffer.reset(); if (shouldWrap) { LOGGER.debug("data length before wrap: {}", dataLength); try { buf = sasl.wrap(buf, 0, dataLength); } catch (SaslException e) { throw new TTransportException(e); } dataLength = buf.length; } LOGGER.debug("writing data length: {}", dataLength); writeLength(dataLength); underlyingTransport.write(buf, 0, dataLength); underlyingTransport.flush(); } /** * Used exclusively by readSaslMessage to return both a status and data. */ protected static class SaslResponse { public NegotiationStatus status; public byte[] payload; public SaslResponse(NegotiationStatus status, byte[] payload) { this.status = status; this.payload = payload; } } /** * Used to abstract over the SaslServer and * SaslClient classes, which share a lot of their interface, but * unfortunately don't share a common superclass. */ private static class SaslParticipant { // One of these will always be null. public SaslServer saslServer; public SaslClient saslClient; public SaslParticipant(SaslServer saslServer) { this.saslServer = saslServer; } public SaslParticipant(SaslClient saslClient) { this.saslClient = saslClient; } public byte[] evaluateChallengeOrResponse(byte[] challengeOrResponse) throws SaslException { if (saslClient != null) { return saslClient.evaluateChallenge(challengeOrResponse); } else { return saslServer.evaluateResponse(challengeOrResponse); } } public boolean isComplete() { if (saslClient != null) return saslClient.isComplete(); else return saslServer.isComplete(); } public void dispose() throws SaslException { if (saslClient != null) saslClient.dispose(); else saslServer.dispose(); } public byte[] unwrap(byte[] buf, int off, int len) throws SaslException { if (saslClient != null) return saslClient.unwrap(buf, off, len); else return saslServer.unwrap(buf, off, len); } public byte[] wrap(byte[] buf, int off, int len) throws SaslException { if (saslClient != null) return saslClient.wrap(buf, off, len); else return saslServer.wrap(buf, off, len); } public Object getNegotiatedProperty(String propName) { if (saslClient != null) return saslClient.getNegotiatedProperty(propName); else return saslServer.getNegotiatedProperty(propName); } } } libthrift-java_0.9.0/src/org/apache/thrift/transport/TSeekableFile.java0000644000175000017500000000230112035665435026736 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import java.io.InputStream; import java.io.OutputStream; import java.io.IOException; public interface TSeekableFile { public InputStream getInputStream() throws IOException; public OutputStream getOutputStream() throws IOException; public void close() throws IOException; public long length() throws IOException; public void seek(long pos) throws IOException; } libthrift-java_0.9.0/src/org/apache/thrift/transport/TSaslServerTransport.java0000644000175000017500000002117412035665435030442 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import java.lang.ref.WeakReference; import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.WeakHashMap; import javax.security.auth.callback.CallbackHandler; import javax.security.sasl.Sasl; import javax.security.sasl.SaslException; import javax.security.sasl.SaslServer; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Wraps another Thrift TTransport, but performs SASL server * negotiation on the call to open(). This class will wrap ensuing * communication over it, if a SASL QOP is negotiated with the other party. */ public class TSaslServerTransport extends TSaslTransport { private static final Logger LOGGER = LoggerFactory.getLogger(TSaslServerTransport.class); /** * Mapping from SASL mechanism name -> all the parameters required to * instantiate a SASL server. */ private Map serverDefinitionMap = new HashMap(); /** * Contains all the parameters used to define a SASL server implementation. */ private static class TSaslServerDefinition { public String mechanism; public String protocol; public String serverName; public Map props; public CallbackHandler cbh; public TSaslServerDefinition(String mechanism, String protocol, String serverName, Map props, CallbackHandler cbh) { this.mechanism = mechanism; this.protocol = protocol; this.serverName = serverName; this.props = props; this.cbh = cbh; } } /** * Uses the given underlying transport. Assumes that addServerDefinition is * called later. * * @param transport * Transport underlying this one. */ public TSaslServerTransport(TTransport transport) { super(transport); } /** * Creates a SaslServer using the given SASL-specific parameters. * See the Java documentation for Sasl.createSaslServer for the * details of the parameters. * * @param transport * The underlying Thrift transport. */ public TSaslServerTransport(String mechanism, String protocol, String serverName, Map props, CallbackHandler cbh, TTransport transport) { super(transport); addServerDefinition(mechanism, protocol, serverName, props, cbh); } private TSaslServerTransport(Map serverDefinitionMap, TTransport transport) { super(transport); this.serverDefinitionMap.putAll(serverDefinitionMap); } /** * Add a supported server definition to this transport. See the Java * documentation for Sasl.createSaslServer for the details of the * parameters. */ public void addServerDefinition(String mechanism, String protocol, String serverName, Map props, CallbackHandler cbh) { serverDefinitionMap.put(mechanism, new TSaslServerDefinition(mechanism, protocol, serverName, props, cbh)); } @Override protected SaslRole getRole() { return SaslRole.SERVER; } /** * Performs the server side of the initial portion of the Thrift SASL protocol. * Receives the initial response from the client, creates a SASL server using * the mechanism requested by the client (if this server supports it), and * sends the first challenge back to the client. */ @Override protected void handleSaslStartMessage() throws TTransportException, SaslException { SaslResponse message = receiveSaslMessage(); LOGGER.debug("Received start message with status {}", message.status); if (message.status != NegotiationStatus.START) { sendAndThrowMessage(NegotiationStatus.ERROR, "Expecting START status, received " + message.status); } // Get the mechanism name. String mechanismName = new String(message.payload); TSaslServerDefinition serverDefinition = serverDefinitionMap.get(mechanismName); LOGGER.debug("Received mechanism name '{}'", mechanismName); if (serverDefinition == null) { sendAndThrowMessage(NegotiationStatus.BAD, "Unsupported mechanism type " + mechanismName); } SaslServer saslServer = Sasl.createSaslServer(serverDefinition.mechanism, serverDefinition.protocol, serverDefinition.serverName, serverDefinition.props, serverDefinition.cbh); setSaslServer(saslServer); } /** * TTransportFactory to create * TSaslServerTransports. Ensures that a given * underlying TTransport instance receives the same * TSaslServerTransport. This is kind of an awful hack to work * around the fact that Thrift is designed assuming that * TTransport instances are stateless, and thus the existing * TServers use different TTransport instances for * input and output. */ public static class Factory extends TTransportFactory { /** * This is the implementation of the awful hack described above. * WeakHashMap is used to ensure that we don't leak memory. */ private static Map> transportMap = Collections.synchronizedMap(new WeakHashMap>()); /** * Mapping from SASL mechanism name -> all the parameters required to * instantiate a SASL server. */ private Map serverDefinitionMap = new HashMap(); /** * Create a new Factory. Assumes that addServerDefinition will * be called later. */ public Factory() { super(); } /** * Create a new Factory, initially with the single server * definition given. You may still call addServerDefinition * later. See the Java documentation for Sasl.createSaslServer * for the details of the parameters. */ public Factory(String mechanism, String protocol, String serverName, Map props, CallbackHandler cbh) { super(); addServerDefinition(mechanism, protocol, serverName, props, cbh); } /** * Add a supported server definition to the transports created by this * factory. See the Java documentation for * Sasl.createSaslServer for the details of the parameters. */ public void addServerDefinition(String mechanism, String protocol, String serverName, Map props, CallbackHandler cbh) { serverDefinitionMap.put(mechanism, new TSaslServerDefinition(mechanism, protocol, serverName, props, cbh)); } /** * Get a new TSaslServerTransport instance, or reuse the * existing one if a TSaslServerTransport has already been * created before using the given TTransport as an underlying * transport. This ensures that a given underlying transport instance * receives the same TSaslServerTransport. */ @Override public TTransport getTransport(TTransport base) { WeakReference ret = transportMap.get(base); if (ret == null || ret.get() == null) { LOGGER.debug("transport map does not contain key", base); ret = new WeakReference(new TSaslServerTransport(serverDefinitionMap, base)); try { ret.get().open(); } catch (TTransportException e) { LOGGER.debug("failed to open server transport", e); throw new RuntimeException(e); } transportMap.put(base, ret); // No need for putIfAbsent(). // Concurrent calls to getTransport() will pass in different TTransports. } else { LOGGER.debug("transport map does contain key {}", base); } return ret.get(); } } } libthrift-java_0.9.0/src/org/apache/thrift/transport/TSocket.java0000644000175000017500000001213512035665435025661 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.IOException; import java.net.InetSocketAddress; import java.net.Socket; import java.net.SocketException; /** * Socket implementation of the TTransport interface. To be commented soon! * */ public class TSocket extends TIOStreamTransport { private static final Logger LOGGER = LoggerFactory.getLogger(TSocket.class.getName()); /** * Wrapped Socket object */ private Socket socket_ = null; /** * Remote host */ private String host_ = null; /** * Remote port */ private int port_ = 0; /** * Socket timeout */ private int timeout_ = 0; /** * Constructor that takes an already created socket. * * @param socket Already created socket object * @throws TTransportException if there is an error setting up the streams */ public TSocket(Socket socket) throws TTransportException { socket_ = socket; try { socket_.setSoLinger(false, 0); socket_.setTcpNoDelay(true); } catch (SocketException sx) { LOGGER.warn("Could not configure socket.", sx); } if (isOpen()) { try { inputStream_ = new BufferedInputStream(socket_.getInputStream(), 1024); outputStream_ = new BufferedOutputStream(socket_.getOutputStream(), 1024); } catch (IOException iox) { close(); throw new TTransportException(TTransportException.NOT_OPEN, iox); } } } /** * Creates a new unconnected socket that will connect to the given host * on the given port. * * @param host Remote host * @param port Remote port */ public TSocket(String host, int port) { this(host, port, 0); } /** * Creates a new unconnected socket that will connect to the given host * on the given port. * * @param host Remote host * @param port Remote port * @param timeout Socket timeout */ public TSocket(String host, int port, int timeout) { host_ = host; port_ = port; timeout_ = timeout; initSocket(); } /** * Initializes the socket object */ private void initSocket() { socket_ = new Socket(); try { socket_.setSoLinger(false, 0); socket_.setTcpNoDelay(true); socket_.setSoTimeout(timeout_); } catch (SocketException sx) { LOGGER.error("Could not configure socket.", sx); } } /** * Sets the socket timeout * * @param timeout Milliseconds timeout */ public void setTimeout(int timeout) { timeout_ = timeout; try { socket_.setSoTimeout(timeout); } catch (SocketException sx) { LOGGER.warn("Could not set socket timeout.", sx); } } /** * Returns a reference to the underlying socket. */ public Socket getSocket() { if (socket_ == null) { initSocket(); } return socket_; } /** * Checks whether the socket is connected. */ public boolean isOpen() { if (socket_ == null) { return false; } return socket_.isConnected(); } /** * Connects the socket, creating a new socket object if necessary. */ public void open() throws TTransportException { if (isOpen()) { throw new TTransportException(TTransportException.ALREADY_OPEN, "Socket already connected."); } if (host_.length() == 0) { throw new TTransportException(TTransportException.NOT_OPEN, "Cannot open null host."); } if (port_ <= 0) { throw new TTransportException(TTransportException.NOT_OPEN, "Cannot open without port."); } if (socket_ == null) { initSocket(); } try { socket_.connect(new InetSocketAddress(host_, port_), timeout_); inputStream_ = new BufferedInputStream(socket_.getInputStream(), 1024); outputStream_ = new BufferedOutputStream(socket_.getOutputStream(), 1024); } catch (IOException iox) { close(); throw new TTransportException(TTransportException.NOT_OPEN, iox); } } /** * Closes the socket. */ public void close() { // Close the underlying streams super.close(); // Close the socket if (socket_ != null) { try { socket_.close(); } catch (IOException iox) { LOGGER.warn("Could not close socket.", iox); } socket_ = null; } } } libthrift-java_0.9.0/src/org/apache/thrift/transport/TIOStreamTransport.java0000644000175000017500000001100712035665435030026 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; /** * This is the most commonly used base transport. It takes an InputStream * and an OutputStream and uses those to perform all transport operations. * This allows for compatibility with all the nice constructs Java already * has to provide a variety of types of streams. * */ public class TIOStreamTransport extends TTransport { private static final Logger LOGGER = LoggerFactory.getLogger(TIOStreamTransport.class.getName()); /** Underlying inputStream */ protected InputStream inputStream_ = null; /** Underlying outputStream */ protected OutputStream outputStream_ = null; /** * Subclasses can invoke the default constructor and then assign the input * streams in the open method. */ protected TIOStreamTransport() {} /** * Input stream constructor. * * @param is Input stream to read from */ public TIOStreamTransport(InputStream is) { inputStream_ = is; } /** * Output stream constructor. * * @param os Output stream to read from */ public TIOStreamTransport(OutputStream os) { outputStream_ = os; } /** * Two-way stream constructor. * * @param is Input stream to read from * @param os Output stream to read from */ public TIOStreamTransport(InputStream is, OutputStream os) { inputStream_ = is; outputStream_ = os; } /** * The streams must already be open at construction time, so this should * always return true. * * @return true */ public boolean isOpen() { return true; } /** * The streams must already be open. This method does nothing. */ public void open() throws TTransportException {} /** * Closes both the input and output streams. */ public void close() { if (inputStream_ != null) { try { inputStream_.close(); } catch (IOException iox) { LOGGER.warn("Error closing input stream.", iox); } inputStream_ = null; } if (outputStream_ != null) { try { outputStream_.close(); } catch (IOException iox) { LOGGER.warn("Error closing output stream.", iox); } outputStream_ = null; } } /** * Reads from the underlying input stream if not null. */ public int read(byte[] buf, int off, int len) throws TTransportException { if (inputStream_ == null) { throw new TTransportException(TTransportException.NOT_OPEN, "Cannot read from null inputStream"); } int bytesRead; try { bytesRead = inputStream_.read(buf, off, len); } catch (IOException iox) { throw new TTransportException(TTransportException.UNKNOWN, iox); } if (bytesRead < 0) { throw new TTransportException(TTransportException.END_OF_FILE); } return bytesRead; } /** * Writes to the underlying output stream if not null. */ public void write(byte[] buf, int off, int len) throws TTransportException { if (outputStream_ == null) { throw new TTransportException(TTransportException.NOT_OPEN, "Cannot write to null outputStream"); } try { outputStream_.write(buf, off, len); } catch (IOException iox) { throw new TTransportException(TTransportException.UNKNOWN, iox); } } /** * Flushes the underlying output stream if not null. */ public void flush() throws TTransportException { if (outputStream_ == null) { throw new TTransportException(TTransportException.NOT_OPEN, "Cannot flush null outputStream"); } try { outputStream_.flush(); } catch (IOException iox) { throw new TTransportException(TTransportException.UNKNOWN, iox); } } } libthrift-java_0.9.0/src/org/apache/thrift/transport/TFastFramedTransport.java0000644000175000017500000001371312035665435030365 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; /** * This transport is wire compatible with {@link TFramedTransport}, but makes * use of reusable, expanding read and write buffers in order to avoid * allocating new byte[]s all the time. Since the buffers only expand, you * should probably only use this transport if your messages are not too variably * large, unless the persistent memory cost is not an issue. * * This implementation is NOT threadsafe. */ public class TFastFramedTransport extends TTransport { public static class Factory extends TTransportFactory { private final int initialCapacity; private final int maxLength; public Factory() { this(DEFAULT_BUF_CAPACITY, DEFAULT_MAX_LENGTH); } public Factory(int initialCapacity) { this(initialCapacity, DEFAULT_MAX_LENGTH); } public Factory(int initialCapacity, int maxLength) { this.initialCapacity = initialCapacity; this.maxLength = maxLength; } @Override public TTransport getTransport(TTransport trans) { return new TFastFramedTransport(trans, initialCapacity, maxLength); } } /** * How big should the default read and write buffers be? */ public static final int DEFAULT_BUF_CAPACITY = 1024; /** * How big is the largest allowable frame? Defaults to 16MB. */ public static final int DEFAULT_MAX_LENGTH = 16384000; private final TTransport underlying; private final AutoExpandingBufferWriteTransport writeBuffer; private final AutoExpandingBufferReadTransport readBuffer; private final byte[] i32buf = new byte[4]; private final int maxLength; /** * Create a new {@link TFastFramedTransport}. Use the defaults * for initial buffer size and max frame length. * @param underlying Transport that real reads and writes will go through to. */ public TFastFramedTransport(TTransport underlying) { this(underlying, DEFAULT_BUF_CAPACITY, DEFAULT_MAX_LENGTH); } /** * Create a new {@link TFastFramedTransport}. Use the specified * initial buffer capacity and the default max frame length. * @param underlying Transport that real reads and writes will go through to. * @param initialBufferCapacity The initial size of the read and write buffers. * In practice, it's not critical to set this unless you know in advance that * your messages are going to be very large. */ public TFastFramedTransport(TTransport underlying, int initialBufferCapacity) { this(underlying, initialBufferCapacity, DEFAULT_MAX_LENGTH); } /** * * @param underlying Transport that real reads and writes will go through to. * @param initialBufferCapacity The initial size of the read and write buffers. * In practice, it's not critical to set this unless you know in advance that * your messages are going to be very large. (You can pass * TFramedTransportWithReusableBuffer.DEFAULT_BUF_CAPACITY if you're only * using this constructor because you want to set the maxLength.) * @param maxLength The max frame size you are willing to read. You can use * this parameter to limit how much memory can be allocated. */ public TFastFramedTransport(TTransport underlying, int initialBufferCapacity, int maxLength) { this.underlying = underlying; this.maxLength = maxLength; writeBuffer = new AutoExpandingBufferWriteTransport(initialBufferCapacity, 1.5); readBuffer = new AutoExpandingBufferReadTransport(initialBufferCapacity, 1.5); } @Override public void close() { underlying.close(); } @Override public boolean isOpen() { return underlying.isOpen(); } @Override public void open() throws TTransportException { underlying.open(); } @Override public int read(byte[] buf, int off, int len) throws TTransportException { int got = readBuffer.read(buf, off, len); if (got > 0) { return got; } // Read another frame of data readFrame(); return readBuffer.read(buf, off, len); } private void readFrame() throws TTransportException { underlying.readAll(i32buf , 0, 4); int size = TFramedTransport.decodeFrameSize(i32buf); if (size < 0) { throw new TTransportException("Read a negative frame size (" + size + ")!"); } if (size > maxLength) { throw new TTransportException("Frame size (" + size + ") larger than max length (" + maxLength + ")!"); } readBuffer.fill(underlying, size); } @Override public void write(byte[] buf, int off, int len) throws TTransportException { writeBuffer.write(buf, off, len); } @Override public void consumeBuffer(int len) { readBuffer.consumeBuffer(len); } @Override public void flush() throws TTransportException { int length = writeBuffer.getPos(); TFramedTransport.encodeFrameSize(length, i32buf); underlying.write(i32buf, 0, 4); underlying.write(writeBuffer.getBuf().array(), 0, length); writeBuffer.reset(); underlying.flush(); } @Override public byte[] getBuffer() { return readBuffer.getBuffer(); } @Override public int getBufferPosition() { return readBuffer.getBufferPosition(); } @Override public int getBytesRemainingInBuffer() { return readBuffer.getBytesRemainingInBuffer(); } } libthrift-java_0.9.0/src/org/apache/thrift/transport/AutoExpandingBuffer.java0000644000175000017500000000355712035665435030215 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; /** * Helper class that wraps a byte[] so that it can expand and be reused. Users * should call resizeIfNecessary to make sure the buffer has suitable capacity, * and then use the array as needed. Note that the internal array will grow at a * rate slightly faster than the requested capacity with the (untested) * objective of avoiding expensive buffer allocations and copies. */ public class AutoExpandingBuffer { private byte[] array; private final double growthCoefficient; public AutoExpandingBuffer(int initialCapacity, double growthCoefficient) { if (growthCoefficient < 1.0) { throw new IllegalArgumentException("Growth coefficient must be >= 1.0"); } array = new byte[initialCapacity]; this.growthCoefficient = growthCoefficient; } public void resizeIfNecessary(int size) { if (array.length < size) { byte[] newBuf = new byte[(int)(size * growthCoefficient)]; System.arraycopy(array, 0, newBuf, 0, array.length); array = newBuf; } } public byte[] array() { return array; } } libthrift-java_0.9.0/src/org/apache/thrift/transport/TServerSocket.java0000644000175000017500000000775712035665435027066 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; import java.net.InetSocketAddress; import java.net.ServerSocket; import java.net.Socket; import java.net.SocketException; /** * Wrapper around ServerSocket for Thrift. * */ public class TServerSocket extends TServerTransport { private static final Logger LOGGER = LoggerFactory.getLogger(TServerSocket.class.getName()); /** * Underlying ServerSocket object */ private ServerSocket serverSocket_ = null; /** * Timeout for client sockets from accept */ private int clientTimeout_ = 0; /** * Creates a server socket from underlying socket object */ public TServerSocket(ServerSocket serverSocket) { this(serverSocket, 0); } /** * Creates a server socket from underlying socket object */ public TServerSocket(ServerSocket serverSocket, int clientTimeout) { serverSocket_ = serverSocket; clientTimeout_ = clientTimeout; } /** * Creates just a port listening server socket */ public TServerSocket(int port) throws TTransportException { this(port, 0); } /** * Creates just a port listening server socket */ public TServerSocket(int port, int clientTimeout) throws TTransportException { this(new InetSocketAddress(port), clientTimeout); } public TServerSocket(InetSocketAddress bindAddr) throws TTransportException { this(bindAddr, 0); } public TServerSocket(InetSocketAddress bindAddr, int clientTimeout) throws TTransportException { clientTimeout_ = clientTimeout; try { // Make server socket serverSocket_ = new ServerSocket(); // Prevent 2MSL delay problem on server restarts serverSocket_.setReuseAddress(true); // Bind to listening port serverSocket_.bind(bindAddr); } catch (IOException ioe) { serverSocket_ = null; throw new TTransportException("Could not create ServerSocket on address " + bindAddr.toString() + "."); } } public void listen() throws TTransportException { // Make sure not to block on accept if (serverSocket_ != null) { try { serverSocket_.setSoTimeout(0); } catch (SocketException sx) { LOGGER.error("Could not set socket timeout.", sx); } } } protected TSocket acceptImpl() throws TTransportException { if (serverSocket_ == null) { throw new TTransportException(TTransportException.NOT_OPEN, "No underlying server socket."); } try { Socket result = serverSocket_.accept(); TSocket result2 = new TSocket(result); result2.setTimeout(clientTimeout_); return result2; } catch (IOException iox) { throw new TTransportException(iox); } } public void close() { if (serverSocket_ != null) { try { serverSocket_.close(); } catch (IOException iox) { LOGGER.warn("Could not close server socket.", iox); } serverSocket_ = null; } } public void interrupt() { // The thread-safeness of this is dubious, but Java documentation suggests // that it is safe to do this from a different thread context close(); } public ServerSocket getServerSocket() { return serverSocket_; } } libthrift-java_0.9.0/src/org/apache/thrift/transport/TTransport.java0000644000175000017500000001117012035665435026423 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; /** * Generic class that encapsulates the I/O layer. This is basically a thin * wrapper around the combined functionality of Java input/output streams. * */ public abstract class TTransport { /** * Queries whether the transport is open. * * @return True if the transport is open. */ public abstract boolean isOpen(); /** * Is there more data to be read? * * @return True if the remote side is still alive and feeding us */ public boolean peek() { return isOpen(); } /** * Opens the transport for reading/writing. * * @throws TTransportException if the transport could not be opened */ public abstract void open() throws TTransportException; /** * Closes the transport. */ public abstract void close(); /** * Reads up to len bytes into buffer buf, starting at offset off. * * @param buf Array to read into * @param off Index to start reading at * @param len Maximum number of bytes to read * @return The number of bytes actually read * @throws TTransportException if there was an error reading data */ public abstract int read(byte[] buf, int off, int len) throws TTransportException; /** * Guarantees that all of len bytes are actually read off the transport. * * @param buf Array to read into * @param off Index to start reading at * @param len Maximum number of bytes to read * @return The number of bytes actually read, which must be equal to len * @throws TTransportException if there was an error reading data */ public int readAll(byte[] buf, int off, int len) throws TTransportException { int got = 0; int ret = 0; while (got < len) { ret = read(buf, off+got, len-got); if (ret <= 0) { throw new TTransportException( "Cannot read. Remote side has closed. Tried to read " + len + " bytes, but only got " + got + " bytes. (This is often indicative of an internal error on the server side. Please check your server logs.)"); } got += ret; } return got; } /** * Writes the buffer to the output * * @param buf The output data buffer * @throws TTransportException if an error occurs writing data */ public void write(byte[] buf) throws TTransportException { write(buf, 0, buf.length); } /** * Writes up to len bytes from the buffer. * * @param buf The output data buffer * @param off The offset to start writing from * @param len The number of bytes to write * @throws TTransportException if there was an error writing data */ public abstract void write(byte[] buf, int off, int len) throws TTransportException; /** * Flush any pending data out of a transport buffer. * * @throws TTransportException if there was an error writing out data. */ public void flush() throws TTransportException {} /** * Access the protocol's underlying buffer directly. If this is not a * buffered transport, return null. * @return protocol's Underlying buffer */ public byte[] getBuffer() { return null; } /** * Return the index within the underlying buffer that specifies the next spot * that should be read from. * @return index within the underlying buffer that specifies the next spot * that should be read from */ public int getBufferPosition() { return 0; } /** * Get the number of bytes remaining in the underlying buffer. Returns -1 if * this is a non-buffered transport. * @return the number of bytes remaining in the underlying buffer.
Returns -1 if * this is a non-buffered transport. */ public int getBytesRemainingInBuffer() { return -1; } /** * Consume len bytes from the underlying buffer. * @param len */ public void consumeBuffer(int len) {} } libthrift-java_0.9.0/src/org/apache/thrift/transport/TNonblockingServerSocket.java0000644000175000017500000001104112035665435031227 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import java.io.IOException; import java.net.InetSocketAddress; import java.net.ServerSocket; import java.net.SocketException; import java.nio.channels.ClosedChannelException; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.ServerSocketChannel; import java.nio.channels.SocketChannel; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Wrapper around ServerSocketChannel */ public class TNonblockingServerSocket extends TNonblockingServerTransport { private static final Logger LOGGER = LoggerFactory.getLogger(TNonblockingServerTransport.class.getName()); /** * This channel is where all the nonblocking magic happens. */ private ServerSocketChannel serverSocketChannel = null; /** * Underlying ServerSocket object */ private ServerSocket serverSocket_ = null; /** * Timeout for client sockets from accept */ private int clientTimeout_ = 0; /** * Creates just a port listening server socket */ public TNonblockingServerSocket(int port) throws TTransportException { this(port, 0); } /** * Creates just a port listening server socket */ public TNonblockingServerSocket(int port, int clientTimeout) throws TTransportException { this(new InetSocketAddress(port), clientTimeout); } public TNonblockingServerSocket(InetSocketAddress bindAddr) throws TTransportException { this(bindAddr, 0); } public TNonblockingServerSocket(InetSocketAddress bindAddr, int clientTimeout) throws TTransportException { clientTimeout_ = clientTimeout; try { serverSocketChannel = ServerSocketChannel.open(); serverSocketChannel.configureBlocking(false); // Make server socket serverSocket_ = serverSocketChannel.socket(); // Prevent 2MSL delay problem on server restarts serverSocket_.setReuseAddress(true); // Bind to listening port serverSocket_.bind(bindAddr); } catch (IOException ioe) { serverSocket_ = null; throw new TTransportException("Could not create ServerSocket on address " + bindAddr.toString() + "."); } } public void listen() throws TTransportException { // Make sure not to block on accept if (serverSocket_ != null) { try { serverSocket_.setSoTimeout(0); } catch (SocketException sx) { sx.printStackTrace(); } } } protected TNonblockingSocket acceptImpl() throws TTransportException { if (serverSocket_ == null) { throw new TTransportException(TTransportException.NOT_OPEN, "No underlying server socket."); } try { SocketChannel socketChannel = serverSocketChannel.accept(); if (socketChannel == null) { return null; } TNonblockingSocket tsocket = new TNonblockingSocket(socketChannel); tsocket.setTimeout(clientTimeout_); return tsocket; } catch (IOException iox) { throw new TTransportException(iox); } } public void registerSelector(Selector selector) { try { // Register the server socket channel, indicating an interest in // accepting new connections serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); } catch (ClosedChannelException e) { // this shouldn't happen, ideally... // TODO: decide what to do with this. } } public void close() { if (serverSocket_ != null) { try { serverSocket_.close(); } catch (IOException iox) { LOGGER.warn("WARNING: Could not close server socket: " + iox.getMessage()); } serverSocket_ = null; } } public void interrupt() { // The thread-safeness of this is dubious, but Java documentation suggests // that it is safe to do this from a different thread context close(); } } libthrift-java_0.9.0/src/org/apache/thrift/transport/TNonblockingSocket.java0000644000175000017500000001414512035665435030050 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import java.io.IOException; import java.net.InetSocketAddress; import java.net.Socket; import java.net.SocketAddress; import java.net.SocketException; import java.nio.ByteBuffer; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.SocketChannel; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Transport for use with async client. */ public class TNonblockingSocket extends TNonblockingTransport { private static final Logger LOGGER = LoggerFactory.getLogger(TNonblockingSocket.class.getName()); /** * Host and port if passed in, used for lazy non-blocking connect. */ private final SocketAddress socketAddress_; private final SocketChannel socketChannel_; public TNonblockingSocket(String host, int port) throws IOException { this(host, port, 0); } /** * Create a new nonblocking socket transport that will be connected to host:port. * @param host * @param port * @throws TTransportException * @throws IOException */ public TNonblockingSocket(String host, int port, int timeout) throws IOException { this(SocketChannel.open(), timeout, new InetSocketAddress(host, port)); } /** * Constructor that takes an already created socket. * * @param socketChannel Already created SocketChannel object * @throws IOException if there is an error setting up the streams */ public TNonblockingSocket(SocketChannel socketChannel) throws IOException { this(socketChannel, 0, null); if (!socketChannel.isConnected()) throw new IOException("Socket must already be connected"); } private TNonblockingSocket(SocketChannel socketChannel, int timeout, SocketAddress socketAddress) throws IOException { socketChannel_ = socketChannel; socketAddress_ = socketAddress; // make it a nonblocking channel socketChannel.configureBlocking(false); // set options Socket socket = socketChannel.socket(); socket.setSoLinger(false, 0); socket.setTcpNoDelay(true); setTimeout(timeout); } /** * Register the new SocketChannel with our Selector, indicating * we'd like to be notified when it's ready for I/O. * * @param selector * @return the selection key for this socket. */ public SelectionKey registerSelector(Selector selector, int interests) throws IOException { return socketChannel_.register(selector, interests); } /** * Sets the socket timeout, although this implementation never uses blocking operations so it is unused. * * @param timeout Milliseconds timeout */ public void setTimeout(int timeout) { try { socketChannel_.socket().setSoTimeout(timeout); } catch (SocketException sx) { LOGGER.warn("Could not set socket timeout.", sx); } } /** * Returns a reference to the underlying SocketChannel. */ public SocketChannel getSocketChannel() { return socketChannel_; } /** * Checks whether the socket is connected. */ public boolean isOpen() { // isConnected() does not return false after close(), but isOpen() does return socketChannel_.isOpen() && socketChannel_.isConnected(); } /** * Do not call, the implementation provides its own lazy non-blocking connect. */ public void open() throws TTransportException { throw new RuntimeException("open() is not implemented for TNonblockingSocket"); } /** * Perform a nonblocking read into buffer. */ public int read(ByteBuffer buffer) throws IOException { return socketChannel_.read(buffer); } /** * Reads from the underlying input stream if not null. */ public int read(byte[] buf, int off, int len) throws TTransportException { if ((socketChannel_.validOps() & SelectionKey.OP_READ) != SelectionKey.OP_READ) { throw new TTransportException(TTransportException.NOT_OPEN, "Cannot read from write-only socket channel"); } try { return socketChannel_.read(ByteBuffer.wrap(buf, off, len)); } catch (IOException iox) { throw new TTransportException(TTransportException.UNKNOWN, iox); } } /** * Perform a nonblocking write of the data in buffer; */ public int write(ByteBuffer buffer) throws IOException { return socketChannel_.write(buffer); } /** * Writes to the underlying output stream if not null. */ public void write(byte[] buf, int off, int len) throws TTransportException { if ((socketChannel_.validOps() & SelectionKey.OP_WRITE) != SelectionKey.OP_WRITE) { throw new TTransportException(TTransportException.NOT_OPEN, "Cannot write to write-only socket channel"); } try { socketChannel_.write(ByteBuffer.wrap(buf, off, len)); } catch (IOException iox) { throw new TTransportException(TTransportException.UNKNOWN, iox); } } /** * Noop. */ public void flush() throws TTransportException { // Not supported by SocketChannel. } /** * Closes the socket. */ public void close() { try { socketChannel_.close(); } catch (IOException iox) { LOGGER.warn("Could not close socket.", iox); } } /** {@inheritDoc} */ public boolean startConnect() throws IOException { return socketChannel_.connect(socketAddress_); } /** {@inheritDoc} */ public boolean finishConnect() throws IOException { return socketChannel_.finishConnect(); } } libthrift-java_0.9.0/src/org/apache/thrift/transport/TNonblockingServerTransport.java0000644000175000017500000000210712035665435031776 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.transport; import java.nio.channels.Selector; /** * Server transport that can be operated in a nonblocking fashion. */ public abstract class TNonblockingServerTransport extends TServerTransport { public abstract void registerSelector(Selector selector); } libthrift-java_0.9.0/src/org/apache/thrift/TProcessorFactory.java0000644000175000017500000000226012035665435025702 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; import org.apache.thrift.transport.TTransport; /** * The default processor factory just returns a singleton * instance. */ public class TProcessorFactory { private final TProcessor processor_; public TProcessorFactory(TProcessor processor) { processor_ = processor; } public TProcessor getProcessor(TTransport trans) { return processor_; } } libthrift-java_0.9.0/src/org/apache/thrift/TServiceClientFactory.java0000644000175000017500000000314512035665435026465 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; import org.apache.thrift.protocol.TProtocol; /** * A TServiceClientFactory provides a general way to get a TServiceClient * connected to a remote TService via a protocol. * @param */ public interface TServiceClientFactory { /** * Get a brand-new T using prot as both the input and output protocol. * @param prot * @return A brand-new T using prot as both the input and output protocol. */ public T getClient(TProtocol prot); /** * Get a brand new T using the specified input and output protocols. The * input and output protocols may be the same instance. * @param iprot * @param oprot * @return a brand new T using the specified input and output protocols */ public T getClient(TProtocol iprot, TProtocol oprot); } libthrift-java_0.9.0/src/org/apache/thrift/TException.java0000644000175000017500000000232312035665435024331 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; /** * Generic exception class for Thrift. * */ public class TException extends Exception { private static final long serialVersionUID = 1L; public TException() { super(); } public TException(String message) { super(message); } public TException(Throwable cause) { super(cause); } public TException(String message, Throwable cause) { super(message, cause); } } libthrift-java_0.9.0/src/org/apache/thrift/TEnum.java0000644000175000017500000000156512035665435023306 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; public interface TEnum { public int getValue(); } libthrift-java_0.9.0/src/org/apache/thrift/scheme/0000755000175000017500000000000012035665714022650 5ustar eevanseevans00000000000000libthrift-java_0.9.0/src/org/apache/thrift/scheme/StandardScheme.java0000644000175000017500000000167112035665435026405 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.scheme; import org.apache.thrift.TBase; public abstract class StandardScheme implements IScheme { } libthrift-java_0.9.0/src/org/apache/thrift/scheme/IScheme.java0000644000175000017500000000217012035665435025030 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.scheme; import org.apache.thrift.TBase; public interface IScheme { public void read(org.apache.thrift.protocol.TProtocol iproto, T struct) throws org.apache.thrift.TException; public void write(org.apache.thrift.protocol.TProtocol oproto, T struct) throws org.apache.thrift.TException; } libthrift-java_0.9.0/src/org/apache/thrift/scheme/SchemeFactory.java0000644000175000017500000000163012035665435026247 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.scheme; public interface SchemeFactory { public S getScheme(); } libthrift-java_0.9.0/src/org/apache/thrift/scheme/TupleScheme.java0000644000175000017500000000166612035665435025742 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.scheme; import org.apache.thrift.TBase; public abstract class TupleScheme implements IScheme { } libthrift-java_0.9.0/src/org/apache/thrift/TSerializer.java0000644000175000017500000000636312035665435024514 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; import java.io.ByteArrayOutputStream; import java.io.UnsupportedEncodingException; import org.apache.thrift.protocol.TBinaryProtocol; import org.apache.thrift.protocol.TProtocol; import org.apache.thrift.protocol.TProtocolFactory; import org.apache.thrift.transport.TIOStreamTransport; /** * Generic utility for easily serializing objects into a byte array or Java * String. * */ public class TSerializer { /** * This is the byte array that data is actually serialized into */ private final ByteArrayOutputStream baos_ = new ByteArrayOutputStream(); /** * This transport wraps that byte array */ private final TIOStreamTransport transport_ = new TIOStreamTransport(baos_); /** * Internal protocol used for serializing objects. */ private TProtocol protocol_; /** * Create a new TSerializer that uses the TBinaryProtocol by default. */ public TSerializer() { this(new TBinaryProtocol.Factory()); } /** * Create a new TSerializer. It will use the TProtocol specified by the * factory that is passed in. * * @param protocolFactory Factory to create a protocol */ public TSerializer(TProtocolFactory protocolFactory) { protocol_ = protocolFactory.getProtocol(transport_); } /** * Serialize the Thrift object into a byte array. The process is simple, * just clear the byte array output, write the object into it, and grab the * raw bytes. * * @param base The object to serialize * @return Serialized object in byte[] format */ public byte[] serialize(TBase base) throws TException { baos_.reset(); base.write(protocol_); return baos_.toByteArray(); } /** * Serialize the Thrift object into a Java string, using a specified * character set for encoding. * * @param base The object to serialize * @param charset Valid JVM charset * @return Serialized object as a String */ public String toString(TBase base, String charset) throws TException { try { return new String(serialize(base), charset); } catch (UnsupportedEncodingException uex) { throw new TException("JVM DOES NOT SUPPORT ENCODING: " + charset); } } /** * Serialize the Thrift object into a Java string, using the default JVM * charset encoding. * * @param base The object to serialize * @return Serialized object as a String */ public String toString(TBase base) throws TException { return new String(serialize(base)); } } libthrift-java_0.9.0/src/org/apache/thrift/TUnion.java0000644000175000017500000002042212035665435023463 0ustar eevanseevans00000000000000/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.thrift; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; import org.apache.thrift.protocol.TField; import org.apache.thrift.protocol.TProtocol; import org.apache.thrift.protocol.TProtocolException; import org.apache.thrift.protocol.TStruct; import org.apache.thrift.scheme.IScheme; import org.apache.thrift.scheme.SchemeFactory; import org.apache.thrift.scheme.StandardScheme; import org.apache.thrift.scheme.TupleScheme; public abstract class TUnion, F extends TFieldIdEnum> implements TBase { protected Object value_; protected F setField_; protected TUnion() { setField_ = null; value_ = null; } private static final Map, SchemeFactory> schemes = new HashMap, SchemeFactory>(); static { schemes.put(StandardScheme.class, new TUnionStandardSchemeFactory()); schemes.put(TupleScheme.class, new TUnionTupleSchemeFactory()); } protected TUnion(F setField, Object value) { setFieldValue(setField, value); } protected TUnion(TUnion other) { if (!other.getClass().equals(this.getClass())) { throw new ClassCastException(); } setField_ = other.setField_; value_ = deepCopyObject(other.value_); } private static Object deepCopyObject(Object o) { if (o instanceof TBase) { return ((TBase)o).deepCopy(); } else if (o instanceof ByteBuffer) { return TBaseHelper.copyBinary((ByteBuffer)o); } else if (o instanceof List) { return deepCopyList((List)o); } else if (o instanceof Set) { return deepCopySet((Set)o); } else if (o instanceof Map) { return deepCopyMap((Map)o); } else { return o; } } private static Map deepCopyMap(Map map) { Map copy = new HashMap(); for (Map.Entry entry : map.entrySet()) { copy.put(deepCopyObject(entry.getKey()), deepCopyObject(entry.getValue())); } return copy; } private static Set deepCopySet(Set set) { Set copy = new HashSet(); for (Object o : set) { copy.add(deepCopyObject(o)); } return copy; } private static List deepCopyList(List list) { List copy = new ArrayList(list.size()); for (Object o : list) { copy.add(deepCopyObject(o)); } return copy; } public F getSetField() { return setField_; } public Object getFieldValue() { return value_; } public Object getFieldValue(F fieldId) { if (fieldId != setField_) { throw new IllegalArgumentException("Cannot get the value of field " + fieldId + " because union's set field is " + setField_); } return getFieldValue(); } public Object getFieldValue(int fieldId) { return getFieldValue(enumForId((short)fieldId)); } public boolean isSet() { return setField_ != null; } public boolean isSet(F fieldId) { return setField_ == fieldId; } public boolean isSet(int fieldId) { return isSet(enumForId((short)fieldId)); } public void read(TProtocol iprot) throws TException { schemes.get(iprot.getScheme()).getScheme().read(iprot, this); } public void setFieldValue(F fieldId, Object value) { checkType(fieldId, value); setField_ = fieldId; value_ = value; } public void setFieldValue(int fieldId, Object value) { setFieldValue(enumForId((short)fieldId), value); } public void write(TProtocol oprot) throws TException { schemes.get(oprot.getScheme()).getScheme().write(oprot, this); } /** * Implementation should be generated so that we can efficiently type check * various values. * @param setField * @param value */ protected abstract void checkType(F setField, Object value) throws ClassCastException; /** * Implementation should be generated to read the right stuff from the wire * based on the field header. * @param field * @return read Object based on the field header, as specified by the argument. */ protected abstract Object standardSchemeReadValue(TProtocol iprot, TField field) throws TException; protected abstract void standardSchemeWriteValue(TProtocol oprot) throws TException; protected abstract Object tupleSchemeReadValue(TProtocol iprot, short fieldID) throws TException; protected abstract void tupleSchemeWriteValue(TProtocol oprot) throws TException; protected abstract TStruct getStructDesc(); protected abstract TField getFieldDesc(F setField); protected abstract F enumForId(short id); @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append("<"); sb.append(this.getClass().getSimpleName()); sb.append(" "); if (getSetField() != null) { Object v = getFieldValue(); sb.append(getFieldDesc(getSetField()).name); sb.append(":"); if(v instanceof ByteBuffer) { TBaseHelper.toString((ByteBuffer)v, sb); } else { sb.append(v.toString()); } } sb.append(">"); return sb.toString(); } public final void clear() { this.setField_ = null; this.value_ = null; } private static class TUnionStandardSchemeFactory implements SchemeFactory { public TUnionStandardScheme getScheme() { return new TUnionStandardScheme(); } } private static class TUnionStandardScheme extends StandardScheme { @Override public void read(TProtocol iprot, TUnion struct) throws TException { struct.setField_ = null; struct.value_ = null; iprot.readStructBegin(); TField field = iprot.readFieldBegin(); struct.value_ = struct.standardSchemeReadValue(iprot, field); if (struct.value_ != null) { struct.setField_ = struct.enumForId(field.id); } iprot.readFieldEnd(); // this is so that we will eat the stop byte. we could put a check here to // make sure that it actually *is* the stop byte, but it's faster to do it // this way. iprot.readFieldBegin(); iprot.readStructEnd(); } @Override public void write(TProtocol oprot, TUnion struct) throws TException { if (struct.getSetField() == null || struct.getFieldValue() == null) { throw new TProtocolException("Cannot write a TUnion with no set value!"); } oprot.writeStructBegin(struct.getStructDesc()); oprot.writeFieldBegin(struct.getFieldDesc(struct.setField_)); struct.standardSchemeWriteValue(oprot); oprot.writeFieldEnd(); oprot.writeFieldStop(); oprot.writeStructEnd(); } } private static class TUnionTupleSchemeFactory implements SchemeFactory { public TUnionTupleScheme getScheme() { return new TUnionTupleScheme(); } } private static class TUnionTupleScheme extends TupleScheme { @Override public void read(TProtocol iprot, TUnion struct) throws TException { struct.setField_ = null; struct.value_ = null; short fieldID = iprot.readI16(); struct.value_ = struct.tupleSchemeReadValue(iprot, fieldID); if (struct.value_ != null) { struct.setField_ = struct.enumForId(fieldID); } } @Override public void write(TProtocol oprot, TUnion struct) throws TException { if (struct.getSetField() == null || struct.getFieldValue() == null) { throw new TProtocolException("Cannot write a TUnion with no set value!"); } oprot.writeI16(struct.setField_.getThriftFieldId()); struct.tupleSchemeWriteValue(oprot); } } } libthrift-java_0.9.0/src/org/apache/thrift/ShortStack.java0000644000175000017500000000406212035665435024336 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; /** * ShortStack is a short-specific Stack implementation written for the express * purpose of very fast operations on TCompactProtocol's field id stack. This * implementation performs at least 10x faster than java.util.Stack. */ public class ShortStack { private short[] vector; private int top = -1; public ShortStack(int initialCapacity) { vector = new short[initialCapacity]; } public short pop() { return vector[top--]; } public void push(short pushed) { if (vector.length == top + 1) { grow(); } vector[++top] = pushed; } private void grow() { short[] newVector = new short[vector.length * 2]; System.arraycopy(vector, 0, newVector, 0, vector.length); vector = newVector; } public short peek() { return vector[top]; } public void clear() { top = -1; } @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append(">"); } sb.append(vector[i]); if (i == top) { sb.append("<<"); } } sb.append("]>"); return sb.toString(); } } libthrift-java_0.9.0/src/org/apache/thrift/TByteArrayOutputStream.java0000644000175000017500000000233712035665435026677 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift; import java.io.ByteArrayOutputStream; /** * Class that allows access to the underlying buf without doing deep * copies on it. * */ public class TByteArrayOutputStream extends ByteArrayOutputStream { public TByteArrayOutputStream(int size) { super(size); } public TByteArrayOutputStream() { super(); } public byte[] get() { return buf; } public int len() { return count; } } libthrift-java_0.9.0/src/org/apache/thrift/server/0000755000175000017500000000000012035665714022712 5ustar eevanseevans00000000000000libthrift-java_0.9.0/src/org/apache/thrift/server/TThreadPoolServer.java0000644000175000017500000001567312035665435027145 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.server; import java.util.concurrent.ExecutorService; import java.util.concurrent.SynchronousQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import org.apache.thrift.TException; import org.apache.thrift.TProcessor; import org.apache.thrift.protocol.TProtocol; import org.apache.thrift.transport.TServerTransport; import org.apache.thrift.transport.TTransport; import org.apache.thrift.transport.TTransportException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Server which uses Java's built in ThreadPool management to spawn off * a worker pool that * */ public class TThreadPoolServer extends TServer { private static final Logger LOGGER = LoggerFactory.getLogger(TThreadPoolServer.class.getName()); public static class Args extends AbstractServerArgs { public int minWorkerThreads = 5; public int maxWorkerThreads = Integer.MAX_VALUE; public ExecutorService executorService; public int stopTimeoutVal = 60; public TimeUnit stopTimeoutUnit = TimeUnit.SECONDS; public Args(TServerTransport transport) { super(transport); } public Args minWorkerThreads(int n) { minWorkerThreads = n; return this; } public Args maxWorkerThreads(int n) { maxWorkerThreads = n; return this; } public Args executorService(ExecutorService executorService) { this.executorService = executorService; return this; } } // Executor service for handling client connections private ExecutorService executorService_; // Flag for stopping the server private volatile boolean stopped_; private final TimeUnit stopTimeoutUnit; private final long stopTimeoutVal; public TThreadPoolServer(Args args) { super(args); stopTimeoutUnit = args.stopTimeoutUnit; stopTimeoutVal = args.stopTimeoutVal; executorService_ = args.executorService != null ? args.executorService : createDefaultExecutorService(args); } private static ExecutorService createDefaultExecutorService(Args args) { SynchronousQueue executorQueue = new SynchronousQueue(); return new ThreadPoolExecutor(args.minWorkerThreads, args.maxWorkerThreads, 60, TimeUnit.SECONDS, executorQueue); } public void serve() { try { serverTransport_.listen(); } catch (TTransportException ttx) { LOGGER.error("Error occurred during listening.", ttx); return; } // Run the preServe event if (eventHandler_ != null) { eventHandler_.preServe(); } stopped_ = false; setServing(true); while (!stopped_) { int failureCount = 0; try { TTransport client = serverTransport_.accept(); WorkerProcess wp = new WorkerProcess(client); executorService_.execute(wp); } catch (TTransportException ttx) { if (!stopped_) { ++failureCount; LOGGER.warn("Transport error occurred during acceptance of message.", ttx); } } } executorService_.shutdown(); // Loop until awaitTermination finally does return without a interrupted // exception. If we don't do this, then we'll shut down prematurely. We want // to let the executorService clear it's task queue, closing client sockets // appropriately. long timeoutMS = stopTimeoutUnit.toMillis(stopTimeoutVal); long now = System.currentTimeMillis(); while (timeoutMS >= 0) { try { executorService_.awaitTermination(timeoutMS, TimeUnit.MILLISECONDS); break; } catch (InterruptedException ix) { long newnow = System.currentTimeMillis(); timeoutMS -= (newnow - now); now = newnow; } } setServing(false); } public void stop() { stopped_ = true; serverTransport_.interrupt(); } private class WorkerProcess implements Runnable { /** * Client that this services. */ private TTransport client_; /** * Default constructor. * * @param client Transport to process */ private WorkerProcess(TTransport client) { client_ = client; } /** * Loops on processing a client forever */ public void run() { TProcessor processor = null; TTransport inputTransport = null; TTransport outputTransport = null; TProtocol inputProtocol = null; TProtocol outputProtocol = null; TServerEventHandler eventHandler = null; ServerContext connectionContext = null; try { processor = processorFactory_.getProcessor(client_); inputTransport = inputTransportFactory_.getTransport(client_); outputTransport = outputTransportFactory_.getTransport(client_); inputProtocol = inputProtocolFactory_.getProtocol(inputTransport); outputProtocol = outputProtocolFactory_.getProtocol(outputTransport); eventHandler = getEventHandler(); if (eventHandler != null) { connectionContext = eventHandler.createContext(inputProtocol, outputProtocol); } // we check stopped_ first to make sure we're not supposed to be shutting // down. this is necessary for graceful shutdown. while (true) { if (eventHandler != null) { eventHandler.processContext(connectionContext, inputTransport, outputTransport); } if(stopped_ || !processor.process(inputProtocol, outputProtocol)) { break; } } } catch (TTransportException ttx) { // Assume the client died and continue silently } catch (TException tx) { LOGGER.error("Thrift error occurred during processing of message.", tx); } catch (Exception x) { LOGGER.error("Error occurred during processing of message.", x); } if (eventHandler != null) { eventHandler.deleteContext(connectionContext, inputProtocol, outputProtocol); } if (inputTransport != null) { inputTransport.close(); } if (outputTransport != null) { outputTransport.close(); } } } } libthrift-java_0.9.0/src/org/apache/thrift/server/TServerEventHandler.java0000644000175000017500000000371512035665435027455 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.server; import org.apache.thrift.protocol.TProtocol; import org.apache.thrift.transport.TTransport; /** * Interface that can handle events from the server core. To * use this you should subclass it and implement the methods that you care * about. Your subclass can also store local data that you may care about, * such as additional "arguments" to these methods (stored in the object * instance's state). */ public interface TServerEventHandler { /** * Called before the server begins. */ void preServe(); /** * Called when a new client has connected and is about to being processing. */ ServerContext createContext(TProtocol input, TProtocol output); /** * Called when a client has finished request-handling to delete server * context. */ void deleteContext(ServerContext serverContext, TProtocol input, TProtocol output); /** * Called when a client is about to call the processor. */ void processContext(ServerContext serverContext, TTransport inputTransport, TTransport outputTransport); }libthrift-java_0.9.0/src/org/apache/thrift/server/THsHaServer.java0000644000175000017500000001164212035665435025717 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.server; import java.util.concurrent.ExecutorService; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import org.apache.thrift.transport.TNonblockingServerTransport; /** * An extension of the TNonblockingServer to a Half-Sync/Half-Async server. * Like TNonblockingServer, it relies on the use of TFramedTransport. */ public class THsHaServer extends TNonblockingServer { public static class Args extends AbstractNonblockingServerArgs { private int workerThreads = 5; private int stopTimeoutVal = 60; private TimeUnit stopTimeoutUnit = TimeUnit.SECONDS; private ExecutorService executorService = null; public Args(TNonblockingServerTransport transport) { super(transport); } public Args workerThreads(int i) { workerThreads = i; return this; } public int getWorkerThreads() { return workerThreads; } public int getStopTimeoutVal() { return stopTimeoutVal; } public Args stopTimeoutVal(int stopTimeoutVal) { this.stopTimeoutVal = stopTimeoutVal; return this; } public TimeUnit getStopTimeoutUnit() { return stopTimeoutUnit; } public Args stopTimeoutUnit(TimeUnit stopTimeoutUnit) { this.stopTimeoutUnit = stopTimeoutUnit; return this; } public ExecutorService getExecutorService() { return executorService; } public Args executorService(ExecutorService executorService) { this.executorService = executorService; return this; } } // This wraps all the functionality of queueing and thread pool management // for the passing of Invocations from the Selector to workers. private final ExecutorService invoker; private final Args args; /** * Create the server with the specified Args configuration */ public THsHaServer(Args args) { super(args); invoker = args.executorService == null ? createInvokerPool(args) : args.executorService; this.args = args; } /** * @inheritDoc */ @Override protected void waitForShutdown() { joinSelector(); gracefullyShutdownInvokerPool(); } /** * Helper to create an invoker pool */ protected static ExecutorService createInvokerPool(Args options) { int workerThreads = options.workerThreads; int stopTimeoutVal = options.stopTimeoutVal; TimeUnit stopTimeoutUnit = options.stopTimeoutUnit; LinkedBlockingQueue queue = new LinkedBlockingQueue(); ExecutorService invoker = new ThreadPoolExecutor(workerThreads, workerThreads, stopTimeoutVal, stopTimeoutUnit, queue); return invoker; } protected void gracefullyShutdownInvokerPool() { // try to gracefully shut down the executor service invoker.shutdown(); // Loop until awaitTermination finally does return without a interrupted // exception. If we don't do this, then we'll shut down prematurely. We want // to let the executorService clear it's task queue, closing client sockets // appropriately. long timeoutMS = args.stopTimeoutUnit.toMillis(args.stopTimeoutVal); long now = System.currentTimeMillis(); while (timeoutMS >= 0) { try { invoker.awaitTermination(timeoutMS, TimeUnit.MILLISECONDS); break; } catch (InterruptedException ix) { long newnow = System.currentTimeMillis(); timeoutMS -= (newnow - now); now = newnow; } } } /** * We override the standard invoke method here to queue the invocation for * invoker service instead of immediately invoking. The thread pool takes care * of the rest. */ @Override protected boolean requestInvoke(FrameBuffer frameBuffer) { try { Runnable invocation = getRunnable(frameBuffer); invoker.execute(invocation); return true; } catch (RejectedExecutionException rx) { LOGGER.warn("ExecutorService rejected execution!", rx); return false; } } protected Runnable getRunnable(FrameBuffer frameBuffer){ return new Invocation(frameBuffer); } } libthrift-java_0.9.0/src/org/apache/thrift/server/TServlet.java0000644000175000017500000000652012035665435025330 0ustar eevanseevans00000000000000package org.apache.thrift.server; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.Collection; import java.util.Map; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.thrift.TException; import org.apache.thrift.TProcessor; import org.apache.thrift.protocol.TProtocol; import org.apache.thrift.protocol.TProtocolFactory; import org.apache.thrift.transport.TIOStreamTransport; import org.apache.thrift.transport.TTransport; /** * Servlet implementation class ThriftServer */ public class TServlet extends HttpServlet { private final TProcessor processor; private final TProtocolFactory inProtocolFactory; private final TProtocolFactory outProtocolFactory; private final Collection> customHeaders; /** * @see HttpServlet#HttpServlet() */ public TServlet(TProcessor processor, TProtocolFactory inProtocolFactory, TProtocolFactory outProtocolFactory) { super(); this.processor = processor; this.inProtocolFactory = inProtocolFactory; this.outProtocolFactory = outProtocolFactory; this.customHeaders = new ArrayList>(); } /** * @see HttpServlet#HttpServlet() */ public TServlet(TProcessor processor, TProtocolFactory protocolFactory) { this(processor, protocolFactory, protocolFactory); } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse * response) */ @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { TTransport inTransport = null; TTransport outTransport = null; try { response.setContentType("application/x-thrift"); if (null != this.customHeaders) { for (Map.Entry header : this.customHeaders) { response.addHeader(header.getKey(), header.getValue()); } } InputStream in = request.getInputStream(); OutputStream out = response.getOutputStream(); TTransport transport = new TIOStreamTransport(in, out); inTransport = transport; outTransport = transport; TProtocol inProtocol = inProtocolFactory.getProtocol(inTransport); TProtocol outProtocol = outProtocolFactory.getProtocol(outTransport); processor.process(inProtocol, outProtocol); out.flush(); } catch (TException te) { throw new ServletException(te); } } /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse * response) */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } public void addCustomHeader(final String key, final String value) { this.customHeaders.add(new Map.Entry() { public String getKey() { return key; } public String getValue() { return value; } public String setValue(String value) { return null; } }); } public void setCustomHeaders(Collection> headers) { this.customHeaders.clear(); this.customHeaders.addAll(headers); } } libthrift-java_0.9.0/src/org/apache/thrift/server/TSimpleServer.java0000644000175000017500000000723012035665435026323 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.server; import org.apache.thrift.TException; import org.apache.thrift.TProcessor; import org.apache.thrift.protocol.TProtocol; import org.apache.thrift.transport.TTransport; import org.apache.thrift.transport.TTransportException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Simple singlethreaded server for testing. * */ public class TSimpleServer extends TServer { private static final Logger LOGGER = LoggerFactory.getLogger(TSimpleServer.class.getName()); private boolean stopped_ = false; public TSimpleServer(AbstractServerArgs args) { super(args); } public void serve() { stopped_ = false; try { serverTransport_.listen(); } catch (TTransportException ttx) { LOGGER.error("Error occurred during listening.", ttx); return; } // Run the preServe event if (eventHandler_ != null) { eventHandler_.preServe(); } setServing(true); while (!stopped_) { TTransport client = null; TProcessor processor = null; TTransport inputTransport = null; TTransport outputTransport = null; TProtocol inputProtocol = null; TProtocol outputProtocol = null; ServerContext connectionContext = null; try { client = serverTransport_.accept(); if (client != null) { processor = processorFactory_.getProcessor(client); inputTransport = inputTransportFactory_.getTransport(client); outputTransport = outputTransportFactory_.getTransport(client); inputProtocol = inputProtocolFactory_.getProtocol(inputTransport); outputProtocol = outputProtocolFactory_.getProtocol(outputTransport); if (eventHandler_ != null) { connectionContext = eventHandler_.createContext(inputProtocol, outputProtocol); } while (true) { if (eventHandler_ != null) { eventHandler_.processContext(connectionContext, inputTransport, outputTransport); } if(!processor.process(inputProtocol, outputProtocol)) { break; } } } } catch (TTransportException ttx) { // Client died, just move on } catch (TException tx) { if (!stopped_) { LOGGER.error("Thrift error occurred during processing of message.", tx); } } catch (Exception x) { if (!stopped_) { LOGGER.error("Error occurred during processing of message.", x); } } if (eventHandler_ != null) { eventHandler_.deleteContext(connectionContext, inputProtocol, outputProtocol); } if (inputTransport != null) { inputTransport.close(); } if (outputTransport != null) { outputTransport.close(); } } setServing(false); } public void stop() { stopped_ = true; serverTransport_.interrupt(); } } libthrift-java_0.9.0/src/org/apache/thrift/server/TExtensibleServlet.java0000644000175000017500000001230312035665435027347 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.server; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; import java.util.Collection; import java.util.Map; import javax.servlet.ServletConfig; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.thrift.TException; import org.apache.thrift.TProcessor; import org.apache.thrift.protocol.TProtocol; import org.apache.thrift.protocol.TProtocolFactory; import org.apache.thrift.transport.TIOStreamTransport; import org.apache.thrift.transport.TTransport; /** * Servlet implementation class ThriftServer, that allows {@link TProcessor} and * {@link TProtocolFactory} to be supplied after the {@link #init()} method has * finished.
* Subclasses must implement the abstract methods that return the TProcessor and * two TProtocolFactory. Those methods are guaranteed to be called exactly once, * and that {@link ServletContext} is available. */ public abstract class TExtensibleServlet extends HttpServlet { private static final long serialVersionUID = 1L; private TProcessor processor; private TProtocolFactory inFactory; private TProtocolFactory outFactory; private Collection> customHeaders; /** * Returns the appropriate {@link TProcessor}. This will be called once just * after the {@link #init()} method * * @return */ protected abstract TProcessor getProcessor(); /** * Returns the appropriate in {@link TProtocolFactory}. This will be called * once just after the {@link #init()} method * * @return */ protected abstract TProtocolFactory getInProtocolFactory(); /** * Returns the appropriate out {@link TProtocolFactory}. This will be called * once just after the {@link #init()} method * * @return */ protected abstract TProtocolFactory getOutProtocolFactory(); @Override public final void init(ServletConfig config) throws ServletException { super.init(config); //no-args init() happens here this.processor = getProcessor(); this.inFactory = getInProtocolFactory(); this.outFactory = getOutProtocolFactory(); this.customHeaders = new ArrayList>(); if (processor == null) { throw new ServletException("processor must be set"); } if (inFactory == null) { throw new ServletException("inFactory must be set"); } if (outFactory == null) { throw new ServletException("outFactory must be set"); } } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse * response) */ @Override protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { TTransport inTransport = null; TTransport outTransport = null; try { response.setContentType("application/x-thrift"); if (null != this.customHeaders) { for (Map.Entry header : this.customHeaders) { response.addHeader(header.getKey(), header.getValue()); } } InputStream in = request.getInputStream(); OutputStream out = response.getOutputStream(); TTransport transport = new TIOStreamTransport(in, out); inTransport = transport; outTransport = transport; TProtocol inProtocol = inFactory.getProtocol(inTransport); TProtocol outProtocol = inFactory.getProtocol(outTransport); processor.process(inProtocol, outProtocol); out.flush(); } catch (TException te) { throw new ServletException(te); } } /** * @see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse * response) */ @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doPost(req, resp); } public void addCustomHeader(final String key, final String value) { this.customHeaders.add(new Map.Entry() { public String getKey() { return key; } public String getValue() { return value; } public String setValue(String value) { return null; } }); } public void setCustomHeaders(Collection> headers) { this.customHeaders.clear(); this.customHeaders.addAll(headers); } } libthrift-java_0.9.0/src/org/apache/thrift/server/AbstractNonblockingServer.java0000644000175000017500000004510512035665435030700 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.server; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.spi.SelectorProvider; import java.util.HashSet; import java.util.Set; import java.util.concurrent.atomic.AtomicLong; import org.apache.thrift.TByteArrayOutputStream; import org.apache.thrift.TException; import org.apache.thrift.protocol.TProtocol; import org.apache.thrift.transport.TFramedTransport; import org.apache.thrift.transport.TIOStreamTransport; import org.apache.thrift.transport.TMemoryInputTransport; import org.apache.thrift.transport.TNonblockingServerTransport; import org.apache.thrift.transport.TNonblockingTransport; import org.apache.thrift.transport.TTransport; import org.apache.thrift.transport.TTransportException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Provides common methods and classes used by nonblocking TServer * implementations. */ public abstract class AbstractNonblockingServer extends TServer { protected final Logger LOGGER = LoggerFactory.getLogger(getClass().getName()); public static abstract class AbstractNonblockingServerArgs> extends AbstractServerArgs { public long maxReadBufferBytes = Long.MAX_VALUE; public AbstractNonblockingServerArgs(TNonblockingServerTransport transport) { super(transport); transportFactory(new TFramedTransport.Factory()); } } /** * The maximum amount of memory we will allocate to client IO buffers at a * time. Without this limit, the server will gladly allocate client buffers * right into an out of memory exception, rather than waiting. */ private final long MAX_READ_BUFFER_BYTES; /** * How many bytes are currently allocated to read buffers. */ private final AtomicLong readBufferBytesAllocated = new AtomicLong(0); public AbstractNonblockingServer(AbstractNonblockingServerArgs args) { super(args); MAX_READ_BUFFER_BYTES = args.maxReadBufferBytes; } /** * Begin accepting connections and processing invocations. */ public void serve() { // start any IO threads if (!startThreads()) { return; } // start listening, or exit if (!startListening()) { return; } setServing(true); // this will block while we serve waitForShutdown(); setServing(false); // do a little cleanup stopListening(); } /** * Starts any threads required for serving. * * @return true if everything went ok, false if threads could not be started. */ protected abstract boolean startThreads(); /** * A method that will block until when threads handling the serving have been * shut down. */ protected abstract void waitForShutdown(); /** * Have the server transport start accepting connections. * * @return true if we started listening successfully, false if something went * wrong. */ protected boolean startListening() { try { serverTransport_.listen(); return true; } catch (TTransportException ttx) { LOGGER.error("Failed to start listening on server socket!", ttx); return false; } } /** * Stop listening for connections. */ protected void stopListening() { serverTransport_.close(); } /** * Perform an invocation. This method could behave several different ways - * invoke immediately inline, queue for separate execution, etc. * * @return true if invocation was successfully requested, which is not a * guarantee that invocation has completed. False if the request * failed. */ protected abstract boolean requestInvoke(FrameBuffer frameBuffer); /** * An abstract thread that handles selecting on a set of transports and * {@link FrameBuffer FrameBuffers} associated with selected keys * corresponding to requests. */ protected abstract class AbstractSelectThread extends Thread { protected final Selector selector; // List of FrameBuffers that want to change their selection interests. protected final Set selectInterestChanges = new HashSet(); public AbstractSelectThread() throws IOException { this.selector = SelectorProvider.provider().openSelector(); } /** * If the selector is blocked, wake it up. */ public void wakeupSelector() { selector.wakeup(); } /** * Add FrameBuffer to the list of select interest changes and wake up the * selector if it's blocked. When the select() call exits, it'll give the * FrameBuffer a chance to change its interests. */ public void requestSelectInterestChange(FrameBuffer frameBuffer) { synchronized (selectInterestChanges) { selectInterestChanges.add(frameBuffer); } // wakeup the selector, if it's currently blocked. selector.wakeup(); } /** * Check to see if there are any FrameBuffers that have switched their * interest type from read to write or vice versa. */ protected void processInterestChanges() { synchronized (selectInterestChanges) { for (FrameBuffer fb : selectInterestChanges) { fb.changeSelectInterests(); } selectInterestChanges.clear(); } } /** * Do the work required to read from a readable client. If the frame is * fully read, then invoke the method call. */ protected void handleRead(SelectionKey key) { FrameBuffer buffer = (FrameBuffer) key.attachment(); if (!buffer.read()) { cleanupSelectionKey(key); return; } // if the buffer's frame read is complete, invoke the method. if (buffer.isFrameFullyRead()) { if (!requestInvoke(buffer)) { cleanupSelectionKey(key); } } } /** * Let a writable client get written, if there's data to be written. */ protected void handleWrite(SelectionKey key) { FrameBuffer buffer = (FrameBuffer) key.attachment(); if (!buffer.write()) { cleanupSelectionKey(key); } } /** * Do connection-close cleanup on a given SelectionKey. */ protected void cleanupSelectionKey(SelectionKey key) { // remove the records from the two maps FrameBuffer buffer = (FrameBuffer) key.attachment(); if (buffer != null) { // close the buffer buffer.close(); } // cancel the selection key key.cancel(); } } // SelectThread /** * Possible states for the FrameBuffer state machine. */ private enum FrameBufferState { // in the midst of reading the frame size off the wire READING_FRAME_SIZE, // reading the actual frame data now, but not all the way done yet READING_FRAME, // completely read the frame, so an invocation can now happen READ_FRAME_COMPLETE, // waiting to get switched to listening for write events AWAITING_REGISTER_WRITE, // started writing response data, not fully complete yet WRITING, // another thread wants this framebuffer to go back to reading AWAITING_REGISTER_READ, // we want our transport and selection key invalidated in the selector // thread AWAITING_CLOSE } /** * Class that implements a sort of state machine around the interaction with a * client and an invoker. It manages reading the frame size and frame data, * getting it handed off as wrapped transports, and then the writing of * response data back to the client. In the process it manages flipping the * read and write bits on the selection key for its client. */ protected class FrameBuffer { // the actual transport hooked up to the client. public final TNonblockingTransport trans_; // the SelectionKey that corresponds to our transport private final SelectionKey selectionKey_; // the SelectThread that owns the registration of our transport private final AbstractSelectThread selectThread_; // where in the process of reading/writing are we? private FrameBufferState state_ = FrameBufferState.READING_FRAME_SIZE; // the ByteBuffer we'll be using to write and read, depending on the state private ByteBuffer buffer_; private TByteArrayOutputStream response_; public FrameBuffer(final TNonblockingTransport trans, final SelectionKey selectionKey, final AbstractSelectThread selectThread) { trans_ = trans; selectionKey_ = selectionKey; selectThread_ = selectThread; buffer_ = ByteBuffer.allocate(4); } /** * Give this FrameBuffer a chance to read. The selector loop should have * received a read event for this FrameBuffer. * * @return true if the connection should live on, false if it should be * closed */ public boolean read() { if (state_ == FrameBufferState.READING_FRAME_SIZE) { // try to read the frame size completely if (!internalRead()) { return false; } // if the frame size has been read completely, then prepare to read the // actual frame. if (buffer_.remaining() == 0) { // pull out the frame size as an integer. int frameSize = buffer_.getInt(0); if (frameSize <= 0) { LOGGER.error("Read an invalid frame size of " + frameSize + ". Are you using TFramedTransport on the client side?"); return false; } // if this frame will always be too large for this server, log the // error and close the connection. if (frameSize > MAX_READ_BUFFER_BYTES) { LOGGER.error("Read a frame size of " + frameSize + ", which is bigger than the maximum allowable buffer size for ALL connections."); return false; } // if this frame will push us over the memory limit, then return. // with luck, more memory will free up the next time around. if (readBufferBytesAllocated.get() + frameSize > MAX_READ_BUFFER_BYTES) { return true; } // increment the amount of memory allocated to read buffers readBufferBytesAllocated.addAndGet(frameSize + 4); // reallocate the readbuffer as a frame-sized buffer buffer_ = ByteBuffer.allocate(frameSize + 4); buffer_.putInt(frameSize); state_ = FrameBufferState.READING_FRAME; } else { // this skips the check of READING_FRAME state below, since we can't // possibly go on to that state if there's data left to be read at // this one. return true; } } // it is possible to fall through from the READING_FRAME_SIZE section // to READING_FRAME if there's already some frame data available once // READING_FRAME_SIZE is complete. if (state_ == FrameBufferState.READING_FRAME) { if (!internalRead()) { return false; } // since we're already in the select loop here for sure, we can just // modify our selection key directly. if (buffer_.remaining() == 0) { // get rid of the read select interests selectionKey_.interestOps(0); state_ = FrameBufferState.READ_FRAME_COMPLETE; } return true; } // if we fall through to this point, then the state must be invalid. LOGGER.error("Read was called but state is invalid (" + state_ + ")"); return false; } /** * Give this FrameBuffer a chance to write its output to the final client. */ public boolean write() { if (state_ == FrameBufferState.WRITING) { try { if (trans_.write(buffer_) < 0) { return false; } } catch (IOException e) { LOGGER.warn("Got an IOException during write!", e); return false; } // we're done writing. now we need to switch back to reading. if (buffer_.remaining() == 0) { prepareRead(); } return true; } LOGGER.error("Write was called, but state is invalid (" + state_ + ")"); return false; } /** * Give this FrameBuffer a chance to set its interest to write, once data * has come in. */ public void changeSelectInterests() { if (state_ == FrameBufferState.AWAITING_REGISTER_WRITE) { // set the OP_WRITE interest selectionKey_.interestOps(SelectionKey.OP_WRITE); state_ = FrameBufferState.WRITING; } else if (state_ == FrameBufferState.AWAITING_REGISTER_READ) { prepareRead(); } else if (state_ == FrameBufferState.AWAITING_CLOSE) { close(); selectionKey_.cancel(); } else { LOGGER.error("changeSelectInterest was called, but state is invalid (" + state_ + ")"); } } /** * Shut the connection down. */ public void close() { // if we're being closed due to an error, we might have allocated a // buffer that we need to subtract for our memory accounting. if (state_ == FrameBufferState.READING_FRAME || state_ == FrameBufferState.READ_FRAME_COMPLETE) { readBufferBytesAllocated.addAndGet(-buffer_.array().length); } trans_.close(); } /** * Check if this FrameBuffer has a full frame read. */ public boolean isFrameFullyRead() { return state_ == FrameBufferState.READ_FRAME_COMPLETE; } /** * After the processor has processed the invocation, whatever thread is * managing invocations should call this method on this FrameBuffer so we * know it's time to start trying to write again. Also, if it turns out that * there actually isn't any data in the response buffer, we'll skip trying * to write and instead go back to reading. */ public void responseReady() { // the read buffer is definitely no longer in use, so we will decrement // our read buffer count. we do this here as well as in close because // we'd like to free this read memory up as quickly as possible for other // clients. readBufferBytesAllocated.addAndGet(-buffer_.array().length); if (response_.len() == 0) { // go straight to reading again. this was probably an oneway method state_ = FrameBufferState.AWAITING_REGISTER_READ; buffer_ = null; } else { buffer_ = ByteBuffer.wrap(response_.get(), 0, response_.len()); // set state that we're waiting to be switched to write. we do this // asynchronously through requestSelectInterestChange() because there is // a possibility that we're not in the main thread, and thus currently // blocked in select(). (this functionality is in place for the sake of // the HsHa server.) state_ = FrameBufferState.AWAITING_REGISTER_WRITE; } requestSelectInterestChange(); } /** * Actually invoke the method signified by this FrameBuffer. */ public void invoke() { TTransport inTrans = getInputTransport(); TProtocol inProt = inputProtocolFactory_.getProtocol(inTrans); TProtocol outProt = outputProtocolFactory_.getProtocol(getOutputTransport()); try { processorFactory_.getProcessor(inTrans).process(inProt, outProt); responseReady(); return; } catch (TException te) { LOGGER.warn("Exception while invoking!", te); } catch (Throwable t) { LOGGER.error("Unexpected throwable while invoking!", t); } // This will only be reached when there is a throwable. state_ = FrameBufferState.AWAITING_CLOSE; requestSelectInterestChange(); } /** * Wrap the read buffer in a memory-based transport so a processor can read * the data it needs to handle an invocation. */ private TTransport getInputTransport() { return inputTransportFactory_.getTransport(new TMemoryInputTransport(buffer_.array())); } /** * Get the transport that should be used by the invoker for responding. */ private TTransport getOutputTransport() { response_ = new TByteArrayOutputStream(); return outputTransportFactory_.getTransport(new TIOStreamTransport(response_)); } /** * Perform a read into buffer. * * @return true if the read succeeded, false if there was an error or the * connection closed. */ private boolean internalRead() { try { if (trans_.read(buffer_) < 0) { return false; } return true; } catch (IOException e) { LOGGER.warn("Got an IOException in internalRead!", e); return false; } } /** * We're done writing, so reset our interest ops and change state * accordingly. */ private void prepareRead() { // we can set our interest directly without using the queue because // we're in the select thread. selectionKey_.interestOps(SelectionKey.OP_READ); // get ready for another go-around buffer_ = ByteBuffer.allocate(4); state_ = FrameBufferState.READING_FRAME_SIZE; } /** * When this FrameBuffer needs to change its select interests and execution * might not be in its select thread, then this method will make sure the * interest change gets done when the select thread wakes back up. When the * current thread is this FrameBuffer's select thread, then it just does the * interest change immediately. */ private void requestSelectInterestChange() { if (Thread.currentThread() == this.selectThread_) { changeSelectInterests(); } else { this.selectThread_.requestSelectInterestChange(this); } } } // FrameBuffer public void setServerEventHandler(TServerEventHandler eventHandler) { throw new UnsupportedOperationException("Not supported yet."); } public TServerEventHandler getEventHandler() { throw new UnsupportedOperationException("Not supported yet."); } } libthrift-java_0.9.0/src/org/apache/thrift/server/TThreadedSelectorServer.java0000644000175000017500000005032012035665435030311 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.server; import java.io.IOException; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.spi.SelectorProvider; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.Set; import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.BlockingQueue; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.RejectedExecutionException; import java.util.concurrent.TimeUnit; import org.apache.thrift.transport.TNonblockingServerTransport; import org.apache.thrift.transport.TNonblockingTransport; import org.apache.thrift.transport.TTransportException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * A Half-Sync/Half-Async server with a separate pool of threads to handle * non-blocking I/O. Accepts are handled on a single thread, and a configurable * number of nonblocking selector threads manage reading and writing of client * connections. A synchronous worker thread pool handles processing of requests. * * Performs better than TNonblockingServer/THsHaServer in multi-core * environments when the the bottleneck is CPU on the single selector thread * handling I/O. In addition, because the accept handling is decoupled from * reads/writes and invocation, the server has better ability to handle back- * pressure from new connections (e.g. stop accepting when busy). * * Like TNonblockingServer, it relies on the use of TFramedTransport. */ public class TThreadedSelectorServer extends AbstractNonblockingServer { private static final Logger LOGGER = LoggerFactory.getLogger(TThreadedSelectorServer.class.getName()); public static class Args extends AbstractNonblockingServerArgs { /** The number of threads for selecting on already-accepted connections */ public int selectorThreads = 2; /** * The size of the executor service (if none is specified) that will handle * invocations. This may be set to 0, in which case invocations will be * handled directly on the selector threads (as is in TNonblockingServer) */ private int workerThreads = 5; /** Time to wait for server to stop gracefully */ private int stopTimeoutVal = 60; private TimeUnit stopTimeoutUnit = TimeUnit.SECONDS; /** The ExecutorService for handling dispatched requests */ private ExecutorService executorService = null; /** * The size of the blocking queue per selector thread for passing accepted * connections to the selector thread */ private int acceptQueueSizePerThread = 4; /** * Determines the strategy for handling new accepted connections. */ public static enum AcceptPolicy { /** * Require accepted connection registration to be handled by the executor. * If the worker pool is saturated, further accepts will be closed * immediately. Slightly increases latency due to an extra scheduling. */ FAIR_ACCEPT, /** * Handle the accepts as fast as possible, disregarding the status of the * executor service. */ FAST_ACCEPT } private AcceptPolicy acceptPolicy = AcceptPolicy.FAST_ACCEPT; public Args(TNonblockingServerTransport transport) { super(transport); } public Args selectorThreads(int i) { selectorThreads = i; return this; } public int getSelectorThreads() { return selectorThreads; } public Args workerThreads(int i) { workerThreads = i; return this; } public int getWorkerThreads() { return workerThreads; } public int getStopTimeoutVal() { return stopTimeoutVal; } public Args stopTimeoutVal(int stopTimeoutVal) { this.stopTimeoutVal = stopTimeoutVal; return this; } public TimeUnit getStopTimeoutUnit() { return stopTimeoutUnit; } public Args stopTimeoutUnit(TimeUnit stopTimeoutUnit) { this.stopTimeoutUnit = stopTimeoutUnit; return this; } public ExecutorService getExecutorService() { return executorService; } public Args executorService(ExecutorService executorService) { this.executorService = executorService; return this; } public int getAcceptQueueSizePerThread() { return acceptQueueSizePerThread; } public Args acceptQueueSizePerThread(int acceptQueueSizePerThread) { this.acceptQueueSizePerThread = acceptQueueSizePerThread; return this; } public AcceptPolicy getAcceptPolicy() { return acceptPolicy; } public Args acceptPolicy(AcceptPolicy acceptPolicy) { this.acceptPolicy = acceptPolicy; return this; } public void validate() { if (selectorThreads <= 0) { throw new IllegalArgumentException("selectorThreads must be positive."); } if (workerThreads < 0) { throw new IllegalArgumentException("workerThreads must be non-negative."); } if (acceptQueueSizePerThread <= 0) { throw new IllegalArgumentException("acceptQueueSizePerThread must be positive."); } } } // Flag for stopping the server private volatile boolean stopped_ = true; // The thread handling all accepts private AcceptThread acceptThread; // Threads handling events on client transports private final Set selectorThreads = new HashSet(); // This wraps all the functionality of queueing and thread pool management // for the passing of Invocations from the selector thread(s) to the workers // (if any). private final ExecutorService invoker; private final Args args; /** * Create the server with the specified Args configuration */ public TThreadedSelectorServer(Args args) { super(args); args.validate(); invoker = args.executorService == null ? createDefaultExecutor(args) : args.executorService; this.args = args; } /** * Start the accept and selector threads running to deal with clients. * * @return true if everything went ok, false if we couldn't start for some * reason. */ @Override protected boolean startThreads() { try { for (int i = 0; i < args.selectorThreads; ++i) { selectorThreads.add(new SelectorThread(args.acceptQueueSizePerThread)); } acceptThread = new AcceptThread((TNonblockingServerTransport) serverTransport_, createSelectorThreadLoadBalancer(selectorThreads)); stopped_ = false; for (SelectorThread thread : selectorThreads) { thread.start(); } acceptThread.start(); return true; } catch (IOException e) { LOGGER.error("Failed to start threads!", e); return false; } } /** * Joins the accept and selector threads and shuts down the executor service. */ @Override protected void waitForShutdown() { try { joinThreads(); } catch (InterruptedException e) { // Non-graceful shutdown occurred LOGGER.error("Interrupted while joining threads!", e); } gracefullyShutdownInvokerPool(); } protected void joinThreads() throws InterruptedException { // wait until the io threads exit acceptThread.join(); for (SelectorThread thread : selectorThreads) { thread.join(); } } /** * Stop serving and shut everything down. */ @Override public void stop() { stopped_ = true; // Stop queuing connect attempts asap stopListening(); if (acceptThread != null) { acceptThread.wakeupSelector(); } if (selectorThreads != null) { for (SelectorThread thread : selectorThreads) { if (thread != null) thread.wakeupSelector(); } } } protected void gracefullyShutdownInvokerPool() { // try to gracefully shut down the executor service invoker.shutdown(); // Loop until awaitTermination finally does return without a interrupted // exception. If we don't do this, then we'll shut down prematurely. We want // to let the executorService clear it's task queue, closing client sockets // appropriately. long timeoutMS = args.stopTimeoutUnit.toMillis(args.stopTimeoutVal); long now = System.currentTimeMillis(); while (timeoutMS >= 0) { try { invoker.awaitTermination(timeoutMS, TimeUnit.MILLISECONDS); break; } catch (InterruptedException ix) { long newnow = System.currentTimeMillis(); timeoutMS -= (newnow - now); now = newnow; } } } /** * We override the standard invoke method here to queue the invocation for * invoker service instead of immediately invoking. If there is no thread * pool, handle the invocation inline on this thread */ @Override protected boolean requestInvoke(FrameBuffer frameBuffer) { Runnable invocation = getRunnable(frameBuffer); if (invoker != null) { try { invoker.execute(invocation); return true; } catch (RejectedExecutionException rx) { LOGGER.warn("ExecutorService rejected execution!", rx); return false; } } else { // Invoke on the caller's thread invocation.run(); return true; } } protected Runnable getRunnable(FrameBuffer frameBuffer) { return new Invocation(frameBuffer); } /** * Helper to create the invoker if one is not specified */ protected static ExecutorService createDefaultExecutor(Args options) { return (options.workerThreads > 0) ? Executors.newFixedThreadPool(options.workerThreads) : null; } private static BlockingQueue createDefaultAcceptQueue(int queueSize) { if (queueSize == 0) { // Unbounded queue return new LinkedBlockingQueue(); } return new ArrayBlockingQueue(queueSize); } /** * The thread that selects on the server transport (listen socket) and accepts * new connections to hand off to the IO selector threads */ protected class AcceptThread extends Thread { // The listen socket to accept on private final TNonblockingServerTransport serverTransport; private final Selector acceptSelector; private final SelectorThreadLoadBalancer threadChooser; /** * Set up the AcceptThead * * @throws IOException */ public AcceptThread(TNonblockingServerTransport serverTransport, SelectorThreadLoadBalancer threadChooser) throws IOException { this.serverTransport = serverTransport; this.threadChooser = threadChooser; this.acceptSelector = SelectorProvider.provider().openSelector(); this.serverTransport.registerSelector(acceptSelector); } /** * The work loop. Selects on the server transport and accepts. If there was * a server transport that had blocking accepts, and returned on blocking * client transports, that should be used instead */ public void run() { try { while (!stopped_) { select(); } } catch (Throwable t) { LOGGER.error("run() exiting due to uncaught error", t); } finally { // This will wake up the selector threads TThreadedSelectorServer.this.stop(); } } /** * If the selector is blocked, wake it up. */ public void wakeupSelector() { acceptSelector.wakeup(); } /** * Select and process IO events appropriately: If there are connections to * be accepted, accept them. */ private void select() { try { // wait for connect events. acceptSelector.select(); // process the io events we received Iterator selectedKeys = acceptSelector.selectedKeys().iterator(); while (!stopped_ && selectedKeys.hasNext()) { SelectionKey key = selectedKeys.next(); selectedKeys.remove(); // skip if not valid if (!key.isValid()) { continue; } if (key.isAcceptable()) { handleAccept(); } else { LOGGER.warn("Unexpected state in select! " + key.interestOps()); } } } catch (IOException e) { LOGGER.warn("Got an IOException while selecting!", e); } } /** * Accept a new connection. */ private void handleAccept() { final TNonblockingTransport client = doAccept(); if (client != null) { // Pass this connection to a selector thread final SelectorThread targetThread = threadChooser.nextThread(); if (args.acceptPolicy == Args.AcceptPolicy.FAST_ACCEPT || invoker == null) { doAddAccept(targetThread, client); } else { // FAIR_ACCEPT try { invoker.submit(new Runnable() { public void run() { doAddAccept(targetThread, client); } }); } catch (RejectedExecutionException rx) { LOGGER.warn("ExecutorService rejected accept registration!", rx); // close immediately client.close(); } } } } private TNonblockingTransport doAccept() { try { return (TNonblockingTransport) serverTransport.accept(); } catch (TTransportException tte) { // something went wrong accepting. LOGGER.warn("Exception trying to accept!", tte); return null; } } private void doAddAccept(SelectorThread thread, TNonblockingTransport client) { if (!thread.addAcceptedConnection(client)) { client.close(); } } } // AcceptThread /** * The SelectorThread(s) will be doing all the selecting on accepted active * connections. */ protected class SelectorThread extends AbstractSelectThread { // Accepted connections added by the accept thread. private final BlockingQueue acceptedQueue; /** * Set up the SelectorThread with an unbounded queue for incoming accepts. * * @throws IOException * if a selector cannot be created */ public SelectorThread() throws IOException { this(new LinkedBlockingQueue()); } /** * Set up the SelectorThread with an bounded queue for incoming accepts. * * @throws IOException * if a selector cannot be created */ public SelectorThread(int maxPendingAccepts) throws IOException { this(createDefaultAcceptQueue(maxPendingAccepts)); } /** * Set up the SelectorThread with a specified queue for connections. * * @param acceptedQueue * The BlockingQueue implementation for holding incoming accepted * connections. * @throws IOException * if a selector cannot be created. */ public SelectorThread(BlockingQueue acceptedQueue) throws IOException { this.acceptedQueue = acceptedQueue; } /** * Hands off an accepted connection to be handled by this thread. This * method will block if the queue for new connections is at capacity. * * @param accepted * The connection that has been accepted. * @return true if the connection has been successfully added. */ public boolean addAcceptedConnection(TNonblockingTransport accepted) { try { acceptedQueue.put(accepted); } catch (InterruptedException e) { LOGGER.warn("Interrupted while adding accepted connection!", e); return false; } selector.wakeup(); return true; } /** * The work loop. Handles selecting (read/write IO), dispatching, and * managing the selection preferences of all existing connections. */ public void run() { try { while (!stopped_) { select(); processAcceptedConnections(); processInterestChanges(); } for (SelectionKey selectionKey : selector.keys()) { cleanupSelectionKey(selectionKey); } } catch (Throwable t) { LOGGER.error("run() exiting due to uncaught error", t); } finally { // This will wake up the accept thread and the other selector threads TThreadedSelectorServer.this.stop(); } } /** * Select and process IO events appropriately: If there are existing * connections with data waiting to be read, read it, buffering until a * whole frame has been read. If there are any pending responses, buffer * them until their target client is available, and then send the data. */ private void select() { try { // wait for io events. selector.select(); // process the io events we received Iterator selectedKeys = selector.selectedKeys().iterator(); while (!stopped_ && selectedKeys.hasNext()) { SelectionKey key = selectedKeys.next(); selectedKeys.remove(); // skip if not valid if (!key.isValid()) { cleanupSelectionKey(key); continue; } if (key.isReadable()) { // deal with reads handleRead(key); } else if (key.isWritable()) { // deal with writes handleWrite(key); } else { LOGGER.warn("Unexpected state in select! " + key.interestOps()); } } } catch (IOException e) { LOGGER.warn("Got an IOException while selecting!", e); } } private void processAcceptedConnections() { // Register accepted connections while (!stopped_) { TNonblockingTransport accepted = acceptedQueue.poll(); if (accepted == null) { break; } registerAccepted(accepted); } } private void registerAccepted(TNonblockingTransport accepted) { SelectionKey clientKey = null; try { clientKey = accepted.registerSelector(selector, SelectionKey.OP_READ); FrameBuffer frameBuffer = new FrameBuffer(accepted, clientKey, SelectorThread.this); clientKey.attach(frameBuffer); } catch (IOException e) { LOGGER.warn("Failed to register accepted connection to selector!", e); if (clientKey != null) { cleanupSelectionKey(clientKey); } accepted.close(); } } } // SelectorThread /** * Creates a SelectorThreadLoadBalancer to be used by the accept thread for * assigning newly accepted connections across the threads. */ protected SelectorThreadLoadBalancer createSelectorThreadLoadBalancer(Collection threads) { return new SelectorThreadLoadBalancer(threads); } /** * A round robin load balancer for choosing selector threads for new * connections. */ protected class SelectorThreadLoadBalancer { private final Collection threads; private Iterator nextThreadIterator; public SelectorThreadLoadBalancer(Collection threads) { if (threads.isEmpty()) { throw new IllegalArgumentException("At least one selector thread is required"); } this.threads = Collections.unmodifiableList(new ArrayList(threads)); nextThreadIterator = this.threads.iterator(); } public SelectorThread nextThread() { // Choose a selector thread (round robin) if (!nextThreadIterator.hasNext()) { nextThreadIterator = threads.iterator(); } return nextThreadIterator.next(); } } } libthrift-java_0.9.0/src/org/apache/thrift/server/TNonblockingServer.java0000644000175000017500000001612312035665435027336 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.server; import org.apache.thrift.transport.TNonblockingServerTransport; import org.apache.thrift.transport.TNonblockingTransport; import org.apache.thrift.transport.TTransportException; import java.io.IOException; import java.nio.channels.SelectionKey; import java.util.Iterator; /** * A nonblocking TServer implementation. This allows for fairness amongst all * connected clients in terms of invocations. * * This server is inherently single-threaded. If you want a limited thread pool * coupled with invocation-fairness, see THsHaServer. * * To use this server, you MUST use a TFramedTransport at the outermost * transport, otherwise this server will be unable to determine when a whole * method call has been read off the wire. Clients must also use TFramedTransport. */ public class TNonblockingServer extends AbstractNonblockingServer { public static class Args extends AbstractNonblockingServerArgs { public Args(TNonblockingServerTransport transport) { super(transport); } } // Flag for stopping the server private volatile boolean stopped_ = true; private SelectAcceptThread selectAcceptThread_; public TNonblockingServer(AbstractNonblockingServerArgs args) { super(args); } /** * Start the selector thread to deal with accepts and client messages. * * @return true if everything went ok, false if we couldn't start for some * reason. */ @Override protected boolean startThreads() { // start the selector try { selectAcceptThread_ = new SelectAcceptThread((TNonblockingServerTransport)serverTransport_); stopped_ = false; selectAcceptThread_.start(); return true; } catch (IOException e) { LOGGER.error("Failed to start selector thread!", e); return false; } } @Override protected void waitForShutdown() { joinSelector(); } /** * Block until the selector thread exits. */ protected void joinSelector() { // wait until the selector thread exits try { selectAcceptThread_.join(); } catch (InterruptedException e) { // for now, just silently ignore. technically this means we'll have less of // a graceful shutdown as a result. } } /** * Stop serving and shut everything down. */ @Override public void stop() { stopped_ = true; if (selectAcceptThread_ != null) { selectAcceptThread_.wakeupSelector(); } } /** * Perform an invocation. This method could behave several different ways * - invoke immediately inline, queue for separate execution, etc. */ @Override protected boolean requestInvoke(FrameBuffer frameBuffer) { frameBuffer.invoke(); return true; } public boolean isStopped() { return selectAcceptThread_.isStopped(); } /** * The thread that will be doing all the selecting, managing new connections * and those that still need to be read. */ protected class SelectAcceptThread extends AbstractSelectThread { // The server transport on which new client transports will be accepted private final TNonblockingServerTransport serverTransport; /** * Set up the thread that will handle the non-blocking accepts, reads, and * writes. */ public SelectAcceptThread(final TNonblockingServerTransport serverTransport) throws IOException { this.serverTransport = serverTransport; serverTransport.registerSelector(selector); } public boolean isStopped() { return stopped_; } /** * The work loop. Handles both selecting (all IO operations) and managing * the selection preferences of all existing connections. */ public void run() { try { while (!stopped_) { select(); processInterestChanges(); } for (SelectionKey selectionKey : selector.keys()) { cleanupSelectionKey(selectionKey); } } catch (Throwable t) { LOGGER.error("run() exiting due to uncaught error", t); } finally { stopped_ = true; } } /** * Select and process IO events appropriately: * If there are connections to be accepted, accept them. * If there are existing connections with data waiting to be read, read it, * buffering until a whole frame has been read. * If there are any pending responses, buffer them until their target client * is available, and then send the data. */ private void select() { try { // wait for io events. selector.select(); // process the io events we received Iterator selectedKeys = selector.selectedKeys().iterator(); while (!stopped_ && selectedKeys.hasNext()) { SelectionKey key = selectedKeys.next(); selectedKeys.remove(); // skip if not valid if (!key.isValid()) { cleanupSelectionKey(key); continue; } // if the key is marked Accept, then it has to be the server // transport. if (key.isAcceptable()) { handleAccept(); } else if (key.isReadable()) { // deal with reads handleRead(key); } else if (key.isWritable()) { // deal with writes handleWrite(key); } else { LOGGER.warn("Unexpected state in select! " + key.interestOps()); } } } catch (IOException e) { LOGGER.warn("Got an IOException while selecting!", e); } } /** * Accept a new connection. */ private void handleAccept() throws IOException { SelectionKey clientKey = null; TNonblockingTransport client = null; try { // accept the connection client = (TNonblockingTransport)serverTransport.accept(); clientKey = client.registerSelector(selector, SelectionKey.OP_READ); // add this key to the map FrameBuffer frameBuffer = new FrameBuffer(client, clientKey, SelectAcceptThread.this); clientKey.attach(frameBuffer); } catch (TTransportException tte) { // something went wrong accepting. LOGGER.warn("Exception trying to accept!", tte); tte.printStackTrace(); if (clientKey != null) cleanupSelectionKey(clientKey); if (client != null) client.close(); } } } // SelectAcceptThread } libthrift-java_0.9.0/src/org/apache/thrift/server/TServer.java0000644000175000017500000001113312035665435025146 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.thrift.server; import org.apache.thrift.TProcessor; import org.apache.thrift.TProcessorFactory; import org.apache.thrift.protocol.TBinaryProtocol; import org.apache.thrift.protocol.TProtocolFactory; import org.apache.thrift.transport.TServerTransport; import org.apache.thrift.transport.TTransportFactory; /** * Generic interface for a Thrift server. * */ public abstract class TServer { public static class Args extends AbstractServerArgs { public Args(TServerTransport transport) { super(transport); } } public static abstract class AbstractServerArgs> { final TServerTransport serverTransport; TProcessorFactory processorFactory; TTransportFactory inputTransportFactory = new TTransportFactory(); TTransportFactory outputTransportFactory = new TTransportFactory(); TProtocolFactory inputProtocolFactory = new TBinaryProtocol.Factory(); TProtocolFactory outputProtocolFactory = new TBinaryProtocol.Factory(); public AbstractServerArgs(TServerTransport transport) { serverTransport = transport; } public T processorFactory(TProcessorFactory factory) { this.processorFactory = factory; return (T) this; } public T processor(TProcessor processor) { this.processorFactory = new TProcessorFactory(processor); return (T) this; } public T transportFactory(TTransportFactory factory) { this.inputTransportFactory = factory; this.outputTransportFactory = factory; return (T) this; } public T inputTransportFactory(TTransportFactory factory) { this.inputTransportFactory = factory; return (T) this; } public T outputTransportFactory(TTransportFactory factory) { this.outputTransportFactory = factory; return (T) this; } public T protocolFactory(TProtocolFactory factory) { this.inputProtocolFactory = factory; this.outputProtocolFactory = factory; return (T) this; } public T inputProtocolFactory(TProtocolFactory factory) { this.inputProtocolFactory = factory; return (T) this; } public T outputProtocolFactory(TProtocolFactory factory) { this.outputProtocolFactory = factory; return (T) this; } } /** * Core processor */ protected TProcessorFactory processorFactory_; /** * Server transport */ protected TServerTransport serverTransport_; /** * Input Transport Factory */ protected TTransportFactory inputTransportFactory_; /** * Output Transport Factory */ protected TTransportFactory outputTransportFactory_; /** * Input Protocol Factory */ protected TProtocolFactory inputProtocolFactory_; /** * Output Protocol Factory */ protected TProtocolFactory outputProtocolFactory_; private boolean isServing; protected TServerEventHandler eventHandler_; protected TServer(AbstractServerArgs args) { processorFactory_ = args.processorFactory; serverTransport_ = args.serverTransport; inputTransportFactory_ = args.inputTransportFactory; outputTransportFactory_ = args.outputTransportFactory; inputProtocolFactory_ = args.inputProtocolFactory; outputProtocolFactory_ = args.outputProtocolFactory; } /** * The run method fires up the server and gets things going. */ public abstract void serve(); /** * Stop the server. This is optional on a per-implementation basis. Not * all servers are required to be cleanly stoppable. */ public void stop() {} public boolean isServing() { return isServing; } protected void setServing(boolean serving) { isServing = serving; } public void setServerEventHandler(TServerEventHandler eventHandler) { eventHandler_ = eventHandler; } public TServerEventHandler getEventHandler() { return eventHandler_; } } libthrift-java_0.9.0/src/org/apache/thrift/server/ServerContext.java0000644000175000017500000000165112035665435026373 0ustar eevanseevans00000000000000/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ /** * Interface for storing server's connection context */ package org.apache.thrift.server; public interface ServerContext {} libthrift-java_0.9.0/src/org/apache/thrift/server/Invocation.java0000644000175000017500000000106612035665435025671 0ustar eevanseevans00000000000000package org.apache.thrift.server; import org.apache.thrift.server.AbstractNonblockingServer.FrameBuffer; /** * An Invocation represents a method call that is prepared to execute, given * an idle worker thread. It contains the input and output protocols the * thread's processor should use to perform the usual Thrift invocation. */ class Invocation implements Runnable { private final FrameBuffer frameBuffer; public Invocation(final FrameBuffer frameBuffer) { this.frameBuffer = frameBuffer; } public void run() { frameBuffer.invoke(); } }libthrift-java_0.9.0/README.Thrift0000644000175000017500000000773212075130200017412 0ustar eevanseevans00000000000000Apache Thrift Last Modified: 2010-Nov-04 License ======= Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. Introduction ============ Thrift is a lightweight, language-independent software stack with an associated code generation mechanism for RPC. Thrift provides clean abstractions for data transport, data serialization, and application level processing. The code generation system takes a simple definition language as its input and generates code across programming languages that uses the abstracted stack to build interoperable RPC clients and servers. Thrift is specifically designed to support non-atomic version changes across client and server code. For more details on Thrift's design and implementation, take a gander at the Thrift whitepaper included in this distribution or at the README files in your particular subdirectory of interest. Hierarchy ========= thrift/ compiler/ Contains the Thrift compiler, implemented in C++. lib/ Contains the Thrift software library implementation, subdivided by language of implementation. cpp/ java/ php/ py/ rb/ test/ Contains sample Thrift files and test code across the target programming languages. tutorial/ Contains a basic tutorial that will teach you how to develop software using Thrift. Requirements ============ See http://wiki.apache.org/thrift/ThriftRequirements for an up-to-date list of build requirements. Resources ========= More information about Thrift can be obtained on the Thrift webpage at: http://thrift.apache.org Acknowledgments =============== Thrift was inspired by pillar, a lightweight RPC tool written by Adam D'Angelo, and also by Google's protocol buffers. Installation ============ If you are building from the first time out of the source repository, you will need to generate the configure scripts. (This is not necessary if you downloaded a tarball.) From the top directory, do: ./bootstrap.sh Once the configure scripts are generated, thrift can be configured. From the top directory, do: ./configure You may need to specify the location of the boost files explicitly. If you installed boost in /usr/local, you would run configure as follows: ./configure --with-boost=/usr/local Note that by default the thrift C++ library is typically built with debugging symbols included. If you want to customize these options you should use the CXXFLAGS option in configure, as such: ./configure CXXFLAGS='-g -O2' ./configure CFLAGS='-g -O2' ./configure CPPFLAGS='-DDEBUG_MY_FEATURE' Run ./configure --help to see other configuration options Please be aware that the Python library will ignore the --prefix option and just install wherever Python's distutils puts it (usually along the lines of /usr/lib/pythonX.Y/site-packages/). If you need to control where the Python modules are installed, set the PY_PREFIX variable. (DESTDIR is respected for Python and C++.) Make thrift: make From the top directory, become superuser and do: make install Note that some language packages must be installed manually using build tools better suited to those languages (at the time of this writing, this applies to Java, Ruby, PHP). Look for the README file in the lib// folder for more details on the installation of each language library package. libthrift-java_0.9.0/NOTICE0000644000175000017500000000024712075130200016171 0ustar eevanseevans00000000000000Apache Thrift Copyright 2006-2010 The Apache Software Foundation. This product includes software developed at The Apache Software Foundation (http://www.apache.org/).