summaryrefslogtreecommitdiffstats
path: root/src/jaegertracing/thrift/tutorial
diff options
context:
space:
mode:
Diffstat (limited to 'src/jaegertracing/thrift/tutorial')
-rwxr-xr-xsrc/jaegertracing/thrift/tutorial/Makefile.am111
-rw-r--r--src/jaegertracing/thrift/tutorial/README.md42
-rw-r--r--src/jaegertracing/thrift/tutorial/as3/build.xml50
-rw-r--r--src/jaegertracing/thrift/tutorial/as3/src/CalculatorUI.as142
-rwxr-xr-xsrc/jaegertracing/thrift/tutorial/c_glib/Makefile.am84
-rw-r--r--src/jaegertracing/thrift/tutorial/c_glib/c_glib_client.c190
-rw-r--r--src/jaegertracing/thrift/tutorial/c_glib/c_glib_server.c527
-rwxr-xr-xsrc/jaegertracing/thrift/tutorial/cl/Makefile.am65
l---------src/jaegertracing/thrift/tutorial/cl/ensure-externals.sh1
-rw-r--r--src/jaegertracing/thrift/tutorial/cl/load-locally.lisp22
-rw-r--r--src/jaegertracing/thrift/tutorial/cl/make-tutorial-client.lisp51
-rw-r--r--src/jaegertracing/thrift/tutorial/cl/make-tutorial-server.lisp29
-rw-r--r--src/jaegertracing/thrift/tutorial/cl/shared-implementation.lisp25
-rw-r--r--src/jaegertracing/thrift/tutorial/cl/thrift-tutorial.asd17
-rw-r--r--src/jaegertracing/thrift/tutorial/cl/tutorial-implementation.lisp41
-rw-r--r--src/jaegertracing/thrift/tutorial/cpp/CMakeLists.txt57
-rw-r--r--src/jaegertracing/thrift/tutorial/cpp/CppClient.cpp80
-rw-r--r--src/jaegertracing/thrift/tutorial/cpp/CppServer.cpp179
-rwxr-xr-xsrc/jaegertracing/thrift/tutorial/cpp/Makefile.am86
-rw-r--r--src/jaegertracing/thrift/tutorial/csharp/CsharpClient/CsharpClient.cs92
-rw-r--r--src/jaegertracing/thrift/tutorial/csharp/CsharpClient/CsharpClient.csproj110
-rw-r--r--src/jaegertracing/thrift/tutorial/csharp/CsharpClient/Properties/AssemblyInfo.cs55
-rw-r--r--src/jaegertracing/thrift/tutorial/csharp/CsharpServer/CsharpServer.cs129
-rw-r--r--src/jaegertracing/thrift/tutorial/csharp/CsharpServer/CsharpServer.csproj111
-rw-r--r--src/jaegertracing/thrift/tutorial/csharp/CsharpServer/Properties/AssemblyInfo.cs55
-rw-r--r--src/jaegertracing/thrift/tutorial/csharp/tutorial.sln39
-rw-r--r--src/jaegertracing/thrift/tutorial/d/Makefile.am53
-rw-r--r--src/jaegertracing/thrift/tutorial/d/async_client.d86
-rw-r--r--src/jaegertracing/thrift/tutorial/d/client.d64
-rw-r--r--src/jaegertracing/thrift/tutorial/d/server.d111
-rw-r--r--src/jaegertracing/thrift/tutorial/dart/Makefile.am81
-rw-r--r--src/jaegertracing/thrift/tutorial/dart/build.sh56
-rw-r--r--src/jaegertracing/thrift/tutorial/dart/client/.analysis_options2
-rw-r--r--src/jaegertracing/thrift/tutorial/dart/client/pubspec.yaml33
-rw-r--r--src/jaegertracing/thrift/tutorial/dart/client/web/client.dart278
-rw-r--r--src/jaegertracing/thrift/tutorial/dart/client/web/index.html35
-rw-r--r--src/jaegertracing/thrift/tutorial/dart/client/web/styles.css33
-rw-r--r--src/jaegertracing/thrift/tutorial/dart/console_client/.analysis_options2
-rw-r--r--src/jaegertracing/thrift/tutorial/dart/console_client/bin/main.dart149
-rw-r--r--src/jaegertracing/thrift/tutorial/dart/console_client/pubspec.yaml36
-rw-r--r--src/jaegertracing/thrift/tutorial/dart/server/.analysis_options2
-rw-r--r--src/jaegertracing/thrift/tutorial/dart/server/bin/main.dart163
-rw-r--r--src/jaegertracing/thrift/tutorial/dart/server/pubspec.yaml34
-rw-r--r--src/jaegertracing/thrift/tutorial/delphi/DelphiClient/DelphiClient.dpr117
-rw-r--r--src/jaegertracing/thrift/tutorial/delphi/DelphiClient/DelphiClient.dproj122
-rw-r--r--src/jaegertracing/thrift/tutorial/delphi/DelphiServer/DelphiServer.dpr174
-rw-r--r--src/jaegertracing/thrift/tutorial/delphi/DelphiServer/DelphiServer.dproj119
-rw-r--r--src/jaegertracing/thrift/tutorial/delphi/Tutorial.groupproj48
-rw-r--r--src/jaegertracing/thrift/tutorial/erl/README.md8
-rw-r--r--src/jaegertracing/thrift/tutorial/erl/client.erl78
-rwxr-xr-xsrc/jaegertracing/thrift/tutorial/erl/client.sh37
-rw-r--r--src/jaegertracing/thrift/tutorial/erl/json_client.erl89
-rw-r--r--src/jaegertracing/thrift/tutorial/erl/server.erl82
-rwxr-xr-xsrc/jaegertracing/thrift/tutorial/erl/server.sh37
-rw-r--r--src/jaegertracing/thrift/tutorial/go/Makefile.am59
-rw-r--r--src/jaegertracing/thrift/tutorial/go/server.crt25
-rw-r--r--src/jaegertracing/thrift/tutorial/go/server.key28
-rw-r--r--src/jaegertracing/thrift/tutorial/go/src/client.go108
-rw-r--r--src/jaegertracing/thrift/tutorial/go/src/handler.go102
-rw-r--r--src/jaegertracing/thrift/tutorial/go/src/main.go82
-rw-r--r--src/jaegertracing/thrift/tutorial/go/src/server.go54
-rw-r--r--src/jaegertracing/thrift/tutorial/haxe/Makefile.am97
-rw-r--r--src/jaegertracing/thrift/tutorial/haxe/Tutorial.hxproj67
-rw-r--r--src/jaegertracing/thrift/tutorial/haxe/cpp.hxml41
-rw-r--r--src/jaegertracing/thrift/tutorial/haxe/csharp.hxml38
-rw-r--r--src/jaegertracing/thrift/tutorial/haxe/flash.hxml41
-rw-r--r--src/jaegertracing/thrift/tutorial/haxe/java.hxml38
-rw-r--r--src/jaegertracing/thrift/tutorial/haxe/javascript.hxml44
-rw-r--r--src/jaegertracing/thrift/tutorial/haxe/make_all.bat68
-rw-r--r--src/jaegertracing/thrift/tutorial/haxe/make_all.sh41
-rw-r--r--src/jaegertracing/thrift/tutorial/haxe/neko.hxml38
-rw-r--r--src/jaegertracing/thrift/tutorial/haxe/php-web-server.hxml43
-rw-r--r--src/jaegertracing/thrift/tutorial/haxe/php.hxml39
-rw-r--r--src/jaegertracing/thrift/tutorial/haxe/project.hide105
-rw-r--r--src/jaegertracing/thrift/tutorial/haxe/python.hxml38
-rw-r--r--src/jaegertracing/thrift/tutorial/haxe/router.php31
-rw-r--r--src/jaegertracing/thrift/tutorial/haxe/src/CalculatorHandler.hx101
-rw-r--r--src/jaegertracing/thrift/tutorial/haxe/src/Main.hx375
-rw-r--r--src/jaegertracing/thrift/tutorial/hs/HaskellClient.hs76
-rw-r--r--src/jaegertracing/thrift/tutorial/hs/HaskellServer.hs103
-rw-r--r--src/jaegertracing/thrift/tutorial/hs/LICENSE239
-rwxr-xr-xsrc/jaegertracing/thrift/tutorial/hs/Makefile.am47
-rw-r--r--src/jaegertracing/thrift/tutorial/hs/Setup.lhs21
-rwxr-xr-xsrc/jaegertracing/thrift/tutorial/hs/ThriftTutorial.cabal73
-rwxr-xr-xsrc/jaegertracing/thrift/tutorial/java/Makefile.am45
-rw-r--r--src/jaegertracing/thrift/tutorial/java/README.md24
-rw-r--r--src/jaegertracing/thrift/tutorial/java/build.xml115
-rw-r--r--src/jaegertracing/thrift/tutorial/java/src/CalculatorHandler.java92
-rw-r--r--src/jaegertracing/thrift/tutorial/java/src/JavaClient.java106
-rw-r--r--src/jaegertracing/thrift/tutorial/java/src/JavaServer.java110
-rwxr-xr-xsrc/jaegertracing/thrift/tutorial/js/Makefile.am39
-rw-r--r--src/jaegertracing/thrift/tutorial/js/build.xml92
-rw-r--r--src/jaegertracing/thrift/tutorial/js/src/Httpd.java299
-rwxr-xr-xsrc/jaegertracing/thrift/tutorial/js/tutorial.html109
-rw-r--r--src/jaegertracing/thrift/tutorial/netcore/.gitignore1
-rw-r--r--src/jaegertracing/thrift/tutorial/netcore/Client/Client.csproj19
-rw-r--r--src/jaegertracing/thrift/tutorial/netcore/Client/Program.cs355
-rw-r--r--src/jaegertracing/thrift/tutorial/netcore/Client/Properties/AssemblyInfo.cs40
-rw-r--r--src/jaegertracing/thrift/tutorial/netcore/Client/Properties/launchSettings.json8
-rw-r--r--src/jaegertracing/thrift/tutorial/netcore/Client/ThriftTest.pfxbin0 -> 2661 bytes
-rw-r--r--src/jaegertracing/thrift/tutorial/netcore/Interfaces/.gitignore3
-rw-r--r--src/jaegertracing/thrift/tutorial/netcore/Interfaces/Interfaces.csproj30
-rw-r--r--src/jaegertracing/thrift/tutorial/netcore/Interfaces/Properties/AssemblyInfo.cs40
-rw-r--r--src/jaegertracing/thrift/tutorial/netcore/Makefile.am51
-rw-r--r--src/jaegertracing/thrift/tutorial/netcore/README.md278
-rw-r--r--src/jaegertracing/thrift/tutorial/netcore/Server/Program.cs428
-rw-r--r--src/jaegertracing/thrift/tutorial/netcore/Server/Properties/AssemblyInfo.cs40
-rw-r--r--src/jaegertracing/thrift/tutorial/netcore/Server/Properties/launchSettings.json8
-rw-r--r--src/jaegertracing/thrift/tutorial/netcore/Server/Server.csproj26
-rw-r--r--src/jaegertracing/thrift/tutorial/netcore/Server/ThriftTest.pfxbin0 -> 2661 bytes
-rw-r--r--src/jaegertracing/thrift/tutorial/netcore/Tutorial.sln78
-rw-r--r--src/jaegertracing/thrift/tutorial/netcore/build.cmd25
-rwxr-xr-xsrc/jaegertracing/thrift/tutorial/netcore/build.sh26
-rw-r--r--src/jaegertracing/thrift/tutorial/netstd/.gitignore1
-rw-r--r--src/jaegertracing/thrift/tutorial/netstd/Client/Client.csproj41
-rw-r--r--src/jaegertracing/thrift/tutorial/netstd/Client/Program.cs409
-rw-r--r--src/jaegertracing/thrift/tutorial/netstd/Client/Properties/AssemblyInfo.cs40
-rw-r--r--src/jaegertracing/thrift/tutorial/netstd/Client/Properties/launchSettings.json8
-rw-r--r--src/jaegertracing/thrift/tutorial/netstd/Client/ThriftTest.pfxbin0 -> 2661 bytes
-rw-r--r--src/jaegertracing/thrift/tutorial/netstd/Interfaces/.gitignore3
-rw-r--r--src/jaegertracing/thrift/tutorial/netstd/Interfaces/Interfaces.csproj48
-rw-r--r--src/jaegertracing/thrift/tutorial/netstd/Interfaces/Properties/AssemblyInfo.cs40
-rw-r--r--src/jaegertracing/thrift/tutorial/netstd/Makefile.am42
-rw-r--r--src/jaegertracing/thrift/tutorial/netstd/README.md284
-rw-r--r--src/jaegertracing/thrift/tutorial/netstd/Server/Program.cs479
-rw-r--r--src/jaegertracing/thrift/tutorial/netstd/Server/Properties/AssemblyInfo.cs40
-rw-r--r--src/jaegertracing/thrift/tutorial/netstd/Server/Properties/launchSettings.json8
-rw-r--r--src/jaegertracing/thrift/tutorial/netstd/Server/Server.csproj44
-rw-r--r--src/jaegertracing/thrift/tutorial/netstd/Server/ThriftTest.pfxbin0 -> 2661 bytes
-rw-r--r--src/jaegertracing/thrift/tutorial/netstd/Tutorial.sln78
-rw-r--r--src/jaegertracing/thrift/tutorial/netstd/build.cmd25
-rw-r--r--src/jaegertracing/thrift/tutorial/netstd/build.sh26
-rw-r--r--src/jaegertracing/thrift/tutorial/nodejs/Makefile.am45
-rw-r--r--src/jaegertracing/thrift/tutorial/nodejs/NodeClient.js77
-rw-r--r--src/jaegertracing/thrift/tutorial/nodejs/NodeClientPromise.js80
-rw-r--r--src/jaegertracing/thrift/tutorial/nodejs/NodeServer.js84
-rw-r--r--src/jaegertracing/thrift/tutorial/nodejs/NodeServerPromise.js80
-rwxr-xr-xsrc/jaegertracing/thrift/tutorial/ocaml/CalcClient.ml74
-rwxr-xr-xsrc/jaegertracing/thrift/tutorial/ocaml/CalcServer.ml89
-rw-r--r--src/jaegertracing/thrift/tutorial/ocaml/README.md15
-rw-r--r--src/jaegertracing/thrift/tutorial/ocaml/_oasis32
-rw-r--r--src/jaegertracing/thrift/tutorial/perl/PerlClient.pl82
-rw-r--r--src/jaegertracing/thrift/tutorial/perl/PerlServer.pl125
-rwxr-xr-xsrc/jaegertracing/thrift/tutorial/php/PhpClient.php91
-rwxr-xr-xsrc/jaegertracing/thrift/tutorial/php/PhpServer.php130
-rwxr-xr-xsrc/jaegertracing/thrift/tutorial/php/runserver.py34
-rwxr-xr-xsrc/jaegertracing/thrift/tutorial/py.tornado/Makefile.am36
-rwxr-xr-xsrc/jaegertracing/thrift/tutorial/py.tornado/PythonClient.py108
-rwxr-xr-xsrc/jaegertracing/thrift/tutorial/py.tornado/PythonServer.py100
-rwxr-xr-xsrc/jaegertracing/thrift/tutorial/py.twisted/Makefile.am37
-rwxr-xr-xsrc/jaegertracing/thrift/tutorial/py.twisted/PythonClient.py80
-rwxr-xr-xsrc/jaegertracing/thrift/tutorial/py.twisted/PythonServer.py97
-rwxr-xr-xsrc/jaegertracing/thrift/tutorial/py.twisted/PythonServer.tac53
-rwxr-xr-xsrc/jaegertracing/thrift/tutorial/py/Makefile.am37
-rwxr-xr-xsrc/jaegertracing/thrift/tutorial/py/PythonClient.py89
-rwxr-xr-xsrc/jaegertracing/thrift/tutorial/py/PythonServer.py103
-rw-r--r--src/jaegertracing/thrift/tutorial/py/setup.cfg2
-rwxr-xr-xsrc/jaegertracing/thrift/tutorial/rb/Makefile.am36
-rwxr-xr-xsrc/jaegertracing/thrift/tutorial/rb/RubyClient.rb75
-rwxr-xr-xsrc/jaegertracing/thrift/tutorial/rb/RubyServer.rb95
-rw-r--r--src/jaegertracing/thrift/tutorial/rs/Cargo.toml16
-rw-r--r--src/jaegertracing/thrift/tutorial/rs/Makefile.am52
-rw-r--r--src/jaegertracing/thrift/tutorial/rs/README.md318
-rw-r--r--src/jaegertracing/thrift/tutorial/rs/src/bin/tutorial_client.rs130
-rw-r--r--src/jaegertracing/thrift/tutorial/rs/src/bin/tutorial_server.rs179
-rw-r--r--src/jaegertracing/thrift/tutorial/rs/src/lib.rs23
-rw-r--r--src/jaegertracing/thrift/tutorial/shared.thrift44
-rw-r--r--src/jaegertracing/thrift/tutorial/tutorial.thrift158
168 files changed, 13790 insertions, 0 deletions
diff --git a/src/jaegertracing/thrift/tutorial/Makefile.am b/src/jaegertracing/thrift/tutorial/Makefile.am
new file mode 100755
index 000000000..17a92573b
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/Makefile.am
@@ -0,0 +1,111 @@
+#
+# 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.
+#
+
+SUBDIRS =
+
+if MINGW
+# do nothing, just build the compiler
+else
+
+if WITH_C_GLIB
+SUBDIRS += c_glib
+endif
+
+if WITH_CPP
+SUBDIRS += cpp
+endif
+
+if WITH_D
+SUBDIRS += d
+endif
+
+if WITH_JAVA
+SUBDIRS += java
+SUBDIRS += js
+endif
+
+if WITH_PYTHON
+SUBDIRS += py
+SUBDIRS += py.twisted
+SUBDIRS += py.tornado
+endif
+
+if WITH_RUBY
+SUBDIRS += rb
+endif
+
+if WITH_HASKELL
+SUBDIRS += hs
+endif
+
+if WITH_HAXE
+SUBDIRS += haxe
+endif
+
+if WITH_DOTNET
+SUBDIRS += netcore
+SUBDIRS += netstd
+endif
+
+if WITH_GO
+SUBDIRS += go
+endif
+
+if WITH_NODEJS
+SUBDIRS += nodejs
+endif
+
+if WITH_DART
+SUBDIRS += dart
+endif
+
+if WITH_RS
+SUBDIRS += rs
+endif
+
+if WITH_CL
+SUBDIRS += cl
+endif
+
+#
+# generate html for ThriftTest.thrift
+#
+all-local:
+ $(top_builddir)/compiler/cpp/thrift --gen html -r $(top_srcdir)/tutorial/tutorial.thrift
+
+clean-local:
+ rm -rf $(top_srcdir)/tutorial/gen-html
+
+endif
+
+# Any folders or files not listed above being added to SUBDIR need to be placed here in
+# EXTRA_DIST to be included in the release
+EXTRA_DIST = \
+ as3 \
+ csharp \
+ d \
+ delphi \
+ erl \
+ hs \
+ ocaml \
+ perl \
+ php \
+ shared.thrift \
+ tutorial.thrift \
+ README.md
diff --git a/src/jaegertracing/thrift/tutorial/README.md b/src/jaegertracing/thrift/tutorial/README.md
new file mode 100644
index 000000000..7772bf3e6
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/README.md
@@ -0,0 +1,42 @@
+Thrift Tutorial
+
+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.
+
+Tutorial
+========
+
+1) First things first, you'll need to install the Thrift compiler and the
+ language libraries. Do that using the instructions in the top level
+ README.md file.
+
+2) Read tutorial.thrift to learn about the syntax of a Thrift file
+
+3) Compile the code for the language of your choice:
+
+ $ thrift
+ $ thrift -r --gen cpp tutorial.thrift
+
+4) Take a look at the generated code.
+
+5) Look in the language directories for sample client/server code.
+
+6) That's about it for now. This tutorial is intentionally brief. It should be
+ just enough to get you started and ready to build your own project.
diff --git a/src/jaegertracing/thrift/tutorial/as3/build.xml b/src/jaegertracing/thrift/tutorial/as3/build.xml
new file mode 100644
index 000000000..f7ed32d04
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/as3/build.xml
@@ -0,0 +1,50 @@
+<project name="tutorial" default="dist" basedir=".">
+
+ <description>Thrift actionscript 3.0 tutorial.</description>
+
+ <property name="gen" location="gen-as3" />
+ <property name="src" location="src" />
+ <property name="thrift.src" location="../../lib/as3/src/" />
+ <property name="dist" location="dist" />
+
+ <property name="final.name" value="as3-tutorial" />
+ <property name="swf.name" value="${dist}/${final.name}.swf" />
+
+ <target name="flex.check" unless="FLEX_HOME">
+ <fail message='You must set the FLEX_HOME property pointing to your flex SDK, eg. ant -DFLEX_HOME="/Applications/Adobe Flex Builder 3/sdks/3.2.0"'/>
+ </target>
+
+ <target name="flex.init" depends="flex.check" unless="flex.finished">
+ <taskdef resource="flexTasks.tasks" classpath="${FLEX_HOME}/ant/lib/flexTasks.jar" />
+ <property name="flex.finished" value="true"/>
+ </target>
+
+ <target name="init">
+ <tstamp />
+ <mkdir dir="${dist}"/>
+ </target>
+
+ <target name="dist" depends="generate, flex.init, init">
+ <mxmlc output="${swf.name}" file="${src}/CalculatorUI.as">
+ <source-path path-element="${gen}" />
+ <source-path path-element="${src}" />
+ <source-path path-element="${thrift.src}" />
+ </mxmlc>
+ </target>
+
+ <target name="generate">
+ <!-- Generate the thrift gen-java source -->
+ <exec executable="../../compiler/cpp/thrift" failonerror="true">
+ <arg line="--gen as3 ../shared.thrift"/>
+ </exec>
+ <exec executable="../../compiler/cpp/thrift" failonerror="true">
+ <arg line="--gen as3 ../tutorial.thrift"/>
+ </exec>
+ </target>
+
+ <target name="clean">
+ <delete dir="${gen}"/>
+ <delete dir="${dist}" />
+ </target>
+
+</project>
diff --git a/src/jaegertracing/thrift/tutorial/as3/src/CalculatorUI.as b/src/jaegertracing/thrift/tutorial/as3/src/CalculatorUI.as
new file mode 100644
index 000000000..d996df5fa
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/as3/src/CalculatorUI.as
@@ -0,0 +1,142 @@
+package {
+ import flash.display.Sprite;
+ import flash.text.TextField;
+ import flash.text.TextFieldType;
+ import flash.events.MouseEvent;
+ import flash.system.Security;
+
+ import org.apache.thrift.transport.TSocket;
+ import org.apache.thrift.transport.TTransport;
+ import org.apache.thrift.protocol.TProtocol;
+ import org.apache.thrift.protocol.TBinaryProtocol;
+
+ /**
+ * Simple interface and connection logic implementation for tutorial.
+ */
+ public class CalculatorUI extends Sprite {
+ public static const BUTTON_PADDING:uint = 5;
+
+ private var mCalculatorClient:Calculator; // we use calculator through interface
+ private var mTransport:TTransport; // Transport, used to comunicate with server
+
+ private var mAddButton:Sprite;
+ private var mLeft:TextField;
+ private var mRight:TextField;
+ private var mResult:TextField;
+
+ private var pingButton:Sprite;
+
+ public function CalculatorUI() {
+ buildInterface();
+ initSecurity();
+ initConnection();
+ }
+
+ private function initSecurity():void {
+ Security.loadPolicyFile("xmlsocket://127.0.0.1:9092");
+ }
+
+ /**
+ * Example of initializing connection.
+ */
+ private function initConnection():void {
+ mTransport = new TSocket("127.0.0.1", 9090); // we connect to server
+ mTransport.open();
+ // initialize protocol:
+ var protocol:TProtocol = new TBinaryProtocol(mTransport, false, false);
+ mCalculatorClient = new CalculatorImpl(protocol); // finally, we create calculator client instance
+ }
+
+ private function onPingClick(me:MouseEvent):void {
+ if(!mTransport.isOpen()) return;
+ mCalculatorClient.ping(onPingError, onPingSuccess);
+ }
+
+ private function onPingError(error:Error):void {
+ trace("Error, while requesting ping.");
+ throw error;
+ }
+
+ private function onPingSuccess():void {
+ trace("Ping returned successfully");
+ }
+
+ private function onAddClick(me:MouseEvent):void {
+ if(!mTransport.isOpen()) return;
+ var num1:Number = Number(mLeft.text);
+ var num2:Number = Number(mRight.text);
+ mResult.text = "Processing...";
+ mCalculatorClient.add(num1, num2, onAddError, onAddSuccess);
+ }
+
+ private function onAddError(error:Error):void {
+ trace("Error, while requesting add.");
+ throw error;
+ }
+
+ private function onAddSuccess(res:Number):void {
+ mResult.text = String(res);
+ }
+
+ private function buildInterface():void {
+ addChild(pingButton = buildButton("PING"));
+ pingButton.x = (stage.stageWidth - pingButton.width) / 2;
+ pingButton.y = 10;
+ pingButton.addEventListener(MouseEvent.CLICK, onPingClick);
+
+ var top:Number = pingButton.y + pingButton.height + 20;
+ addChild(mLeft = buildDigitInput());
+ mLeft.x = 15;
+ mLeft.y = top + BUTTON_PADDING;
+ addChild(mRight = buildDigitInput());
+ mRight.x = mLeft.x + mLeft.width + 15;
+ mRight.y = top + BUTTON_PADDING;
+ addChild(mAddButton = buildButton("ADD"));
+ mAddButton.x = mRight.x + mRight.width + 15;
+ mAddButton.y = top;
+ mAddButton.addEventListener(MouseEvent.CLICK, onAddClick);
+ addChild(mResult = buildDigitInput());
+ mResult.x = mAddButton.x + mAddButton.width + 15;
+ mResult.y = top + BUTTON_PADDING;
+ }
+
+ /**
+ * Simple digit-only input field.
+ */
+ private function buildDigitInput():TextField {
+ var textField:TextField = new TextField;
+ textField.width = 75;
+ textField.height = 20;
+ textField.restrict = "0987654321.";
+ textField.type = TextFieldType.INPUT;
+ textField.background = true;
+ textField.backgroundColor = 0xaaaaff;
+ textField.textColor = 0xffff00;
+ return textField;
+ }
+
+ /**
+ * Simple button drawing.
+ */
+ private function buildButton(text:String):Sprite {
+ var button:Sprite = new Sprite;
+ var textField:TextField = new TextField;
+ textField.width = 4000;
+ textField.text = text;
+ textField.textColor = 0xffff00;
+ textField.width = textField.textWidth + 4;
+ textField.height = textField.textHeight + 4;
+ textField.mouseEnabled = false;
+ button.graphics.beginFill(0x0000ff);
+ button.graphics.lineStyle(0, 0x000000);
+ button.graphics.drawRoundRect(0, 0, textField.width + BUTTON_PADDING * 2,
+ textField.height + BUTTON_PADDING * 2, BUTTON_PADDING);
+ button.graphics.endFill();
+ button.addChild(textField);
+ textField.x = BUTTON_PADDING;
+ textField.y = BUTTON_PADDING;
+ button.useHandCursor = button.buttonMode = true;
+ return button;
+ }
+ }
+}
diff --git a/src/jaegertracing/thrift/tutorial/c_glib/Makefile.am b/src/jaegertracing/thrift/tutorial/c_glib/Makefile.am
new file mode 100755
index 000000000..f37649495
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/c_glib/Makefile.am
@@ -0,0 +1,84 @@
+#
+# 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.
+#
+AUTOMAKE_OPTIONS = subdir-objects serial-tests nostdinc
+
+BUILT_SOURCES = \
+ gen-c_glib/calculator.h \
+ gen-c_glib/shared_service.h \
+ gen-c_glib/shared_types.h \
+ gen-c_glib/tutorial_types.h
+
+AM_CFLAGS = -g -Wall -Wextra -pedantic $(GLIB_CFLAGS) $(GOBJECT_CFLAGS) $(OPENSSL_INCLUDES) @GCOV_CFLAGS@ -I$(top_builddir)/lib/c_glib/src/thrift
+AM_CPPFLAGS = -I$(top_srcdir)/lib/c_glib/src -Igen-c_glib
+AM_LDFLAGS = $(GLIB_LIBS) $(GOBJECT_LIBS) $(OPENSSL_LDFLAGS) $(OPENSSL_LIBS) @GCOV_LDFLAGS@
+
+noinst_LTLIBRARIES = \
+ libtutorialgencglib.la
+
+nodist_libtutorialgencglib_la_SOURCES = \
+ gen-c_glib/calculator.c \
+ gen-c_glib/calculator.h \
+ gen-c_glib/shared_service.c \
+ gen-c_glib/shared_service.h \
+ gen-c_glib/shared_types.c \
+ gen-c_glib/shared_types.h \
+ gen-c_glib/tutorial_types.c \
+ gen-c_glib/tutorial_types.h
+
+libtutorialgencglib_la_LIBADD = \
+ $(top_builddir)/lib/c_glib/libthrift_c_glib.la
+
+libtutorialgencglib_la_CFLAGS = \
+ $(AM_CFLAGS) -Wno-unused-function
+
+noinst_PROGRAMS = \
+ tutorial_server \
+ tutorial_client
+
+tutorial_server_SOURCES = \
+ c_glib_server.c
+tutorial_server_LDFLAGS = $(OPENSSL_LIBS)
+
+tutorial_server_LDADD = \
+ libtutorialgencglib.la \
+ $(top_builddir)/lib/c_glib/libthrift_c_glib.la
+
+tutorial_client_SOURCES = \
+ c_glib_client.c
+
+tutorial_client_LDADD = \
+ libtutorialgencglib.la \
+ $(top_builddir)/lib/c_glib/libthrift_c_glib.la
+
+
+gen-c_glib/calculator.c gen-c_glib/calculator.h gen-c_glib/shared_service.c gen-c_glib/shared_service.h gen-c_glib/shared_types.c gen-c_glib/shared_types.h gen-c_glib/tutorial_types.c gen-c_glib/tutorial_types.h: $(top_srcdir)/tutorial/tutorial.thrift
+ $(THRIFT) --gen c_glib -r $<
+
+clean-local:
+ $(RM) gen-c_glib/*
+
+tutorialserver: all
+ ./tutorial_server
+
+tutorialclient: all
+ ./tutorial_client
+
+EXTRA_DIST = \
+ c_glib_server.c \
+ c_glib_client.c
diff --git a/src/jaegertracing/thrift/tutorial/c_glib/c_glib_client.c b/src/jaegertracing/thrift/tutorial/c_glib/c_glib_client.c
new file mode 100644
index 000000000..986d5174c
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/c_glib/c_glib_client.c
@@ -0,0 +1,190 @@
+/*
+ * 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.
+ */
+
+#include <stdio.h>
+#include <glib-object.h>
+
+#include <thrift/c_glib/protocol/thrift_binary_protocol.h>
+#include <thrift/c_glib/transport/thrift_buffered_transport.h>
+#include <thrift/c_glib/transport/thrift_socket.h>
+
+#include "gen-c_glib/calculator.h"
+
+int main (void)
+{
+ ThriftSocket *socket;
+ ThriftTransport *transport;
+ ThriftProtocol *protocol;
+ CalculatorIf *client;
+
+ GError *error = NULL;
+ InvalidOperation *invalid_operation = NULL;
+
+ Work *work;
+
+ gint32 sum;
+ gint32 diff;
+
+ int exit_status = 0;
+
+#if (!GLIB_CHECK_VERSION (2, 36, 0))
+ g_type_init ();
+#endif
+
+ socket = g_object_new (THRIFT_TYPE_SOCKET,
+ "hostname", "localhost",
+ "port", 9090,
+ NULL);
+ transport = g_object_new (THRIFT_TYPE_BUFFERED_TRANSPORT,
+ "transport", socket,
+ NULL);
+ protocol = g_object_new (THRIFT_TYPE_BINARY_PROTOCOL,
+ "transport", transport,
+ NULL);
+
+ thrift_transport_open (transport, &error);
+
+
+ /* In the C (GLib) implementation of Thrift, service methods on the
+ server are accessed via a generated client class that implements
+ the service interface. In this tutorial, we access a Calculator
+ service through an instance of CalculatorClient, which implements
+ CalculatorIf. */
+ client = g_object_new (TYPE_CALCULATOR_CLIENT,
+ "input_protocol", protocol,
+ "output_protocol", protocol,
+ NULL);
+
+ /* Each of the client methods requires at least two parameters: A
+ pointer to the client-interface implementation (the client
+ object), and a handle to a GError structure to receive
+ information about any error that occurs.
+
+ On success, client methods return TRUE. A return value of FALSE
+ indicates an error occurred and the error parameter has been
+ set. */
+ if (!error && calculator_if_ping (client, &error)) {
+ puts ("ping()");
+ }
+
+ /* Service methods that return a value do so by passing the result
+ back via an output parameter (here, "sum"). */
+ if (!error && calculator_if_add (client, &sum, 1, 1, &error)) {
+ printf ("1+1=%d\n", sum);
+ }
+
+ /* Thrift structs are implemented as GObjects, with each of the
+ struct's members exposed as an object property. */
+ work = g_object_new (TYPE_WORK, NULL);
+
+ if (!error) {
+ g_object_set (work,
+ "num1", 1,
+ "num2", 0,
+ "op", OPERATION_DIVIDE,
+ NULL);
+
+ /* Exceptions are passed back from service methods in a manner
+ similar to return values. */
+ if (calculator_if_calculate (client,
+ NULL,
+ 1,
+ work,
+ &invalid_operation,
+ &error)) {
+ puts ("Whoa? We can divide by zero!");
+ }
+ else {
+ if (invalid_operation) {
+ gchar *why;
+
+ /* Like structs, exceptions are implemented as objects with
+ properties. */
+ g_object_get (invalid_operation, "why", &why, NULL);
+
+ printf ("InvalidOperation: %s\n", why);
+
+ if (why != NULL)
+ g_free (why);
+ g_object_unref (invalid_operation);
+ invalid_operation = NULL;
+ }
+
+ g_clear_error (&error);
+ }
+ }
+
+ if (!error) {
+ /* Struct objects can be reused across method invocations. */
+ g_object_set (work,
+ "num1", 15,
+ "num2", 10,
+ "op", OPERATION_SUBTRACT,
+ NULL);
+
+ if (calculator_if_calculate (client,
+ &diff,
+ 1,
+ work,
+ &invalid_operation,
+ &error)) {
+ printf ("15-10=%d\n", diff);
+ }
+ }
+
+ g_object_unref (work);
+
+ if (!error) {
+ SharedStruct *shared_struct;
+ gchar *value;
+
+ shared_struct = g_object_new (TYPE_SHARED_STRUCT, NULL);
+
+ /* As defined in the Thrift file, the Calculator service extends
+ the SharedService service. Correspondingly, in the generated
+ code CalculatorIf inherits from SharedServiceIf, and the parent
+ service's methods are accessible through a simple cast. */
+ if (shared_service_client_get_struct (SHARED_SERVICE_IF (client),
+ &shared_struct,
+ 1,
+ &error)) {
+ g_object_get (shared_struct, "value", &value, NULL);
+ printf ("Check log: %s\n", value);
+ g_free (value);
+ }
+
+ g_object_unref (shared_struct);
+ }
+
+ if (error) {
+ printf ("ERROR: %s\n", error->message);
+ g_clear_error (&error);
+
+ exit_status = 1;
+ }
+
+ thrift_transport_close (transport, NULL);
+
+ g_object_unref (client);
+ g_object_unref (protocol);
+ g_object_unref (transport);
+ g_object_unref (socket);
+
+ return exit_status;
+}
diff --git a/src/jaegertracing/thrift/tutorial/c_glib/c_glib_server.c b/src/jaegertracing/thrift/tutorial/c_glib/c_glib_server.c
new file mode 100644
index 000000000..47bf47fa0
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/c_glib/c_glib_server.c
@@ -0,0 +1,527 @@
+/*
+ * 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.
+ */
+
+#include <glib-object.h>
+#include <signal.h>
+#include <stdio.h>
+#include <string.h>
+
+#include <thrift/c_glib/thrift.h>
+#include <thrift/c_glib/protocol/thrift_binary_protocol_factory.h>
+#include <thrift/c_glib/protocol/thrift_protocol_factory.h>
+#include <thrift/c_glib/server/thrift_server.h>
+#include <thrift/c_glib/server/thrift_simple_server.h>
+#include <thrift/c_glib/transport/thrift_buffered_transport_factory.h>
+#include <thrift/c_glib/transport/thrift_server_socket.h>
+#include <thrift/c_glib/transport/thrift_server_transport.h>
+
+#include "gen-c_glib/calculator.h"
+
+G_BEGIN_DECLS
+
+/* In the C (GLib) implementation of Thrift, the actual work done by a
+ server---that is, the code that runs when a client invokes a
+ service method---is defined in a separate "handler" class that
+ implements the service interface. Here we define the
+ TutorialCalculatorHandler class, which implements the CalculatorIf
+ interface and provides the behavior expected by tutorial clients.
+ (Typically this code would be placed in its own module but for
+ clarity this tutorial is presented entirely in a single file.)
+
+ For each service the Thrift compiler generates an abstract base
+ class from which handler implementations should inherit. In our
+ case TutorialCalculatorHandler inherits from CalculatorHandler,
+ defined in gen-c_glib/calculator.h.
+
+ If you're new to GObject, try not to be intimidated by the quantity
+ of code here---much of it is boilerplate and can mostly be
+ copied-and-pasted from existing work. For more information refer to
+ the GObject Reference Manual, available online at
+ https://developer.gnome.org/gobject/. */
+
+#define TYPE_TUTORIAL_CALCULATOR_HANDLER \
+ (tutorial_calculator_handler_get_type ())
+
+#define TUTORIAL_CALCULATOR_HANDLER(obj) \
+ (G_TYPE_CHECK_INSTANCE_CAST ((obj), \
+ TYPE_TUTORIAL_CALCULATOR_HANDLER, \
+ TutorialCalculatorHandler))
+#define TUTORIAL_CALCULATOR_HANDLER_CLASS(c) \
+ (G_TYPE_CHECK_CLASS_CAST ((c), \
+ TYPE_TUTORIAL_CALCULATOR_HANDLER, \
+ TutorialCalculatorHandlerClass))
+#define IS_TUTORIAL_CALCULATOR_HANDLER(obj) \
+ (G_TYPE_CHECK_INSTANCE_TYPE ((obj), \
+ TYPE_TUTORIAL_CALCULATOR_HANDLER))
+#define IS_TUTORIAL_CALCULATOR_HANDLER_CLASS(c) \
+ (G_TYPE_CHECK_CLASS_TYPE ((c), \
+ TYPE_TUTORIAL_CALCULATOR_HANDLER))
+#define TUTORIAL_CALCULATOR_HANDLER_GET_CLASS(obj) \
+ (G_TYPE_INSTANCE_GET_CLASS ((obj), \
+ TYPE_TUTORIAL_CALCULATOR_HANDLER, \
+ TutorialCalculatorHandlerClass))
+
+struct _TutorialCalculatorHandler {
+ CalculatorHandler parent_instance;
+
+ /* private */
+ GHashTable *log;
+};
+typedef struct _TutorialCalculatorHandler TutorialCalculatorHandler;
+
+struct _TutorialCalculatorHandlerClass {
+ CalculatorHandlerClass parent_class;
+};
+typedef struct _TutorialCalculatorHandlerClass TutorialCalculatorHandlerClass;
+
+GType tutorial_calculator_handler_get_type (void);
+
+G_END_DECLS
+
+/* ---------------------------------------------------------------- */
+
+/* The implementation of TutorialCalculatorHandler follows. */
+
+G_DEFINE_TYPE (TutorialCalculatorHandler,
+ tutorial_calculator_handler,
+ TYPE_CALCULATOR_HANDLER)
+
+/* Each of a handler's methods accepts at least two parameters: A
+ pointer to the service-interface implementation (the handler object
+ itself) and a handle to a GError structure to receive information
+ about any error that occurs.
+
+ On success, a handler method returns TRUE. A return value of FALSE
+ indicates an error occurred and the error parameter has been
+ set. (Methods should not return FALSE without first setting the
+ error parameter.) */
+static gboolean
+tutorial_calculator_handler_ping (CalculatorIf *iface,
+ GError **error)
+{
+ THRIFT_UNUSED_VAR (iface);
+ THRIFT_UNUSED_VAR (error);
+
+ puts ("ping()");
+
+ return TRUE;
+}
+
+/* Service-method parameters are passed through as parameters to the
+ handler method.
+
+ If the service method returns a value an output parameter, _return,
+ is additionally passed to the handler method. This parameter should
+ be set appropriately before the method returns, whenever it
+ succeeds.
+
+ The return value from this method happens to be of a base type,
+ i32, but note if a method returns a complex type such as a map or
+ list *_return will point to a pre-allocated data structure that
+ does not need to be re-allocated and should not be destroyed. */
+static gboolean
+tutorial_calculator_handler_add (CalculatorIf *iface,
+ gint32 *_return,
+ const gint32 num1,
+ const gint32 num2,
+ GError **error)
+{
+ THRIFT_UNUSED_VAR (iface);
+ THRIFT_UNUSED_VAR (error);
+
+ printf ("add(%d,%d)\n", num1, num2);
+ *_return = num1 + num2;
+
+ return TRUE;
+}
+
+/* Any handler method can return a ThriftApplicationException to the
+ client by setting its error parameter appropriately and returning
+ FALSE. See the ThriftApplicationExceptionError enumeration defined
+ in thrift_application_exception.h for a list of recognized
+ exception types (GError codes).
+
+ If a service method can also throw a custom exception (that is, one
+ defined in the .thrift file) an additional output parameter will be
+ provided (here, "ouch") to hold an instance of the exception, when
+ necessary. Note there will be a separate parameter added for each
+ type of exception the method can throw.
+
+ Unlike return values, exception objects are never pre-created; this
+ is always the responsibility of the handler method. */
+static gboolean
+tutorial_calculator_handler_calculate (CalculatorIf *iface,
+ gint32 *_return,
+ const gint32 logid,
+ const Work *w,
+ InvalidOperation **ouch,
+ GError **error)
+{
+ TutorialCalculatorHandler *self;
+
+ gint *log_key;
+ gchar log_value[12];
+ SharedStruct *log_struct;
+
+ gint num1;
+ gint num2;
+ Operation op;
+ gboolean result = TRUE;
+
+ THRIFT_UNUSED_VAR (error);
+
+ g_return_val_if_fail (IS_TUTORIAL_CALCULATOR_HANDLER (iface),
+ FALSE);
+ self = TUTORIAL_CALCULATOR_HANDLER (iface);
+
+ /* Remember: Exception objects are never pre-created */
+ g_assert (*ouch == NULL);
+
+ /* Fetch the contents of our Work parameter.
+
+ Note that integer properties of thirty-two bits or fewer in width
+ are _always_ of type gint, regardless of the range of values they
+ hold. A common error is trying to retrieve, say, a structure
+ member defined in the .thrift file as type i16 into a variable of
+ type gint16, which will clobber variables adjacent on the
+ stack. Remember: If you're retrieving an integer property the
+ receiving variable must be of either type gint or gint64, as
+ appropriate. */
+ g_object_get ((Work *)w,
+ "num1", &num1,
+ "num2", &num2,
+ "op", &op,
+ NULL);
+
+ printf ("calculate(%d,{%d,%d,%d})\n", logid, op, num1, num2);
+
+ switch (op) {
+ case OPERATION_ADD:
+ *_return = num1 + num2;
+ break;
+
+ case OPERATION_SUBTRACT:
+ *_return = num1 - num2;
+ break;
+
+ case OPERATION_MULTIPLY:
+ *_return = num1 * num2;
+ break;
+
+ case OPERATION_DIVIDE:
+ if (num2 == 0) {
+ /* For each custom exception type a subclass of ThriftStruct is
+ generated by the Thrift compiler. Throw an exception by
+ setting the corresponding output parameter to a new instance
+ of its type and returning FALSE. */
+ *ouch = g_object_new (TYPE_INVALID_OPERATION,
+ "whatOp", op,
+ "why", g_strdup ("Cannot divide by 0"),
+ NULL);
+ result = FALSE;
+
+ /* Note the call to g_strdup above: All the memory used by a
+ ThriftStruct's properties belongs to the object itself and
+ will be freed on destruction. Removing this call to g_strdup
+ will lead to a segmentation fault as the object tries to
+ release memory allocated statically to the program. */
+ }
+ else {
+ *_return = num1 / num2;
+ }
+ break;
+
+ default:
+ *ouch = g_object_new (TYPE_INVALID_OPERATION,
+ "whatOp", op,
+ "why", g_strdup ("Invalid Operation"),
+ NULL);
+ result = FALSE;
+ }
+
+ /* On success, log a record of the result to our hash table */
+ if (result) {
+ log_key = g_malloc (sizeof *log_key);
+ *log_key = logid;
+
+ snprintf (log_value, sizeof log_value, "%d", *_return);
+
+ log_struct = g_object_new (TYPE_SHARED_STRUCT,
+ "key", *log_key,
+ "value", g_strdup (log_value),
+ NULL);
+ g_hash_table_replace (self->log, log_key, log_struct);
+ }
+
+ return result;
+}
+
+/* A one-way method has the same signature as an equivalent, regular
+ method that returns no value. */
+static gboolean
+tutorial_calculator_handler_zip (CalculatorIf *iface,
+ GError **error)
+{
+ THRIFT_UNUSED_VAR (iface);
+ THRIFT_UNUSED_VAR (error);
+
+ puts ("zip()");
+
+ return TRUE;
+}
+
+/* As specified in the .thrift file (tutorial.thrift), the Calculator
+ service extends the SharedService service. Correspondingly, in the
+ generated code the Calculator interface, CalculatorIf, extends the
+ SharedService interface, SharedServiceIf, and subclasses of
+ CalculatorHandler should implement its methods as well.
+
+ Here we provide an implementation for the getStruct method from the
+ parent service. */
+static gboolean
+tutorial_calculator_handler_get_struct (SharedServiceIf *iface,
+ SharedStruct **_return,
+ const gint32 key32,
+ GError **error)
+{
+ gint key = (gint)key32;
+ TutorialCalculatorHandler *self;
+ SharedStruct *log_struct;
+ gint log_key;
+ gchar *log_value;
+
+ THRIFT_UNUSED_VAR (error);
+
+ g_return_val_if_fail (IS_TUTORIAL_CALCULATOR_HANDLER (iface),
+ FALSE);
+ self = TUTORIAL_CALCULATOR_HANDLER (iface);
+
+ /* Remember: Complex return types are always pre-created and need
+ only be populated */
+ g_assert (*_return != NULL);
+
+ printf ("getStruct(%d)\n", key);
+
+ /* If the key exists in our log, return the corresponding logged
+ data (or an empty SharedStruct structure if it does not).
+
+ Incidentally, note we _must_ here copy the values from the hash
+ table into the return structure. All memory used by the return
+ structure belongs to the structure itself and will be freed once
+ a response is sent to the client. If we merely freed *_return and
+ set it to point to our hash-table entry, that would mean memory
+ would be released (effectively, data erased) out of the hash
+ table! */
+ log_struct = g_hash_table_lookup (self->log, &key);
+ if (log_struct != NULL) {
+ g_object_get (log_struct,
+ "key", &log_key,
+ "value", &log_value,
+ NULL);
+ g_object_set (*_return,
+ "key", log_key,
+ "value", g_strdup (log_value),
+ NULL);
+ }
+
+ return TRUE;
+}
+
+/* TutorialCalculatorHandler's instance finalizer (destructor) */
+static void
+tutorial_calculator_handler_finalize (GObject *object)
+{
+ TutorialCalculatorHandler *self =
+ TUTORIAL_CALCULATOR_HANDLER (object);
+
+ /* Free our calculation-log hash table */
+ g_hash_table_unref (self->log);
+ self->log = NULL;
+
+ /* Chain up to the parent class */
+ G_OBJECT_CLASS (tutorial_calculator_handler_parent_class)->
+ finalize (object);
+}
+
+/* TutorialCalculatorHandler's instance initializer (constructor) */
+static void
+tutorial_calculator_handler_init (TutorialCalculatorHandler *self)
+{
+ /* Create our calculation-log hash table */
+ self->log = g_hash_table_new_full (g_int_hash,
+ g_int_equal,
+ g_free,
+ g_object_unref);
+}
+
+/* TutorialCalculatorHandler's class initializer */
+static void
+tutorial_calculator_handler_class_init (TutorialCalculatorHandlerClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ SharedServiceHandlerClass *shared_service_handler_class =
+ SHARED_SERVICE_HANDLER_CLASS (klass);
+ CalculatorHandlerClass *calculator_handler_class =
+ CALCULATOR_HANDLER_CLASS (klass);
+
+ /* Register our destructor */
+ gobject_class->finalize = tutorial_calculator_handler_finalize;
+
+ /* Register our implementations of CalculatorHandler's methods */
+ calculator_handler_class->ping =
+ tutorial_calculator_handler_ping;
+ calculator_handler_class->add =
+ tutorial_calculator_handler_add;
+ calculator_handler_class->calculate =
+ tutorial_calculator_handler_calculate;
+ calculator_handler_class->zip =
+ tutorial_calculator_handler_zip;
+
+ /* Register our implementation of SharedServiceHandler's method */
+ shared_service_handler_class->get_struct =
+ tutorial_calculator_handler_get_struct;
+}
+
+/* ---------------------------------------------------------------- */
+
+/* That ends the implementation of TutorialCalculatorHandler.
+ Everything below is fairly generic code that sets up a minimal
+ Thrift server for tutorial clients. */
+
+
+/* Our server object, declared globally so it is accessible within the
+ SIGINT signal handler */
+ThriftServer *server = NULL;
+
+/* A flag that indicates whether the server was interrupted with
+ SIGINT (i.e. Ctrl-C) so we can tell whether its termination was
+ abnormal */
+gboolean sigint_received = FALSE;
+
+/* Handle SIGINT ("Ctrl-C") signals by gracefully stopping the
+ server */
+static void
+sigint_handler (int signal_number)
+{
+ THRIFT_UNUSED_VAR (signal_number);
+
+ /* Take note we were called */
+ sigint_received = TRUE;
+
+ /* Shut down the server gracefully */
+ if (server != NULL)
+ thrift_server_stop (server);
+}
+
+int main (void)
+{
+ TutorialCalculatorHandler *handler;
+ CalculatorProcessor *processor;
+
+ ThriftServerTransport *server_transport;
+ ThriftTransportFactory *transport_factory;
+ ThriftProtocolFactory *protocol_factory;
+
+ struct sigaction sigint_action;
+
+ GError *error = NULL;
+ int exit_status = 0;
+
+#if (!GLIB_CHECK_VERSION (2, 36, 0))
+ g_type_init ();
+#endif
+
+ /* Create an instance of our handler, which provides the service's
+ methods' implementation */
+ handler =
+ g_object_new (TYPE_TUTORIAL_CALCULATOR_HANDLER,
+ NULL);
+
+ /* Create an instance of the service's processor, automatically
+ generated by the Thrift compiler, which parses incoming messages
+ and dispatches them to the appropriate method in the handler */
+ processor =
+ g_object_new (TYPE_CALCULATOR_PROCESSOR,
+ "handler", handler,
+ NULL);
+
+ /* Create our server socket, which binds to the specified port and
+ listens for client connections */
+ server_transport =
+ g_object_new (THRIFT_TYPE_SERVER_SOCKET,
+ "port", 9090,
+ NULL);
+
+ /* Create our transport factory, used by the server to wrap "raw"
+ incoming connections from the client (in this case with a
+ ThriftBufferedTransport to improve performance) */
+ transport_factory =
+ g_object_new (THRIFT_TYPE_BUFFERED_TRANSPORT_FACTORY,
+ NULL);
+
+ /* Create our protocol factory, which determines which wire protocol
+ the server will use (in this case, Thrift's binary protocol) */
+ protocol_factory =
+ g_object_new (THRIFT_TYPE_BINARY_PROTOCOL_FACTORY,
+ NULL);
+
+ /* Create the server itself */
+ server =
+ g_object_new (THRIFT_TYPE_SIMPLE_SERVER,
+ "processor", processor,
+ "server_transport", server_transport,
+ "input_transport_factory", transport_factory,
+ "output_transport_factory", transport_factory,
+ "input_protocol_factory", protocol_factory,
+ "output_protocol_factory", protocol_factory,
+ NULL);
+
+ /* Install our SIGINT handler, which handles Ctrl-C being pressed by
+ stopping the server gracefully (not strictly necessary, but a
+ nice touch) */
+ memset (&sigint_action, 0, sizeof (sigint_action));
+ sigint_action.sa_handler = sigint_handler;
+ sigint_action.sa_flags = SA_RESETHAND;
+ sigaction (SIGINT, &sigint_action, NULL);
+
+ /* Start the server, which will run until its stop method is invoked
+ (from within the SIGINT handler, in this case) */
+ puts ("Starting the server...");
+ thrift_server_serve (server, &error);
+
+ /* If the server stopped for any reason other than having been
+ interrupted by the user, report the error */
+ if (!sigint_received) {
+ g_message ("thrift_server_serve: %s",
+ error != NULL ? error->message : "(null)");
+ g_clear_error (&error);
+ }
+
+ puts ("done.");
+
+ g_object_unref (server);
+ g_object_unref (transport_factory);
+ g_object_unref (protocol_factory);
+ g_object_unref (server_transport);
+
+ g_object_unref (processor);
+ g_object_unref (handler);
+
+ return exit_status;
+}
diff --git a/src/jaegertracing/thrift/tutorial/cl/Makefile.am b/src/jaegertracing/thrift/tutorial/cl/Makefile.am
new file mode 100755
index 000000000..2b2013a3c
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/cl/Makefile.am
@@ -0,0 +1,65 @@
+#
+# 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.
+
+setup-local-lisp-env: ensure-externals.sh
+ bash ensure-externals.sh
+
+gen-cl: $(top_srcdir)/tutorial/tutorial.thrift
+ $(THRIFT) --gen cl -r $<
+
+ALL_FILE_PREREQS = \
+ load-locally.lisp \
+ make-tutorial-server.lisp \
+ make-tutorial-client.lisp \
+ shared-implementation.lisp \
+ thrift-tutorial.asd \
+ tutorial-implementation.lisp
+
+# NOTE: the server and client cannot be built in parallel
+# because on loading the make-tutorial-* scripts SBCL will
+# attempt to compile their dependencies. Unfortunately,
+# because their dependencies are shared, parallel jobs can
+# end up overwriting or corrupting the compiled files
+all-local: gen-cl setup-local-lisp-env $(ALL_FILE_PREREQS)
+ $(SBCL) --script make-tutorial-server.lisp
+ $(SBCL) --script make-tutorial-client.lisp
+
+tutorialserver: all
+ ./TutorialServer
+
+tutorialclient: all
+ ./TutorialClient
+
+clean-local:
+ -$(RM) -r gen-*
+ -$(RM) -r externals
+ -$(RM) -r quicklisp
+ -$(RM) -r lib
+ -$(RM) quicklisp.lisp
+ -$(RM) backport-update.zip
+ -$(RM) shared-implementation.fasl
+ -$(RM) tutorial-implementation.fasl
+ -$(RM) TutorialServer
+ -$(RM) TutorialClient
+
+EXTRA_DIST = \
+ tutorial-implementation.lisp \
+ shared-implementation.lisp \
+ thrift-tutorial.asd \
+ make-tutorial-server.lisp \
+ make-tutorial-client.lisp
diff --git a/src/jaegertracing/thrift/tutorial/cl/ensure-externals.sh b/src/jaegertracing/thrift/tutorial/cl/ensure-externals.sh
new file mode 120000
index 000000000..5ae8c5657
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/cl/ensure-externals.sh
@@ -0,0 +1 @@
+../../lib/cl/ensure-externals.sh \ No newline at end of file
diff --git a/src/jaegertracing/thrift/tutorial/cl/load-locally.lisp b/src/jaegertracing/thrift/tutorial/cl/load-locally.lisp
new file mode 100644
index 000000000..b52a0a269
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/cl/load-locally.lisp
@@ -0,0 +1,22 @@
+(in-package #:cl-user)
+
+;;;; 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.
+
+;;;; Just a script for loading the library itself, using bundled dependencies.
+;;;; This is an identical copy of the file in lib/cl.
+
+(require "asdf")
+
+(load (merge-pathnames "externals/bundle.lisp" *load-truename*))
+(asdf:load-asd (merge-pathnames "lib/de.setf.thrift-backport-update/thrift.asd" *load-truename*))
+(asdf:load-system :thrift)
diff --git a/src/jaegertracing/thrift/tutorial/cl/make-tutorial-client.lisp b/src/jaegertracing/thrift/tutorial/cl/make-tutorial-client.lisp
new file mode 100644
index 000000000..3a6d86134
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/cl/make-tutorial-client.lisp
@@ -0,0 +1,51 @@
+(in-package #:cl-user)
+
+;;;; 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.
+
+(require "asdf")
+(load (merge-pathnames "load-locally.lisp" *load-truename*))
+(asdf:load-system :net.didierverna.clon)
+(asdf:load-asd (merge-pathnames "gen-cl/shared/thrift-gen-shared.asd" *load-truename*))
+(asdf:load-asd (merge-pathnames "gen-cl/tutorial/thrift-gen-tutorial.asd" *load-truename*))
+(asdf:load-asd (merge-pathnames "thrift-tutorial.asd" *load-truename*))
+(asdf:load-system :thrift-tutorial)
+
+(net.didierverna.clon:nickname-package)
+
+(defun main ()
+ "Entry point for the binary."
+ (thrift:with-client (prot #u"thrift://127.0.0.1:9090")
+ (tutorial.calculator:ping prot)
+ (format t "ping()~%")
+ (format t "1 + 1 = ~a~%" (tutorial.calculator:add prot 1 1))
+ (let ((work-instance (tutorial:make-work :num1 5
+ :num2 0
+ :op tutorial:operation.divide
+ :comment "Booya!")))
+ (handler-case (format t
+ "5 / 0 = ~a - Oh, really? An exception should have been thrown here.~%"
+ (tutorial.calculator:calculate prot 1 work-instance))
+ (tutorial:invalidoperation (e)
+ (format t "---~%(Expected) Invalid Operation caught: ~%~a~%---~%" e))))
+ (let ((work-instance (tutorial:make-work :num1 15
+ :num2 10
+ :op tutorial:operation.subtract
+ :comment "Playing nice this time.")))
+ (handler-case (format t
+ "15 - 10 = ~a~%"
+ (tutorial.calculator:calculate prot 1 work-instance))
+ (tutorial:invalidoperation (e)
+ (format t "---~%(Unexpected) Invalid Operation caught: ~%~a~%---~%" e))))
+ (format t "Check log: ~a~%" (shared.shared-service:get-struct prot 1))))
+
+(clon:dump "TutorialClient" main)
diff --git a/src/jaegertracing/thrift/tutorial/cl/make-tutorial-server.lisp b/src/jaegertracing/thrift/tutorial/cl/make-tutorial-server.lisp
new file mode 100644
index 000000000..4cf1a9026
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/cl/make-tutorial-server.lisp
@@ -0,0 +1,29 @@
+(in-package #:cl-user)
+
+;;;; 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.
+
+(require "asdf")
+(load (merge-pathnames "load-locally.lisp" *load-truename*))
+(asdf:load-system :net.didierverna.clon)
+(asdf:load-asd (merge-pathnames "gen-cl/shared/thrift-gen-shared.asd" *load-truename*))
+(asdf:load-asd (merge-pathnames "gen-cl/tutorial/thrift-gen-tutorial.asd" *load-truename*))
+(asdf:load-asd (merge-pathnames "thrift-tutorial.asd" *load-truename*))
+(asdf:load-system :thrift-tutorial)
+
+(net.didierverna.clon:nickname-package)
+
+(defun main ()
+ "Entry point for the binary."
+ (thrift:serve #u"thrift://127.0.0.1:9090" tutorial:calculator))
+
+(clon:dump "TutorialServer" main)
diff --git a/src/jaegertracing/thrift/tutorial/cl/shared-implementation.lisp b/src/jaegertracing/thrift/tutorial/cl/shared-implementation.lisp
new file mode 100644
index 000000000..c197626a5
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/cl/shared-implementation.lisp
@@ -0,0 +1,25 @@
+(in-package #:shared-implementation)
+
+;;;; 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.
+
+(defvar *structs* (make-hash-table))
+
+(defun shared.shared-service-implementation:get-struct (key)
+ (format t "getStruct(~a)~%" key)
+ (gethash key *structs*))
+
+(defun add-log (key value)
+ (setf (gethash key *structs*)
+ (make-instance 'shared:sharedstruct
+ :key key
+ :value (write-to-string value))))
diff --git a/src/jaegertracing/thrift/tutorial/cl/thrift-tutorial.asd b/src/jaegertracing/thrift/tutorial/cl/thrift-tutorial.asd
new file mode 100644
index 000000000..8a0353763
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/cl/thrift-tutorial.asd
@@ -0,0 +1,17 @@
+;;;; 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.
+
+(asdf:defsystem #:thrift-tutorial
+ :depends-on (#:thrift-gen-tutorial)
+ :serial t
+ :components ((:file "shared-implementation")
+ (:file "tutorial-implementation")))
diff --git a/src/jaegertracing/thrift/tutorial/cl/tutorial-implementation.lisp b/src/jaegertracing/thrift/tutorial/cl/tutorial-implementation.lisp
new file mode 100644
index 000000000..5c92fe405
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/cl/tutorial-implementation.lisp
@@ -0,0 +1,41 @@
+(in-package #:tutorial-implementation)
+
+;;;; 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.
+
+(defun tutorial.calculator-implementation:ping ()
+ (format t "ping()~%"))
+
+(defun tutorial.calculator-implementation:add (num1 num2)
+ (format t "add(~a, ~a)~%" num1 num2)
+ (+ num1 num2))
+
+(defun tutorial.calculator-implementation:calculate (logid work)
+ (format t "calculate(~a, ~a)~%" logid work)
+ (handler-case
+ (let* ((num1 (tutorial:work-num1 work))
+ (num2 (tutorial:work-num2 work))
+ (op (tutorial:work-op work))
+ (result
+ (cond
+ ((= op tutorial:operation.add) (+ num1 num2))
+ ((= op tutorial:operation.subtract) (- num1 num2))
+ ((= op tutorial:operation.multiply) (* num1 num2))
+ ((= op tutorial:operation.divide) (/ num1 num2)))))
+ (shared-implementation::add-log logid result)
+ result)
+ (division-by-zero () (error 'tutorial:invalidoperation
+ :why "Division by zero."
+ :what-op (tutorial:work-op work)))))
+
+(defun tutorial.calculator-implementation:zip ()
+ (format t "zip()~%"))
diff --git a/src/jaegertracing/thrift/tutorial/cpp/CMakeLists.txt b/src/jaegertracing/thrift/tutorial/cpp/CMakeLists.txt
new file mode 100644
index 000000000..c6d8fc320
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/cpp/CMakeLists.txt
@@ -0,0 +1,57 @@
+#
+# 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.
+#
+
+include(BoostMacros)
+REQUIRE_BOOST_HEADERS()
+
+#Make sure gen-cpp files can be included
+include_directories("${CMAKE_CURRENT_BINARY_DIR}")
+include_directories("${CMAKE_CURRENT_BINARY_DIR}/gen-cpp")
+include_directories("${PROJECT_SOURCE_DIR}/lib/cpp/src")
+
+include(ThriftMacros)
+
+set(tutorialgencpp_SOURCES
+ gen-cpp/Calculator.cpp
+ gen-cpp/SharedService.cpp
+ gen-cpp/shared_constants.cpp
+ gen-cpp/shared_types.cpp
+ gen-cpp/tutorial_constants.cpp
+ gen-cpp/tutorial_types.cpp
+)
+add_library(tutorialgencpp STATIC ${tutorialgencpp_SOURCES})
+LINK_AGAINST_THRIFT_LIBRARY(tutorialgencpp thrift)
+
+add_custom_command(OUTPUT gen-cpp/Calculator.cpp gen-cpp/SharedService.cpp gen-cpp/shared_constants.cpp gen-cpp/shared_types.cpp gen-cpp/tutorial_constants.cpp gen-cpp/tutorial_types.cpp
+ COMMAND ${THRIFT_COMPILER} --gen cpp -r ${PROJECT_SOURCE_DIR}/tutorial/tutorial.thrift
+)
+
+add_executable(TutorialServer CppServer.cpp)
+target_link_libraries(TutorialServer tutorialgencpp)
+LINK_AGAINST_THRIFT_LIBRARY(TutorialServer thrift)
+if (ZLIB_FOUND)
+ target_link_libraries(TutorialServer ${ZLIB_LIBRARIES})
+endif ()
+
+add_executable(TutorialClient CppClient.cpp)
+target_link_libraries(TutorialClient tutorialgencpp)
+LINK_AGAINST_THRIFT_LIBRARY(TutorialClient thrift)
+if (ZLIB_FOUND)
+ target_link_libraries(TutorialClient ${ZLIB_LIBRARIES})
+endif ()
diff --git a/src/jaegertracing/thrift/tutorial/cpp/CppClient.cpp b/src/jaegertracing/thrift/tutorial/cpp/CppClient.cpp
new file mode 100644
index 000000000..520841143
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/cpp/CppClient.cpp
@@ -0,0 +1,80 @@
+/*
+ * 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.
+ */
+
+#include <iostream>
+
+#include <thrift/protocol/TBinaryProtocol.h>
+#include <thrift/transport/TSocket.h>
+#include <thrift/transport/TTransportUtils.h>
+
+#include "../gen-cpp/Calculator.h"
+
+using namespace std;
+using namespace apache::thrift;
+using namespace apache::thrift::protocol;
+using namespace apache::thrift::transport;
+
+using namespace tutorial;
+using namespace shared;
+
+int main() {
+ std::shared_ptr<TTransport> socket(new TSocket("localhost", 9090));
+ std::shared_ptr<TTransport> transport(new TBufferedTransport(socket));
+ std::shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport));
+ CalculatorClient client(protocol);
+
+ try {
+ transport->open();
+
+ client.ping();
+ cout << "ping()" << endl;
+
+ cout << "1 + 1 = " << client.add(1, 1) << endl;
+
+ Work work;
+ work.op = Operation::DIVIDE;
+ work.num1 = 1;
+ work.num2 = 0;
+
+ try {
+ client.calculate(1, work);
+ cout << "Whoa? We can divide by zero!" << endl;
+ } catch (InvalidOperation& io) {
+ cout << "InvalidOperation: " << io.why << endl;
+ // or using generated operator<<: cout << io << endl;
+ // or by using std::exception native method what(): cout << io.what() << endl;
+ }
+
+ work.op = Operation::SUBTRACT;
+ work.num1 = 15;
+ work.num2 = 10;
+ int32_t diff = client.calculate(1, work);
+ cout << "15 - 10 = " << diff << endl;
+
+ // Note that C++ uses return by reference for complex types to avoid
+ // costly copy construction
+ SharedStruct ss;
+ client.getStruct(ss, 1);
+ cout << "Received log: " << ss << endl;
+
+ transport->close();
+ } catch (TException& tx) {
+ cout << "ERROR: " << tx.what() << endl;
+ }
+}
diff --git a/src/jaegertracing/thrift/tutorial/cpp/CppServer.cpp b/src/jaegertracing/thrift/tutorial/cpp/CppServer.cpp
new file mode 100644
index 000000000..635afefda
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/cpp/CppServer.cpp
@@ -0,0 +1,179 @@
+/*
+ * 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.
+ */
+
+#include <thrift/concurrency/ThreadManager.h>
+#include <thrift/concurrency/ThreadFactory.h>
+#include <thrift/protocol/TBinaryProtocol.h>
+#include <thrift/server/TSimpleServer.h>
+#include <thrift/server/TThreadPoolServer.h>
+#include <thrift/server/TThreadedServer.h>
+#include <thrift/transport/TServerSocket.h>
+#include <thrift/transport/TSocket.h>
+#include <thrift/transport/TTransportUtils.h>
+#include <thrift/TToString.h>
+
+#include <iostream>
+#include <stdexcept>
+#include <sstream>
+
+#include "../gen-cpp/Calculator.h"
+
+using namespace std;
+using namespace apache::thrift;
+using namespace apache::thrift::concurrency;
+using namespace apache::thrift::protocol;
+using namespace apache::thrift::transport;
+using namespace apache::thrift::server;
+
+using namespace tutorial;
+using namespace shared;
+
+class CalculatorHandler : public CalculatorIf {
+public:
+ CalculatorHandler() = default;
+
+ void ping() override { cout << "ping()" << endl; }
+
+ int32_t add(const int32_t n1, const int32_t n2) override {
+ cout << "add(" << n1 << ", " << n2 << ")" << endl;
+ return n1 + n2;
+ }
+
+ int32_t calculate(const int32_t logid, const Work& work) override {
+ cout << "calculate(" << logid << ", " << work << ")" << endl;
+ int32_t val;
+
+ switch (work.op) {
+ case Operation::ADD:
+ val = work.num1 + work.num2;
+ break;
+ case Operation::SUBTRACT:
+ val = work.num1 - work.num2;
+ break;
+ case Operation::MULTIPLY:
+ val = work.num1 * work.num2;
+ break;
+ case Operation::DIVIDE:
+ if (work.num2 == 0) {
+ InvalidOperation io;
+ io.whatOp = work.op;
+ io.why = "Cannot divide by 0";
+ throw io;
+ }
+ val = work.num1 / work.num2;
+ break;
+ default:
+ InvalidOperation io;
+ io.whatOp = work.op;
+ io.why = "Invalid Operation";
+ throw io;
+ }
+
+ SharedStruct ss;
+ ss.key = logid;
+ ss.value = to_string(val);
+
+ log[logid] = ss;
+
+ return val;
+ }
+
+ void getStruct(SharedStruct& ret, const int32_t logid) override {
+ cout << "getStruct(" << logid << ")" << endl;
+ ret = log[logid];
+ }
+
+ void zip() override { cout << "zip()" << endl; }
+
+protected:
+ map<int32_t, SharedStruct> log;
+};
+
+/*
+ CalculatorIfFactory is code generated.
+ CalculatorCloneFactory is useful for getting access to the server side of the
+ transport. It is also useful for making per-connection state. Without this
+ CloneFactory, all connections will end up sharing the same handler instance.
+*/
+class CalculatorCloneFactory : virtual public CalculatorIfFactory {
+ public:
+ ~CalculatorCloneFactory() override = default;
+ CalculatorIf* getHandler(const ::apache::thrift::TConnectionInfo& connInfo) override
+ {
+ std::shared_ptr<TSocket> sock = std::dynamic_pointer_cast<TSocket>(connInfo.transport);
+ cout << "Incoming connection\n";
+ cout << "\tSocketInfo: " << sock->getSocketInfo() << "\n";
+ cout << "\tPeerHost: " << sock->getPeerHost() << "\n";
+ cout << "\tPeerAddress: " << sock->getPeerAddress() << "\n";
+ cout << "\tPeerPort: " << sock->getPeerPort() << "\n";
+ return new CalculatorHandler;
+ }
+ void releaseHandler( ::shared::SharedServiceIf* handler) override {
+ delete handler;
+ }
+};
+
+int main() {
+ TThreadedServer server(
+ std::make_shared<CalculatorProcessorFactory>(std::make_shared<CalculatorCloneFactory>()),
+ std::make_shared<TServerSocket>(9090), //port
+ std::make_shared<TBufferedTransportFactory>(),
+ std::make_shared<TBinaryProtocolFactory>());
+
+ /*
+ // if you don't need per-connection state, do the following instead
+ TThreadedServer server(
+ std::make_shared<CalculatorProcessor>(std::make_shared<CalculatorHandler>()),
+ std::make_shared<TServerSocket>(9090), //port
+ std::make_shared<TBufferedTransportFactory>(),
+ std::make_shared<TBinaryProtocolFactory>());
+ */
+
+ /**
+ * Here are some alternate server types...
+
+ // This server only allows one connection at a time, but spawns no threads
+ TSimpleServer server(
+ std::make_shared<CalculatorProcessor>(std::make_shared<CalculatorHandler>()),
+ std::make_shared<TServerSocket>(9090),
+ std::make_shared<TBufferedTransportFactory>(),
+ std::make_shared<TBinaryProtocolFactory>());
+
+ const int workerCount = 4;
+
+ std::shared_ptr<ThreadManager> threadManager =
+ ThreadManager::newSimpleThreadManager(workerCount);
+ threadManager->threadFactory(
+ std::make_shared<ThreadFactory>());
+ threadManager->start();
+
+ // This server allows "workerCount" connection at a time, and reuses threads
+ TThreadPoolServer server(
+ std::make_shared<CalculatorProcessorFactory>(std::make_shared<CalculatorCloneFactory>()),
+ std::make_shared<TServerSocket>(9090),
+ std::make_shared<TBufferedTransportFactory>(),
+ std::make_shared<TBinaryProtocolFactory>(),
+ threadManager);
+ */
+
+ cout << "Starting the server..." << endl;
+ server.serve();
+ cout << "Done." << endl;
+ return 0;
+}
diff --git a/src/jaegertracing/thrift/tutorial/cpp/Makefile.am b/src/jaegertracing/thrift/tutorial/cpp/Makefile.am
new file mode 100755
index 000000000..95497d5f3
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/cpp/Makefile.am
@@ -0,0 +1,86 @@
+#
+# 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.
+#
+AUTOMAKE_OPTIONS = subdir-objects serial-tests nostdinc
+
+BUILT_SOURCES = gen-cpp/shared_types.cpp \
+ gen-cpp/tutorial_types.cpp
+
+noinst_LTLIBRARIES = libtutorialgencpp.la
+nodist_libtutorialgencpp_la_SOURCES = \
+ gen-cpp/Calculator.cpp \
+ gen-cpp/Calculator.h \
+ gen-cpp/SharedService.cpp \
+ gen-cpp/SharedService.h \
+ gen-cpp/shared_constants.cpp \
+ gen-cpp/shared_constants.h \
+ gen-cpp/shared_types.cpp \
+ gen-cpp/shared_types.h \
+ gen-cpp/tutorial_constants.cpp \
+ gen-cpp/tutorial_constants.h \
+ gen-cpp/tutorial_types.cpp \
+ gen-cpp/tutorial_types.h
+
+
+
+libtutorialgencpp_la_LIBADD = $(top_builddir)/lib/cpp/libthrift.la
+
+noinst_PROGRAMS = \
+ TutorialServer \
+ TutorialClient
+
+TutorialServer_SOURCES = \
+ CppServer.cpp
+
+TutorialServer_LDADD = \
+ libtutorialgencpp.la \
+ $(top_builddir)/lib/cpp/libthrift.la
+
+TutorialClient_SOURCES = \
+ CppClient.cpp
+
+TutorialClient_LDADD = \
+ libtutorialgencpp.la \
+ $(top_builddir)/lib/cpp/libthrift.la
+
+#
+# Common thrift code generation rules
+#
+gen-cpp/Calculator.cpp gen-cpp/SharedService.cpp gen-cpp/shared_constants.cpp gen-cpp/shared_types.cpp gen-cpp/tutorial_constants.cpp gen-cpp/tutorial_types.cpp: $(top_srcdir)/tutorial/tutorial.thrift
+ $(THRIFT) --gen cpp -r $<
+
+AM_CPPFLAGS = $(BOOST_CPPFLAGS) $(LIBEVENT_CPPFLAGS) -I$(top_srcdir)/lib/cpp/src -Igen-cpp
+AM_CXXFLAGS = -Wall -Wextra -pedantic
+AM_LDFLAGS = $(BOOST_LDFLAGS) $(LIBEVENT_LDFLAGS)
+
+clean-local:
+ $(RM) gen-cpp/*
+
+tutorialserver: all
+ ./TutorialServer
+
+tutorialclient: all
+ ./TutorialClient
+
+style-local:
+ $(CPPSTYLE_CMD)
+
+EXTRA_DIST = \
+ CMakeLists.txt \
+ CppClient.cpp \
+ CppServer.cpp
diff --git a/src/jaegertracing/thrift/tutorial/csharp/CsharpClient/CsharpClient.cs b/src/jaegertracing/thrift/tutorial/csharp/CsharpClient/CsharpClient.cs
new file mode 100644
index 000000000..113a47223
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/csharp/CsharpClient/CsharpClient.cs
@@ -0,0 +1,92 @@
+/*
+ * 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 System;
+using Thrift;
+using Thrift.Protocol;
+using Thrift.Server;
+using Thrift.Transport;
+
+
+namespace CSharpTutorial
+{
+ public class CSharpClient
+ {
+ public static void Main()
+ {
+ try
+ {
+ TTransport transport = new TSocket("localhost", 9090);
+ TProtocol protocol = new TBinaryProtocol(transport);
+ Calculator.Client client = new Calculator.Client(protocol);
+
+ transport.Open();
+ try
+ {
+ client.ping();
+ Console.WriteLine("ping()");
+
+ int sum = client.add(1, 1);
+ Console.WriteLine("1+1={0}", sum);
+
+ Work work = new Work();
+
+ work.Op = Operation.DIVIDE;
+ work.Num1 = 1;
+ work.Num2 = 0;
+ try
+ {
+ int quotient = client.calculate(1, work);
+ Console.WriteLine("Whoa we can divide by 0");
+ }
+ catch (InvalidOperation io)
+ {
+ Console.WriteLine("Invalid operation: " + io.Why);
+ }
+
+ work.Op = Operation.SUBTRACT;
+ work.Num1 = 15;
+ work.Num2 = 10;
+ try
+ {
+ int diff = client.calculate(1, work);
+ Console.WriteLine("15-10={0}", diff);
+ }
+ catch (InvalidOperation io)
+ {
+ Console.WriteLine("Invalid operation: " + io.Why);
+ }
+
+ SharedStruct log = client.getStruct(1);
+ Console.WriteLine("Check log: {0}", log.Value);
+
+ }
+ finally
+ {
+ transport.Close();
+ }
+ }
+ catch (TApplicationException x)
+ {
+ Console.WriteLine(x.StackTrace);
+ }
+
+ }
+ }
+}
diff --git a/src/jaegertracing/thrift/tutorial/csharp/CsharpClient/CsharpClient.csproj b/src/jaegertracing/thrift/tutorial/csharp/CsharpClient/CsharpClient.csproj
new file mode 100644
index 000000000..1ea7ff639
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/csharp/CsharpClient/CsharpClient.csproj
@@ -0,0 +1,110 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.30729</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{18F24087-4760-43DA-ACAB-7B9F0E096B11}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>CsharpClient</RootNamespace>
+ <AssemblyName>CsharpClient</AssemblyName>
+ <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Core">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Xml.Linq">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Data.DataSetExtensions">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="..\gen-csharp\Calculator.cs">
+ <Link>Calculator.cs</Link>
+ </Compile>
+ <Compile Include="..\gen-csharp\InvalidOperation.cs">
+ <Link>InvalidOperation.cs</Link>
+ </Compile>
+ <Compile Include="..\gen-csharp\Operation.cs">
+ <Link>Operation.cs</Link>
+ </Compile>
+ <Compile Include="..\gen-csharp\SharedService.cs">
+ <Link>SharedService.cs</Link>
+ </Compile>
+ <Compile Include="..\gen-csharp\SharedStruct.cs">
+ <Link>SharedStruct.cs</Link>
+ </Compile>
+ <Compile Include="..\gen-csharp\tutorial.Constants.cs">
+ <Link>tutorial.Constants.cs</Link>
+ </Compile>
+ <Compile Include="..\gen-csharp\Work.cs">
+ <Link>Work.cs</Link>
+ </Compile>
+ <Compile Include="CsharpClient.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\..\lib\csharp\src\Thrift.csproj">
+ <Project>{499eb63c-d74c-47e8-ae48-a2fc94538e9d}</Project>
+ <Name>Thrift</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <PropertyGroup>
+ <PreBuildEvent>pushd "$(SolutionDir)"
+thrift -gen csharp -r ../tutorial.thrift
+popd
+</PreBuildEvent>
+ </PropertyGroup>
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project> \ No newline at end of file
diff --git a/src/jaegertracing/thrift/tutorial/csharp/CsharpClient/Properties/AssemblyInfo.cs b/src/jaegertracing/thrift/tutorial/csharp/CsharpClient/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000..bae5e70c9
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/csharp/CsharpClient/Properties/AssemblyInfo.cs
@@ -0,0 +1,55 @@
+/*
+ * 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 System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("CsharpClient")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("The Apache Software Foundation")]
+[assembly: AssemblyProduct("Thrift")]
+[assembly: AssemblyCopyright("The Apache Software Foundation")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("1a461214-fa28-452a-bd1d-d23ca8e947e3")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("0.13.0.0")]
+[assembly: AssemblyFileVersion("0.13.0.0")]
diff --git a/src/jaegertracing/thrift/tutorial/csharp/CsharpServer/CsharpServer.cs b/src/jaegertracing/thrift/tutorial/csharp/CsharpServer/CsharpServer.cs
new file mode 100644
index 000000000..439790aaf
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/csharp/CsharpServer/CsharpServer.cs
@@ -0,0 +1,129 @@
+/*
+ * 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 System;
+using System.Collections.Generic;
+using Thrift.Server;
+using Thrift.Transport;
+
+namespace CSharpTutorial
+{
+ public class CalculatorHandler : Calculator.Iface
+ {
+ Dictionary<int, SharedStruct> log;
+
+ public CalculatorHandler()
+ {
+ log = new Dictionary<int, SharedStruct>();
+ }
+
+ public void ping()
+ {
+ Console.WriteLine("ping()");
+ }
+
+ public int add(int n1, int n2)
+ {
+ Console.WriteLine("add({0},{1})", n1, n2);
+ return n1 + n2;
+ }
+
+ public int calculate(int logid, Work work)
+ {
+ Console.WriteLine("calculate({0}, [{1},{2},{3}])", logid, work.Op, work.Num1, work.Num2);
+ int val = 0;
+ switch (work.Op)
+ {
+ case Operation.ADD:
+ val = work.Num1 + work.Num2;
+ break;
+
+ case Operation.SUBTRACT:
+ val = work.Num1 - work.Num2;
+ break;
+
+ case Operation.MULTIPLY:
+ val = work.Num1 * work.Num2;
+ break;
+
+ case Operation.DIVIDE:
+ if (work.Num2 == 0)
+ {
+ InvalidOperation io = new InvalidOperation();
+ io.WhatOp = (int)work.Op;
+ io.Why = "Cannot divide by 0";
+ throw io;
+ }
+ val = work.Num1 / work.Num2;
+ break;
+
+ default:
+ {
+ InvalidOperation io = new InvalidOperation();
+ io.WhatOp = (int)work.Op;
+ io.Why = "Unknown operation";
+ throw io;
+ }
+ }
+
+ SharedStruct entry = new SharedStruct();
+ entry.Key = logid;
+ entry.Value = val.ToString();
+ log[logid] = entry;
+
+ return val;
+ }
+
+ public SharedStruct getStruct(int key)
+ {
+ Console.WriteLine("getStruct({0})", key);
+ return log[key];
+ }
+
+ public void zip()
+ {
+ Console.WriteLine("zip()");
+ }
+ }
+
+ public class CSharpServer
+ {
+ public static void Main()
+ {
+ try
+ {
+ CalculatorHandler handler = new CalculatorHandler();
+ Calculator.Processor processor = new Calculator.Processor(handler);
+ TServerTransport serverTransport = new TServerSocket(9090);
+ TServer server = new TSimpleServer(processor, serverTransport);
+
+ // Use this for a multithreaded server
+ // server = new TThreadPoolServer(processor, serverTransport);
+
+ Console.WriteLine("Starting the server...");
+ server.Serve();
+ }
+ catch (Exception x)
+ {
+ Console.WriteLine(x.StackTrace);
+ }
+ Console.WriteLine("done.");
+ }
+ }
+}
diff --git a/src/jaegertracing/thrift/tutorial/csharp/CsharpServer/CsharpServer.csproj b/src/jaegertracing/thrift/tutorial/csharp/CsharpServer/CsharpServer.csproj
new file mode 100644
index 000000000..07481806c
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/csharp/CsharpServer/CsharpServer.csproj
@@ -0,0 +1,111 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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.
+-->
+<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+ <ProductVersion>9.0.30729</ProductVersion>
+ <SchemaVersion>2.0</SchemaVersion>
+ <ProjectGuid>{66707BAE-BBF9-4F03-B53E-BE3AD58322F8}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <AppDesignerFolder>Properties</AppDesignerFolder>
+ <RootNamespace>CsharpServer</RootNamespace>
+ <AssemblyName>CsharpServer</AssemblyName>
+ <TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
+ <FileAlignment>512</FileAlignment>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="System" />
+ <Reference Include="System.Core">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Xml.Linq">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Data.DataSetExtensions">
+ <RequiredTargetFramework>3.5</RequiredTargetFramework>
+ </Reference>
+ <Reference Include="System.Data" />
+ <Reference Include="System.Xml" />
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="..\gen-csharp\Calculator.cs">
+ <Link>Calculator.cs</Link>
+ </Compile>
+ <Compile Include="..\gen-csharp\InvalidOperation.cs">
+ <Link>InvalidOperation.cs</Link>
+ </Compile>
+ <Compile Include="..\gen-csharp\Operation.cs">
+ <Link>Operation.cs</Link>
+ </Compile>
+ <Compile Include="..\gen-csharp\SharedService.cs">
+ <Link>SharedService.cs</Link>
+ </Compile>
+ <Compile Include="..\gen-csharp\SharedStruct.cs">
+ <Link>SharedStruct.cs</Link>
+ </Compile>
+ <Compile Include="..\gen-csharp\tutorial.Constants.cs">
+ <Link>tutorial.Constants.cs</Link>
+ </Compile>
+ <Compile Include="..\gen-csharp\Work.cs">
+ <Link>Work.cs</Link>
+ </Compile>
+ <Compile Include="CsharpServer.cs" />
+ <Compile Include="Properties\AssemblyInfo.cs" />
+ </ItemGroup>
+ <ItemGroup>
+ <ProjectReference Include="..\..\..\lib\csharp\src\Thrift.csproj">
+ <Project>{499eb63c-d74c-47e8-ae48-a2fc94538e9d}</Project>
+ <Name>Thrift</Name>
+ </ProjectReference>
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+ <PropertyGroup>
+ <PreBuildEvent>pushd "$(SolutionDir)"
+thrift -gen csharp -r ../tutorial.thrift
+popd
+
+</PreBuildEvent>
+ </PropertyGroup>
+ <!-- To modify your build process, add your task inside one of the targets below and uncomment it.
+ Other similar extension points exist, see Microsoft.Common.targets.
+ <Target Name="BeforeBuild">
+ </Target>
+ <Target Name="AfterBuild">
+ </Target>
+ -->
+</Project> \ No newline at end of file
diff --git a/src/jaegertracing/thrift/tutorial/csharp/CsharpServer/Properties/AssemblyInfo.cs b/src/jaegertracing/thrift/tutorial/csharp/CsharpServer/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000..e3ed39a9c
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/csharp/CsharpServer/Properties/AssemblyInfo.cs
@@ -0,0 +1,55 @@
+/*
+ * 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 System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("CsharpServer")]
+[assembly: AssemblyDescription("")]
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("The Apache Software Foundation")]
+[assembly: AssemblyProduct("Thrift")]
+[assembly: AssemblyCopyright("The Apache Software Foundation")]
+[assembly: AssemblyTrademark("")]
+[assembly: AssemblyCulture("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+[assembly: Guid("e3b428f4-b2e9-4fc1-8a34-84abc4339860")]
+
+// Version information for an assembly consists of the following four values:
+//
+// Major Version
+// Minor Version
+// Build Number
+// Revision
+//
+// You can specify all the values or you can default the Build and Revision Numbers
+// by using the '*' as shown below:
+// [assembly: AssemblyVersion("1.0.*")]
+[assembly: AssemblyVersion("0.13.0.0")]
+[assembly: AssemblyFileVersion("0.13.0.0")]
diff --git a/src/jaegertracing/thrift/tutorial/csharp/tutorial.sln b/src/jaegertracing/thrift/tutorial/csharp/tutorial.sln
new file mode 100644
index 000000000..ec57a188d
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/csharp/tutorial.sln
@@ -0,0 +1,39 @@
+
+Microsoft Visual Studio Solution File, Format Version 11.00
+# Visual Studio 2010
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Thrift", "..\..\lib\csharp\src\Thrift.csproj", "{499EB63C-D74C-47E8-AE48-A2FC94538E9D}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CsharpClient", "CsharpClient\CsharpClient.csproj", "{18F24087-4760-43DA-ACAB-7B9F0E096B11}"
+ ProjectSection(ProjectDependencies) = postProject
+ {499EB63C-D74C-47E8-AE48-A2FC94538E9D} = {499EB63C-D74C-47E8-AE48-A2FC94538E9D}
+ {66707BAE-BBF9-4F03-B53E-BE3AD58322F8} = {66707BAE-BBF9-4F03-B53E-BE3AD58322F8}
+ EndProjectSection
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CsharpServer", "CsharpServer\CsharpServer.csproj", "{66707BAE-BBF9-4F03-B53E-BE3AD58322F8}"
+ ProjectSection(ProjectDependencies) = postProject
+ {499EB63C-D74C-47E8-AE48-A2FC94538E9D} = {499EB63C-D74C-47E8-AE48-A2FC94538E9D}
+ EndProjectSection
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {499EB63C-D74C-47E8-AE48-A2FC94538E9D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {499EB63C-D74C-47E8-AE48-A2FC94538E9D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {499EB63C-D74C-47E8-AE48-A2FC94538E9D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {499EB63C-D74C-47E8-AE48-A2FC94538E9D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {18F24087-4760-43DA-ACAB-7B9F0E096B11}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {18F24087-4760-43DA-ACAB-7B9F0E096B11}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {18F24087-4760-43DA-ACAB-7B9F0E096B11}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {18F24087-4760-43DA-ACAB-7B9F0E096B11}.Release|Any CPU.Build.0 = Release|Any CPU
+ {66707BAE-BBF9-4F03-B53E-BE3AD58322F8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {66707BAE-BBF9-4F03-B53E-BE3AD58322F8}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {66707BAE-BBF9-4F03-B53E-BE3AD58322F8}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {66707BAE-BBF9-4F03-B53E-BE3AD58322F8}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+EndGlobal
diff --git a/src/jaegertracing/thrift/tutorial/d/Makefile.am b/src/jaegertracing/thrift/tutorial/d/Makefile.am
new file mode 100644
index 000000000..358294ce5
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/d/Makefile.am
@@ -0,0 +1,53 @@
+#
+# 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.
+#
+
+LIB_D_DIR = $(top_srcdir)/lib/d
+
+GEN_SRC = gen-d/share/SharedService.d gen-d/share/shared_types.d \
+ gen-d/tutorial/tutorial_types.d gen-d/tutorial/Calculator.d
+
+$(GEN_SRC): $(top_srcdir)/tutorial/tutorial.thrift
+ $(top_builddir)/compiler/cpp/thrift --gen d -r $<
+
+server: server.d $(GEN_SRC)
+ $(DMD) -I${LIB_D_DIR}/src -L-L${LIB_D_DIR} -L-lthriftd server.d ${GEN_SRC}
+
+client: client.d $(GEN_SRC)
+ $(DMD) -I${LIB_D_DIR}/src -L-L${LIB_D_DIR} -L-lthriftd client.d ${GEN_SRC}
+
+PROGS = server client
+
+if WITH_D_EVENT_TESTS
+async_client: async_client.d $(GEN_SRC)
+ $(DMD) -I${LIB_D_DIR}/src -L-L${LIB_D_DIR} -L-lthriftd-event -L-lthriftd -L-levent async_client.d ${GEN_SRC}
+
+PROGS += async_client
+endif
+
+all-local: $(PROGS)
+
+clean:
+ $(RM) -f $(PROGS)
+ $(RM) -r gen-d/
+ find . -type f -name '*.o' | xargs rm -f
+
+dist-hook:
+ $(RM) -f $(distdir)/$(PROGS)
+ $(RM) -r $(distdir)/gen-d/
+ find $(destdir) -type f -name '*.o' | xargs rm -f
diff --git a/src/jaegertracing/thrift/tutorial/d/async_client.d b/src/jaegertracing/thrift/tutorial/d/async_client.d
new file mode 100644
index 000000000..1defce082
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/d/async_client.d
@@ -0,0 +1,86 @@
+/*
+ * 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.
+ */
+module async_client;
+
+import std.exception;
+import std.stdio;
+import thrift.async.libevent;
+import thrift.async.socket;
+import thrift.base;
+import thrift.codegen.async_client;
+import thrift.protocol.binary;
+import thrift.transport.buffered;
+
+import tutorial.Calculator;
+import tutorial.tutorial_types;
+
+void main() {
+ auto asyncManager = new TLibeventAsyncManager;
+
+ // If we are done, gracefully stop the async manager to avoid hanging on
+ // appplication shutdown.
+ scope (exit) asyncManager.stop();
+
+ auto socket = new TAsyncSocket(asyncManager, "localhost", 9090);
+ auto client = new TAsyncClient!Calculator(
+ socket,
+ new TBufferedTransportFactory,
+ new TBinaryProtocolFactory!TBufferedTransport
+ );
+
+ socket.open();
+
+ // Invoke all the methods.
+ auto pingResult = client.ping();
+
+ auto addResult = client.add(1, 1);
+
+ auto work = Work();
+ work.op = Operation.DIVIDE;
+ work.num1 = 1;
+ work.num2 = 0;
+ auto quotientResult = client.calculate(1, work);
+
+ work.op = Operation.SUBTRACT;
+ work.num1 = 15;
+ work.num2 = 10;
+ auto diffResult = client.calculate(1, work);
+
+ auto logResult = client.getStruct(1);
+
+ // Await the responses.
+ pingResult.waitGet();
+ writeln("ping()");
+
+ int sum = addResult.waitGet();
+ writefln("1 + 1 = %s", sum);
+
+ try {
+ quotientResult.waitGet();
+ writeln("Whoa we can divide by 0");
+ } catch (InvalidOperation io) {
+ writeln("Invalid operation: " ~ io.why);
+ }
+
+ writefln("15 - 10 = %s", diffResult.waitGet());
+
+ // TFuture is implicitly convertible to the result type via »alias this«,
+ // for which it (eagerly, of course) awaits completion.
+ writefln("Check log: %s", logResult.value);
+}
diff --git a/src/jaegertracing/thrift/tutorial/d/client.d b/src/jaegertracing/thrift/tutorial/d/client.d
new file mode 100644
index 000000000..1867a17bc
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/d/client.d
@@ -0,0 +1,64 @@
+/*
+ * 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.
+ */
+module client;
+
+import std.stdio;
+import thrift.base;
+import thrift.codegen.client;
+import thrift.protocol.binary;
+import thrift.transport.buffered;
+import thrift.transport.socket;
+
+import tutorial.Calculator;
+import tutorial.tutorial_types;
+
+void main() {
+ auto socket = new TSocket("localhost", 9090);
+ auto transport = new TBufferedTransport(socket);
+ auto protocol = tBinaryProtocol(transport);
+ auto client = tClient!Calculator(protocol);
+
+ transport.open();
+
+ client.ping();
+ writeln("ping()");
+
+ int sum = client.add(1, 1);
+ writefln("1 + 1 = %s", sum);
+
+ auto work = Work();
+ work.op = Operation.DIVIDE;
+ work.num1 = 1;
+ work.num2 = 0;
+ try {
+ int quotient = client.calculate(1, work);
+ writeln("Whoa we can divide by 0");
+ } catch (InvalidOperation io) {
+ writeln("Invalid operation: " ~ io.why);
+ }
+
+ work.op = Operation.SUBTRACT;
+ work.num1 = 15;
+ work.num2 = 10;
+ int diff = client.calculate(1, work);
+ writefln("15 - 10 = %s", diff);
+
+ auto log = client.getStruct(1);
+ writefln("Check log: %s", log.value);
+}
diff --git a/src/jaegertracing/thrift/tutorial/d/server.d b/src/jaegertracing/thrift/tutorial/d/server.d
new file mode 100644
index 000000000..cbcedccf3
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/d/server.d
@@ -0,0 +1,111 @@
+/*
+ * 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.
+ */
+module server;
+
+import std.conv : to;
+import std.stdio;
+import thrift.codegen.processor;
+import thrift.protocol.binary;
+import thrift.server.simple;
+import thrift.server.transport.socket;
+import thrift.transport.buffered;
+
+import share.SharedService;
+import share.shared_types;
+import tutorial.Calculator;
+import tutorial.tutorial_types;
+
+/**
+ * The actual implementation of the Calculator interface that is called by
+ * the server to answer the requests.
+ */
+class CalculatorHandler : Calculator {
+ void ping() {
+ writeln("ping()");
+ }
+
+ int add(int n1, int n2) {
+ writefln("add(%s,%s)", n1, n2);
+ return n1 + n2;
+ }
+
+ int calculate(int logid, ref const(Work) work) {
+ writefln("calculate(%s, {%s, %s, %s})", logid, work.op, work.num1, work.num2);
+ int val;
+
+ switch (work.op) {
+ case Operation.ADD:
+ val = work.num1 + work.num2;
+ break;
+ case Operation.SUBTRACT:
+ val = work.num1 - work.num2;
+ break;
+ case Operation.MULTIPLY:
+ val = work.num1 * work.num2;
+ break;
+ case Operation.DIVIDE:
+ if (work.num2 == 0) {
+ auto io = new InvalidOperation();
+ io.whatOp = work.op;
+ io.why = "Cannot divide by 0";
+ throw io;
+ }
+ val = work.num1 / work.num2;
+ break;
+ default:
+ auto io = new InvalidOperation();
+ io.whatOp = work.op;
+ io.why = "Invalid Operation";
+ throw io;
+ }
+
+ auto ss = SharedStruct();
+ ss.key = logid;
+ ss.value = to!string(val);
+ log[logid] = ss;
+
+ return val;
+ }
+
+ SharedStruct getStruct(int logid) {
+ writefln("getStruct(%s)", logid);
+ return log[logid];
+ }
+
+ void zip() {
+ writeln("zip()");
+ }
+
+protected:
+ SharedStruct[int] log;
+}
+
+void main() {
+ auto protocolFactory = new TBinaryProtocolFactory!();
+ auto processor = new TServiceProcessor!Calculator(new CalculatorHandler);
+ auto serverTransport = new TServerSocket(9090);
+ auto transportFactory = new TBufferedTransportFactory;
+
+ auto server = new TSimpleServer(
+ processor, serverTransport, transportFactory, protocolFactory);
+
+ writeln("Starting the server on port 9090...");
+ server.serve();
+ writeln("done.");
+}
diff --git a/src/jaegertracing/thrift/tutorial/dart/Makefile.am b/src/jaegertracing/thrift/tutorial/dart/Makefile.am
new file mode 100644
index 000000000..0b93ac859
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/dart/Makefile.am
@@ -0,0 +1,81 @@
+#
+# 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.
+#
+
+BUILT_SOURCES = gen-dart/tutorial/lib/tutorial.dart gen-dart/shared/lib/shared.dart
+
+gen-dart/tutorial/lib/tutorial.dart gen-dart/shared/lib/shared.dart: $(top_srcdir)/tutorial/tutorial.thrift
+ $(THRIFT) --gen dart -r $<
+
+all-local: gen-dart/tutorial/lib/tutorial.dart pub-get
+
+clean-local:
+ $(RM) -r gen-*/
+ find . -type d -name ".dart_tool" | xargs $(RM) -r
+ find . -type d -name "packages" | xargs $(RM) -r
+ find . -type f -name ".packages" | xargs $(RM)
+ find . -type f -name "pubspec.lock" | xargs $(RM)
+
+dist-hook:
+ $(RM) -r $(distdir)/gen-*/
+ find $(distdir) -type d -name ".dart_tool" | xargs $(RM) -r
+ find $(distdir) -type d -name "packages" | xargs $(RM) -r
+ find $(distdir) -type f -name ".packages" | xargs $(RM)
+ find $(distdir) -type f -name "pubspec.lock" | xargs $(RM)
+
+pub-get: pub-get-gen pub-get-client pub-get-console-client pub-get-server
+
+pub-get-gen: pub-get-tutorial pub-get-shared
+
+pub-get-tutorial: gen-dart/tutorial/lib/tutorial.dart
+ cd gen-dart/tutorial; ${DARTPUB} get
+
+pub-get-shared: gen-dart/shared/lib/shared.dart
+ cd gen-dart/shared; ${DARTPUB} get
+
+pub-get-client:
+ cd client; ${DARTPUB} get
+
+pub-get-console-client:
+ cd console_client; ${DARTPUB} get
+
+pub-get-server:
+ cd server; ${DARTPUB} get
+
+tutorialserver: pub-get-gen pub-get-server
+ ${DART} server/bin/main.dart
+
+tutorialclient: pub-get-gen pub-get-client
+ cd client; ${DARTPUB} serve
+
+tutorialconsoleclient: pub-get-console-client
+ ${DART} console_client/bin/main.dart
+
+EXTRA_DIST = \
+ client/web/client.dart \
+ client/web/index.html \
+ client/web/styles.css \
+ client/pubspec.yaml \
+ console_client/bin/main.dart \
+ console_client/pubspec.yaml \
+ server/bin/main.dart \
+ server/pubspec.yaml \
+ console_client/.analysis_options \
+ client/.analysis_options \
+ server/.analysis_options \
+ build.sh
diff --git a/src/jaegertracing/thrift/tutorial/dart/build.sh b/src/jaegertracing/thrift/tutorial/dart/build.sh
new file mode 100644
index 000000000..eabe04a18
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/dart/build.sh
@@ -0,0 +1,56 @@
+#!/bin/sh
+
+# 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.
+
+set -e;
+rm -r gen-dart || true;
+
+thrift --gen dart ../shared.thrift;
+cd gen-dart/shared;
+pub get;
+cd ../..;
+
+thrift --gen dart ../tutorial.thrift;
+cd gen-dart/tutorial;
+pub get;
+cd ../..;
+
+cd client;
+pub get;
+cd ..;
+
+cd console_client;
+pub get;
+cd ..;
+
+cd server;
+pub get;
+cd ..;
+
+dartfmt -w gen-dart;
+
+echo "\nEnjoy the Dart tutorial!";
+echo "\nTo run the server:";
+echo "> dart server/bin/main.dart";
+echo "\nTo run the client:";
+echo "# Serve the app from the client directory and view in a browser";
+echo "> cd client;";
+echo "> pub serve;";
+echo "\nTo run the console client:";
+echo "> dart console_client/bin/main.dart";
+echo "";
diff --git a/src/jaegertracing/thrift/tutorial/dart/client/.analysis_options b/src/jaegertracing/thrift/tutorial/dart/client/.analysis_options
new file mode 100644
index 000000000..a10d4c5a0
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/dart/client/.analysis_options
@@ -0,0 +1,2 @@
+analyzer:
+ strong-mode: true
diff --git a/src/jaegertracing/thrift/tutorial/dart/client/pubspec.yaml b/src/jaegertracing/thrift/tutorial/dart/client/pubspec.yaml
new file mode 100644
index 000000000..6581b4d21
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/dart/client/pubspec.yaml
@@ -0,0 +1,33 @@
+# 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.
+
+name: tutorial_client
+version: 0.13.0
+description: A Dart client implementation of the Apache Thrift tutorial
+author: Apache Thrift Developers <dev@thrift.apache.org>
+homepage: http://thrift.apache.org
+
+environment:
+ sdk: ">=1.13.0 <3.0.0"
+
+dependencies:
+ shared:
+ path: ../gen-dart/shared
+ thrift:
+ path: ../../../lib/dart
+ tutorial:
+ path: ../gen-dart/tutorial
diff --git a/src/jaegertracing/thrift/tutorial/dart/client/web/client.dart b/src/jaegertracing/thrift/tutorial/dart/client/web/client.dart
new file mode 100644
index 000000000..4f02d0d98
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/dart/client/web/client.dart
@@ -0,0 +1,278 @@
+/// 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.
+
+import 'dart:html';
+
+import 'package:thrift/thrift.dart';
+import 'package:thrift/thrift_browser.dart';
+import 'package:shared/shared.dart';
+import 'package:tutorial/tutorial.dart';
+
+/// Adapted from the AS3 tutorial
+void main() {
+ new CalculatorUI(querySelector('#output')).start();
+}
+
+class CalculatorUI {
+ final DivElement output;
+
+ CalculatorUI(this.output);
+
+ TTransport _transport;
+ Calculator _calculatorClient;
+
+ void start() {
+ _buildInterface();
+ _initConnection();
+ }
+
+ void _validate() {
+ if (!_transport.isOpen) {
+ window.alert("The transport is not open!");
+ }
+ }
+
+ void _initConnection() {
+ _transport = new TAsyncClientSocketTransport(
+ new TWebSocket(Uri.parse('ws://127.0.0.1:9090/ws')),
+ new TMessageReader(new TBinaryProtocolFactory()));
+ TProtocol protocol = new TBinaryProtocol(_transport);
+ _transport.open();
+
+ _calculatorClient = new CalculatorClient(protocol);
+ }
+
+ void _buildInterface() {
+ output.children.forEach((e) {
+ e.remove();
+ });
+
+ _buildPingComponent();
+
+ _buildAddComponent();
+
+ _buildCalculatorComponent();
+
+ _buildGetStructComponent();
+ }
+
+ void _buildPingComponent() {
+ output.append(new HeadingElement.h3()..text = "Ping");
+ ButtonElement pingButton = new ButtonElement()
+ ..text = "PING"
+ ..onClick.listen(_onPingClick);
+ output.append(pingButton);
+ }
+
+ void _onPingClick(MouseEvent e) {
+ _validate();
+
+ _calculatorClient.ping();
+ }
+
+ void _buildAddComponent() {
+ output.append(new HeadingElement.h3()..text = "Add");
+ InputElement num1 = new InputElement()
+ ..id = "add1"
+ ..type = "number"
+ ..style.fontSize = "14px"
+ ..style.width = "50px";
+ output.append(num1);
+ SpanElement op = new SpanElement()
+ ..text = "+"
+ ..style.fontSize = "14px"
+ ..style.marginLeft = "10px";
+ output.append(op);
+ InputElement num2 = new InputElement()
+ ..id = "add2"
+ ..type = "number"
+ ..style.fontSize = "14px"
+ ..style.width = "50px"
+ ..style.marginLeft = "10px";
+ output.append(num2);
+ ButtonElement addButton = new ButtonElement()
+ ..text = "="
+ ..style.fontSize = "14px"
+ ..style.marginLeft = "10px"
+ ..onClick.listen(_onAddClick);
+ output.append(addButton);
+ SpanElement result = new SpanElement()
+ ..id = "addResult"
+ ..style.fontSize = "14px"
+ ..style.marginLeft = "10px";
+ output.append(result);
+ }
+
+ void _onAddClick(MouseEvent e) {
+ _validate();
+
+ InputElement num1 = querySelector("#add1");
+ InputElement num2 = querySelector("#add2");
+ SpanElement result = querySelector("#addResult");
+
+ _calculatorClient
+ .add(int.parse(num1.value), int.parse(num2.value))
+ .then((int n) {
+ result.text = "$n";
+ });
+ }
+
+ void _buildCalculatorComponent() {
+ output.append(new HeadingElement.h3()..text = "Calculator");
+ InputElement num1 = new InputElement()
+ ..id = "calc1"
+ ..type = "number"
+ ..style.fontSize = "14px"
+ ..style.width = "50px";
+ output.append(num1);
+ SelectElement op = new SelectElement()
+ ..id = "calcOp"
+ ..multiple = false
+ ..selectedIndex = 0
+ ..style.fontSize = "16px"
+ ..style.marginLeft = "10px"
+ ..style.width = "50px";
+ OptionElement addOp = new OptionElement()
+ ..text = "+"
+ ..value = Operation.ADD.toString();
+ op.add(addOp, 0);
+ OptionElement subtractOp = new OptionElement()
+ ..text = "-"
+ ..value = Operation.SUBTRACT.toString();
+ op.add(subtractOp, 1);
+ OptionElement multiplyOp = new OptionElement()
+ ..text = "*"
+ ..value = Operation.MULTIPLY.toString();
+ op.add(multiplyOp, 2);
+ OptionElement divideOp = new OptionElement()
+ ..text = "/"
+ ..value = Operation.DIVIDE.toString();
+ op.add(divideOp, 3);
+ output.append(op);
+ InputElement num2 = new InputElement()
+ ..id = "calc2"
+ ..type = "number"
+ ..style.fontSize = "14px"
+ ..style.width = "50px"
+ ..style.marginLeft = "10px";
+ output.append(num2);
+ ButtonElement calcButton = new ButtonElement()
+ ..text = "="
+ ..style.fontSize = "14px"
+ ..style.marginLeft = "10px"
+ ..onClick.listen(_onCalcClick);
+ output.append(calcButton);
+ SpanElement result = new SpanElement()
+ ..id = "calcResult"
+ ..style.fontSize = "14px"
+ ..style.marginLeft = "10px";
+ output.append(result);
+ output.append(new BRElement());
+ output.append(new BRElement());
+ LabelElement logIdLabel = new LabelElement()
+ ..text = "Log ID:"
+ ..style.fontSize = "14px";
+ output.append(logIdLabel);
+ InputElement logId = new InputElement()
+ ..id = "logId"
+ ..type = "number"
+ ..value = "1"
+ ..style.fontSize = "14px"
+ ..style.width = "50px"
+ ..style.marginLeft = "10px";
+ output.append(logId);
+ LabelElement commentLabel = new LabelElement()
+ ..text = "Comment:"
+ ..style.fontSize = "14px"
+ ..style.marginLeft = "10px";
+ output.append(commentLabel);
+ InputElement comment = new InputElement()
+ ..id = "comment"
+ ..style.fontSize = "14px"
+ ..style.width = "100px"
+ ..style.marginLeft = "10px";
+ output.append(comment);
+ }
+
+ void _onCalcClick(MouseEvent e) {
+ _validate();
+
+ InputElement num1 = querySelector("#calc1");
+ InputElement num2 = querySelector("#calc2");
+ SelectElement op = querySelector("#calcOp");
+ SpanElement result = querySelector("#calcResult");
+ InputElement logId = querySelector("#logId");
+ InputElement comment = querySelector("#comment");
+
+ int logIdValue = int.parse(logId.value);
+ logId.value = (logIdValue + 1).toString();
+
+ Work work = new Work();
+ work.num1 = int.parse(num1.value);
+ work.num2 = int.parse(num2.value);
+ work.op = int.parse(op.options[op.selectedIndex].value);
+ work.comment = comment.value;
+
+ _calculatorClient.calculate(logIdValue, work).then((int n) {
+ result.text = "$n";
+ });
+ }
+
+ void _buildGetStructComponent() {
+ output.append(new HeadingElement.h3()..text = "Get Struct");
+ LabelElement logIdLabel = new LabelElement()
+ ..text = "Struct Key:"
+ ..style.fontSize = "14px";
+ output.append(logIdLabel);
+ InputElement logId = new InputElement()
+ ..id = "structKey"
+ ..type = "number"
+ ..value = "1"
+ ..style.fontSize = "14px"
+ ..style.width = "50px"
+ ..style.marginLeft = "10px";
+ output.append(logId);
+ ButtonElement getStructButton = new ButtonElement()
+ ..text = "GET"
+ ..style.fontSize = "14px"
+ ..style.marginLeft = "10px"
+ ..onClick.listen(_onGetStructClick);
+ output.append(getStructButton);
+ output.append(new BRElement());
+ output.append(new BRElement());
+ TextAreaElement result = new TextAreaElement()
+ ..id = "getStructResult"
+ ..style.fontSize = "14px"
+ ..style.width = "300px"
+ ..style.height = "50px"
+ ..style.marginLeft = "10px";
+ output.append(result);
+ }
+
+ void _onGetStructClick(MouseEvent e) {
+ _validate();
+
+ InputElement structKey = querySelector("#structKey");
+ TextAreaElement result = querySelector("#getStructResult");
+
+ _calculatorClient
+ .getStruct(int.parse(structKey.value))
+ .then((SharedStruct s) {
+ result.text = "${s.toString()}";
+ });
+ }
+}
diff --git a/src/jaegertracing/thrift/tutorial/dart/client/web/index.html b/src/jaegertracing/thrift/tutorial/dart/client/web/index.html
new file mode 100644
index 000000000..9d36b4388
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/dart/client/web/index.html
@@ -0,0 +1,35 @@
+<!--
+ * 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.
+-->
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="utf-8">
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <title>Thrift Tutorial</title>
+ <link rel="stylesheet" href="styles.css">
+ <script async src="client.dart.js"></script>
+</head>
+
+<body>
+
+ <div id="output"></div>
+
+</body>
+</html>
diff --git a/src/jaegertracing/thrift/tutorial/dart/client/web/styles.css b/src/jaegertracing/thrift/tutorial/dart/client/web/styles.css
new file mode 100644
index 000000000..c0315025b
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/dart/client/web/styles.css
@@ -0,0 +1,33 @@
+/*
+ * 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.
+ */
+@import url(https://fonts.googleapis.com/css?family=Roboto);
+
+html, body {
+ width: 100%;
+ height: 100%;
+ margin: 0;
+ padding: 10px;
+ font-family: 'Roboto', sans-serif;
+}
+
+h3 {
+ border-bottom: solid;
+ border-width: thin;
+ padding-top: 20px;
+}
diff --git a/src/jaegertracing/thrift/tutorial/dart/console_client/.analysis_options b/src/jaegertracing/thrift/tutorial/dart/console_client/.analysis_options
new file mode 100644
index 000000000..a10d4c5a0
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/dart/console_client/.analysis_options
@@ -0,0 +1,2 @@
+analyzer:
+ strong-mode: true
diff --git a/src/jaegertracing/thrift/tutorial/dart/console_client/bin/main.dart b/src/jaegertracing/thrift/tutorial/dart/console_client/bin/main.dart
new file mode 100644
index 000000000..fda206ab9
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/dart/console_client/bin/main.dart
@@ -0,0 +1,149 @@
+/// 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.
+
+import 'dart:async';
+import 'dart:io';
+
+import 'package:args/args.dart';
+import 'package:logging/logging.dart';
+import 'package:thrift/thrift.dart';
+import 'package:thrift/thrift_console.dart';
+import 'package:tutorial/tutorial.dart';
+
+TTransport _transport;
+Calculator _calculator;
+int logid = 0;
+
+const Map<String, int> operationLookup = const {
+ '+': Operation.ADD,
+ '-': Operation.SUBTRACT,
+ '*': Operation.MULTIPLY,
+ '/': Operation.DIVIDE
+};
+
+main(List<String> args) {
+ Logger.root.level = Level.ALL;
+ Logger.root.onRecord.listen((LogRecord rec) {
+ print('${rec.level.name}: ${rec.time}: ${rec.message}');
+ });
+
+ var parser = new ArgParser();
+ parser.addOption('port', defaultsTo: '9090', help: 'The port to connect to');
+
+ ArgResults results;
+ try {
+ results = parser.parse(args);
+ } catch (e) {
+ results = null;
+ }
+
+ if (results == null) {
+ print(parser.usage);
+ exit(0);
+ }
+
+ int port = int.parse(results['port']);
+
+ _initConnection(port).then((_) => _run());
+}
+
+Future _initConnection(int port) async {
+ var socket = await Socket.connect('127.0.0.1', port);
+ _transport = new TAsyncClientSocketTransport(
+ new TTcpSocket(socket), new TMessageReader(new TBinaryProtocolFactory()));
+ TProtocol protocol = new TBinaryProtocol(_transport);
+ await _transport.open();
+
+ _calculator = new CalculatorClient(protocol);
+}
+
+Future _run() async {
+ _help();
+
+ while (true) {
+ stdout.write("> ");
+ var input = stdin.readLineSync();
+ var parts = input.split(' ');
+ var command = parts[0];
+ var args = parts.length > 1 ? parts.sublist(1) : [];
+
+ switch (command) {
+ case 'ping':
+ await _ping();
+ break;
+
+ case 'add':
+ await _add(int.parse(args[0]), int.parse(args[1]));
+ break;
+
+ case 'calc':
+ int op = operationLookup[args[1]];
+ if (!Operation.VALID_VALUES.contains(op)) {
+ stdout.writeln('Unknown operator ${args[1]}');
+ break;
+ }
+
+ var work = new Work()
+ ..num1 = int.parse(args[0])
+ ..op = op
+ ..num2 = int.parse(args[2])
+ ..comment = args.length > 3 ? args[3] : '';
+
+ await _calc(work);
+ break;
+
+ case 'struct':
+ await _struct(int.parse(args[0]));
+ break;
+
+ case 'help':
+ default:
+ _help();
+ break;
+ }
+ }
+}
+
+void _help() {
+ stdout.writeln('Commands:');
+ stdout.writeln(' help');
+ stdout.writeln(' ping');
+ stdout.writeln(' add x y');
+ stdout.writeln(' calc x op y [comment]');
+ stdout.writeln(' struct id');
+ stdout.writeln('');
+}
+
+Future _ping() async {
+ await _calculator.ping();
+ stdout.writeln('ping succeeded');
+}
+
+Future _add(int x, int y) async {
+ int result = await _calculator.add(x, y);
+ stdout.writeln('= $result');
+}
+
+Future _calc(Work work) async {
+ int result = await _calculator.calculate(logid++, work);
+ stdout.writeln('= $result');
+}
+
+Future _struct(int key) async {
+ var struct = await _calculator.getStruct(key);
+ stdout.writeln(struct.toString());
+}
diff --git a/src/jaegertracing/thrift/tutorial/dart/console_client/pubspec.yaml b/src/jaegertracing/thrift/tutorial/dart/console_client/pubspec.yaml
new file mode 100644
index 000000000..ca122d2fd
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/dart/console_client/pubspec.yaml
@@ -0,0 +1,36 @@
+# 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.
+
+name: tutorial_console_client
+version: 0.13.0
+description: >
+ A Dart console client to implementation of the Apache Thrift tutorial
+author: Apache Thrift Developers <dev@thrift.apache.org>
+homepage: http://thrift.apache.org
+
+environment:
+ sdk: ">=1.13.0 <3.0.0"
+
+dependencies:
+ args: ">=0.13.0 <2.0.0"
+ collection: ^1.1.0
+ shared:
+ path: ../gen-dart/shared
+ thrift:
+ path: ../../../lib/dart
+ tutorial:
+ path: ../gen-dart/tutorial
diff --git a/src/jaegertracing/thrift/tutorial/dart/server/.analysis_options b/src/jaegertracing/thrift/tutorial/dart/server/.analysis_options
new file mode 100644
index 000000000..a10d4c5a0
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/dart/server/.analysis_options
@@ -0,0 +1,2 @@
+analyzer:
+ strong-mode: true
diff --git a/src/jaegertracing/thrift/tutorial/dart/server/bin/main.dart b/src/jaegertracing/thrift/tutorial/dart/server/bin/main.dart
new file mode 100644
index 000000000..b8ac30d3d
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/dart/server/bin/main.dart
@@ -0,0 +1,163 @@
+/// 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.
+
+import 'dart:async';
+import 'dart:io';
+
+import 'package:args/args.dart';
+import 'package:logging/logging.dart';
+import 'package:thrift/thrift.dart';
+import 'package:thrift/thrift_console.dart';
+import 'package:tutorial/tutorial.dart';
+import 'package:shared/shared.dart';
+
+TProtocol _protocol;
+TProcessor _processor;
+WebSocket _webSocket;
+
+main(List<String> args) {
+ Logger.root.level = Level.ALL;
+ Logger.root.onRecord.listen((LogRecord rec) {
+ print('${rec.level.name}: ${rec.time}: ${rec.message}');
+ });
+
+ var parser = new ArgParser();
+ parser.addOption('port', defaultsTo: '9090', help: 'The port to listen on');
+ parser.addOption('type',
+ defaultsTo: 'ws',
+ allowed: ['ws', 'tcp'],
+ help: 'The type of socket',
+ allowedHelp: {'ws': 'WebSocket', 'tcp': 'TCP Socket'});
+
+ ArgResults results;
+ try {
+ results = parser.parse(args);
+ } catch (e) {
+ results = null;
+ }
+
+ if (results == null) {
+ print(parser.usage);
+ exit(0);
+ }
+
+ int port = int.parse(results['port']);
+ String socketType = results['type'];
+
+ if (socketType == 'tcp') {
+ _runTcpServer(port);
+ } else if (socketType == 'ws') {
+ _runWebSocketServer(port);
+ }
+}
+
+Future _runWebSocketServer(int port) async {
+ var httpServer = await HttpServer.bind('127.0.0.1', port);
+ print('listening for WebSocket connections on $port');
+
+ httpServer.listen((HttpRequest request) async {
+ if (request.uri.path == '/ws') {
+ _webSocket = await WebSocketTransformer.upgrade(request);
+ await _initProcessor(new TWebSocket(_webSocket));
+ } else {
+ print('Invalid path: ${request.uri.path}');
+ }
+ });
+}
+
+Future _runTcpServer(int port) async {
+ var serverSocket = await ServerSocket.bind('127.0.0.1', port);
+ print('listening for TCP connections on $port');
+
+ Socket socket = await serverSocket.first;
+ await _initProcessor(new TTcpSocket(socket));
+}
+
+Future _initProcessor(TSocket socket) async {
+ TServerSocketTransport transport = new TServerSocketTransport(socket);
+ transport.onIncomingMessage.listen(_processMessage);
+ _processor = new CalculatorProcessor(new CalculatorServer());
+ _protocol = new TBinaryProtocol(transport);
+ await _protocol.transport.open();
+
+ print('connected');
+}
+
+Future _processMessage(_) async {
+ _processor.process(_protocol, _protocol);
+}
+
+class CalculatorServer implements Calculator {
+ final Map<int, SharedStruct> _log = {};
+
+ Future ping() async {
+ print('ping()');
+ }
+
+ Future<int> add(int num1, int num2) async {
+ print('add($num1, $num2)');
+
+ return num1 + num2;
+ }
+
+ Future<int> calculate(int logid, Work work) async {
+ print('calulate($logid, ${work.toString()})');
+
+ int val;
+
+ switch (work.op) {
+ case Operation.ADD:
+ val = work.num1 + work.num2;
+ break;
+
+ case Operation.SUBTRACT:
+ val = work.num1 - work.num2;
+ break;
+
+ case Operation.MULTIPLY:
+ val = work.num1 * work.num2;
+ break;
+
+ case Operation.DIVIDE:
+ if (work.num2 == 0) {
+ var x = new InvalidOperation();
+ x.whatOp = work.op;
+ x.why = 'Cannot divide by 0';
+ throw x;
+ }
+ val = (work.num1 / work.num2).floor();
+ break;
+ }
+
+ var log = new SharedStruct();
+ log.key = logid;
+ log.value = '$val "${work.comment}"';
+ this._log[logid] = log;
+
+ return val;
+ }
+
+ Future zip() async {
+ print('zip()');
+ }
+
+ Future<SharedStruct> getStruct(int key) async {
+ print('getStruct($key)');
+
+ return _log[key];
+ }
+}
diff --git a/src/jaegertracing/thrift/tutorial/dart/server/pubspec.yaml b/src/jaegertracing/thrift/tutorial/dart/server/pubspec.yaml
new file mode 100644
index 000000000..e09465e70
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/dart/server/pubspec.yaml
@@ -0,0 +1,34 @@
+# 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.
+
+name: tutorial_server
+version: 0.13.0
+description: A Dart server to support the Apache Thrift tutorial
+author: Apache Thrift Developers <dev@thrift.apache.org>
+homepage: http://thrift.apache.org
+
+environment:
+ sdk: ">=1.13.0 <3.0.0"
+
+dependencies:
+ args: ">=0.13.0 <2.0.0"
+ shared:
+ path: ../gen-dart/shared
+ thrift:
+ path: ../../../lib/dart
+ tutorial:
+ path: ../gen-dart/tutorial
diff --git a/src/jaegertracing/thrift/tutorial/delphi/DelphiClient/DelphiClient.dpr b/src/jaegertracing/thrift/tutorial/delphi/DelphiClient/DelphiClient.dpr
new file mode 100644
index 000000000..4ea9eb3e9
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/delphi/DelphiClient/DelphiClient.dpr
@@ -0,0 +1,117 @@
+(*
+ * 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.
+ *)
+program DelphiClient;
+
+{$APPTYPE CONSOLE}
+{$D 'Copyright (c) 2012 The Apache Software Foundation'}
+
+uses
+ SysUtils,
+ Generics.Collections,
+ Thrift in '..\..\..\lib\delphi\src\Thrift.pas',
+ Thrift.Collections in '..\..\..\lib\delphi\src\Thrift.Collections.pas',
+ Thrift.Exception in '..\..\..\lib\delphi\src\Thrift.Exception.pas',
+ Thrift.Utils in '..\..\..\lib\delphi\src\Thrift.Utils.pas',
+ Thrift.Stream in '..\..\..\lib\delphi\src\Thrift.Stream.pas',
+ Thrift.Protocol in '..\..\..\lib\delphi\src\Thrift.Protocol.pas',
+ Thrift.Server in '..\..\..\lib\delphi\src\Thrift.Server.pas',
+ Thrift.Transport in '..\..\..\lib\delphi\src\Thrift.Transport.pas',
+ Thrift.Transport.WinHTTP in '..\..\..\lib\delphi\src\Thrift.Transport.WinHTTP.pas',
+ Thrift.Transport.MsxmlHTTP in '..\..\..\lib\delphi\src\Thrift.Transport.MsxmlHTTP.pas',
+ Thrift.WinHTTP in '..\..\..\lib\delphi\src\Thrift.WinHTTP.pas',
+ Shared in '..\..\gen-delphi\Shared.pas',
+ Tutorial in '..\..\gen-delphi\Tutorial.pas';
+
+
+type
+ DelphiTutorialClient = class
+ public
+ class procedure Main;
+ end;
+
+
+//--- DelphiTutorialClient ---------------------------------------
+
+
+class procedure DelphiTutorialClient.Main;
+var transport : ITransport;
+ protocol : IProtocol;
+ client : TCalculator.Iface;
+ work : IWork;
+ sum, quotient, diff : Integer;
+ log : ISharedStruct;
+begin
+ try
+ transport := TSocketImpl.Create( 'localhost', 9090);
+ protocol := TBinaryProtocolImpl.Create( transport);
+ client := TCalculator.TClient.Create( protocol);
+
+ transport.Open;
+
+ client.ping;
+ WriteLn('ping()');
+
+ sum := client.add( 1, 1);
+ WriteLn( Format( '1+1=%d', [sum]));
+
+ work := TWorkImpl.Create;
+
+ work.Op := TOperation.DIVIDE;
+ work.Num1 := 1;
+ work.Num2 := 0;
+ try
+ quotient := client.calculate(1, work);
+ WriteLn( 'Whoa we can divide by 0');
+ WriteLn( Format('1/0=%d',[quotient]));
+ except
+ on io: TInvalidOperation
+ do WriteLn( 'Invalid operation: ' + io.Why);
+ end;
+
+ work.Op := TOperation.SUBTRACT;
+ work.Num1 := 15;
+ work.Num2 := 10;
+ try
+ diff := client.calculate( 1, work);
+ WriteLn( Format('15-10=%d', [diff]));
+ except
+ on io: TInvalidOperation
+ do WriteLn( 'Invalid operation: ' + io.Why);
+ end;
+
+ log := client.getStruct(1);
+ WriteLn( Format( 'Check log: %s', [log.Value]));
+
+ transport.Close();
+
+ except
+ on e : Exception
+ do WriteLn( e.ClassName+': '+e.Message);
+ end;
+end;
+
+
+begin
+ try
+ DelphiTutorialClient.Main;
+ except
+ on E: Exception do
+ Writeln(E.ClassName, ': ', E.Message);
+ end;
+end.
diff --git a/src/jaegertracing/thrift/tutorial/delphi/DelphiClient/DelphiClient.dproj b/src/jaegertracing/thrift/tutorial/delphi/DelphiClient/DelphiClient.dproj
new file mode 100644
index 000000000..7026747d0
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/delphi/DelphiClient/DelphiClient.dproj
@@ -0,0 +1,122 @@
+ <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <ProjectGuid>{2B8FB3A1-2F9E-4883-8C53-0F56220B34F6}</ProjectGuid>
+ <MainSource>DelphiClient.dpr</MainSource>
+ <ProjectVersion>12.3</ProjectVersion>
+ <Basis>True</Basis>
+ <Config Condition="'$(Config)'==''">Debug</Config>
+ <Platform>Win32</Platform>
+ <AppType>Console</AppType>
+ <FrameworkType>None</FrameworkType>
+ <DCC_DCCCompiler>DCC32</DCC_DCCCompiler>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Config)'=='Basis' or '$(Base)'!=''">
+ <Base>true</Base>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_1)'!=''">
+ <Cfg_1>true</Cfg_1>
+ <CfgParent>Base</CfgParent>
+ <Base>true</Base>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_2)'!=''">
+ <Cfg_2>true</Cfg_2>
+ <CfgParent>Base</CfgParent>
+ <Base>true</Base>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Base)'!=''">
+ <DCC_UnitSearchPath>..\..\..\lib\delphi\src;$(DCC_UnitSearchPath)</DCC_UnitSearchPath>
+ <DCC_ImageBase>00400000</DCC_ImageBase>
+ <DCC_DcuOutput>.\dcu\$(Config)\$(Platform)</DCC_DcuOutput>
+ <DCC_UnitAlias>WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;$(DCC_UnitAlias)</DCC_UnitAlias>
+ <DCC_ExeOutput>..\bin\$(Config)\$(Platform)</DCC_ExeOutput>
+ <DCC_E>false</DCC_E>
+ <DCC_N>false</DCC_N>
+ <DCC_S>false</DCC_S>
+ <DCC_F>false</DCC_F>
+ <DCC_K>false</DCC_K>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Cfg_1)'!=''">
+ <DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
+ <DCC_Optimize>false</DCC_Optimize>
+ <DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Cfg_2)'!=''">
+ <DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
+ <DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
+ <DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
+ <DCC_DebugInformation>false</DCC_DebugInformation>
+ </PropertyGroup>
+ <ItemGroup>
+ <DelphiCompile Include="DelphiClient.dpr">
+ <MainSource>MainSource</MainSource>
+ </DelphiCompile>
+ <DCCReference Include="..\..\..\lib\delphi\src\Thrift.pas"/>
+ <DCCReference Include="..\..\..\lib\delphi\src\Thrift.Collections.pas"/>
+ <DCCReference Include="..\..\..\lib\delphi\src\Thrift.Exception.pas"/>
+ <DCCReference Include="..\..\..\lib\delphi\src\Thrift.Utils.pas"/>
+ <DCCReference Include="..\..\..\lib\delphi\src\Thrift.Stream.pas"/>
+ <DCCReference Include="..\..\..\lib\delphi\src\Thrift.Protocol.pas"/>
+ <DCCReference Include="..\..\..\lib\delphi\src\Thrift.Server.pas"/>
+ <DCCReference Include="..\..\..\lib\delphi\src\Thrift.Transport.pas"/>
+ <DCCReference Include="..\..\..\lib\delphi\src\Thrift.Transport.WinHTTP.pas"/>
+ <DCCReference Include="..\..\..\lib\delphi\src\Thrift.Transport.MsxmlHTTP.pas"/>
+ <DCCReference Include="..\..\..\lib\delphi\src\Thrift.WinHTTP.pas"/>
+ <DCCReference Include="..\..\gen-delphi\Shared.pas"/>
+ <DCCReference Include="..\..\gen-delphi\Tutorial.pas"/>
+ <BuildConfiguration Include="Release">
+ <Key>Cfg_2</Key>
+ <CfgParent>Base</CfgParent>
+ </BuildConfiguration>
+ <BuildConfiguration Include="Basis">
+ <Key>Base</Key>
+ </BuildConfiguration>
+ <BuildConfiguration Include="Debug">
+ <Key>Cfg_1</Key>
+ <CfgParent>Base</CfgParent>
+ </BuildConfiguration>
+ </ItemGroup>
+ <Import Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')" Project="$(BDS)\Bin\CodeGear.Delphi.Targets"/>
+ <Import Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')" Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj"/>
+ <ProjectExtensions>
+ <Borland.Personality>Delphi.Personality.12</Borland.Personality>
+ <Borland.ProjectType/>
+ <BorlandProject>
+ <Delphi.Personality>
+ <VersionInfo>
+ <VersionInfo Name="IncludeVerInfo">True</VersionInfo>
+ <VersionInfo Name="AutoIncBuild">False</VersionInfo>
+ <VersionInfo Name="MajorVer">0</VersionInfo>
+ <VersionInfo Name="MinorVer">12</VersionInfo>
+ <VersionInfo Name="Release">0</VersionInfo>
+ <VersionInfo Name="Build">0</VersionInfo>
+ <VersionInfo Name="Debug">False</VersionInfo>
+ <VersionInfo Name="PreRelease">False</VersionInfo>
+ <VersionInfo Name="Special">False</VersionInfo>
+ <VersionInfo Name="Private">False</VersionInfo>
+ <VersionInfo Name="DLL">False</VersionInfo>
+ <VersionInfo Name="Locale">1033</VersionInfo>
+ <VersionInfo Name="CodePage">1252</VersionInfo>
+ </VersionInfo>
+ <VersionInfoKeys>
+ <VersionInfoKeys Name="CompanyName"/>
+ <VersionInfoKeys Name="FileDescription">Thrift Tutorial</VersionInfoKeys>
+ <VersionInfoKeys Name="FileVersion">0.13.0.0</VersionInfoKeys>
+ <VersionInfoKeys Name="InternalName">DelphiClient</VersionInfoKeys>
+ <VersionInfoKeys Name="LegalCopyright">Copyright © 2012 The Apache Software Foundation</VersionInfoKeys>
+ <VersionInfoKeys Name="LegalTrademarks"/>
+ <VersionInfoKeys Name="OriginalFilename">DelphiClient.exe</VersionInfoKeys>
+ <VersionInfoKeys Name="ProductName">Thrift</VersionInfoKeys>
+ <VersionInfoKeys Name="ProductVersion">0.13.0.0</VersionInfoKeys>
+ <VersionInfoKeys Name="Comments"/>
+ </VersionInfoKeys>
+ <Source>
+ <Source Name="MainSource">DelphiClient.dpr</Source>
+ </Source>
+ </Delphi.Personality>
+ <Platforms>
+ <Platform value="Win32">True</Platform>
+ </Platforms>
+ </BorlandProject>
+ <ProjectFileVersion>12</ProjectFileVersion>
+ </ProjectExtensions>
+ </Project>
diff --git a/src/jaegertracing/thrift/tutorial/delphi/DelphiServer/DelphiServer.dpr b/src/jaegertracing/thrift/tutorial/delphi/DelphiServer/DelphiServer.dpr
new file mode 100644
index 000000000..fc9997a3f
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/delphi/DelphiServer/DelphiServer.dpr
@@ -0,0 +1,174 @@
+(*
+ * 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.
+ *)
+program DelphiServer;
+
+{$APPTYPE CONSOLE}
+{$D 'Copyright (c) 2012 The Apache Software Foundation'}
+
+{$Q+} // throws exceptions on numeric overflows
+
+uses
+ SysUtils,
+ Generics.Collections,
+ Thrift in '..\..\..\lib\delphi\src\Thrift.pas',
+ Thrift.Collections in '..\..\..\lib\delphi\src\Thrift.Collections.pas',
+ Thrift.Exception in '..\..\..\lib\delphi\src\Thrift.Exception.pas',
+ Thrift.Utils in '..\..\..\lib\delphi\src\Thrift.Utils.pas',
+ Thrift.Stream in '..\..\..\lib\delphi\src\Thrift.Stream.pas',
+ Thrift.Protocol in '..\..\..\lib\delphi\src\Thrift.Protocol.pas',
+ Thrift.Server in '..\..\..\lib\delphi\src\Thrift.Server.pas',
+ Thrift.Transport in '..\..\..\lib\delphi\src\Thrift.Transport.pas',
+ Thrift.WinHTTP in '..\..\..\lib\delphi\src\Thrift.WinHTTP.pas',
+ Shared in '..\..\gen-delphi\Shared.pas',
+ Tutorial in '..\..\gen-delphi\Tutorial.pas';
+
+
+type
+ TCalculatorHandler = class( TInterfacedObject, TCalculator.Iface)
+ protected
+ FLog : TDictionary< Integer, ISharedStruct>;
+
+ // TSharedService.Iface
+ function getStruct(key: Integer): ISharedStruct;
+
+ // TCalculator.Iface
+ procedure ping();
+ function add(num1: Integer; num2: Integer): Integer;
+ function calculate(logid: Integer; const w: IWork): Integer;
+ procedure zip();
+
+ public
+ constructor Create;
+ destructor Destroy; override;
+
+ end;
+
+ DelphiTutorialServer = class
+ public
+ class procedure Main;
+ end;
+
+
+//--- TCalculatorHandler ---------------------------------------------------
+
+
+constructor TCalculatorHandler.Create;
+begin
+ inherited Create;
+ FLog := TDictionary< Integer, ISharedStruct>.Create();
+end;
+
+
+destructor TCalculatorHandler.Destroy;
+begin
+ try
+ FreeAndNil( FLog);
+ finally
+ inherited Destroy;
+ end;
+end;
+
+
+procedure TCalculatorHandler.ping;
+begin
+ WriteLn( 'ping()');
+end;
+
+
+function TCalculatorHandler.add(num1: Integer; num2: Integer): Integer;
+begin
+ WriteLn( Format( 'add( %d, %d)', [num1, num2]));
+ result := num1 + num2;
+end;
+
+
+function TCalculatorHandler.calculate(logid: Integer; const w: IWork): Integer;
+var entry : ISharedStruct;
+begin
+ try
+ WriteLn( Format('calculate( %d, [%d,%d,%d])', [logid, Ord(w.Op), w.Num1, w.Num2]));
+
+ case w.Op of
+ TOperation.ADD : result := w.Num1 + w.Num2;
+ TOperation.SUBTRACT : result := w.Num1 - w.Num2;
+ TOperation.MULTIPLY : result := w.Num1 * w.Num2;
+ TOperation.DIVIDE : result := Round( w.Num1 / w.Num2);
+ else
+ raise TInvalidOperation.Create( Ord(w.Op), 'Unknown operation');
+ end;
+
+ except
+ on e:Thrift.TException do raise; // let Thrift Exceptions pass through
+ on e:Exception do raise TInvalidOperation.Create( Ord(w.Op), e.Message); // repackage all other
+ end;
+
+ entry := TSharedStructImpl.Create;
+ entry.Key := logid;
+ entry.Value := IntToStr( result);
+ FLog.AddOrSetValue( logid, entry);
+end;
+
+
+function TCalculatorHandler.getStruct(key: Integer): ISharedStruct;
+begin
+ WriteLn( Format( 'getStruct(%d)', [key]));
+ result := FLog[key];
+end;
+
+
+procedure TCalculatorHandler.zip;
+begin
+ WriteLn( 'zip()');
+end;
+
+
+//--- DelphiTutorialServer ----------------------------------------------------------------------
+
+
+class procedure DelphiTutorialServer.Main;
+var handler : TCalculator.Iface;
+ processor : IProcessor;
+ transport : IServerTransport;
+ server : IServer;
+begin
+ try
+ handler := TCalculatorHandler.Create;
+ processor := TCalculator.TProcessorImpl.Create( handler);
+ transport := TServerSocketImpl.Create( 9090);
+ server := TSimpleServer.Create( processor, transport);
+
+ WriteLn( 'Starting the server...');
+ server.Serve();
+
+ except
+ on e: Exception do WriteLn( e.Message);
+ end;
+
+ WriteLn('done.');
+end;
+
+
+begin
+ try
+ DelphiTutorialServer.Main;
+ except
+ on E: Exception do
+ Writeln(E.ClassName, ': ', E.Message);
+ end;
+end.
diff --git a/src/jaegertracing/thrift/tutorial/delphi/DelphiServer/DelphiServer.dproj b/src/jaegertracing/thrift/tutorial/delphi/DelphiServer/DelphiServer.dproj
new file mode 100644
index 000000000..ec1da2e69
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/delphi/DelphiServer/DelphiServer.dproj
@@ -0,0 +1,119 @@
+ <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <ProjectGuid>{2B8FB3A1-2F9E-4883-8C53-0F56220B34F6}</ProjectGuid>
+ <MainSource>DelphiServer.dpr</MainSource>
+ <ProjectVersion>12.3</ProjectVersion>
+ <Basis>True</Basis>
+ <Config Condition="'$(Config)'==''">Debug</Config>
+ <Platform>Win32</Platform>
+ <AppType>Console</AppType>
+ <FrameworkType>None</FrameworkType>
+ <DCC_DCCCompiler>DCC32</DCC_DCCCompiler>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Config)'=='Basis' or '$(Base)'!=''">
+ <Base>true</Base>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Config)'=='Debug' or '$(Cfg_1)'!=''">
+ <Cfg_1>true</Cfg_1>
+ <CfgParent>Base</CfgParent>
+ <Base>true</Base>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Config)'=='Release' or '$(Cfg_2)'!=''">
+ <Cfg_2>true</Cfg_2>
+ <CfgParent>Base</CfgParent>
+ <Base>true</Base>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Base)'!=''">
+ <DCC_ImageBase>00400000</DCC_ImageBase>
+ <DCC_DcuOutput>.\dcu\$(Config)\$(Platform)</DCC_DcuOutput>
+ <DCC_UnitAlias>WinTypes=Windows;WinProcs=Windows;DbiTypes=BDE;DbiProcs=BDE;$(DCC_UnitAlias)</DCC_UnitAlias>
+ <DCC_ExeOutput>..\bin\$(Config)\$(Platform)</DCC_ExeOutput>
+ <DCC_E>false</DCC_E>
+ <DCC_N>false</DCC_N>
+ <DCC_S>false</DCC_S>
+ <DCC_F>false</DCC_F>
+ <DCC_K>false</DCC_K>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Cfg_1)'!=''">
+ <DCC_Define>DEBUG;$(DCC_Define)</DCC_Define>
+ <DCC_Optimize>false</DCC_Optimize>
+ <DCC_GenerateStackFrames>true</DCC_GenerateStackFrames>
+ </PropertyGroup>
+ <PropertyGroup Condition="'$(Cfg_2)'!=''">
+ <DCC_LocalDebugSymbols>false</DCC_LocalDebugSymbols>
+ <DCC_Define>RELEASE;$(DCC_Define)</DCC_Define>
+ <DCC_SymbolReferenceInfo>0</DCC_SymbolReferenceInfo>
+ <DCC_DebugInformation>false</DCC_DebugInformation>
+ </PropertyGroup>
+ <ItemGroup>
+ <DelphiCompile Include="DelphiServer.dpr">
+ <MainSource>MainSource</MainSource>
+ </DelphiCompile>
+ <DCCReference Include="..\..\..\lib\delphi\src\Thrift.pas"/>
+ <DCCReference Include="..\..\..\lib\delphi\src\Thrift.Collections.pas"/>
+ <DCCReference Include="..\..\..\lib\delphi\src\Thrift.Exception.pas"/>
+ <DCCReference Include="..\..\..\lib\delphi\src\Thrift.Utils.pas"/>
+ <DCCReference Include="..\..\..\lib\delphi\src\Thrift.Stream.pas"/>
+ <DCCReference Include="..\..\..\lib\delphi\src\Thrift.Protocol.pas"/>
+ <DCCReference Include="..\..\..\lib\delphi\src\Thrift.Server.pas"/>
+ <DCCReference Include="..\..\..\lib\delphi\src\Thrift.Transport.pas"/>
+ <DCCReference Include="..\..\..\lib\delphi\src\Thrift.WinHTTP.pas"/>
+ <DCCReference Include="..\..\gen-delphi\Shared.pas"/>
+ <DCCReference Include="..\..\gen-delphi\Tutorial.pas"/>
+ <BuildConfiguration Include="Release">
+ <Key>Cfg_2</Key>
+ <CfgParent>Base</CfgParent>
+ </BuildConfiguration>
+ <BuildConfiguration Include="Basis">
+ <Key>Base</Key>
+ </BuildConfiguration>
+ <BuildConfiguration Include="Debug">
+ <Key>Cfg_1</Key>
+ <CfgParent>Base</CfgParent>
+ </BuildConfiguration>
+ </ItemGroup>
+ <Import Condition="Exists('$(BDS)\Bin\CodeGear.Delphi.Targets')" Project="$(BDS)\Bin\CodeGear.Delphi.Targets"/>
+ <Import Condition="Exists('$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj')" Project="$(APPDATA)\Embarcadero\$(BDSAPPDATABASEDIR)\$(PRODUCTVERSION)\UserTools.proj"/>
+ <ProjectExtensions>
+ <Borland.Personality>Delphi.Personality.12</Borland.Personality>
+ <Borland.ProjectType/>
+ <BorlandProject>
+ <Delphi.Personality>
+ <VersionInfo>
+ <VersionInfo Name="IncludeVerInfo">True</VersionInfo>
+ <VersionInfo Name="AutoIncBuild">False</VersionInfo>
+ <VersionInfo Name="MajorVer">0</VersionInfo>
+ <VersionInfo Name="MinorVer">12</VersionInfo>
+ <VersionInfo Name="Release">0</VersionInfo>
+ <VersionInfo Name="Build">0</VersionInfo>
+ <VersionInfo Name="Debug">False</VersionInfo>
+ <VersionInfo Name="PreRelease">False</VersionInfo>
+ <VersionInfo Name="Special">False</VersionInfo>
+ <VersionInfo Name="Private">False</VersionInfo>
+ <VersionInfo Name="DLL">False</VersionInfo>
+ <VersionInfo Name="Locale">1033</VersionInfo>
+ <VersionInfo Name="CodePage">1252</VersionInfo>
+ </VersionInfo>
+ <VersionInfoKeys>
+ <VersionInfoKeys Name="CompanyName"/>
+ <VersionInfoKeys Name="FileDescription">Thrift Tutorial</VersionInfoKeys>
+ <VersionInfoKeys Name="FileVersion">0.13.0.0</VersionInfoKeys>
+ <VersionInfoKeys Name="InternalName">DelphiServer</VersionInfoKeys>
+ <VersionInfoKeys Name="LegalCopyright">Copyright © 2012 The Apache Software Foundation</VersionInfoKeys>
+ <VersionInfoKeys Name="LegalTrademarks"/>
+ <VersionInfoKeys Name="OriginalFilename">DelphiServer.exe</VersionInfoKeys>
+ <VersionInfoKeys Name="ProductName">Thrift</VersionInfoKeys>
+ <VersionInfoKeys Name="ProductVersion">0.13.0.0</VersionInfoKeys>
+ <VersionInfoKeys Name="Comments"/>
+ </VersionInfoKeys>
+ <Source>
+ <Source Name="MainSource">DelphiServer.dpr</Source>
+ </Source>
+ </Delphi.Personality>
+ <Platforms>
+ <Platform value="Win32">True</Platform>
+ </Platforms>
+ </BorlandProject>
+ <ProjectFileVersion>12</ProjectFileVersion>
+ </ProjectExtensions>
+ </Project>
diff --git a/src/jaegertracing/thrift/tutorial/delphi/Tutorial.groupproj b/src/jaegertracing/thrift/tutorial/delphi/Tutorial.groupproj
new file mode 100644
index 000000000..3a2a23751
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/delphi/Tutorial.groupproj
@@ -0,0 +1,48 @@
+ <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <ProjectGuid>{3D042C7F-3EF2-4574-8304-AB7FB79F814C}</ProjectGuid>
+ </PropertyGroup>
+ <ItemGroup>
+ <Projects Include="DelphiServer\DelphiServer.dproj">
+ <Dependencies/>
+ </Projects>
+ <Projects Include="DelphiClient\DelphiClient.dproj">
+ <Dependencies/>
+ </Projects>
+ </ItemGroup>
+ <ProjectExtensions>
+ <Borland.Personality>Default.Personality.12</Borland.Personality>
+ <Borland.ProjectType/>
+ <BorlandProject>
+ <Default.Personality/>
+ </BorlandProject>
+ </ProjectExtensions>
+ <Target Name="DelphiServer">
+ <MSBuild Projects="DelphiServer\DelphiServer.dproj"/>
+ </Target>
+ <Target Name="DelphiServer:Clean">
+ <MSBuild Projects="DelphiServer\DelphiServer.dproj" Targets="Clean"/>
+ </Target>
+ <Target Name="DelphiServer:Make">
+ <MSBuild Projects="DelphiServer\DelphiServer.dproj" Targets="Make"/>
+ </Target>
+ <Target Name="DelphiClient">
+ <MSBuild Projects="DelphiClient\DelphiClient.dproj"/>
+ </Target>
+ <Target Name="DelphiClient:Clean">
+ <MSBuild Projects="DelphiClient\DelphiClient.dproj" Targets="Clean"/>
+ </Target>
+ <Target Name="DelphiClient:Make">
+ <MSBuild Projects="DelphiClient\DelphiClient.dproj" Targets="Make"/>
+ </Target>
+ <Target Name="Build">
+ <CallTarget Targets="DelphiServer;DelphiClient"/>
+ </Target>
+ <Target Name="Clean">
+ <CallTarget Targets="DelphiServer:Clean;DelphiClient:Clean"/>
+ </Target>
+ <Target Name="Make">
+ <CallTarget Targets="DelphiServer:Make;DelphiClient:Make"/>
+ </Target>
+ <Import Condition="Exists('$(BDS)\Bin\CodeGear.Group.Targets')" Project="$(BDS)\Bin\CodeGear.Group.Targets"/>
+ </Project>
diff --git a/src/jaegertracing/thrift/tutorial/erl/README.md b/src/jaegertracing/thrift/tutorial/erl/README.md
new file mode 100644
index 000000000..9d17cd0c5
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/erl/README.md
@@ -0,0 +1,8 @@
+To try things out, run
+
+% ./server.sh
+Erlang R14B (erts-5.8.1) [source] [64-bit] [smp:4:4] [rq:4] [async-threads:0] [hipe] [kernel-poll:false]
+
+Eshell V5.8.1 (abort with ^G)
+> server:start().
+> client:t().
diff --git a/src/jaegertracing/thrift/tutorial/erl/client.erl b/src/jaegertracing/thrift/tutorial/erl/client.erl
new file mode 100644
index 000000000..037422085
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/erl/client.erl
@@ -0,0 +1,78 @@
+%%
+%% 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.
+%%
+
+-module(client).
+
+-include("calculator_thrift.hrl").
+
+-export([t/0]).
+
+p(X) ->
+ io:format("~p~n", [X]),
+ ok.
+
+t() ->
+ Port = 9090,
+
+ {ok, Client0} = thrift_client_util:new("127.0.0.1",
+ Port,
+ calculator_thrift,
+ []),
+
+ {Client1, {ok, ok}} = thrift_client:call(Client0, ping, []),
+ io:format("ping~n", []),
+
+ {Client2, {ok, Sum}} = thrift_client:call(Client1, add, [1, 1]),
+ io:format("1+1=~p~n", [Sum]),
+
+ {Client3, {ok, Sum1}} = thrift_client:call(Client2, add, [1, 4]),
+ io:format("1+4=~p~n", [Sum1]),
+
+ Work = #'Work'{op=?TUTORIAL_OPERATION_SUBTRACT,
+ num1=15,
+ num2=10},
+ {Client4, {ok, Diff}} = thrift_client:call(Client3, calculate, [1, Work]),
+ io:format("15-10=~p~n", [Diff]),
+
+ {Client5, {ok, Log}} = thrift_client:call(Client4, getStruct, [1]),
+ io:format("Log: ~p~n", [Log]),
+
+ Client6 =
+ try
+ Work1 = #'Work'{op=?TUTORIAL_OPERATION_DIVIDE,
+ num1=1,
+ num2=0},
+ {ClientS1, {ok, _Quot}} = thrift_client:call(Client5, calculate, [2, Work1]),
+
+ io:format("LAME: exception handling is broken~n", []),
+ ClientS1
+ catch
+ throw:{ClientS2, Z} ->
+ io:format("Got exception where expecting - the " ++
+ "following is NOT a problem!!!~n"),
+ p(Z),
+ ClientS2
+ end,
+
+
+ {Client7, {ok, ok}} = thrift_client:call(Client6, zip, []),
+ io:format("zip~n", []),
+
+ {_Client8, ok} = thrift_client:close(Client7),
+ ok.
diff --git a/src/jaegertracing/thrift/tutorial/erl/client.sh b/src/jaegertracing/thrift/tutorial/erl/client.sh
new file mode 100755
index 000000000..775afb62d
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/erl/client.sh
@@ -0,0 +1,37 @@
+#!/bin/sh
+
+#
+# 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.
+#
+
+ERL_THRIFT=../../lib/erl
+
+if ! [ -d ${ERL_THRIFT}/ebin ]; then
+ echo "Please build the Thrift library by running \`make' in ${ERL_THRIFT}"
+ exit 1
+fi
+
+if ! [ -d gen-erl ]; then
+ ../../compiler/cpp/thrift -r --gen erl ../tutorial.thrift
+fi
+
+
+erlc -I ${ERL_THRIFT}/include -I ${ERL_THRIFT}/ebin \
+ -I gen-erl -o gen-erl gen-erl/*.erl &&
+ erlc -I ${ERL_THRIFT}/include -I gen-erl *.erl &&
+ erl +K true -pa ${ERL_THRIFT}/ebin -pa gen-erl
diff --git a/src/jaegertracing/thrift/tutorial/erl/json_client.erl b/src/jaegertracing/thrift/tutorial/erl/json_client.erl
new file mode 100644
index 000000000..0b39ceda9
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/erl/json_client.erl
@@ -0,0 +1,89 @@
+%%
+%% 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.
+%%
+%% The JSON protocol over HTTP implementation was created by
+%% Peter Neumark <neumark.peter@gmail.com> based on
+%% the binary protocol + socket tutorial. Use with the same server
+%% that the Javascript tutorial uses!
+
+-module(json_client).
+
+-include("calculator_thrift.hrl").
+
+-export([t/0]).
+
+%% Client constructor for the http transports
+%% with the json protocol
+new_client(Host, Path, Service, _Options) ->
+ {ProtoOpts, TransOpts} = {[],[]},
+ TransportFactory = fun() -> thrift_http_transport:new(Host, Path, TransOpts) end,
+ {ok, ProtocolFactory} = thrift_json_protocol:new_protocol_factory(
+ TransportFactory, ProtoOpts),
+ {ok, Protocol} = ProtocolFactory(),
+ thrift_client:new(Protocol, Service).
+
+p(X) ->
+ io:format("~p~n", [X]),
+ ok.
+
+t() ->
+ inets:start(),
+ {ok, Client0} = new_client("127.0.0.1:8088", "/thrift/service/tutorial/",
+ calculator_thrift,
+ []),
+ {Client1, {ok, ok}} = thrift_client:call(Client0, ping, []),
+ io:format("ping~n", []),
+
+ {Client2, {ok, Sum}} = thrift_client:call(Client1, add, [1, 1]),
+ io:format("1+1=~p~n", [Sum]),
+
+ {Client3, {ok, Sum1}} = thrift_client:call(Client2, add, [1, 4]),
+ io:format("1+4=~p~n", [Sum1]),
+
+ Work = #'Work'{op=?TUTORIAL_OPERATION_SUBTRACT,
+ num1=15,
+ num2=10},
+ {Client4, {ok, Diff}} = thrift_client:call(Client3, calculate, [1, Work]),
+ io:format("15-10=~p~n", [Diff]),
+
+ {Client5, {ok, Log}} = thrift_client:call(Client4, getStruct, [1]),
+ io:format("Log: ~p~n", [Log]),
+
+ Client6 =
+ try
+ Work1 = #'Work'{op=?TUTORIAL_OPERATION_DIVIDE,
+ num1=1,
+ num2=0},
+ {ClientS1, {ok, _Quot}} = thrift_client:call(Client5, calculate, [2, Work1]),
+
+ io:format("LAME: exception handling is broken~n", []),
+ ClientS1
+ catch
+ throw:{ClientS2, Z} ->
+ io:format("Got exception where expecting - the " ++
+ "following is NOT a problem!!!~n"),
+ p(Z),
+ ClientS2
+ end,
+
+
+ {Client7, {ok, ok}} = thrift_client:call(Client6, zip, []),
+ io:format("zip~n", []),
+
+ {_Client8, ok} = thrift_client:close(Client7),
+ ok.
diff --git a/src/jaegertracing/thrift/tutorial/erl/server.erl b/src/jaegertracing/thrift/tutorial/erl/server.erl
new file mode 100644
index 000000000..647cc2474
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/erl/server.erl
@@ -0,0 +1,82 @@
+%%
+%% 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.
+%%
+
+-module(server).
+
+-include("calculator_thrift.hrl").
+
+-export([start/0, start/1, handle_function/2,
+ stop/1, ping/0, add/2, calculate/2, getStruct/1, zip/0]).
+
+debug(Format, Data) ->
+ error_logger:info_msg(Format, Data).
+
+ping() ->
+ debug("ping()",[]),
+ ok.
+
+add(N1, N2) ->
+ debug("add(~p,~p)",[N1,N2]),
+ N1+N2.
+
+calculate(Logid, Work) ->
+ { Op, Num1, Num2 } = { Work#'Work'.op, Work#'Work'.num1, Work#'Work'.num2 },
+ debug("calculate(~p, {~p,~p,~p})", [Logid, Op, Num1, Num2]),
+ case Op of
+ ?TUTORIAL_OPERATION_ADD -> Num1 + Num2;
+ ?TUTORIAL_OPERATION_SUBTRACT -> Num1 - Num2;
+ ?TUTORIAL_OPERATION_MULTIPLY -> Num1 * Num2;
+
+ ?TUTORIAL_OPERATION_DIVIDE when Num2 == 0 ->
+ throw(#'InvalidOperation'{whatOp=Op, why="Cannot divide by 0"});
+ ?TUTORIAL_OPERATION_DIVIDE ->
+ Num1 div Num2;
+
+ _Else ->
+ throw(#'InvalidOperation'{whatOp=Op, why="Invalid operation"})
+ end.
+
+getStruct(Key) ->
+ debug("getStruct(~p)", [Key]),
+ #'SharedStruct'{key=Key, value="RARG"}.
+
+zip() ->
+ debug("zip", []),
+ ok.
+
+%%
+
+start() ->
+ start(9090).
+
+start(Port) ->
+ Handler = ?MODULE,
+ thrift_socket_server:start([{handler, Handler},
+ {service, calculator_thrift},
+ {port, Port},
+ {name, tutorial_server}]).
+
+stop(Server) ->
+ thrift_socket_server:stop(Server).
+
+handle_function(Function, Args) when is_atom(Function), is_tuple(Args) ->
+ case apply(?MODULE, Function, tuple_to_list(Args)) of
+ ok -> ok;
+ Reply -> {reply, Reply}
+ end.
diff --git a/src/jaegertracing/thrift/tutorial/erl/server.sh b/src/jaegertracing/thrift/tutorial/erl/server.sh
new file mode 100755
index 000000000..775afb62d
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/erl/server.sh
@@ -0,0 +1,37 @@
+#!/bin/sh
+
+#
+# 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.
+#
+
+ERL_THRIFT=../../lib/erl
+
+if ! [ -d ${ERL_THRIFT}/ebin ]; then
+ echo "Please build the Thrift library by running \`make' in ${ERL_THRIFT}"
+ exit 1
+fi
+
+if ! [ -d gen-erl ]; then
+ ../../compiler/cpp/thrift -r --gen erl ../tutorial.thrift
+fi
+
+
+erlc -I ${ERL_THRIFT}/include -I ${ERL_THRIFT}/ebin \
+ -I gen-erl -o gen-erl gen-erl/*.erl &&
+ erlc -I ${ERL_THRIFT}/include -I gen-erl *.erl &&
+ erl +K true -pa ${ERL_THRIFT}/ebin -pa gen-erl
diff --git a/src/jaegertracing/thrift/tutorial/go/Makefile.am b/src/jaegertracing/thrift/tutorial/go/Makefile.am
new file mode 100644
index 000000000..bd57d656f
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/go/Makefile.am
@@ -0,0 +1,59 @@
+#
+# 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.
+#
+
+gen-go/tutorial/calculator.go gen-go/shared/shared_service.go: $(top_srcdir)/tutorial/tutorial.thrift
+ $(THRIFT) --gen go$(COMPILER_EXTRAFLAG) -r $<
+
+all-local: gen-go/tutorial/calculator.go
+
+check: src/github.com/apache/thrift/lib/go/thrift thirdparty-dep
+ $(THRIFT) -r --gen go$(COMPILER_EXTRAFLAG) $(top_srcdir)/tutorial/tutorial.thrift
+ cp -r gen-go/* src/
+ GOPATH=`pwd` $(GO) build -o go-tutorial ./src
+ GOPATH=`pwd` $(GO) build -o calculator-remote src/tutorial/calculator-remote/calculator-remote.go
+
+src/github.com/apache/thrift/lib/go/thrift:
+ mkdir -p src/github.com/apache/thrift/lib/go
+ ln -sf $(realpath $(top_srcdir)/lib/go/thrift) src/github.com/apache/thrift/lib/go/thrift
+
+thirdparty-dep:
+
+tutorialserver: all
+ GOPATH=`pwd` $(GO) run src/*.go -server=true
+
+tutorialclient: all
+ GOPATH=`pwd` $(GO) run src/*.go
+
+tutorialsecureserver: all
+ GOPATH=`pwd` $(GO) run src/*.go -server=true -secure=true
+
+tutorialsecureclient: all
+ GOPATH=`pwd` $(GO) run src/*.go -secure=true
+
+clean-local:
+ $(RM) -r gen-* src/shared src/tutorial src/git.apache.org go-tutorial calculator-remote
+
+EXTRA_DIST = \
+ src/client.go \
+ src/handler.go \
+ src/server.go \
+ src/main.go \
+ server.crt \
+ server.key
+
diff --git a/src/jaegertracing/thrift/tutorial/go/server.crt b/src/jaegertracing/thrift/tutorial/go/server.crt
new file mode 100644
index 000000000..8a5ef3c3a
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/go/server.crt
@@ -0,0 +1,25 @@
+-----BEGIN CERTIFICATE-----
+MIIENzCCAx+gAwIBAgIJAOYfYfw7NCOcMA0GCSqGSIb3DQEBBQUAMIGxMQswCQYD
+VQQGEwJVUzERMA8GA1UECAwITWFyeWxhbmQxFDASBgNVBAcMC0ZvcmVzdCBIaWxs
+MScwJQYDVQQKDB5UaGUgQXBhY2hlIFNvZnR3YXJlIEZvdW5kYXRpb24xFjAUBgNV
+BAsMDUFwYWNoZSBUaHJpZnQxEjAQBgNVBAMMCWxvY2FsaG9zdDEkMCIGCSqGSIb3
+DQEJARYVZGV2QHRocmlmdC5hcGFjaGUub3JnMB4XDTE0MDQwNzE4NTgwMFoXDTIy
+MDYyNDE4NTgwMFowgbExCzAJBgNVBAYTAlVTMREwDwYDVQQIDAhNYXJ5bGFuZDEU
+MBIGA1UEBwwLRm9yZXN0IEhpbGwxJzAlBgNVBAoMHlRoZSBBcGFjaGUgU29mdHdh
+cmUgRm91bmRhdGlvbjEWMBQGA1UECwwNQXBhY2hlIFRocmlmdDESMBAGA1UEAwwJ
+bG9jYWxob3N0MSQwIgYJKoZIhvcNAQkBFhVkZXZAdGhyaWZ0LmFwYWNoZS5vcmcw
+ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCqE9TE9wEXp5LRtLQVDSGQ
+GV78+7ZtP/I/ZaJ6Q6ZGlfxDFvZjFF73seNhAvlKlYm/jflIHYLnNOCySN8I2Xw6
+L9MbC+jvwkEKfQo4eDoxZnOZjNF5J1/lZtBeOowMkhhzBMH1Rds351/HjKNg6ZKg
+2Cldd0j7HbDtEixOLgLbPRpBcaYrLrNMasf3Hal+x8/b8ue28x93HSQBGmZmMIUw
+AinEu/fNP4lLGl/0kZb76TnyRpYSPYojtS6CnkH+QLYnsRREXJYwD1Xku62LipkX
+wCkRTnZ5nUsDMX6FPKgjQFQCWDXG/N096+PRUQAChhrXsJ+gF3NqWtDmtrhVQF4n
+AgMBAAGjUDBOMB0GA1UdDgQWBBQo8v0wzQPx3EEexJPGlxPK1PpgKjAfBgNVHSME
+GDAWgBQo8v0wzQPx3EEexJPGlxPK1PpgKjAMBgNVHRMEBTADAQH/MA0GCSqGSIb3
+DQEBBQUAA4IBAQBGFRiJslcX0aJkwZpzTwSUdgcfKbpvNEbCNtVohfQVTI4a/oN5
+U+yqDZJg3vOaOuiAZqyHcIlZ8qyesCgRN314Tl4/JQ++CW8mKj1meTgo5YFxcZYm
+T9vsI3C+Nzn84DINgI9mx6yktIt3QOKZRDpzyPkUzxsyJ8J427DaimDrjTR+fTwD
+1Dh09xeeMnSa5zeV1HEDyJTqCXutLetwQ/IyfmMBhIx+nvB5f67pz/m+Dv6V0r3I
+p4HCcdnDUDGJbfqtoqsAATQQWO+WWuswB6mOhDbvPTxhRpZq6AkgWqv4S+u3M2GO
+r5p9FrBgavAw5bKO54C0oQKpN/5fta5l6Ws0
+-----END CERTIFICATE-----
diff --git a/src/jaegertracing/thrift/tutorial/go/server.key b/src/jaegertracing/thrift/tutorial/go/server.key
new file mode 100644
index 000000000..263cfce59
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/go/server.key
@@ -0,0 +1,28 @@
+-----BEGIN PRIVATE KEY-----
+MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQCqE9TE9wEXp5LR
+tLQVDSGQGV78+7ZtP/I/ZaJ6Q6ZGlfxDFvZjFF73seNhAvlKlYm/jflIHYLnNOCy
+SN8I2Xw6L9MbC+jvwkEKfQo4eDoxZnOZjNF5J1/lZtBeOowMkhhzBMH1Rds351/H
+jKNg6ZKg2Cldd0j7HbDtEixOLgLbPRpBcaYrLrNMasf3Hal+x8/b8ue28x93HSQB
+GmZmMIUwAinEu/fNP4lLGl/0kZb76TnyRpYSPYojtS6CnkH+QLYnsRREXJYwD1Xk
+u62LipkXwCkRTnZ5nUsDMX6FPKgjQFQCWDXG/N096+PRUQAChhrXsJ+gF3NqWtDm
+trhVQF4nAgMBAAECggEAW/y52YYW6ypROGbZ94DQpFV0kLO7qT8q0Ksxw5sPNaIt
+fEPRIymDa8ikyHWJS5Oxmw84wo5jnJV26jaLmwe2Lupq7Xf1lqej8f5LJtuv7cQR
+xfzp1vM65KJFFJHp6WqjGqJ6HSSZOpVDsnQYcXQjQCdpyAmaSWd3p+FqYSZ1mQmD
+bFNI7jqpczWSZhTdotQ7p7Hn9TVCehflP3yGIB3bQ+wCcCB85dOBz201L+YgaIck
+Sz43A4NvWaQIRLRDw7s9GW4jY5T0Jv282WIeAlVpVxLIwu48r4R4yGTIx9Ydowvq
+57+Y5iPPjAXxu0V9t00oS3bYxDaKh2DUfc/5zowq8QKBgQDYNVPXmaG0aIH4vjQ9
+7fRdw/UDkYcQbn6CnglQOu77/S8ogQzpKCVJgJgkZNqOVtQMEPzekGEcLTbje1gU
+8Bky2k+PL9UwbFy0emnOVh4rqrNXHsRvJcehNT/PRb5hjF3MUMFV/0iD4b+naFaE
+jrSWiZ2ZXj2qfwAK52GFbtOuBQKBgQDJYQuGiY0r22E4waJmCSKczoBT3cwlVzWj
+V2ljgA9RHLNTVkvNNYQLGu2qngFrtwpeaSnsMDerVG4wKAQWyCnYzxVrlnC4uDrJ
+HXuFEltBWi9Ffbgfsnd3749AT0oBP1NT2tMleguyf5DFgjCR3VRJLdrVaaZ8row/
+LqKcFMqnOwKBgB+OIO99l7E584Y3VG6ZdSneOLtNmRXX2pT7tcZE465ZdHGH7Dd3
+SYHhx9K/+Xn+yDH+pLli/xlarAEldmSP6k2WuTfftlC78AfTOfAId5zN7CDR9791
+Fx67I9X/itq33tS8EIuZl57P6uXm/4GXRloWOa8xpvRkVsBApuYPl8t1AoGATQDS
+y2sllDObBXzlgGbV2WgNIgSZ311toTv3jJiXQsjauW8yJRHln+l4H9mzaWDgkiFc
+ang1kUoDqF5k0eFQPxtQcYdhKwEnWWfwp33RbzfxA32DPnubuzzbZhfrkHaKgnIW
+cyor9uFYlm2l7ODZLfJez2RKyTplXnOSsmQw6akCgYAz3dj9Hskyj+HVJ+ht1OcE
+c7ai/ESkSA7Vajp0tjJp0EKjW/zq8DvUSXOtcdnJgkKycFluLwbmnaN4txBds1C1
+Qr8Rt2sUCCBNZe1L6DHe3XBdbkJe9sgZVNTjtUSQrzy8UhvsCqG4YWeCu07Szcbc
+rdPUV9/uQkdx8VrShxlD8A==
+-----END PRIVATE KEY-----
diff --git a/src/jaegertracing/thrift/tutorial/go/src/client.go b/src/jaegertracing/thrift/tutorial/go/src/client.go
new file mode 100644
index 000000000..e3ebe00df
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/go/src/client.go
@@ -0,0 +1,108 @@
+package main
+
+/*
+ * 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.
+ */
+
+import (
+ "context"
+ "crypto/tls"
+ "fmt"
+ "tutorial"
+
+ "github.com/apache/thrift/lib/go/thrift"
+)
+
+var defaultCtx = context.Background()
+
+func handleClient(client *tutorial.CalculatorClient) (err error) {
+ client.Ping(defaultCtx)
+ fmt.Println("ping()")
+
+ sum, _ := client.Add(defaultCtx, 1, 1)
+ fmt.Print("1+1=", sum, "\n")
+
+ work := tutorial.NewWork()
+ work.Op = tutorial.Operation_DIVIDE
+ work.Num1 = 1
+ work.Num2 = 0
+ quotient, err := client.Calculate(defaultCtx, 1, work)
+ if err != nil {
+ switch v := err.(type) {
+ case *tutorial.InvalidOperation:
+ fmt.Println("Invalid operation:", v)
+ default:
+ fmt.Println("Error during operation:", err)
+ }
+ return err
+ } else {
+ fmt.Println("Whoa we can divide by 0 with new value:", quotient)
+ }
+
+ work.Op = tutorial.Operation_SUBTRACT
+ work.Num1 = 15
+ work.Num2 = 10
+ diff, err := client.Calculate(defaultCtx, 1, work)
+ if err != nil {
+ switch v := err.(type) {
+ case *tutorial.InvalidOperation:
+ fmt.Println("Invalid operation:", v)
+ default:
+ fmt.Println("Error during operation:", err)
+ }
+ return err
+ } else {
+ fmt.Print("15-10=", diff, "\n")
+ }
+
+ log, err := client.GetStruct(defaultCtx, 1)
+ if err != nil {
+ fmt.Println("Unable to get struct:", err)
+ return err
+ } else {
+ fmt.Println("Check log:", log.Value)
+ }
+ return err
+}
+
+func runClient(transportFactory thrift.TTransportFactory, protocolFactory thrift.TProtocolFactory, addr string, secure bool) error {
+ var transport thrift.TTransport
+ var err error
+ if secure {
+ cfg := new(tls.Config)
+ cfg.InsecureSkipVerify = true
+ transport, err = thrift.NewTSSLSocket(addr, cfg)
+ } else {
+ transport, err = thrift.NewTSocket(addr)
+ }
+ if err != nil {
+ fmt.Println("Error opening socket:", err)
+ return err
+ }
+ transport, err = transportFactory.GetTransport(transport)
+ if err != nil {
+ return err
+ }
+ defer transport.Close()
+ if err := transport.Open(); err != nil {
+ return err
+ }
+ iprot := protocolFactory.GetProtocol(transport)
+ oprot := protocolFactory.GetProtocol(transport)
+ return handleClient(tutorial.NewCalculatorClient(thrift.NewTStandardClient(iprot, oprot)))
+}
diff --git a/src/jaegertracing/thrift/tutorial/go/src/handler.go b/src/jaegertracing/thrift/tutorial/go/src/handler.go
new file mode 100644
index 000000000..5c0eed006
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/go/src/handler.go
@@ -0,0 +1,102 @@
+package main
+
+/*
+ * 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.
+ */
+
+import (
+ "context"
+ "fmt"
+ "shared"
+ "strconv"
+ "tutorial"
+)
+
+type CalculatorHandler struct {
+ log map[int]*shared.SharedStruct
+}
+
+func NewCalculatorHandler() *CalculatorHandler {
+ return &CalculatorHandler{log: make(map[int]*shared.SharedStruct)}
+}
+
+func (p *CalculatorHandler) Ping(ctx context.Context) (err error) {
+ fmt.Print("ping()\n")
+ return nil
+}
+
+func (p *CalculatorHandler) Add(ctx context.Context, num1 int32, num2 int32) (retval17 int32, err error) {
+ fmt.Print("add(", num1, ",", num2, ")\n")
+ return num1 + num2, nil
+}
+
+func (p *CalculatorHandler) Calculate(ctx context.Context, logid int32, w *tutorial.Work) (val int32, err error) {
+ fmt.Print("calculate(", logid, ", {", w.Op, ",", w.Num1, ",", w.Num2, "})\n")
+ switch w.Op {
+ case tutorial.Operation_ADD:
+ val = w.Num1 + w.Num2
+ break
+ case tutorial.Operation_SUBTRACT:
+ val = w.Num1 - w.Num2
+ break
+ case tutorial.Operation_MULTIPLY:
+ val = w.Num1 * w.Num2
+ break
+ case tutorial.Operation_DIVIDE:
+ if w.Num2 == 0 {
+ ouch := tutorial.NewInvalidOperation()
+ ouch.WhatOp = int32(w.Op)
+ ouch.Why = "Cannot divide by 0"
+ err = ouch
+ return
+ }
+ val = w.Num1 / w.Num2
+ break
+ default:
+ ouch := tutorial.NewInvalidOperation()
+ ouch.WhatOp = int32(w.Op)
+ ouch.Why = "Unknown operation"
+ err = ouch
+ return
+ }
+ entry := shared.NewSharedStruct()
+ entry.Key = logid
+ entry.Value = strconv.Itoa(int(val))
+ k := int(logid)
+ /*
+ oldvalue, exists := p.log[k]
+ if exists {
+ fmt.Print("Replacing ", oldvalue, " with ", entry, " for key ", k, "\n")
+ } else {
+ fmt.Print("Adding ", entry, " for key ", k, "\n")
+ }
+ */
+ p.log[k] = entry
+ return val, err
+}
+
+func (p *CalculatorHandler) GetStruct(ctx context.Context, key int32) (*shared.SharedStruct, error) {
+ fmt.Print("getStruct(", key, ")\n")
+ v, _ := p.log[int(key)]
+ return v, nil
+}
+
+func (p *CalculatorHandler) Zip(ctx context.Context) (err error) {
+ fmt.Print("zip()\n")
+ return nil
+}
diff --git a/src/jaegertracing/thrift/tutorial/go/src/main.go b/src/jaegertracing/thrift/tutorial/go/src/main.go
new file mode 100644
index 000000000..7730d7b32
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/go/src/main.go
@@ -0,0 +1,82 @@
+package main
+
+/*
+ * 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.
+ */
+
+import (
+ "flag"
+ "fmt"
+ "github.com/apache/thrift/lib/go/thrift"
+ "os"
+)
+
+func Usage() {
+ fmt.Fprint(os.Stderr, "Usage of ", os.Args[0], ":\n")
+ flag.PrintDefaults()
+ fmt.Fprint(os.Stderr, "\n")
+}
+
+func main() {
+ flag.Usage = Usage
+ server := flag.Bool("server", false, "Run server")
+ protocol := flag.String("P", "binary", "Specify the protocol (binary, compact, json, simplejson)")
+ framed := flag.Bool("framed", false, "Use framed transport")
+ buffered := flag.Bool("buffered", false, "Use buffered transport")
+ addr := flag.String("addr", "localhost:9090", "Address to listen to")
+ secure := flag.Bool("secure", false, "Use tls secure transport")
+
+ flag.Parse()
+
+ var protocolFactory thrift.TProtocolFactory
+ switch *protocol {
+ case "compact":
+ protocolFactory = thrift.NewTCompactProtocolFactory()
+ case "simplejson":
+ protocolFactory = thrift.NewTSimpleJSONProtocolFactory()
+ case "json":
+ protocolFactory = thrift.NewTJSONProtocolFactory()
+ case "binary", "":
+ protocolFactory = thrift.NewTBinaryProtocolFactoryDefault()
+ default:
+ fmt.Fprint(os.Stderr, "Invalid protocol specified", protocol, "\n")
+ Usage()
+ os.Exit(1)
+ }
+
+ var transportFactory thrift.TTransportFactory
+ if *buffered {
+ transportFactory = thrift.NewTBufferedTransportFactory(8192)
+ } else {
+ transportFactory = thrift.NewTTransportFactory()
+ }
+
+ if *framed {
+ transportFactory = thrift.NewTFramedTransportFactory(transportFactory)
+ }
+
+ if *server {
+ if err := runServer(transportFactory, protocolFactory, *addr, *secure); err != nil {
+ fmt.Println("error running server:", err)
+ }
+ } else {
+ if err := runClient(transportFactory, protocolFactory, *addr, *secure); err != nil {
+ fmt.Println("error running client:", err)
+ }
+ }
+}
diff --git a/src/jaegertracing/thrift/tutorial/go/src/server.go b/src/jaegertracing/thrift/tutorial/go/src/server.go
new file mode 100644
index 000000000..95708eb87
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/go/src/server.go
@@ -0,0 +1,54 @@
+package main
+
+/*
+ * 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.
+ */
+
+import (
+ "crypto/tls"
+ "fmt"
+ "github.com/apache/thrift/lib/go/thrift"
+ "tutorial"
+)
+
+func runServer(transportFactory thrift.TTransportFactory, protocolFactory thrift.TProtocolFactory, addr string, secure bool) error {
+ var transport thrift.TServerTransport
+ var err error
+ if secure {
+ cfg := new(tls.Config)
+ if cert, err := tls.LoadX509KeyPair("server.crt", "server.key"); err == nil {
+ cfg.Certificates = append(cfg.Certificates, cert)
+ } else {
+ return err
+ }
+ transport, err = thrift.NewTSSLServerSocket(addr, cfg)
+ } else {
+ transport, err = thrift.NewTServerSocket(addr)
+ }
+
+ if err != nil {
+ return err
+ }
+ fmt.Printf("%T\n", transport)
+ handler := NewCalculatorHandler()
+ processor := tutorial.NewCalculatorProcessor(handler)
+ server := thrift.NewTSimpleServer4(processor, transport, transportFactory, protocolFactory)
+
+ fmt.Println("Starting the simple server... on ", addr)
+ return server.Serve()
+}
diff --git a/src/jaegertracing/thrift/tutorial/haxe/Makefile.am b/src/jaegertracing/thrift/tutorial/haxe/Makefile.am
new file mode 100644
index 000000000..e6f271346
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/haxe/Makefile.am
@@ -0,0 +1,97 @@
+#
+# 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.
+#
+
+BIN_CPP = bin/Main-debug
+BIN_PHP = bin/php/Main-debug.php
+BIN_PHP_WEB = bin/php-web-server/Main-debug.php
+
+gen-haxe/tutorial/calculator.hx gen-haxe/shared/shared_service.hx: $(top_srcdir)/tutorial/tutorial.thrift
+ $(THRIFT) --gen haxe -r $<
+
+all-local: $(BIN_CPP) $(BIN_PHP) $(BIN_PHP_WEB)
+
+check: gen-haxe/tutorial/calculator.hx
+
+$(BIN_CPP): \
+ src/*.hx \
+ ../../lib/haxe/src/org/apache/thrift/**/*.hx \
+ gen-haxe/tutorial/calculator.hx
+ $(HAXE) --cwd . cpp.hxml
+
+$(BIN_PHP): \
+ src/*.hx \
+ ../../lib/haxe/src/org/apache/thrift/**/*.hx \
+ gen-haxe/tutorial/calculator.hx
+ $(HAXE) --cwd . php.hxml
+
+$(BIN_PHP_WEB): \
+ src/*.hx \
+ ../../lib/haxe/src/org/apache/thrift/**/*.hx \
+ gen-haxe/tutorial/calculator.hx
+ $(HAXE) --cwd . php-web-server.hxml
+
+tutorialserver: all
+ $(BIN_CPP) server
+
+tutorialserver_php: all
+ php -f $(BIN_PHP) server
+
+tutorialclient: all
+ $(BIN_CPP)
+
+tutorialclient_php: all
+ php -f $(BIN_PHP)
+
+tutorialsecureserver: all
+ $(BIN_CPP) server secure
+
+tutorialsecureserver_php: all
+ php -f $(BIN_PHP) server secure
+
+tutorialsecureclient: all
+ $(BIN_CPP) secure
+
+tutorialsecureclient_php: all
+ php -f $(BIN_PHP) secure
+
+tutorialserver_php_http: all
+ php -S 127.0.0.1:9090 router.php
+
+tutorialclient_http: all
+ $(BIN_CPP) client http
+
+clean-local:
+ $(RM) -r gen-haxe bin
+
+EXTRA_DIST = \
+ src \
+ cpp.hxml \
+ csharp.hxml \
+ flash.hxml \
+ java.hxml \
+ javascript.hxml \
+ php-web-server.hxml \
+ neko.hxml \
+ php.hxml \
+ python.hxml \
+ router.php \
+ project.hide \
+ Tutorial.hxproj \
+ make_all.bat \
+ make_all.sh
diff --git a/src/jaegertracing/thrift/tutorial/haxe/Tutorial.hxproj b/src/jaegertracing/thrift/tutorial/haxe/Tutorial.hxproj
new file mode 100644
index 000000000..796f648a5
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/haxe/Tutorial.hxproj
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="utf-8"?>
+<project version="2">
+ <!-- Output SWF options -->
+ <output>
+ <movie outputType="Application" />
+ <movie input="" />
+ <movie path="bin/HaxeTutorial" />
+ <movie fps="30" />
+ <movie width="800" />
+ <movie height="600" />
+ <movie version="1" />
+ <movie minorVersion="0" />
+ <movie platform="C++" />
+ <movie background="#FFFFFF" />
+ </output>
+ <!-- Other classes to be compiled into your SWF -->
+ <classpaths>
+ <class path="src" />
+ <class path="gen-haxe" />
+ <class path="../../lib/haxe/src" />
+ </classpaths>
+ <!-- Build options -->
+ <build>
+ <option directives="" />
+ <option flashStrict="False" />
+ <option noInlineOnDebug="False" />
+ <option mainClass="Main" />
+ <option enabledebug="False" />
+ <option additional="" />
+ </build>
+ <!-- haxelib libraries -->
+ <haxelib>
+ <!-- example: <library name="..." /> -->
+ </haxelib>
+ <!-- Class files to compile (other referenced classes will automatically be included) -->
+ <compileTargets>
+ <!-- example: <compile path="..." /> -->
+ </compileTargets>
+ <!-- Paths to exclude from the Project Explorer tree -->
+ <hiddenPaths>
+ <hidden path="obj" />
+ <hidden path="cpp.hxml" />
+ <hidden path="csharp.hxml" />
+ <hidden path="flash.hxml" />
+ <hidden path="java.hxml" />
+ <hidden path="javascript.hxml" />
+ <hidden path="make_all.bat" />
+ <hidden path="make_all.sh" />
+ <hidden path="Makefile.am" />
+ <hidden path="neko.hxml" />
+ <hidden path="php.hxml" />
+ <hidden path="project.hide" />
+ <hidden path="python.hxml" />
+ </hiddenPaths>
+ <!-- Executed before build -->
+ <preBuildCommand>thrift -r -gen haxe ../tutorial.thrift</preBuildCommand>
+ <!-- Executed after build -->
+ <postBuildCommand alwaysRun="False" />
+ <!-- Other project options -->
+ <options>
+ <option showHiddenPaths="False" />
+ <option testMovie="Unknown" />
+ <option testMovieCommand="" />
+ </options>
+ <!-- Plugin storage -->
+ <storage />
+</project> \ No newline at end of file
diff --git a/src/jaegertracing/thrift/tutorial/haxe/cpp.hxml b/src/jaegertracing/thrift/tutorial/haxe/cpp.hxml
new file mode 100644
index 000000000..6adb52d7e
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/haxe/cpp.hxml
@@ -0,0 +1,41 @@
+#
+# 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.
+#
+
+#integrate files to classpath
+-cp src
+-cp gen-haxe
+-cp ../../lib/haxe/src
+
+#this class wil be used as entry point for your app.
+-main Main
+
+#CPP target
+-cpp bin
+
+#To produce 64 bit binaries the file should define the HXCPP_M64 compile variable:
+#-D HXCPP_M64
+
+#Add debug information
+-debug
+
+#dead code elimination : remove unused code
+#"-dce no" : do not remove unused code
+#"-dce std" : remove unused code in the std lib (default)
+#"-dce full" : remove all unused code
+-dce full \ No newline at end of file
diff --git a/src/jaegertracing/thrift/tutorial/haxe/csharp.hxml b/src/jaegertracing/thrift/tutorial/haxe/csharp.hxml
new file mode 100644
index 000000000..295c017e7
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/haxe/csharp.hxml
@@ -0,0 +1,38 @@
+#
+# 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.
+#
+
+#integrate files to classpath
+-cp src
+-cp gen-haxe
+-cp ../../lib/haxe/src
+
+#this class wil be used as entry point for your app.
+-main Main
+
+#CSHARP target
+-cs bin/Tutorial.exe
+
+#Add debug information
+-debug
+
+#dead code elimination : remove unused code
+#"-dce no" : do not remove unused code
+#"-dce std" : remove unused code in the std lib (default)
+#"-dce full" : remove all unused code
+-dce full \ No newline at end of file
diff --git a/src/jaegertracing/thrift/tutorial/haxe/flash.hxml b/src/jaegertracing/thrift/tutorial/haxe/flash.hxml
new file mode 100644
index 000000000..a1f0568ad
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/haxe/flash.hxml
@@ -0,0 +1,41 @@
+#
+# 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.
+#
+
+#integrate files to classpath
+-cp src
+-cp gen-haxe
+-cp ../../lib/haxe/src
+
+#this class wil be used as entry point for your app.
+-main Main
+
+#Flash target
+-swf bin/Tutorial.swf
+
+#Add debug information
+-debug
+
+# we need some goodies from sys.net
+# --macro allowPackage("sys")
+
+#dead code elimination : remove unused code
+#"-dce no" : do not remove unused code
+#"-dce std" : remove unused code in the std lib (default)
+#"-dce full" : remove all unused code
+-dce full \ No newline at end of file
diff --git a/src/jaegertracing/thrift/tutorial/haxe/java.hxml b/src/jaegertracing/thrift/tutorial/haxe/java.hxml
new file mode 100644
index 000000000..c615565a9
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/haxe/java.hxml
@@ -0,0 +1,38 @@
+#
+# 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.
+#
+
+#integrate files to classpath
+-cp src
+-cp gen-haxe
+-cp ../../lib/haxe/src
+
+#this class wil be used as entry point for your app.
+-main Main
+
+#Java target
+-java bin/Tutorial.jar
+
+#Add debug information
+-debug
+
+#dead code elimination : remove unused code
+#"-dce no" : do not remove unused code
+#"-dce std" : remove unused code in the std lib (default)
+#"-dce full" : remove all unused code
+-dce full \ No newline at end of file
diff --git a/src/jaegertracing/thrift/tutorial/haxe/javascript.hxml b/src/jaegertracing/thrift/tutorial/haxe/javascript.hxml
new file mode 100644
index 000000000..b2b3876cf
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/haxe/javascript.hxml
@@ -0,0 +1,44 @@
+#
+# 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.
+#
+
+#integrate files to classpath
+-cp src
+-cp gen-haxe
+-cp ../../lib/haxe/src
+
+#this class wil be used as entry point for your app.
+-main Main
+
+#JavaScript target
+-js bin/Tutorial.js
+
+#You can use -D source-map-content (requires Haxe 3.1+) to have the .hx
+#files directly embedded into the map file, this way you only have to
+#upload it, and it will be always in sync with the compiled .js even if
+#you modify your .hx files.
+-D source-map-content
+
+#Generate source map and add debug information
+-debug
+
+#dead code elimination : remove unused code
+#"-dce no" : do not remove unused code
+#"-dce std" : remove unused code in the std lib (default)
+#"-dce full" : remove all unused code
+-dce full \ No newline at end of file
diff --git a/src/jaegertracing/thrift/tutorial/haxe/make_all.bat b/src/jaegertracing/thrift/tutorial/haxe/make_all.bat
new file mode 100644
index 000000000..656dd1530
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/haxe/make_all.bat
@@ -0,0 +1,68 @@
+@echo off
+rem /*
+rem * Licensed to the Apache Software Foundation (ASF) under one
+rem * or more contributor license agreements. See the NOTICE file
+rem * distributed with this work for additional information
+rem * regarding copyright ownership. The ASF licenses this file
+rem * to you under the Apache License, Version 2.0 (the
+rem * "License"); you may not use this file except in compliance
+rem * with the License. You may obtain a copy of the License at
+rem *
+rem * http://www.apache.org/licenses/LICENSE-2.0
+rem *
+rem * Unless required by applicable law or agreed to in writing,
+rem * software distributed under the License is distributed on an
+rem * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+rem * KIND, either express or implied. See the License for the
+rem * specific language governing permissions and limitations
+rem * under the License.
+rem */
+
+setlocal
+if "%HOMEDRIVE%"=="" goto MISSINGVARS
+if "%HOMEPATH%"=="" goto MISSINGVARS
+if "%HAXEPATH%"=="" goto NOTINSTALLED
+
+set path=%HAXEPATH%;%HAXEPATH%\..\neko;%path%
+
+rem # invoke Thrift comnpiler
+thrift -r -gen haxe ..\tutorial.thrift
+if errorlevel 1 goto STOP
+
+rem # invoke Haxe compiler for all targets
+for %%a in (*.hxml) do (
+ rem * filter Python, as it is not supported by Haxe 3.1.3 (but will be in 3.1.4)
+ if not "%%a"=="python.hxml" (
+ echo --------------------------
+ echo Building %%a ...
+ echo --------------------------
+ haxe --cwd . %%a
+ )
+)
+
+
+echo.
+echo done.
+pause
+goto eof
+
+:NOTINSTALLED
+echo FATAL: Either Haxe is not installed, or the HAXEPATH variable is not set.
+pause
+goto eof
+
+:MISSINGVARS
+echo FATAL: Unable to locate home folder.
+echo.
+echo Both HOMEDRIVE and HOMEPATH need to be set to point to your Home folder.
+echo The current values are:
+echo HOMEDRIVE=%HOMEDRIVE%
+echo HOMEPATH=%HOMEPATH%
+pause
+goto eof
+
+:STOP
+pause
+goto eof
+
+:eof
diff --git a/src/jaegertracing/thrift/tutorial/haxe/make_all.sh b/src/jaegertracing/thrift/tutorial/haxe/make_all.sh
new file mode 100644
index 000000000..2ee650dce
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/haxe/make_all.sh
@@ -0,0 +1,41 @@
+#!/bin/sh
+#
+# 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.
+#
+
+# invoke Thrift comnpiler
+thrift -r -gen haxe ../tutorial.thrift
+
+# output folder
+if [ ! -d bin ]; then
+ mkdir bin
+fi
+
+# invoke Haxe compoiler
+for target in *.hxml; do
+ echo --------------------------
+ echo Building ${target} ...
+ echo --------------------------
+ if [ ! -d bin/${target} ]; then
+ mkdir bin/${target}
+ fi
+ haxe --cwd . ${target}
+done
+
+
+#eof
diff --git a/src/jaegertracing/thrift/tutorial/haxe/neko.hxml b/src/jaegertracing/thrift/tutorial/haxe/neko.hxml
new file mode 100644
index 000000000..6161f6977
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/haxe/neko.hxml
@@ -0,0 +1,38 @@
+#
+# 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.
+#
+
+#integrate files to classpath
+-cp src
+-cp gen-haxe
+-cp ../../lib/haxe/src
+
+#this class wil be used as entry point for your app.
+-main Main
+
+#neko target
+-neko bin/Tutorial.n
+
+#Add debug information
+-debug
+
+#dead code elimination : remove unused code
+#"-dce no" : do not remove unused code
+#"-dce std" : remove unused code in the std lib (default)
+#"-dce full" : remove all unused code
+-dce full \ No newline at end of file
diff --git a/src/jaegertracing/thrift/tutorial/haxe/php-web-server.hxml b/src/jaegertracing/thrift/tutorial/haxe/php-web-server.hxml
new file mode 100644
index 000000000..395a8521e
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/haxe/php-web-server.hxml
@@ -0,0 +1,43 @@
+#
+# 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.
+#
+
+#integrate files to classpath
+-cp src
+-cp gen-haxe
+-cp ../../lib/haxe/src
+
+#this class wil be used as entry point for your app.
+-main Main
+
+#PHP target
+-php bin/php-web-server/
+--php-front Main-debug.php
+
+#defines
+-D phpwebserver
+
+
+#Add debug information
+-debug
+
+#dead code elimination : remove unused code
+#"-dce no" : do not remove unused code
+#"-dce std" : remove unused code in the std lib (default)
+#"-dce full" : remove all unused code
+-dce full
diff --git a/src/jaegertracing/thrift/tutorial/haxe/php.hxml b/src/jaegertracing/thrift/tutorial/haxe/php.hxml
new file mode 100644
index 000000000..c2f68878e
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/haxe/php.hxml
@@ -0,0 +1,39 @@
+#
+# 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.
+#
+
+#integrate files to classpath
+-cp src
+-cp gen-haxe
+-cp ../../lib/haxe/src
+
+#this class wil be used as entry point for your app.
+-main Main
+
+#PHP target
+-php bin/php/
+--php-front Main-debug.php
+
+#Add debug information
+-debug
+
+#dead code elimination : remove unused code
+#"-dce no" : do not remove unused code
+#"-dce std" : remove unused code in the std lib (default)
+#"-dce full" : remove all unused code
+-dce full
diff --git a/src/jaegertracing/thrift/tutorial/haxe/project.hide b/src/jaegertracing/thrift/tutorial/haxe/project.hide
new file mode 100644
index 000000000..8d5d4ec56
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/haxe/project.hide
@@ -0,0 +1,105 @@
+{
+ "type" : 0
+ ,"target" : 4
+ ,"name" : "Apache Thrift Tutorial"
+ ,"main" : null
+ ,"projectPackage" : ""
+ ,"company" : "Apache Software Foundation (ASF)"
+ ,"license" : "Apache License, Version 2.0"
+ ,"url" : "http://www.apache.org/licenses/LICENSE-2.0"
+ ,"targetData" : [
+ {
+ "pathToHxml" : "flash.hxml"
+ ,"runActionType" : 1
+ ,"runActionText" : "bin/Tutorial.swf"
+ }
+ ,{
+ "pathToHxml" : "javascript.hxml"
+ ,"runActionType" : 1
+ ,"runActionText" : "bin\\index.html"
+ }
+ ,{
+ "pathToHxml" : "neko.hxml"
+ ,"runActionType" : 2
+ ,"runActionText" : "neko bin/Tutorial.n"
+ }
+ ,{
+ "pathToHxml" : "php.hxml"
+ }
+ ,{
+ "pathToHxml" : "cpp.hxml"
+ ,"runActionType" : 2
+ ,"runActionText" : "bin/Main-debug.exe"
+ }
+ ,{
+ "pathToHxml" : "java.hxml"
+ }
+ ,{
+ "pathToHxml" : "csharp.hxml"
+ ,"runActionType" : 2
+ ,"runActionText" : "bin\\Tutorial.exe\\bin\\Main-Debug.exe"
+ }
+ ,{
+ "pathToHxml" : "python.hxml"
+ ,"runActionType" : 2
+ ,"runActionText" : "python bin/Tutorial.py"
+ }
+ ]
+ ,"files" : [
+ {
+ "path" : "src\\org\\apache\\thrift\\server\\TServer.hx"
+ ,"useTabs" : true
+ ,"indentSize" : 4
+ ,"foldedRegions" : [
+
+ ]
+ ,"activeLine" : 76
+ }
+ ,{
+ "path" : "src\\org\\apache\\thrift\\server\\TSimpleServer.hx"
+ ,"useTabs" : true
+ ,"indentSize" : 4
+ ,"foldedRegions" : [
+
+ ]
+ ,"activeLine" : 100
+ }
+ ,{
+ "path" : "src\\shared\\SharedServiceProcessor.hx"
+ ,"useTabs" : true
+ ,"indentSize" : 4
+ ,"foldedRegions" : [
+
+ ]
+ ,"activeLine" : 20
+ }
+ ,{
+ "path" : "src\\tutorial\\CalculatorProcessor.hx"
+ ,"useTabs" : true
+ ,"indentSize" : 4
+ ,"foldedRegions" : [
+
+ ]
+ ,"activeLine" : 79
+ }
+ ,{
+ "path" : "src\\Main.hx"
+ ,"useTabs" : true
+ ,"indentSize" : 4
+ ,"foldedRegions" : [
+
+ ]
+ ,"activeLine" : 0
+ }
+ ]
+ ,"activeFile" : "src\\Main.hx"
+ ,"openFLTarget" : null
+ ,"openFLBuildMode" : "Debug"
+ ,"runActionType" : null
+ ,"runActionText" : null
+ ,"buildActionCommand" : null
+ ,"hiddenItems" : [
+
+ ]
+ ,"showHiddenItems" : false
+} \ No newline at end of file
diff --git a/src/jaegertracing/thrift/tutorial/haxe/python.hxml b/src/jaegertracing/thrift/tutorial/haxe/python.hxml
new file mode 100644
index 000000000..f2c19fa93
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/haxe/python.hxml
@@ -0,0 +1,38 @@
+#
+# 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.
+#
+
+#integrate files to classpath
+-cp src
+-cp gen-haxe
+-cp ../../lib/haxe/src
+
+#this class wil be used as entry point for your app.
+-main Main
+
+#Python target
+-python bin/Tutorial.py
+
+#Add debug information
+-debug
+
+#dead code elimination : remove unused code
+#"-dce no" : do not remove unused code
+#"-dce std" : remove unused code in the std lib (default)
+#"-dce full" : remove all unused code
+-dce full \ No newline at end of file
diff --git a/src/jaegertracing/thrift/tutorial/haxe/router.php b/src/jaegertracing/thrift/tutorial/haxe/router.php
new file mode 100644
index 000000000..e34135cc9
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/haxe/router.php
@@ -0,0 +1,31 @@
+<?php
+/*
+ * 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 thrift
+ */
+
+
+
+//router file to run testing web server
+
+//set_time_limit(1);
+
+require_once dirname(__FILE__) . '/bin/php-web-server/Main-debug.php';
+
+
diff --git a/src/jaegertracing/thrift/tutorial/haxe/src/CalculatorHandler.hx b/src/jaegertracing/thrift/tutorial/haxe/src/CalculatorHandler.hx
new file mode 100644
index 000000000..e9752db9f
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/haxe/src/CalculatorHandler.hx
@@ -0,0 +1,101 @@
+/*
+ * 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;
+
+import haxe.ds.IntMap;
+
+import org.apache.thrift.*;
+import org.apache.thrift.protocol.*;
+import org.apache.thrift.transport.*;
+import org.apache.thrift.server.*;
+import org.apache.thrift.meta_data.*;
+
+import tutorial.*;
+import shared.*;
+
+
+class CalculatorHandler implements Calculator {
+
+ private var log = new IntMap<SharedStruct>();
+
+ public function new() {
+ }
+
+ public function ping() : Void {
+ trace("ping()");
+ }
+
+
+ public function add( num1 : haxe.Int32, num2 : haxe.Int32) : haxe.Int32 {
+ trace('add( $num1, $num2)');
+ return num1 + num2;
+ }
+
+ public function calculate( logid : haxe.Int32, work : Work) : haxe.Int32 {
+ trace('calculate( $logid, '+work.op+","+work.num1+","+work.num2+")");
+
+ var val : haxe.Int32 = 0;
+ switch (work.op)
+ {
+ case Operation.ADD:
+ val = work.num1 + work.num2;
+
+ case Operation.SUBTRACT:
+ val = work.num1 - work.num2;
+
+ case Operation.MULTIPLY:
+ val = work.num1 * work.num2;
+
+ case Operation.DIVIDE:
+ if (work.num2 == 0)
+ {
+ var io = new InvalidOperation();
+ io.whatOp = work.op;
+ io.why = "Cannot divide by 0";
+ throw io;
+ }
+ val = Std.int( work.num1 / work.num2);
+
+ default:
+ var io = new InvalidOperation();
+ io.whatOp = work.op;
+ io.why = "Unknown operation";
+ throw io;
+ }
+
+ var entry = new SharedStruct();
+ entry.key = logid;
+ entry.value = '$val';
+ log.set(logid, entry);
+
+ return val;
+ }
+
+ public function getStruct( key : haxe.Int32) : SharedStruct {
+ trace('getStruct($key)');
+ return log.get(key);
+ }
+
+ // oneway method, no args
+ public function zip() : Void {
+ trace("zip()");
+ }
+
+}
diff --git a/src/jaegertracing/thrift/tutorial/haxe/src/Main.hx b/src/jaegertracing/thrift/tutorial/haxe/src/Main.hx
new file mode 100644
index 000000000..6bebe7164
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/haxe/src/Main.hx
@@ -0,0 +1,375 @@
+/*
+ * 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;
+
+import org.apache.thrift.*;
+import org.apache.thrift.protocol.*;
+import org.apache.thrift.transport.*;
+import org.apache.thrift.server.*;
+import org.apache.thrift.meta_data.*;
+
+import tutorial.*;
+import shared.*;
+
+
+enum Prot {
+ binary;
+ json;
+}
+
+enum Trns {
+ socket;
+ http;
+}
+
+class Main {
+
+ private static var server : Bool = false;
+ private static var framed : Bool = false;
+ private static var buffered : Bool = false;
+ private static var prot : Prot = binary;
+ private static var trns : Trns = socket;
+
+ private static var targetHost : String = "localhost";
+ private static var targetPort : Int = 9090;
+
+ static function main() {
+
+ #if ! (flash || js || phpwebserver)
+ try {
+ ParseArgs();
+ } catch (e : String) {
+ trace(e);
+ trace(GetHelp());
+ return;
+ }
+
+ #elseif phpwebserver
+ //forcing server
+ server = true;
+ trns = http;
+ initPhpWebServer();
+ //check method
+ if(php.Web.getMethod() != 'POST') {
+ Sys.println('http endpoint for thrift test server');
+ return;
+ }
+ #end
+
+ try {
+ if (server)
+ RunServer();
+ else
+ RunClient();
+ } catch (e : String) {
+ trace(e);
+ }
+
+ trace("Completed.");
+ }
+
+ #if phpwebserver
+ private static function initPhpWebServer()
+ {
+ //remap trace to error log
+ haxe.Log.trace = function(v:Dynamic, ?infos:haxe.PosInfos)
+ {
+ // handle trace
+ var newValue : Dynamic;
+ if (infos != null && infos.customParams!=null) {
+ var extra:String = "";
+ for( v in infos.customParams )
+ extra += "," + v;
+ newValue = v + extra;
+ }
+ else {
+ newValue = v;
+ }
+ var msg = infos != null ? infos.fileName + ':' + infos.lineNumber + ': ' : '';
+ Sys.stderr().writeString('${msg}${newValue}\n');
+ }
+ }
+ #end
+
+
+ #if ! (flash || js)
+
+ private static function GetHelp() : String {
+ return Sys.executablePath()+" modus trnsOption transport protocol\n"
+ +"Options:\n"
+ +" modus: client, server (default: client)\n"
+ +" trnsOption: framed, buffered (default: none)\n"
+ +" transport: socket, http (default: socket)\n"
+ +" protocol: binary, json (default: binary)\n"
+ +"\n"
+ +"All arguments are optional.\n";
+ }
+
+
+ private static function ParseArgs() : Void {
+ var step = 0;
+ for (arg in Sys.args()) {
+
+ // server|client
+ switch(step) {
+ case 0:
+ ++step;
+ if ( arg == "client")
+ server = false;
+ else if ( arg == "server")
+ server = true;
+ else
+ throw "First argument must be 'server' or 'client'";
+
+ case 1:
+ if ( arg == "framed") {
+ framed = true;
+ } else if ( arg == "buffered") {
+ buffered = true;
+ } else if ( arg == "socket") {
+ trns = socket;
+ ++step;
+ } else if ( arg == "http") {
+ trns = http;
+ ++step;
+ } else {
+ throw "Unknown transport "+arg;
+ }
+
+ case 2:
+ if ( arg == "binary") {
+ prot = binary;
+ ++step;
+ } else if ( arg == "json") {
+ prot = json;
+ ++step;
+ } else {
+ throw "Unknown protocol "+arg;
+ }
+
+ default:
+ throw "Unexpected argument "+arg;
+ }
+
+ if ( framed && buffered)
+ {
+ trace("WN: framed supersedes buffered");
+ }
+
+ }
+ }
+
+ #end
+
+ private static function ClientSetup() : Calculator {
+ trace("Client configuration:");
+
+ // endpoint transport
+ var transport : TTransport;
+ switch(trns)
+ {
+ case socket:
+ trace('- socket transport $targetHost:$targetPort');
+ transport = new TSocket( targetHost, targetPort);
+ case http:
+ var uri = 'http://${targetHost}:${targetPort}';
+ trace('- HTTP transport $uri');
+ transport = new THttpClient(uri);
+ default:
+ throw "Unhandled transport";
+ }
+
+
+ // optinal layered transport
+ if ( framed) {
+ trace("- framed transport");
+ transport = new TFramedTransport(transport);
+ } else if ( buffered) {
+ trace("- buffered transport");
+ transport = new TBufferedTransport(transport);
+ }
+
+
+ // protocol
+ var protocol : TProtocol;
+ switch(prot)
+ {
+ case binary:
+ trace("- binary protocol");
+ protocol = new TBinaryProtocol( transport);
+ case json:
+ trace("- JSON protocol");
+ protocol = new TJSONProtocol( transport);
+ default:
+ throw "Unhandled protocol";
+ }
+
+
+ // put everything together
+ transport.open();
+ return new CalculatorImpl(protocol,protocol);
+ }
+
+
+ private static function RunClient() : Void {
+ var client = ClientSetup();
+
+ try {
+ client.ping();
+ trace("ping() successful");
+ } catch(error : TException) {
+ trace('ping() failed: $error');
+ } catch(error : Dynamic) {
+ trace('ping() failed: $error');
+ }
+
+ try {
+ var sum = client.add( 1, 1);
+ trace('1+1=$sum');
+ } catch(error : TException) {
+ trace('add() failed: $error');
+ } catch(error : Dynamic) {
+ trace('add() failed: $error');
+ }
+
+
+ var work = new tutorial.Work();
+ work.op = tutorial.Operation.DIVIDE;
+ work.num1 = 1;
+ work.num2 = 0;
+ try {
+ var quotient = client.calculate( 1, work);
+ trace('Whoa we can divide by 0! Result = $quotient');
+ } catch(error : TException) {
+ trace('calculate() failed: $error');
+ } catch(error : Dynamic) {
+ trace('calculate() failed: $error');
+ }
+
+ work.op = tutorial.Operation.SUBTRACT;
+ work.num1 = 15;
+ work.num2 = 10;
+ try {
+ var diff = client.calculate( 1, work);
+ trace('15-10=$diff');
+ } catch(error : TException) {
+ trace('calculate() failed: $error');
+ } catch(error : Dynamic) {
+ trace('calculate() failed: $error');
+ }
+
+
+ try {
+ var log : SharedStruct = client.getStruct( 1);
+ var logval = log.value;
+ trace('Check log: $logval');
+ } catch(error : TException) {
+ trace('getStruct() failed: $error');
+ } catch(error : Dynamic) {
+ trace('getStruct() failed: $error');
+ }
+ }
+
+
+ private static function ServerSetup() : TServer {
+ trace("Server configuration:");
+
+ // endpoint transport
+ var transport : TServerTransport = null;
+ switch(trns)
+ {
+ case socket:
+ #if (flash || js)
+ throw 'current platform does not support socket servers';
+ #else
+ trace('- socket transport port $targetPort');
+ transport = new TServerSocket( targetPort);
+ #end
+ case http:
+ #if !phpwebserver
+ throw "HTTP server not implemented yet";
+ //trace("- http transport");
+ //transport = new THttpClient( targetHost);
+ #else
+ trace("- http transport");
+ transport = new TWrappingServerTransport(
+ new TStreamTransport(
+ new TFileStream("php://input", Read),
+ new TFileStream("php://output", Append)
+ )
+ );
+
+ #end
+ default:
+ throw "Unhandled transport";
+ }
+
+ // optional: layered transport
+ var transfactory : TTransportFactory = null;
+ if ( framed) {
+ trace("- framed transport");
+ transfactory = new TFramedTransportFactory();
+ } else if ( buffered) {
+ trace("- buffered transport");
+ transfactory = new TBufferedTransportFactory();
+ }
+
+ // protocol
+ var protfactory : TProtocolFactory = null;
+ switch(prot)
+ {
+ case binary:
+ trace("- binary protocol");
+ protfactory = new TBinaryProtocolFactory();
+ case json:
+ trace("- JSON protocol");
+ protfactory = new TJSONProtocolFactory();
+ default:
+ throw "Unhandled protocol";
+ }
+
+ var handler = new CalculatorHandler();
+ var processor = new CalculatorProcessor(handler);
+ var server = new TSimpleServer( processor, transport, transfactory, protfactory);
+ #if phpwebserver
+ server.runOnce = true;
+ #end
+
+ return server;
+ }
+
+
+ private static function RunServer() : Void {
+ try
+ {
+ var server = ServerSetup();
+
+ trace("\nStarting the server...");
+ server.Serve();
+ }
+ catch( e : Dynamic)
+ {
+ trace('RunServer() failed: $e');
+ }
+ trace("done.");
+ }
+
+}
+
diff --git a/src/jaegertracing/thrift/tutorial/hs/HaskellClient.hs b/src/jaegertracing/thrift/tutorial/hs/HaskellClient.hs
new file mode 100644
index 000000000..bd29df06d
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/hs/HaskellClient.hs
@@ -0,0 +1,76 @@
+--
+-- 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.
+--
+
+import qualified Calculator
+import qualified Calculator_Client as Client
+import qualified SharedService_Client as SClient
+import Tutorial_Types
+import SharedService_Iface
+import Shared_Types
+
+import Thrift
+import Thrift.Protocol.Binary
+import Thrift.Transport
+import Thrift.Transport.Handle
+import Thrift.Server
+
+import Control.Exception
+import Data.Maybe
+import Data.Text.Lazy
+import Text.Printf
+import Network
+
+main = do
+ transport <- hOpen ("localhost", PortNumber 9090)
+ let binProto = BinaryProtocol transport
+ let client = (binProto, binProto)
+
+ Client.ping client
+ print "ping()"
+
+ sum <- Client.add client 1 1
+ printf "1+1=%d\n" sum
+
+
+ let work = Work { work_op = DIVIDE,
+ work_num1 = 1,
+ work_num2 = 0,
+ work_comment = Nothing
+ }
+
+ Control.Exception.catch (printf "1/0=%d\n" =<< Client.calculate client 1 work)
+ (\e -> printf "InvalidOperation %s\n" (show (e :: InvalidOperation)))
+
+
+ let work = Work { work_op = SUBTRACT,
+ work_num1 = 15,
+ work_num2 = 10,
+ work_comment = Nothing
+ }
+
+ diff <- Client.calculate client 1 work
+ printf "15-10=%d\n" diff
+
+ log <- SClient.getStruct client 1
+ printf "Check log: %s\n" $ unpack $ sharedStruct_value log
+
+ -- Close!
+ tClose transport
+
+
diff --git a/src/jaegertracing/thrift/tutorial/hs/HaskellServer.hs b/src/jaegertracing/thrift/tutorial/hs/HaskellServer.hs
new file mode 100644
index 000000000..cfe13441d
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/hs/HaskellServer.hs
@@ -0,0 +1,103 @@
+--
+-- 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.
+--
+
+{-# LANGUAGE OverloadedStrings #-}
+
+import qualified Calculator
+import Calculator_Iface
+import Tutorial_Types
+import SharedService_Iface
+import Shared_Types
+
+import Thrift
+import Thrift.Protocol.Binary
+import Thrift.Transport
+import Thrift.Server
+
+import Data.Int
+import Data.String
+import Data.Maybe
+import Text.Printf
+import Control.Exception (throw)
+import Control.Concurrent.MVar
+import qualified Data.Map as M
+import Data.Map ((!))
+import Data.Monoid
+
+data CalculatorHandler = CalculatorHandler {mathLog :: MVar (M.Map Int32 SharedStruct)}
+
+newCalculatorHandler = do
+ log <- newMVar mempty
+ return $ CalculatorHandler log
+
+instance SharedService_Iface CalculatorHandler where
+ getStruct self k = do
+ myLog <- readMVar (mathLog self)
+ return $ (myLog ! k)
+
+
+instance Calculator_Iface CalculatorHandler where
+ ping _ =
+ print "ping()"
+
+ add _ n1 n2 = do
+ printf "add(%d,%d)\n" n1 n2
+ return (n1 + n2)
+
+ calculate self mlogid mwork = do
+ printf "calculate(%d, %s)\n" logid (show work)
+
+ let val = case op work of
+ ADD ->
+ num1 work + num2 work
+ SUBTRACT ->
+ num1 work - num2 work
+ MULTIPLY ->
+ num1 work * num2 work
+ DIVIDE ->
+ if num2 work == 0 then
+ throw $
+ InvalidOperation {
+ invalidOperation_whatOp = fromIntegral $ fromEnum $ op work,
+ invalidOperation_why = "Cannot divide by 0"
+ }
+ else
+ num1 work `div` num2 work
+
+ let logEntry = SharedStruct logid (fromString $ show $ val)
+ modifyMVar_ (mathLog self) $ return .(M.insert logid logEntry)
+
+ return $! val
+
+ where
+ -- stupid dynamic languages f'ing it up
+ num1 = work_num1
+ num2 = work_num2
+ op = work_op
+ logid = mlogid
+ work = mwork
+
+ zip _ =
+ print "zip()"
+
+main = do
+ handler <- newCalculatorHandler
+ print "Starting the server..."
+ runBasicServer handler Calculator.process 9090
+ print "done."
diff --git a/src/jaegertracing/thrift/tutorial/hs/LICENSE b/src/jaegertracing/thrift/tutorial/hs/LICENSE
new file mode 100644
index 000000000..3b6d7d74c
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/hs/LICENSE
@@ -0,0 +1,239 @@
+
+ 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.
+
+--------------------------------------------------
+For the aclocal/ax_boost_base.m4 and contrib/fb303/aclocal/ax_boost_base.m4 components:
+
+# Copyright (c) 2007 Thomas Porschberg <thomas@randspringer.de>
+#
+# 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 lib/nodejs/lib/thrift/json_parse.js:
+
+/*
+ json_parse.js
+ 2015-05-02
+ Public Domain.
+ NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
+
+*/
+(By Douglas Crockford <douglas@crockford.com>)
+--------------------------------------------------
diff --git a/src/jaegertracing/thrift/tutorial/hs/Makefile.am b/src/jaegertracing/thrift/tutorial/hs/Makefile.am
new file mode 100755
index 000000000..9c6fd8308
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/hs/Makefile.am
@@ -0,0 +1,47 @@
+#
+# 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.
+#
+
+all-local:
+ $(top_builddir)/compiler/cpp/thrift --gen hs -r $(top_srcdir)/tutorial/tutorial.thrift
+ $(CABAL) install
+
+install-exec-hook:
+ $(CABAL) install
+
+# Make sure this doesn't fail if Haskell is not configured.
+clean-local:
+ $(CABAL) clean
+ $(RM) -r dist/
+ $(RM) -r gen-*/
+
+dist-hook:
+ $(RM) -r $(distdir)/dist/
+ $(RM) -r $(distdir)/gen-*/
+
+check-local:
+ $(CABAL) check
+
+tutorialserver: all
+ dist/build/HaskellServer/HaskellServer
+
+tutorialclient: all
+ dist/build/HaskellClient/HaskellClient
+
+EXTRA_DIST = \
+ LICENSE
diff --git a/src/jaegertracing/thrift/tutorial/hs/Setup.lhs b/src/jaegertracing/thrift/tutorial/hs/Setup.lhs
new file mode 100644
index 000000000..c7df182d3
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/hs/Setup.lhs
@@ -0,0 +1,21 @@
+#!/usr/bin/env runhaskell
+
+> -- 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.
+
+> import Distribution.Simple
+> main = defaultMain
diff --git a/src/jaegertracing/thrift/tutorial/hs/ThriftTutorial.cabal b/src/jaegertracing/thrift/tutorial/hs/ThriftTutorial.cabal
new file mode 100755
index 000000000..b6a612216
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/hs/ThriftTutorial.cabal
@@ -0,0 +1,73 @@
+--
+-- 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.
+--
+
+Name: ThriftTutorial
+Version: 0.13.0
+Cabal-Version: >= 1.4
+License: OtherLicense
+Category: Foreign
+Build-Type: Simple
+Synopsis: Thrift Tutorial library package
+Homepage: http://thrift.apache.org
+Bug-Reports: https://issues.apache.org/jira/browse/THRIFT
+Maintainer: dev@thrift.apache.org
+License-File: LICENSE
+
+Description:
+ Haskell tutorial for the Apache Thrift RPC system. Requires the use of the thrift code generator.
+
+flag network-uri
+ description: Get Network.URI from the network-uri package
+ default: True
+
+Executable HaskellServer
+ Main-is: HaskellServer.hs
+ Hs-Source-Dirs:
+ ., gen-hs/
+ Build-Depends:
+ base >= 4, base < 5, ghc-prim, containers, thrift, vector, unordered-containers, text, hashable, bytestring, QuickCheck
+ Extensions:
+ DeriveDataTypeable,
+ ExistentialQuantification,
+ FlexibleInstances,
+ KindSignatures,
+ MagicHash,
+ RankNTypes,
+ ScopedTypeVariables,
+ TypeSynonymInstances
+
+Executable HaskellClient
+ Main-is: HaskellClient.hs
+ Hs-Source-Dirs:
+ ., gen-hs/
+ Build-Depends:
+ base >= 4, base < 5, ghc-prim, containers, thrift, vector, QuickCheck
+ if flag(network-uri)
+ build-depends: network-uri >= 2.6, network >= 2.6
+ else
+ build-depends: network < 2.6
+ Extensions:
+ DeriveDataTypeable,
+ ExistentialQuantification,
+ FlexibleInstances,
+ KindSignatures,
+ MagicHash,
+ RankNTypes,
+ ScopedTypeVariables,
+ TypeSynonymInstances
diff --git a/src/jaegertracing/thrift/tutorial/java/Makefile.am b/src/jaegertracing/thrift/tutorial/java/Makefile.am
new file mode 100755
index 000000000..95908b154
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/java/Makefile.am
@@ -0,0 +1,45 @@
+#
+# 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.
+#
+
+export CLASSPATH
+
+# Make sure this doesn't fail if ant is not configured.
+clean-local:
+ ANT=$(ANT) ; if test -z "$$ANT" ; then ANT=: ; fi ; \
+ $$ANT $(ANT_FLAGS) clean
+
+all-local:
+ $(ANT) $(ANT_FLAGS) compile
+
+check-local: all
+ $(ANT) $(ANT_FLAGS) test
+
+tutorial: all
+ $(ANT) $(ANT_FLAGS) tutorial
+
+tutorialserver: all
+ $(ANT) $(ANT_FLAGS) tutorialserver
+
+tutorialclient: all
+ $(ANT) $(ANT_FLAGS) tutorialclient
+
+EXTRA_DIST = \
+ build.xml \
+ src \
+ README.md
diff --git a/src/jaegertracing/thrift/tutorial/java/README.md b/src/jaegertracing/thrift/tutorial/java/README.md
new file mode 100644
index 000000000..f109fea4a
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/java/README.md
@@ -0,0 +1,24 @@
+Thrift Java Tutorial
+==================================================
+1) Compile the Java library
+
+ thrift/lib/java$ make
+or:
+
+ thrift/lib/java$ ant
+
+4) Run the tutorial:
+
+start server and client with one step:
+
+ thrift/tutorial/java$ make tutorial
+
+or:
+
+ thrift/tutorial/java$ make tutorialserver
+ thrift/tutorial/java$ make tutorialclient
+
+or:
+
+ thrift/tutorial/java$ ant tutorialserver
+ thrift/tutorial/java$ ant tutorialclient
diff --git a/src/jaegertracing/thrift/tutorial/java/build.xml b/src/jaegertracing/thrift/tutorial/java/build.xml
new file mode 100644
index 000000000..55cdb8fab
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/java/build.xml
@@ -0,0 +1,115 @@
+<!--
+ 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.
+-->
+<project name="tutorial" default="tutorial" basedir=".">
+
+ <description>Thrift Java Tutorial</description>
+
+ <property name="src" location="src" />
+ <property name="gen" location="gen-java" />
+ <property name="build" location="build" />
+
+ <path id="libs.classpath">
+ <fileset dir="../../lib/java/build/libs">
+ <include name="libthrift*.jar" />
+ <exclude name="libthrift*test.jar" />
+ <exclude name="libthrift*javadoc.jar" />
+ <exclude name="libthrift*sources.jar" />
+ </fileset>
+ <fileset dir="../../lib/java/build/deps">
+ <include name="*.jar" />
+ </fileset>
+ </path>
+ <path id="build.classpath">
+ <path refid="libs.classpath" />
+ <pathelement path="${gen}" />
+ </path>
+ <path id="tutorial.classpath">
+ <path refid="build.classpath" />
+ <pathelement path="${build}" />
+ <pathelement path="tutorial.jar" />
+ </path>
+
+ <target name="init">
+ <tstamp />
+ <mkdir dir="${build}"/>
+ <mkdir dir="${build}/log"/>
+ </target>
+
+ <target name="compile" depends="init, generate">
+ <javac compiler="modern" includeantruntime="false" srcdir="${gen}" destdir="${build}" classpathref="libs.classpath" />
+ <javac compiler="modern" includeantruntime="false" srcdir="${src}" destdir="${build}" classpathref="build.classpath" />
+ </target>
+
+ <target name="test" depends="tutorial" />
+
+ <target name="tutorial" description="Run the tutorial" depends="compile">
+ <jar jarfile="tutorial.jar" basedir="${build}"/>
+ <parallel>
+ <java classname="JavaServer" fork="true" timeout="10000"
+ classpathref="tutorial.classpath" failonerror="false" output="${build}/log/tutorial.log">
+ </java>
+ <sequential>
+ <sleep seconds="2"/>
+ <echo>tutorial client simple:</echo>
+ <java classname="JavaClient"
+ classpathref="tutorial.classpath" failonerror="true">
+ <arg line="simple"/>
+ </java>
+ <echo>tutorial client secure:</echo>
+ <java classname="JavaClient"
+ classpathref="tutorial.classpath" failonerror="true">
+ <arg line="secure"/>
+ </java>
+ </sequential>
+ </parallel>
+ </target>
+
+ <target name="generate">
+ <!-- Generate the thrift gen-java source -->
+ <exec executable="../../compiler/cpp/thrift" failonerror="true">
+ <arg line="--gen java -r ../tutorial.thrift"/>
+ </exec>
+ </target>
+
+ <target name="tutorialclient" description="Run a tutorial client" depends="compile">
+ <echo>tutorial client simple:</echo>
+ <java classname="JavaClient"
+ classpathref="tutorial.classpath" failonerror="true">
+ <arg line="simple"/>
+ </java>
+ <echo>tutorial client secure:</echo>
+ <java classname="JavaClient"
+ classpathref="tutorial.classpath" failonerror="true">
+ <arg line="secure"/>
+ </java>
+ </target>
+
+ <target name="tutorialserver" description="Run a tutorial server" depends="compile">
+ <java classname="JavaServer" fork="true"
+ classpathref="tutorial.classpath" failonerror="false" output="${build}/log/tutorial.log">
+ </java>
+ </target>
+
+ <target name="clean">
+ <delete dir="${build}" />
+ <delete dir="${gen}"/>
+ <delete file="tutorial.jar" />
+ </target>
+
+</project>
diff --git a/src/jaegertracing/thrift/tutorial/java/src/CalculatorHandler.java b/src/jaegertracing/thrift/tutorial/java/src/CalculatorHandler.java
new file mode 100644
index 000000000..92944b07f
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/java/src/CalculatorHandler.java
@@ -0,0 +1,92 @@
+/*
+ * 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.
+ */
+
+import org.apache.thrift.TException;
+
+// Generated code
+import tutorial.*;
+import shared.*;
+
+import java.util.HashMap;
+
+public class CalculatorHandler implements Calculator.Iface {
+
+ private HashMap<Integer,SharedStruct> log;
+
+ public CalculatorHandler() {
+ log = new HashMap<Integer, SharedStruct>();
+ }
+
+ public void ping() {
+ System.out.println("ping()");
+ }
+
+ public int add(int n1, int n2) {
+ System.out.println("add(" + n1 + "," + n2 + ")");
+ return n1 + n2;
+ }
+
+ public int calculate(int logid, Work work) throws InvalidOperation {
+ System.out.println("calculate(" + logid + ", {" + work.op + "," + work.num1 + "," + work.num2 + "})");
+ int val = 0;
+ switch (work.op) {
+ case ADD:
+ val = work.num1 + work.num2;
+ break;
+ case SUBTRACT:
+ val = work.num1 - work.num2;
+ break;
+ case MULTIPLY:
+ val = work.num1 * work.num2;
+ break;
+ case DIVIDE:
+ if (work.num2 == 0) {
+ InvalidOperation io = new InvalidOperation();
+ io.whatOp = work.op.getValue();
+ io.why = "Cannot divide by 0";
+ throw io;
+ }
+ val = work.num1 / work.num2;
+ break;
+ default:
+ InvalidOperation io = new InvalidOperation();
+ io.whatOp = work.op.getValue();
+ io.why = "Unknown operation";
+ throw io;
+ }
+
+ SharedStruct entry = new SharedStruct();
+ entry.key = logid;
+ entry.value = Integer.toString(val);
+ log.put(logid, entry);
+
+ return val;
+ }
+
+ public SharedStruct getStruct(int key) {
+ System.out.println("getStruct(" + key + ")");
+ return log.get(key);
+ }
+
+ public void zip() {
+ System.out.println("zip()");
+ }
+
+}
+
diff --git a/src/jaegertracing/thrift/tutorial/java/src/JavaClient.java b/src/jaegertracing/thrift/tutorial/java/src/JavaClient.java
new file mode 100644
index 000000000..2e35d412a
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/java/src/JavaClient.java
@@ -0,0 +1,106 @@
+/*
+ * 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.
+ */
+
+// Generated code
+import tutorial.*;
+import shared.*;
+
+import org.apache.thrift.TException;
+import org.apache.thrift.transport.TSSLTransportFactory;
+import org.apache.thrift.transport.TTransport;
+import org.apache.thrift.transport.TSocket;
+import org.apache.thrift.transport.TSSLTransportFactory.TSSLTransportParameters;
+import org.apache.thrift.protocol.TBinaryProtocol;
+import org.apache.thrift.protocol.TProtocol;
+
+public class JavaClient {
+ public static void main(String [] args) {
+
+ if (args.length != 1) {
+ System.out.println("Please enter 'simple' or 'secure'");
+ System.exit(0);
+ }
+
+ try {
+ TTransport transport;
+ if (args[0].contains("simple")) {
+ transport = new TSocket("localhost", 9090);
+ transport.open();
+ }
+ else {
+ /*
+ * Similar to the server, you can use the parameters to setup client parameters or
+ * use the default settings. On the client side, you will need a TrustStore which
+ * contains the trusted certificate along with the public key.
+ * For this example it's a self-signed cert.
+ */
+ TSSLTransportParameters params = new TSSLTransportParameters();
+ params.setTrustStore("../../lib/java/test/.truststore", "thrift", "SunX509", "JKS");
+ /*
+ * Get a client transport instead of a server transport. The connection is opened on
+ * invocation of the factory method, no need to specifically call open()
+ */
+ transport = TSSLTransportFactory.getClientSocket("localhost", 9091, 0, params);
+ }
+
+ TProtocol protocol = new TBinaryProtocol(transport);
+ Calculator.Client client = new Calculator.Client(protocol);
+
+ perform(client);
+
+ transport.close();
+ } catch (TException x) {
+ x.printStackTrace();
+ }
+ }
+
+ private static void perform(Calculator.Client client) throws TException
+ {
+ client.ping();
+ System.out.println("ping()");
+
+ int sum = client.add(1,1);
+ System.out.println("1+1=" + sum);
+
+ Work work = new Work();
+
+ work.op = Operation.DIVIDE;
+ work.num1 = 1;
+ work.num2 = 0;
+ try {
+ int quotient = client.calculate(1, work);
+ System.out.println("Whoa we can divide by 0");
+ } catch (InvalidOperation io) {
+ System.out.println("Invalid operation: " + io.why);
+ }
+
+ work.op = Operation.SUBTRACT;
+ work.num1 = 15;
+ work.num2 = 10;
+ try {
+ int diff = client.calculate(1, work);
+ System.out.println("15-10=" + diff);
+ } catch (InvalidOperation io) {
+ System.out.println("Invalid operation: " + io.why);
+ }
+
+ SharedStruct log = client.getStruct(1);
+ System.out.println("Check log: " + log.value);
+ }
+}
diff --git a/src/jaegertracing/thrift/tutorial/java/src/JavaServer.java b/src/jaegertracing/thrift/tutorial/java/src/JavaServer.java
new file mode 100644
index 000000000..788473a8d
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/java/src/JavaServer.java
@@ -0,0 +1,110 @@
+/*
+ * 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.
+ */
+
+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.TSSLTransportFactory;
+import org.apache.thrift.transport.TServerSocket;
+import org.apache.thrift.transport.TServerTransport;
+import org.apache.thrift.transport.TSSLTransportFactory.TSSLTransportParameters;
+
+// Generated code
+import tutorial.*;
+import shared.*;
+
+import java.util.HashMap;
+
+public class JavaServer {
+
+ public static CalculatorHandler handler;
+
+ public static Calculator.Processor processor;
+
+ public static void main(String [] args) {
+ try {
+ handler = new CalculatorHandler();
+ processor = new Calculator.Processor(handler);
+
+ Runnable simple = new Runnable() {
+ public void run() {
+ simple(processor);
+ }
+ };
+ Runnable secure = new Runnable() {
+ public void run() {
+ secure(processor);
+ }
+ };
+
+ new Thread(simple).start();
+ new Thread(secure).start();
+ } catch (Exception x) {
+ x.printStackTrace();
+ }
+ }
+
+ public static void simple(Calculator.Processor processor) {
+ try {
+ TServerTransport serverTransport = new TServerSocket(9090);
+ TServer server = new TSimpleServer(new Args(serverTransport).processor(processor));
+
+ // Use this for a multithreaded server
+ // TServer server = new TThreadPoolServer(new TThreadPoolServer.Args(serverTransport).processor(processor));
+
+ System.out.println("Starting the simple server...");
+ server.serve();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public static void secure(Calculator.Processor processor) {
+ try {
+ /*
+ * Use TSSLTransportParameters to setup the required SSL parameters. In this example
+ * we are setting the keystore and the keystore password. Other things like algorithms,
+ * cipher suites, client auth etc can be set.
+ */
+ TSSLTransportParameters params = new TSSLTransportParameters();
+ // The Keystore contains the private key
+ params.setKeyStore("../../lib/java/test/.keystore", "thrift", null, null);
+
+ /*
+ * Use any of the TSSLTransportFactory to get a server transport with the appropriate
+ * SSL configuration. You can use the default settings if properties are set in the command line.
+ * Ex: -Djavax.net.ssl.keyStore=.keystore and -Djavax.net.ssl.keyStorePassword=thrift
+ *
+ * Note: You need not explicitly call open(). The underlying server socket is bound on return
+ * from the factory class.
+ */
+ TServerTransport serverTransport = TSSLTransportFactory.getServerSocket(9091, 0, null, params);
+ TServer server = new TSimpleServer(new Args(serverTransport).processor(processor));
+
+ // Use this for a multi threaded server
+ // TServer server = new TThreadPoolServer(new TThreadPoolServer.Args(serverTransport).processor(processor));
+
+ System.out.println("Starting the secure server...");
+ server.serve();
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/src/jaegertracing/thrift/tutorial/js/Makefile.am b/src/jaegertracing/thrift/tutorial/js/Makefile.am
new file mode 100755
index 000000000..3fe088842
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/js/Makefile.am
@@ -0,0 +1,39 @@
+#
+# 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.
+#
+
+export CLASSPATH
+
+# Make sure this doesn't fail if ant is not configured.
+clean-local:
+ ANT=$(ANT) ; if test -z "$$ANT" ; then ANT=: ; fi ; \
+ $$ANT $(ANT_FLAGS) clean
+
+all-local:
+ $(ANT) $(ANT_FLAGS) compile
+
+check-local: all
+ $(ANT) $(ANT_FLAGS) test
+
+tutorialserver: all
+ $(ANT) $(ANT_FLAGS) tutorialserver
+
+EXTRA_DIST = \
+ build.xml \
+ src \
+ tutorial.html
diff --git a/src/jaegertracing/thrift/tutorial/js/build.xml b/src/jaegertracing/thrift/tutorial/js/build.xml
new file mode 100644
index 000000000..03a6e7c64
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/js/build.xml
@@ -0,0 +1,92 @@
+<!--
+ 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.
+-->
+<project name="tutorial" default="test" basedir=".">
+
+ <description>Thrift JavaScript Tutorial</description>
+
+ <property name="src" location="src" />
+ <property name="javasrc" location="../java/src" />
+ <property name="gen" location="../java/gen-java" />
+ <property name="build" location="build" />
+
+ <!-- the root directory, where you unpack thrift distibution (e.g. thrift-0.x.x.tar.gz) -->
+ <property name="thrift.dir" location="../../" />
+ <!-- JavaScript tutorial depends on the java tutorial thrift handler and server infrastructure -->
+ <property name="thrift.java.dir" location="${thrift.dir}/lib/java" />
+
+ <path id="libs.classpath">
+ <fileset dir="${thrift.java.dir}/build/libs">
+ <include name="libthrift*.jar" />
+ <exclude name="libthrift*test.jar" />
+ <exclude name="libthrift*javadoc.jar" />
+ <exclude name="libthrift*sources.jar" />
+ </fileset>
+ <fileset dir="${thrift.java.dir}/build/deps">
+ <include name="*.jar" />
+ </fileset>
+ </path>
+ <path id="build.classpath">
+ <path refid="libs.classpath" />
+ <pathelement path="${gen}" />
+ <pathelement path="${build}" />
+ </path>
+
+ <target name="init">
+ <tstamp />
+ <mkdir dir="${build}"/>
+ </target>
+
+ <target name="compile" depends="init">
+ <javac compiler="modern" includeantruntime="false" srcdir="${gen}" destdir="${build}" classpathref="libs.classpath" />
+ <javac compiler="modern" includeantruntime="false" srcdir="${javasrc}" destdir="${build}" classpathref="build.classpath">
+ <exclude name="JavaClient.java"/>
+ <exclude name="JavaServer.java"/>
+ <include name="CalculatorHandler.java"/>
+ </javac>
+ <javac compiler="modern" includeantruntime="false" srcdir="${src}" destdir="${build}" classpathref="build.classpath">
+ <compilerarg value="-Xlint:all"/>
+ </javac>
+ </target>
+
+ <target name="test" depends="tutorial" />
+
+ <target name="tutorial" depends="compile">
+ <jar jarfile="tutorial-js.jar" basedir="${build}"/>
+ </target>
+
+ <target name="tutorialserver" description="run the test server" depends="tutorial, generate">
+ <java classname="Httpd" fork="true"
+ classpathref="build.classpath" failonerror="true">
+ <arg value="../../" />
+ </java>
+ </target>
+
+ <target name="generate">
+ <exec executable="../../compiler/cpp/thrift" failonerror="true">
+ <arg line="--gen js -r ../tutorial.thrift"/>
+ </exec>
+ </target>
+
+ <target name="clean">
+ <delete dir="${build}" />
+ <delete dir="gen-js"/>
+ <delete file="tutorial-js.jar" />
+ </target>
+
+</project>
diff --git a/src/jaegertracing/thrift/tutorial/js/src/Httpd.java b/src/jaegertracing/thrift/tutorial/js/src/Httpd.java
new file mode 100644
index 000000000..4985471a7
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/js/src/Httpd.java
@@ -0,0 +1,299 @@
+/*
+ * ====================================================================
+ * 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 software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation. For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InterruptedIOException;
+import java.io.OutputStream;
+import java.io.OutputStreamWriter;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.URLDecoder;
+import java.util.Locale;
+
+import org.apache.http.ConnectionClosedException;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpEntityEnclosingRequest;
+import org.apache.http.HttpException;
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpServerConnection;
+import org.apache.http.HttpStatus;
+import org.apache.http.MethodNotSupportedException;
+import org.apache.http.entity.ContentProducer;
+import org.apache.http.entity.EntityTemplate;
+import org.apache.http.entity.FileEntity;
+import org.apache.http.impl.DefaultHttpResponseFactory;
+import org.apache.http.impl.DefaultHttpServerConnection;
+import org.apache.http.impl.NoConnectionReuseStrategy;
+import org.apache.http.params.BasicHttpParams;
+import org.apache.http.params.CoreConnectionPNames;
+import org.apache.http.params.CoreProtocolPNames;
+import org.apache.http.params.HttpParams;
+import org.apache.http.protocol.BasicHttpContext;
+import org.apache.http.protocol.BasicHttpProcessor;
+import org.apache.http.protocol.HttpContext;
+import org.apache.http.protocol.HttpProcessor;
+import org.apache.http.protocol.HttpRequestHandler;
+import org.apache.http.protocol.HttpRequestHandlerRegistry;
+import org.apache.http.protocol.HttpService;
+import org.apache.http.util.EntityUtils;
+import org.apache.thrift.TProcessor;
+import org.apache.thrift.protocol.TJSONProtocol;
+import org.apache.thrift.protocol.TProtocol;
+import org.apache.thrift.transport.TMemoryBuffer;
+
+// Generated code
+import tutorial.*;
+import shared.*;
+
+import java.util.HashMap;
+
+/**
+ * Basic, yet fully functional and spec compliant, HTTP/1.1 file server.
+ * <p>
+ * Please note the purpose of this application is demonstrate the usage of
+ * HttpCore APIs. It is NOT intended to demonstrate the most efficient way of
+ * building an HTTP file server.
+ *
+ *
+ */
+public class Httpd {
+
+ public static void main(String[] args) throws Exception {
+ if (args.length < 1) {
+ System.err.println("Please specify document root directory");
+ System.exit(1);
+ }
+ Thread t = new RequestListenerThread(8088, args[0]);
+ t.setDaemon(false);
+ t.start();
+ }
+
+ static class HttpFileHandler implements HttpRequestHandler {
+
+ private final String docRoot;
+
+ public HttpFileHandler(final String docRoot) {
+ super();
+ this.docRoot = docRoot;
+ }
+
+ public void handle(final HttpRequest request, final HttpResponse response, final HttpContext context) throws HttpException, IOException {
+
+ String method = request.getRequestLine().getMethod().toUpperCase(Locale.ENGLISH);
+ if (!method.equals("GET") && !method.equals("HEAD") && !method.equals("POST")) {
+ throw new MethodNotSupportedException(method + " method not supported");
+ }
+ String target = request.getRequestLine().getUri();
+
+ if (request instanceof HttpEntityEnclosingRequest && target.equals("/thrift/service/tutorial/")) {
+ HttpEntity entity = ((HttpEntityEnclosingRequest) request).getEntity();
+ byte[] entityContent = EntityUtils.toByteArray(entity);
+ System.out.println("Incoming content: " + new String(entityContent));
+
+ final String output = this.thriftRequest(entityContent);
+
+ System.out.println("Outgoing content: "+output);
+
+ EntityTemplate body = new EntityTemplate(new ContentProducer() {
+
+ public void writeTo(final OutputStream outstream) throws IOException {
+ OutputStreamWriter writer = new OutputStreamWriter(outstream, "UTF-8");
+ writer.write(output);
+ writer.flush();
+ }
+
+ });
+ body.setContentType("text/html; charset=UTF-8");
+ response.setEntity(body);
+ } else {
+ final File file = new File(this.docRoot, URLDecoder.decode(target, "UTF-8"));
+ if (!file.exists()) {
+
+ response.setStatusCode(HttpStatus.SC_NOT_FOUND);
+ EntityTemplate body = new EntityTemplate(new ContentProducer() {
+
+ public void writeTo(final OutputStream outstream) throws IOException {
+ OutputStreamWriter writer = new OutputStreamWriter(outstream, "UTF-8");
+ writer.write("<html><body><h1>");
+ writer.write("File ");
+ writer.write(file.getPath());
+ writer.write(" not found");
+ writer.write("</h1></body></html>");
+ writer.flush();
+ }
+
+ });
+ body.setContentType("text/html; charset=UTF-8");
+ response.setEntity(body);
+ System.out.println("File " + file.getPath() + " not found");
+
+ } else if (!file.canRead() || file.isDirectory()) {
+
+ response.setStatusCode(HttpStatus.SC_FORBIDDEN);
+ EntityTemplate body = new EntityTemplate(new ContentProducer() {
+
+ public void writeTo(final OutputStream outstream) throws IOException {
+ OutputStreamWriter writer = new OutputStreamWriter(outstream, "UTF-8");
+ writer.write("<html><body><h1>");
+ writer.write("Access denied");
+ writer.write("</h1></body></html>");
+ writer.flush();
+ }
+
+ });
+ body.setContentType("text/html; charset=UTF-8");
+ response.setEntity(body);
+ System.out.println("Cannot read file " + file.getPath());
+
+ } else {
+
+ response.setStatusCode(HttpStatus.SC_OK);
+ FileEntity body = new FileEntity(file, "text/html");
+ response.setEntity(body);
+ System.out.println("Serving file " + file.getPath());
+
+ }
+ }
+ }
+
+ private String thriftRequest(byte[] input){
+ try{
+
+ //Input
+ TMemoryBuffer inbuffer = new TMemoryBuffer(input.length);
+ inbuffer.write(input);
+ TProtocol inprotocol = new TJSONProtocol(inbuffer);
+
+ //Output
+ TMemoryBuffer outbuffer = new TMemoryBuffer(100);
+ TProtocol outprotocol = new TJSONProtocol(outbuffer);
+
+ TProcessor processor = new Calculator.Processor(new CalculatorHandler());
+ processor.process(inprotocol, outprotocol);
+
+ byte[] output = new byte[outbuffer.length()];
+ outbuffer.readAll(output, 0, output.length);
+
+ return new String(output,"UTF-8");
+ }catch(Throwable t){
+ return "Error:"+t.getMessage();
+ }
+
+
+ }
+
+ }
+
+ static class RequestListenerThread extends Thread {
+
+ private final ServerSocket serversocket;
+ private final HttpParams params;
+ private final HttpService httpService;
+
+ public RequestListenerThread(int port, final String docroot) throws IOException {
+ this.serversocket = new ServerSocket(port);
+ this.params = new BasicHttpParams();
+ this.params.setIntParameter(CoreConnectionPNames.SO_TIMEOUT, 1000).setIntParameter(CoreConnectionPNames.SOCKET_BUFFER_SIZE, 8 * 1024)
+ .setBooleanParameter(CoreConnectionPNames.STALE_CONNECTION_CHECK, false).setBooleanParameter(CoreConnectionPNames.TCP_NODELAY, true)
+ .setParameter(CoreProtocolPNames.ORIGIN_SERVER, "HttpComponents/1.1");
+
+ // Set up the HTTP protocol processor
+ HttpProcessor httpproc = new BasicHttpProcessor();
+
+ // Set up request handlers
+ HttpRequestHandlerRegistry reqistry = new HttpRequestHandlerRegistry();
+ reqistry.register("*", new HttpFileHandler(docroot));
+
+ // Set up the HTTP service
+ this.httpService = new HttpService(httpproc, new NoConnectionReuseStrategy(), new DefaultHttpResponseFactory());
+ this.httpService.setParams(this.params);
+ this.httpService.setHandlerResolver(reqistry);
+ }
+
+ public void run() {
+ System.out.println("Listening on port " + this.serversocket.getLocalPort());
+ System.out.println("Point your browser to http://localhost:8088/tutorial/js/tutorial.html");
+
+ while (!Thread.interrupted()) {
+ try {
+ // Set up HTTP connection
+ Socket socket = this.serversocket.accept();
+ DefaultHttpServerConnection conn = new DefaultHttpServerConnection();
+ System.out.println("Incoming connection from " + socket.getInetAddress());
+ conn.bind(socket, this.params);
+
+ // Start worker thread
+ Thread t = new WorkerThread(this.httpService, conn);
+ t.setDaemon(true);
+ t.start();
+ } catch (InterruptedIOException ex) {
+ break;
+ } catch (IOException e) {
+ System.err.println("I/O error initialising connection thread: " + e.getMessage());
+ break;
+ }
+ }
+ }
+ }
+
+ static class WorkerThread extends Thread {
+
+ private final HttpService httpservice;
+ private final HttpServerConnection conn;
+
+ public WorkerThread(final HttpService httpservice, final HttpServerConnection conn) {
+ super();
+ this.httpservice = httpservice;
+ this.conn = conn;
+ }
+
+ public void run() {
+ System.out.println("New connection thread");
+ HttpContext context = new BasicHttpContext(null);
+ try {
+ while (!Thread.interrupted() && this.conn.isOpen()) {
+ this.httpservice.handleRequest(this.conn, context);
+ }
+ } catch (ConnectionClosedException ex) {
+ System.err.println("Client closed connection");
+ } catch (IOException ex) {
+ System.err.println("I/O error: " + ex.getMessage());
+ } catch (HttpException ex) {
+ System.err.println("Unrecoverable HTTP protocol violation: " + ex.getMessage());
+ } finally {
+ try {
+ this.conn.shutdown();
+ } catch (IOException ignore) {
+ }
+ }
+ }
+
+ }
+
+}
diff --git a/src/jaegertracing/thrift/tutorial/js/tutorial.html b/src/jaegertracing/thrift/tutorial/js/tutorial.html
new file mode 100755
index 000000000..d020bed37
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/js/tutorial.html
@@ -0,0 +1,109 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<!--
+ 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.
+-->
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+ <title>Thrift Javascript Bindings - Tutorial Example</title>
+
+ <script src="../../lib/js/src/thrift.js" type="text/javascript"></script>
+ <script src="gen-js/tutorial_types.js" type="text/javascript"></script>
+ <script src="gen-js/shared_types.js" type="text/javascript"></script>
+ <script src="gen-js/SharedService.js" type="text/javascript"></script>
+ <script src="gen-js/Calculator.js" type="text/javascript"></script>
+
+ <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
+
+
+ <script type="text/javascript" charset="utf-8">
+ //<![CDATA[
+ $(document).ready(function(){
+ // remove pseudo child required for valid xhtml strict
+ $("#op").children().remove();
+ // add operations to it's dropdown menu
+ $.each(Operation, function(key, value) {
+ $('#op').append($("<option></option>").attr("value",value).text(key));
+ });
+
+ $('table.calculator').attr('width', 500);
+ });
+
+ function calc() {
+ var transport = new Thrift.Transport("/thrift/service/tutorial/");
+ var protocol = new Thrift.Protocol(transport);
+ var client = new CalculatorClient(protocol);
+
+ var work = new Work();
+ work.num1 = $("#num1").val();
+ work.num2 = $("#num2").val();
+ work.op = $("#op").val();
+
+ try {
+ result = client.calculate(1, work);
+ $('#result').val(result);
+ $('#result').css('color', 'black');
+ } catch(ouch){
+ $('#result').val(ouch.why);
+ $('#result').css('color', 'red');
+ }
+ }
+
+ function auto_calc() {
+ if ($('#autoupdate:checked').val() !== undefined) {
+ calc();
+ }
+ }
+ //]]>
+ </script>
+
+</head>
+<body>
+ <h2>Thrift Javascript Bindings</h2>
+ <form action="">
+ <table class="calculator">
+ <tr>
+ <td>num1</td>
+ <td><input type="text" id="num1" value="20" onkeyup="javascript:auto_calc();"/></td>
+ </tr>
+ <tr>
+ <td>Operation</td>
+ <td><select id="op" size="1" onchange="javascript:auto_calc();"><option></option></select></td>
+ </tr>
+ <tr>
+ <td>num2</td>
+ <td><input type="text" id="num2" value="5" onkeyup="javascript:auto_calc();"/></td></tr>
+ <tr>
+ <td>result</td>
+ <td><input type="text" id="result" value=""/></td></tr>
+ <tr>
+ <td><input type="checkbox" id="autoupdate" checked="checked"/>autoupdate</td>
+ <td><input type="button" id="calculate" value="calculate" onclick="javascript:calc();"/></td>
+ </tr>
+ </table>
+ </form>
+
+ <p>This Java Script example uses <a href="https://github.com/apache/thrift/blob/master/tutorial/tutorial.thrift">tutorial.thrift</a> and a Thrift server using JSON protocol and HTTP transport.
+ </p>
+ <p>
+ <a href="http://validator.w3.org/check/referer"><img
+ src="http://www.w3.org/Icons/valid-xhtml10"
+ alt="Valid XHTML 1.0!" height="31" width="88" /></a>
+ </p>
+</body>
+</html>
diff --git a/src/jaegertracing/thrift/tutorial/netcore/.gitignore b/src/jaegertracing/thrift/tutorial/netcore/.gitignore
new file mode 100644
index 000000000..9938bb237
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/netcore/.gitignore
@@ -0,0 +1 @@
+!**/*.pfx \ No newline at end of file
diff --git a/src/jaegertracing/thrift/tutorial/netcore/Client/Client.csproj b/src/jaegertracing/thrift/tutorial/netcore/Client/Client.csproj
new file mode 100644
index 000000000..911272d3f
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/netcore/Client/Client.csproj
@@ -0,0 +1,19 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+ <PropertyGroup>
+ <TargetFramework>netcoreapp2.0</TargetFramework>
+ <AssemblyName>Client</AssemblyName>
+ <PackageId>Client</PackageId>
+ <OutputType>Exe</OutputType>
+ <GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
+ <GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
+ <GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
+ <GenerateAssemblyCopyrightAttribute>false</GenerateAssemblyCopyrightAttribute>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\Interfaces\Interfaces.csproj" />
+ <ProjectReference Include="..\..\..\lib\netcore\Thrift\Thrift.csproj" />
+ </ItemGroup>
+
+</Project>
diff --git a/src/jaegertracing/thrift/tutorial/netcore/Client/Program.cs b/src/jaegertracing/thrift/tutorial/netcore/Client/Program.cs
new file mode 100644
index 000000000..ce5d8c7e4
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/netcore/Client/Program.cs
@@ -0,0 +1,355 @@
+// 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 System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Net;
+using System.Net.Security;
+using System.Security.Cryptography.X509Certificates;
+using System.Threading;
+using System.Threading.Tasks;
+using Microsoft.Extensions.Logging;
+using Thrift;
+using Thrift.Protocols;
+using Thrift.Transports;
+using Thrift.Transports.Client;
+using tutorial;
+using shared;
+
+namespace Client
+{
+ public class Program
+ {
+ private static readonly ILogger Logger = new LoggerFactory().AddConsole().AddDebug().CreateLogger(nameof(Client));
+
+ private static void DisplayHelp()
+ {
+ Logger.LogInformation(@"
+Usage:
+ Client.exe -help
+ will diplay help information
+
+ Client.exe -tr:<transport> -pr:<protocol> -mc:<numClients>
+ will run client with specified arguments (tcp transport and binary protocol by default) and with 1 client
+
+Options:
+ -tr (transport):
+ tcp - (default) tcp transport will be used (host - ""localhost"", port - 9090)
+ tcpbuffered - buffered transport over tcp will be used (host - ""localhost"", port - 9090)
+ namedpipe - namedpipe transport will be used (pipe address - "".test"")
+ http - http transport will be used (address - ""http://localhost:9090"")
+ tcptls - tcp tls transport will be used (host - ""localhost"", port - 9090)
+ framed - tcp framed transport will be used (host - ""localhost"", port - 9090)
+
+ -pr (protocol):
+ binary - (default) binary protocol will be used
+ compact - compact protocol will be used
+ json - json protocol will be used
+ multiplexed - multiplexed protocol will be used
+
+ -mc (multiple clients):
+ <numClients> - number of multiple clients to connect to server (max 100, default 1)
+
+Sample:
+ Client.exe -tr:tcp -p:binary
+");
+ }
+
+ public static void Main(string[] args)
+ {
+ args = args ?? new string[0];
+
+ if (args.Any(x => x.StartsWith("-help", StringComparison.OrdinalIgnoreCase)))
+ {
+ DisplayHelp();
+ return;
+ }
+
+ Logger.LogInformation("Starting client...");
+
+ using (var source = new CancellationTokenSource())
+ {
+ RunAsync(args, source.Token).GetAwaiter().GetResult();
+ }
+ }
+
+ private static async Task RunAsync(string[] args, CancellationToken cancellationToken)
+ {
+ var numClients = GetNumberOfClients(args);
+
+ Logger.LogInformation($"Selected # of clients: {numClients}");
+
+ var transports = new TClientTransport[numClients];
+ for (int i = 0; i < numClients; i++)
+ {
+ var t = GetTransport(args);
+ transports[i] = t;
+ }
+
+ Logger.LogInformation($"Selected client transport: {transports[0]}");
+
+ var protocols = new Tuple<Protocol, TProtocol>[numClients];
+ for (int i = 0; i < numClients; i++)
+ {
+ var p = GetProtocol(args, transports[i]);
+ protocols[i] = p;
+ }
+
+ Logger.LogInformation($"Selected client protocol: {protocols[0].Item1}");
+
+ var tasks = new Task[numClients];
+ for (int i = 0; i < numClients; i++)
+ {
+ var task = RunClientAsync(protocols[i], cancellationToken);
+ tasks[i] = task;
+ }
+
+ Task.WaitAll(tasks);
+
+ await Task.CompletedTask;
+ }
+
+ private static TClientTransport GetTransport(string[] args)
+ {
+ var transport = args.FirstOrDefault(x => x.StartsWith("-tr"))?.Split(':')?[1];
+
+ Transport selectedTransport;
+ if (Enum.TryParse(transport, true, out selectedTransport))
+ {
+ switch (selectedTransport)
+ {
+ case Transport.Tcp:
+ return new TSocketClientTransport(IPAddress.Loopback, 9090);
+ case Transport.NamedPipe:
+ return new TNamedPipeClientTransport(".test");
+ case Transport.Http:
+ return new THttpClientTransport(new Uri("http://localhost:9090"), null);
+ case Transport.TcpBuffered:
+ return new TBufferedClientTransport(new TSocketClientTransport(IPAddress.Loopback, 9090));
+ case Transport.TcpTls:
+ return new TTlsSocketClientTransport(IPAddress.Loopback, 9090, GetCertificate(), CertValidator, LocalCertificateSelectionCallback);
+ case Transport.Framed:
+ return new TFramedClientTransport(new TSocketClientTransport(IPAddress.Loopback, 9090));
+ }
+ }
+
+ return new TSocketClientTransport(IPAddress.Loopback, 9090);
+ }
+
+ private static int GetNumberOfClients(string[] args)
+ {
+ var numClients = args.FirstOrDefault(x => x.StartsWith("-mc"))?.Split(':')?[1];
+
+ Logger.LogInformation($"Selected # of clients: {numClients}");
+
+ int c;
+ if( int.TryParse(numClients, out c) && (0 < c) && (c <= 100))
+ return c;
+ else
+ return 1;
+ }
+
+ private static X509Certificate2 GetCertificate()
+ {
+ // due to files location in net core better to take certs from top folder
+ var certFile = GetCertPath(Directory.GetParent(Directory.GetCurrentDirectory()));
+ return new X509Certificate2(certFile, "ThriftTest");
+ }
+
+ private static string GetCertPath(DirectoryInfo di, int maxCount = 6)
+ {
+ var topDir = di;
+ var certFile =
+ topDir.EnumerateFiles("ThriftTest.pfx", SearchOption.AllDirectories)
+ .FirstOrDefault();
+ if (certFile == null)
+ {
+ if (maxCount == 0)
+ throw new FileNotFoundException("Cannot find file in directories");
+ return GetCertPath(di.Parent, maxCount - 1);
+ }
+
+ return certFile.FullName;
+ }
+
+ private static X509Certificate LocalCertificateSelectionCallback(object sender,
+ string targetHost, X509CertificateCollection localCertificates,
+ X509Certificate remoteCertificate, string[] acceptableIssuers)
+ {
+ return GetCertificate();
+ }
+
+ private static bool CertValidator(object sender, X509Certificate certificate,
+ X509Chain chain, SslPolicyErrors sslPolicyErrors)
+ {
+ return true;
+ }
+
+ private static Tuple<Protocol, TProtocol> GetProtocol(string[] args, TClientTransport transport)
+ {
+ var protocol = args.FirstOrDefault(x => x.StartsWith("-pr"))?.Split(':')?[1];
+
+ Protocol selectedProtocol;
+ if (Enum.TryParse(protocol, true, out selectedProtocol))
+ {
+ switch (selectedProtocol)
+ {
+ case Protocol.Binary:
+ return new Tuple<Protocol, TProtocol>(selectedProtocol, new TBinaryProtocol(transport));
+ case Protocol.Compact:
+ return new Tuple<Protocol, TProtocol>(selectedProtocol, new TCompactProtocol(transport));
+ case Protocol.Json:
+ return new Tuple<Protocol, TProtocol>(selectedProtocol, new TJsonProtocol(transport));
+ case Protocol.Multiplexed:
+ // it returns BinaryProtocol to avoid making wrapped protocol as public in TProtocolDecorator (in RunClientAsync it will be wrapped into Multiplexed protocol)
+ return new Tuple<Protocol, TProtocol>(selectedProtocol, new TBinaryProtocol(transport));
+ }
+ }
+
+ return new Tuple<Protocol, TProtocol>(selectedProtocol, new TBinaryProtocol(transport));
+ }
+
+ private static async Task RunClientAsync(Tuple<Protocol, TProtocol> protocolTuple, CancellationToken cancellationToken)
+ {
+ try
+ {
+ var protocol = protocolTuple.Item2;
+ var protocolType = protocolTuple.Item1;
+
+ TBaseClient client = null;
+
+ try
+ {
+ if (protocolType != Protocol.Multiplexed)
+ {
+
+ client = new Calculator.Client(protocol);
+ await ExecuteCalculatorClientOperations(cancellationToken, (Calculator.Client)client);
+ }
+ else
+ {
+ // it uses binary protocol there to create Multiplexed protocols
+ var multiplex = new TMultiplexedProtocol(protocol, nameof(Calculator));
+ client = new Calculator.Client(multiplex);
+ await ExecuteCalculatorClientOperations(cancellationToken, (Calculator.Client)client);
+
+ multiplex = new TMultiplexedProtocol(protocol, nameof(SharedService));
+ client = new SharedService.Client(multiplex);
+ await ExecuteSharedServiceClientOperations(cancellationToken, (SharedService.Client)client);
+ }
+ }
+ catch (Exception ex)
+ {
+ Logger.LogError($"{client?.ClientId} " + ex);
+ }
+ finally
+ {
+ protocol.Transport.Close();
+ }
+ }
+ catch (TApplicationException x)
+ {
+ Logger.LogError(x.ToString());
+ }
+ }
+
+ private static async Task ExecuteCalculatorClientOperations(CancellationToken cancellationToken, Calculator.Client client)
+ {
+ await client.OpenTransportAsync(cancellationToken);
+
+ // Async version
+
+ Logger.LogInformation($"{client.ClientId} PingAsync()");
+ await client.pingAsync(cancellationToken);
+
+ Logger.LogInformation($"{client.ClientId} AddAsync(1,1)");
+ var sum = await client.addAsync(1, 1, cancellationToken);
+ Logger.LogInformation($"{client.ClientId} AddAsync(1,1)={sum}");
+
+ var work = new Work
+ {
+ Op = Operation.DIVIDE,
+ Num1 = 1,
+ Num2 = 0
+ };
+
+ try
+ {
+ Logger.LogInformation($"{client.ClientId} CalculateAsync(1)");
+ await client.calculateAsync(1, work, cancellationToken);
+ Logger.LogInformation($"{client.ClientId} Whoa we can divide by 0");
+ }
+ catch (InvalidOperation io)
+ {
+ Logger.LogInformation($"{client.ClientId} Invalid operation: " + io);
+ }
+
+ work.Op = Operation.SUBTRACT;
+ work.Num1 = 15;
+ work.Num2 = 10;
+
+ try
+ {
+ Logger.LogInformation($"{client.ClientId} CalculateAsync(1)");
+ var diff = await client.calculateAsync(1, work, cancellationToken);
+ Logger.LogInformation($"{client.ClientId} 15-10={diff}");
+ }
+ catch (InvalidOperation io)
+ {
+ Logger.LogInformation($"{client.ClientId} Invalid operation: " + io);
+ }
+
+ Logger.LogInformation($"{client.ClientId} GetStructAsync(1)");
+ var log = await client.getStructAsync(1, cancellationToken);
+ Logger.LogInformation($"{client.ClientId} Check log: {log.Value}");
+
+ Logger.LogInformation($"{client.ClientId} ZipAsync() with delay 100mc on server side");
+ await client.zipAsync(cancellationToken);
+ }
+ private static async Task ExecuteSharedServiceClientOperations(CancellationToken cancellationToken, SharedService.Client client)
+ {
+ await client.OpenTransportAsync(cancellationToken);
+
+ // Async version
+
+ Logger.LogInformation($"{client.ClientId} SharedService GetStructAsync(1)");
+ var log = await client.getStructAsync(1, cancellationToken);
+ Logger.LogInformation($"{client.ClientId} SharedService Value: {log.Value}");
+ }
+
+
+ private enum Transport
+ {
+ Tcp,
+ NamedPipe,
+ Http,
+ TcpBuffered,
+ Framed,
+ TcpTls
+ }
+
+ private enum Protocol
+ {
+ Binary,
+ Compact,
+ Json,
+ Multiplexed
+ }
+ }
+}
diff --git a/src/jaegertracing/thrift/tutorial/netcore/Client/Properties/AssemblyInfo.cs b/src/jaegertracing/thrift/tutorial/netcore/Client/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000..568382e66
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/netcore/Client/Properties/AssemblyInfo.cs
@@ -0,0 +1,40 @@
+// 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 System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("The Apache Software Foundation")]
+[assembly: AssemblyProduct("Thrift")]
+[assembly: AssemblyCopyright("The Apache Software Foundation")]
+[assembly: AssemblyTrademark("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+
+[assembly: Guid("de78a01b-f7c6-49d1-97da-669d2ed37641")] \ No newline at end of file
diff --git a/src/jaegertracing/thrift/tutorial/netcore/Client/Properties/launchSettings.json b/src/jaegertracing/thrift/tutorial/netcore/Client/Properties/launchSettings.json
new file mode 100644
index 000000000..6b7b60d78
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/netcore/Client/Properties/launchSettings.json
@@ -0,0 +1,8 @@
+{
+ "profiles": {
+ "Client": {
+ "commandName": "Project",
+ "commandLineArgs": "-p:multiplexed"
+ }
+ }
+} \ No newline at end of file
diff --git a/src/jaegertracing/thrift/tutorial/netcore/Client/ThriftTest.pfx b/src/jaegertracing/thrift/tutorial/netcore/Client/ThriftTest.pfx
new file mode 100644
index 000000000..f0ded2817
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/netcore/Client/ThriftTest.pfx
Binary files differ
diff --git a/src/jaegertracing/thrift/tutorial/netcore/Interfaces/.gitignore b/src/jaegertracing/thrift/tutorial/netcore/Interfaces/.gitignore
new file mode 100644
index 000000000..2e7446e33
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/netcore/Interfaces/.gitignore
@@ -0,0 +1,3 @@
+# ignore for autogenerated files
+/shared
+/tutorial
diff --git a/src/jaegertracing/thrift/tutorial/netcore/Interfaces/Interfaces.csproj b/src/jaegertracing/thrift/tutorial/netcore/Interfaces/Interfaces.csproj
new file mode 100644
index 000000000..4297a0654
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/netcore/Interfaces/Interfaces.csproj
@@ -0,0 +1,30 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+ <PropertyGroup>
+ <TargetFramework>netstandard2.0</TargetFramework>
+ <AssemblyName>Interfaces</AssemblyName>
+ <PackageId>Interfaces</PackageId>
+ <GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
+ <GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
+ <GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
+ <GenerateAssemblyCopyrightAttribute>false</GenerateAssemblyCopyrightAttribute>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="../../../lib/netcore/Thrift/Thrift.csproj" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <PackageReference Include="System.ServiceModel.Primitives" Version="[4.4,)" />
+ </ItemGroup>
+
+ <Target Name="PreBuild" BeforeTargets="_GenerateRestoreProjectSpec;Restore;Compile">
+ <Exec Condition="'$(OS)' == 'Windows_NT'" Command="where thrift" ConsoleToMSBuild="true">
+ <Output TaskParameter="ConsoleOutput" PropertyName="PathToThrift" />
+ </Exec>
+ <Exec Condition="Exists('$(PathToThrift)')" Command="$(PathToThrift) -out $(ProjectDir) -gen netcore:wcf,union,serial,hashcode -r ./../../tutorial.thrift" />
+ <Exec Condition="Exists('thrift')" Command="thrift -out $(ProjectDir) -gen netcore:wcf,union,serial,hashcode -r ./../../tutorial.thrift" />
+ <Exec Condition="Exists('./../../../compiler/cpp/thrift')" Command="./../../../compiler/cpp/thrift -out $(ProjectDir) -gen netcore:wcf,union,serial,hashcode -r ./../../tutorial.thrift" />
+ </Target>
+
+</Project>
diff --git a/src/jaegertracing/thrift/tutorial/netcore/Interfaces/Properties/AssemblyInfo.cs b/src/jaegertracing/thrift/tutorial/netcore/Interfaces/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000..9126b173e
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/netcore/Interfaces/Properties/AssemblyInfo.cs
@@ -0,0 +1,40 @@
+// 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 System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("The Apache Software Foundation")]
+[assembly: AssemblyProduct("Thrift")]
+[assembly: AssemblyCopyright("The Apache Software Foundation")]
+[assembly: AssemblyTrademark("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+
+[assembly: Guid("4d13163d-9067-4c9c-8af0-64e08451397d")] \ No newline at end of file
diff --git a/src/jaegertracing/thrift/tutorial/netcore/Makefile.am b/src/jaegertracing/thrift/tutorial/netcore/Makefile.am
new file mode 100644
index 000000000..bd19dfe6a
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/netcore/Makefile.am
@@ -0,0 +1,51 @@
+#
+# 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.
+#
+
+SUBDIRS = .
+
+all-local:
+ $(DOTNETCORE) build
+
+clean-local:
+ $(RM) Interfaces.dll
+ $(RM) -r Client/bin
+ $(RM) -r Client/obj
+ $(RM) -r Server/bin
+ $(RM) -r Server/obj
+ $(RM) -r Interfaces/bin
+ $(RM) -r Interfaces/obj
+
+dist-hook:
+ $(RM) $(distdir)/Interfaces.dll
+ $(RM) -r $(distdir)/Client/bin
+ $(RM) -r $(distdir)/Client/obj
+ $(RM) -r $(distdir)/Server/bin
+ $(RM) -r $(distdir)/Server/obj
+ $(RM) -r $(distdir)/Interfaces/bin
+ $(RM) -r $(distdir)/Interfaces/obj
+
+EXTRA_DIST = \
+ Client \
+ Interfaces \
+ README.md \
+ Server \
+ Tutorial.sln \
+ build.cmd \
+ build.sh
+
diff --git a/src/jaegertracing/thrift/tutorial/netcore/README.md b/src/jaegertracing/thrift/tutorial/netcore/README.md
new file mode 100644
index 000000000..626ef9212
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/netcore/README.md
@@ -0,0 +1,278 @@
+# Building of samples for different platforms
+
+# Reused components
+- NET Core Standard 2.0
+- NET Core App 2.0
+
+# How to build
+- Download and install the latest .NET Core SDK for your platform https://www.microsoft.com/net/core#windowsvs2015 (archive for SDK 1.0.0-preview2-003121 located by: https://github.com/dotnet/core/blob/master/release-notes/download-archive.md)
+- Ensure that you have thrift.exe which supports netcore lib and it added to PATH
+- Go to current folder
+- Run **build.sh** or **build.cmd** from the root of cloned repository
+- Check tests in **src/Tests** folder
+- Continue with /tutorials/netcore
+
+# How to run
+
+Notes: dotnet run supports passing arguments to app after -- symbols (https://docs.microsoft.com/en-us/dotnet/articles/core/tools/dotnet-run) - example: **dotnet run -- -h** will show help for app
+
+- build
+- go to folder (Client/Server)
+- run with specifying of correct parameters **dotnet run -tr:tcp -pr:multiplexed**, **dotnet run -help** (later, after migration to csproj and latest SDK will be possibility to use more usable form **dotnet run -- arguments**)
+
+#Notes
+- Possible adding additional platforms after stabilization of .NET Core (runtimes, platforms (Red Hat Linux, OpenSuse, etc.)
+
+#Known issues
+- In trace logging mode you can see some not important internal exceptions
+
+# Running of samples
+Please install Thrift C# .NET Core library or copy sources and build them to correcly build and run samples
+
+# NetCore Server
+
+Usage:
+
+ Server.exe -h
+ will diplay help information
+
+ Server.exe -tr:<transport> -pr:<protocol>
+ will run server with specified arguments (tcp transport and binary protocol by default)
+
+Options:
+
+ -tr (transport):
+ tcp - (default) tcp transport will be used (host - ""localhost"", port - 9090)
+ tcpbuffered - tcp buffered transport will be used (host - ""localhost"", port - 9090)
+ namedpipe - namedpipe transport will be used (pipe address - "".test"")
+ http - http transport will be used (http address - ""localhost:9090"")
+ tcptls - tcp transport with tls will be used (host - ""localhost"", port - 9090)
+ framed - tcp framed transport will be used (host - ""localhost"", port - 9090)
+
+ -pr (protocol):
+ binary - (default) binary protocol will be used
+ compact - compact protocol will be used
+ json - json protocol will be used
+
+Sample:
+
+ Server.exe -tr:tcp
+
+**Remarks**:
+
+ For TcpTls mode certificate's file ThriftTest.pfx should be in directory with binaries in case of command line usage (or at project level in case of debugging from IDE).
+ Password for certificate - "ThriftTest".
+
+
+
+# NetCore Client
+
+Usage:
+
+ Client.exe -h
+ will diplay help information
+
+ Client.exe -tr:<transport> -pr:<protocol> -mc:<numClients>
+ will run client with specified arguments (tcp transport and binary protocol by default)
+
+Options:
+
+ -tr (transport):
+ tcp - (default) tcp transport will be used (host - ""localhost"", port - 9090)
+ tcpbuffered - buffered transport over tcp will be used (host - ""localhost"", port - 9090)
+ namedpipe - namedpipe transport will be used (pipe address - "".test"")
+ http - http transport will be used (address - ""http://localhost:9090"")
+ tcptls - tcp tls transport will be used (host - ""localhost"", port - 9090)
+ framed - tcp framed transport will be used (host - ""localhost"", port - 9090)
+
+ -pr (protocol):
+ binary - (default) binary protocol will be used
+ compact - compact protocol will be used
+ json - json protocol will be used
+
+ -mc (multiple clients):
+ <numClients> - number of multiple clients to connect to server (max 100, default 1)
+
+Sample:
+
+ Client.exe -tr:tcp -pr:binary -mc:10
+
+Remarks:
+
+ For TcpTls mode certificate's file ThriftTest.pfx should be in directory
+ with binaries in case of command line usage (or at project level in case of debugging from IDE).
+ Password for certificate - "ThriftTest".
+
+# How to test communication between NetCore and Python
+
+* Generate code with the latest **thrift.exe** util
+* Ensure that **thrift.exe** util generated folder **gen-py** with generated code for Python
+* Create **client.py** and **server.py** from the code examples below and save them to the folder with previosly generated folder **gen-py**
+* Run netcore samples (client and server) and python samples (client and server)
+
+Remarks:
+
+Samples of client and server code below use correct methods (operations)
+and fields (properties) according to generated contracts from *.thrift files
+
+At Windows 10 add record **127.0.0.1 testserver** to **C:\Windows\System32\drivers\etc\hosts** file
+for correct work of python server
+
+
+**Python Client:**
+
+```python
+import sys
+import glob
+sys.path.append('gen-py')
+
+from tutorial import Calculator
+from tutorial.ttypes import InvalidOperation, Operation, Work
+
+from thrift import Thrift
+from thrift.transport import TSocket
+from thrift.transport import TTransport
+from thrift.protocol import TBinaryProtocol
+
+
+def main():
+ # Make socket
+ transport = TSocket.TSocket('127.0.0.1', 9090)
+
+ # Buffering is critical. Raw sockets are very slow
+ transport = TTransport.TBufferedTransport(transport)
+
+ # Wrap in a protocol
+ protocol = TBinaryProtocol.TBinaryProtocol(transport)
+
+ # Create a client to use the protocol encoder
+ client = Calculator.Client(protocol)
+
+ # Connect!
+ transport.open()
+
+ client.Ping()
+ print('ping()')
+
+ sum = client.Add(1, 1)
+ print(('1+1=%d' % (sum)))
+
+ work = Work()
+
+ work.Op = Operation.Divide
+ work.Num1 = 1
+ work.Num2 = 0
+
+ try:
+ quotient = client.Calculate(1, work)
+ print('Whoa? You know how to divide by zero?')
+ print('FYI the answer is %d' % quotient)
+ except InvalidOperation as e:
+ print(('InvalidOperation: %r' % e))
+
+ work.Op = Operation.Substract
+ work.Num1 = 15
+ work.Num2 = 10
+
+ diff = client.Calculate(1, work)
+ print(('15-10=%d' % (diff)))
+
+ log = client.GetStruct(1)
+ print(('Check log: %s' % (log.Value)))
+
+ client.Zip()
+ print('zip()')
+
+ # Close!
+ transport.close()
+
+if __name__ == '__main__':
+ try:
+ main()
+ except Thrift.TException as tx:
+ print('%s' % tx.message)
+```
+
+
+**Python Server:**
+
+
+```python
+import glob
+import sys
+sys.path.append('gen-py')
+
+from tutorial import Calculator
+from tutorial.ttypes import InvalidOperation, Operation
+
+from shared.ttypes import SharedStruct
+
+from thrift.transport import TSocket
+from thrift.transport import TTransport
+from thrift.protocol import TBinaryProtocol
+from thrift.server import TServer
+
+
+class CalculatorHandler:
+ def __init__(self):
+ self.log = {}
+
+ def Ping(self):
+ print('ping()')
+
+ def Add(self, n1, n2):
+ print('add(%d,%d)' % (n1, n2))
+ return n1 + n2
+
+ def Calculate(self, logid, work):
+ print('calculate(%d, %r)' % (logid, work))
+
+ if work.Op == Operation.Add:
+ val = work.Num1 + work.Num2
+ elif work.Op == Operation.Substract:
+ val = work.Num1 - work.Num2
+ elif work.Op == Operation.Multiply:
+ val = work.Num1 * work.Num2
+ elif work.Op == Operation.Divide:
+ if work.Num2 == 0:
+ x = InvalidOperation()
+ x.WhatOp = work.Op
+ x.Why = 'Cannot divide by 0'
+ raise x
+ val = work.Num1 / work.Num2
+ else:
+ x = InvalidOperation()
+ x.WhatOp = work.Op
+ x.Why = 'Invalid operation'
+ raise x
+
+ log = SharedStruct()
+ log.Key = logid
+ log.Value = '%d' % (val)
+ self.log[logid] = log
+
+ return val
+
+ def GetStruct(self, key):
+ print('getStruct(%d)' % (key))
+ return self.log[key]
+
+ def Zip(self):
+ print('zip()')
+
+if __name__ == '__main__':
+ handler = CalculatorHandler()
+ processor = Calculator.Processor(handler)
+ transport = TSocket.TServerSocket(host="testserver", port=9090)
+ tfactory = TTransport.TBufferedTransportFactory()
+ pfactory = TBinaryProtocol.TBinaryProtocolFactory()
+
+ server = TServer.TSimpleServer(processor, transport, tfactory, pfactory)
+ print('Starting the server...')
+ server.serve()
+ print('done.')
+
+ # You could do one of these for a multithreaded server
+ # server = TServer.TThreadedServer(processor, transport, tfactory, pfactory)
+ # server = TServer.TThreadPoolServer(processor, transport, tfactory, pfactory)
+```
diff --git a/src/jaegertracing/thrift/tutorial/netcore/Server/Program.cs b/src/jaegertracing/thrift/tutorial/netcore/Server/Program.cs
new file mode 100644
index 000000000..6a181bab7
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/netcore/Server/Program.cs
@@ -0,0 +1,428 @@
+// 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 System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Net.Security;
+using System.Security.Cryptography.X509Certificates;
+using System.Threading;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging;
+using Thrift;
+using Thrift.Protocols;
+using Thrift.Server;
+using Thrift.Transports;
+using Thrift.Transports.Server;
+using tutorial;
+using shared;
+
+namespace Server
+{
+ public class Program
+ {
+ private static readonly ILogger Logger = new LoggerFactory().AddConsole(LogLevel.Trace).AddDebug(LogLevel.Trace).CreateLogger(nameof(Server));
+
+ public static void Main(string[] args)
+ {
+ args = args ?? new string[0];
+
+ if (args.Any(x => x.StartsWith("-help", StringComparison.OrdinalIgnoreCase)))
+ {
+ DisplayHelp();
+ return;
+ }
+
+ using (var source = new CancellationTokenSource())
+ {
+ RunAsync(args, source.Token).GetAwaiter().GetResult();
+
+ Logger.LogInformation("Press any key to stop...");
+
+ Console.ReadLine();
+ source.Cancel();
+ }
+
+ Logger.LogInformation("Server stopped");
+ }
+
+ private static void DisplayHelp()
+ {
+ Logger.LogInformation(@"
+Usage:
+ Server.exe -help
+ will diplay help information
+
+ Server.exe -tr:<transport> -pr:<protocol>
+ will run server with specified arguments (tcp transport and binary protocol by default)
+
+Options:
+ -tr (transport):
+ tcp - (default) tcp transport will be used (host - ""localhost"", port - 9090)
+ tcpbuffered - tcp buffered transport will be used (host - ""localhost"", port - 9090)
+ namedpipe - namedpipe transport will be used (pipe address - "".test"")
+ http - http transport will be used (http address - ""localhost:9090"")
+ tcptls - tcp transport with tls will be used (host - ""localhost"", port - 9090)
+ framed - tcp framed transport will be used (host - ""localhost"", port - 9090)
+
+ -pr (protocol):
+ binary - (default) binary protocol will be used
+ compact - compact protocol will be used
+ json - json protocol will be used
+ multiplexed - multiplexed protocol will be used
+
+Sample:
+ Server.exe -tr:tcp
+");
+ }
+
+ private static async Task RunAsync(string[] args, CancellationToken cancellationToken)
+ {
+ var selectedTransport = GetTransport(args);
+ var selectedProtocol = GetProtocol(args);
+
+ if (selectedTransport == Transport.Http)
+ {
+ new HttpServerSample().Run(cancellationToken);
+ }
+ else
+ {
+ await RunSelectedConfigurationAsync(selectedTransport, selectedProtocol, cancellationToken);
+ }
+ }
+
+ private static Protocol GetProtocol(string[] args)
+ {
+ var transport = args.FirstOrDefault(x => x.StartsWith("-pr"))?.Split(':')?[1];
+
+ Enum.TryParse(transport, true, out Protocol selectedProtocol);
+
+ return selectedProtocol;
+ }
+
+ private static Transport GetTransport(string[] args)
+ {
+ var transport = args.FirstOrDefault(x => x.StartsWith("-tr"))?.Split(':')?[1];
+
+ Enum.TryParse(transport, true, out Transport selectedTransport);
+
+ return selectedTransport;
+ }
+
+ private static async Task RunSelectedConfigurationAsync(Transport transport, Protocol protocol, CancellationToken cancellationToken)
+ {
+ var fabric = new LoggerFactory().AddConsole(LogLevel.Trace).AddDebug(LogLevel.Trace);
+ var handler = new CalculatorAsyncHandler();
+ ITAsyncProcessor processor = null;
+
+ TServerTransport serverTransport = null;
+
+ switch (transport)
+ {
+ case Transport.Tcp:
+ serverTransport = new TServerSocketTransport(9090);
+ break;
+ case Transport.TcpBuffered:
+ serverTransport = new TServerSocketTransport(port: 9090, clientTimeout: 10000, useBufferedSockets: true);
+ break;
+ case Transport.NamedPipe:
+ serverTransport = new TNamedPipeServerTransport(".test");
+ break;
+ case Transport.TcpTls:
+ serverTransport = new TTlsServerSocketTransport(9090, false, GetCertificate(), ClientCertValidator, LocalCertificateSelectionCallback);
+ break;
+ case Transport.Framed:
+ serverTransport = new TServerFramedTransport(9090);
+ break;
+ }
+
+ ITProtocolFactory inputProtocolFactory;
+ ITProtocolFactory outputProtocolFactory;
+
+ switch (protocol)
+ {
+ case Protocol.Binary:
+ {
+ inputProtocolFactory = new TBinaryProtocol.Factory();
+ outputProtocolFactory = new TBinaryProtocol.Factory();
+ processor = new Calculator.AsyncProcessor(handler);
+ }
+ break;
+ case Protocol.Compact:
+ {
+ inputProtocolFactory = new TCompactProtocol.Factory();
+ outputProtocolFactory = new TCompactProtocol.Factory();
+ processor = new Calculator.AsyncProcessor(handler);
+ }
+ break;
+ case Protocol.Json:
+ {
+ inputProtocolFactory = new TJsonProtocol.Factory();
+ outputProtocolFactory = new TJsonProtocol.Factory();
+ processor = new Calculator.AsyncProcessor(handler);
+ }
+ break;
+ case Protocol.Multiplexed:
+ {
+ inputProtocolFactory = new TBinaryProtocol.Factory();
+ outputProtocolFactory = new TBinaryProtocol.Factory();
+
+ var calcHandler = new CalculatorAsyncHandler();
+ var calcProcessor = new Calculator.AsyncProcessor(calcHandler);
+
+ var sharedServiceHandler = new SharedServiceAsyncHandler();
+ var sharedServiceProcessor = new SharedService.AsyncProcessor(sharedServiceHandler);
+
+ var multiplexedProcessor = new TMultiplexedProcessor();
+ multiplexedProcessor.RegisterProcessor(nameof(Calculator), calcProcessor);
+ multiplexedProcessor.RegisterProcessor(nameof(SharedService), sharedServiceProcessor);
+
+ processor = multiplexedProcessor;
+ }
+ break;
+ default:
+ throw new ArgumentOutOfRangeException(nameof(protocol), protocol, null);
+ }
+
+ try
+ {
+ Logger.LogInformation(
+ $"Selected TAsyncServer with {serverTransport} transport, {processor} processor and {inputProtocolFactory} protocol factories");
+
+ var server = new AsyncBaseServer(processor, serverTransport, inputProtocolFactory, outputProtocolFactory, fabric);
+
+ Logger.LogInformation("Starting the server...");
+ await server.ServeAsync(cancellationToken);
+ }
+ catch (Exception x)
+ {
+ Logger.LogInformation(x.ToString());
+ }
+ }
+
+ private static X509Certificate2 GetCertificate()
+ {
+ // due to files location in net core better to take certs from top folder
+ var certFile = GetCertPath(Directory.GetParent(Directory.GetCurrentDirectory()));
+ return new X509Certificate2(certFile, "ThriftTest");
+ }
+
+ private static string GetCertPath(DirectoryInfo di, int maxCount = 6)
+ {
+ var topDir = di;
+ var certFile =
+ topDir.EnumerateFiles("ThriftTest.pfx", SearchOption.AllDirectories)
+ .FirstOrDefault();
+ if (certFile == null)
+ {
+ if (maxCount == 0)
+ throw new FileNotFoundException("Cannot find file in directories");
+ return GetCertPath(di.Parent, maxCount - 1);
+ }
+
+ return certFile.FullName;
+ }
+
+ private static X509Certificate LocalCertificateSelectionCallback(object sender,
+ string targetHost, X509CertificateCollection localCertificates,
+ X509Certificate remoteCertificate, string[] acceptableIssuers)
+ {
+ return GetCertificate();
+ }
+
+ private static bool ClientCertValidator(object sender, X509Certificate certificate,
+ X509Chain chain, SslPolicyErrors sslPolicyErrors)
+ {
+ return true;
+ }
+
+ private enum Transport
+ {
+ Tcp,
+ TcpBuffered,
+ NamedPipe,
+ Http,
+ TcpTls,
+ Framed
+ }
+
+ private enum Protocol
+ {
+ Binary,
+ Compact,
+ Json,
+ Multiplexed
+ }
+
+ public class HttpServerSample
+ {
+ public void Run(CancellationToken cancellationToken)
+ {
+ var config = new ConfigurationBuilder()
+ .AddEnvironmentVariables(prefix: "ASPNETCORE_")
+ .Build();
+
+ var host = new WebHostBuilder()
+ .UseConfiguration(config)
+ .UseKestrel()
+ .UseUrls("http://localhost:9090")
+ .UseContentRoot(Directory.GetCurrentDirectory())
+ .UseStartup<Startup>()
+ .Build();
+
+ host.RunAsync(cancellationToken).GetAwaiter().GetResult();
+ }
+
+ public class Startup
+ {
+ public Startup(IHostingEnvironment env)
+ {
+ var builder = new ConfigurationBuilder()
+ .SetBasePath(env.ContentRootPath)
+ .AddEnvironmentVariables();
+
+ Configuration = builder.Build();
+ }
+
+ public IConfigurationRoot Configuration { get; }
+
+ // This method gets called by the runtime. Use this method to add services to the container.
+ public void ConfigureServices(IServiceCollection services)
+ {
+ services.AddTransient<Calculator.IAsync, CalculatorAsyncHandler>();
+ services.AddTransient<ITAsyncProcessor, Calculator.AsyncProcessor>();
+ services.AddTransient<THttpServerTransport, THttpServerTransport>();
+ }
+
+ // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
+ public void Configure(IApplicationBuilder app, IHostingEnvironment env,
+ ILoggerFactory loggerFactory)
+ {
+ app.UseMiddleware<THttpServerTransport>();
+ }
+ }
+ }
+
+ public class CalculatorAsyncHandler : Calculator.IAsync
+ {
+ private readonly Dictionary<int, SharedStruct> _log = new Dictionary<int, SharedStruct>();
+
+ public CalculatorAsyncHandler()
+ {
+ }
+
+ public async Task<SharedStruct> getStructAsync(int key,
+ CancellationToken cancellationToken)
+ {
+ Logger.LogInformation("GetStructAsync({0})", key);
+ return await Task.FromResult(_log[key]);
+ }
+
+ public async Task pingAsync(CancellationToken cancellationToken)
+ {
+ Logger.LogInformation("PingAsync()");
+ await Task.CompletedTask;
+ }
+
+ public async Task<int> addAsync(int num1, int num2, CancellationToken cancellationToken)
+ {
+ Logger.LogInformation($"AddAsync({num1},{num2})");
+ return await Task.FromResult(num1 + num2);
+ }
+
+ public async Task<int> calculateAsync(int logid, Work w, CancellationToken cancellationToken)
+ {
+ Logger.LogInformation($"CalculateAsync({logid}, [{w.Op},{w.Num1},{w.Num2}])");
+
+ var val = 0;
+ switch (w.Op)
+ {
+ case Operation.ADD:
+ val = w.Num1 + w.Num2;
+ break;
+
+ case Operation.SUBTRACT:
+ val = w.Num1 - w.Num2;
+ break;
+
+ case Operation.MULTIPLY:
+ val = w.Num1 * w.Num2;
+ break;
+
+ case Operation.DIVIDE:
+ if (w.Num2 == 0)
+ {
+ var io = new InvalidOperation
+ {
+ WhatOp = (int) w.Op,
+ Why = "Cannot divide by 0"
+ };
+
+ throw io;
+ }
+ val = w.Num1 / w.Num2;
+ break;
+
+ default:
+ {
+ var io = new InvalidOperation
+ {
+ WhatOp = (int) w.Op,
+ Why = "Unknown operation"
+ };
+
+ throw io;
+ }
+ }
+
+ var entry = new SharedStruct
+ {
+ Key = logid,
+ Value = val.ToString()
+ };
+
+ _log[logid] = entry;
+
+ return await Task.FromResult(val);
+ }
+
+ public async Task zipAsync(CancellationToken cancellationToken)
+ {
+ Logger.LogInformation("ZipAsync() with delay 100mc");
+ await Task.Delay(100, CancellationToken.None);
+ }
+ }
+
+ public class SharedServiceAsyncHandler : SharedService.IAsync
+ {
+ public async Task<SharedStruct> getStructAsync(int key, CancellationToken cancellationToken)
+ {
+ Logger.LogInformation("GetStructAsync({0})", key);
+ return await Task.FromResult(new SharedStruct()
+ {
+ Key = key,
+ Value = "GetStructAsync"
+ });
+ }
+ }
+ }
+}
diff --git a/src/jaegertracing/thrift/tutorial/netcore/Server/Properties/AssemblyInfo.cs b/src/jaegertracing/thrift/tutorial/netcore/Server/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000..a0442350b
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/netcore/Server/Properties/AssemblyInfo.cs
@@ -0,0 +1,40 @@
+// 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 System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("The Apache Software Foundation")]
+[assembly: AssemblyProduct("Thrift")]
+[assembly: AssemblyCopyright("The Apache Software Foundation")]
+[assembly: AssemblyTrademark("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+
+[assembly: Guid("e210fc10-5aff-4b04-ac21-58afc7b74b0c")] \ No newline at end of file
diff --git a/src/jaegertracing/thrift/tutorial/netcore/Server/Properties/launchSettings.json b/src/jaegertracing/thrift/tutorial/netcore/Server/Properties/launchSettings.json
new file mode 100644
index 000000000..78076ff7c
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/netcore/Server/Properties/launchSettings.json
@@ -0,0 +1,8 @@
+{
+ "profiles": {
+ "Server": {
+ "commandName": "Project",
+ "commandLineArgs": "-p:multiplexed"
+ }
+ }
+} \ No newline at end of file
diff --git a/src/jaegertracing/thrift/tutorial/netcore/Server/Server.csproj b/src/jaegertracing/thrift/tutorial/netcore/Server/Server.csproj
new file mode 100644
index 000000000..0fbd30323
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/netcore/Server/Server.csproj
@@ -0,0 +1,26 @@
+<Project Sdk="Microsoft.NET.Sdk.Web">
+
+ <PropertyGroup>
+ <TargetFramework>netcoreapp2.0</TargetFramework>
+ <AssemblyName>Server</AssemblyName>
+ <PackageId>Server</PackageId>
+ <OutputType>Exe</OutputType>
+ <GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
+ <GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
+ <GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
+ <GenerateAssemblyCopyrightAttribute>false</GenerateAssemblyCopyrightAttribute>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="../Interfaces/Interfaces.csproj" />
+ <ProjectReference Include="../../../lib/netcore/Thrift/Thrift.csproj" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <PackageReference Include="Microsoft.AspNetCore" Version="[2.0,)" />
+ <PackageReference Include="Microsoft.AspNetCore.Server.IISIntegration" Version="[2.0,)" />
+ <PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="[2.0,)" />
+ <PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="[2.0,)" />
+ </ItemGroup>
+
+</Project>
diff --git a/src/jaegertracing/thrift/tutorial/netcore/Server/ThriftTest.pfx b/src/jaegertracing/thrift/tutorial/netcore/Server/ThriftTest.pfx
new file mode 100644
index 000000000..f0ded2817
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/netcore/Server/ThriftTest.pfx
Binary files differ
diff --git a/src/jaegertracing/thrift/tutorial/netcore/Tutorial.sln b/src/jaegertracing/thrift/tutorial/netcore/Tutorial.sln
new file mode 100644
index 000000000..2ddcd4617
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/netcore/Tutorial.sln
@@ -0,0 +1,78 @@
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.26114.2
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Thrift", "..\..\lib\netcore\Thrift\Thrift.csproj", "{C20EA2A9-7660-47DE-9A49-D1EF12FB2895}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Interfaces", "Interfaces\Interfaces.csproj", "{B9E24D84-2712-4158-8F1A-DDE44CD1BB0A}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Client", "Client\Client.csproj", "{E4CA1EF0-B181-4A5D-A02C-DB0750A59CDF}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Server", "Server\Server.csproj", "{E08F5B84-2B4A-4E09-82D1-E0715775CE5E}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|Any CPU = Release|Any CPU
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {C20EA2A9-7660-47DE-9A49-D1EF12FB2895}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C20EA2A9-7660-47DE-9A49-D1EF12FB2895}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C20EA2A9-7660-47DE-9A49-D1EF12FB2895}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {C20EA2A9-7660-47DE-9A49-D1EF12FB2895}.Debug|x64.Build.0 = Debug|Any CPU
+ {C20EA2A9-7660-47DE-9A49-D1EF12FB2895}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {C20EA2A9-7660-47DE-9A49-D1EF12FB2895}.Debug|x86.Build.0 = Debug|Any CPU
+ {C20EA2A9-7660-47DE-9A49-D1EF12FB2895}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C20EA2A9-7660-47DE-9A49-D1EF12FB2895}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C20EA2A9-7660-47DE-9A49-D1EF12FB2895}.Release|x64.ActiveCfg = Release|Any CPU
+ {C20EA2A9-7660-47DE-9A49-D1EF12FB2895}.Release|x64.Build.0 = Release|Any CPU
+ {C20EA2A9-7660-47DE-9A49-D1EF12FB2895}.Release|x86.ActiveCfg = Release|Any CPU
+ {C20EA2A9-7660-47DE-9A49-D1EF12FB2895}.Release|x86.Build.0 = Release|Any CPU
+ {B9E24D84-2712-4158-8F1A-DDE44CD1BB0A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B9E24D84-2712-4158-8F1A-DDE44CD1BB0A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B9E24D84-2712-4158-8F1A-DDE44CD1BB0A}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {B9E24D84-2712-4158-8F1A-DDE44CD1BB0A}.Debug|x64.Build.0 = Debug|Any CPU
+ {B9E24D84-2712-4158-8F1A-DDE44CD1BB0A}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {B9E24D84-2712-4158-8F1A-DDE44CD1BB0A}.Debug|x86.Build.0 = Debug|Any CPU
+ {B9E24D84-2712-4158-8F1A-DDE44CD1BB0A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B9E24D84-2712-4158-8F1A-DDE44CD1BB0A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B9E24D84-2712-4158-8F1A-DDE44CD1BB0A}.Release|x64.ActiveCfg = Release|Any CPU
+ {B9E24D84-2712-4158-8F1A-DDE44CD1BB0A}.Release|x64.Build.0 = Release|Any CPU
+ {B9E24D84-2712-4158-8F1A-DDE44CD1BB0A}.Release|x86.ActiveCfg = Release|Any CPU
+ {B9E24D84-2712-4158-8F1A-DDE44CD1BB0A}.Release|x86.Build.0 = Release|Any CPU
+ {E4CA1EF0-B181-4A5D-A02C-DB0750A59CDF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E4CA1EF0-B181-4A5D-A02C-DB0750A59CDF}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E4CA1EF0-B181-4A5D-A02C-DB0750A59CDF}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {E4CA1EF0-B181-4A5D-A02C-DB0750A59CDF}.Debug|x64.Build.0 = Debug|Any CPU
+ {E4CA1EF0-B181-4A5D-A02C-DB0750A59CDF}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {E4CA1EF0-B181-4A5D-A02C-DB0750A59CDF}.Debug|x86.Build.0 = Debug|Any CPU
+ {E4CA1EF0-B181-4A5D-A02C-DB0750A59CDF}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E4CA1EF0-B181-4A5D-A02C-DB0750A59CDF}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E4CA1EF0-B181-4A5D-A02C-DB0750A59CDF}.Release|x64.ActiveCfg = Release|Any CPU
+ {E4CA1EF0-B181-4A5D-A02C-DB0750A59CDF}.Release|x64.Build.0 = Release|Any CPU
+ {E4CA1EF0-B181-4A5D-A02C-DB0750A59CDF}.Release|x86.ActiveCfg = Release|Any CPU
+ {E4CA1EF0-B181-4A5D-A02C-DB0750A59CDF}.Release|x86.Build.0 = Release|Any CPU
+ {E08F5B84-2B4A-4E09-82D1-E0715775CE5E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E08F5B84-2B4A-4E09-82D1-E0715775CE5E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E08F5B84-2B4A-4E09-82D1-E0715775CE5E}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {E08F5B84-2B4A-4E09-82D1-E0715775CE5E}.Debug|x64.Build.0 = Debug|Any CPU
+ {E08F5B84-2B4A-4E09-82D1-E0715775CE5E}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {E08F5B84-2B4A-4E09-82D1-E0715775CE5E}.Debug|x86.Build.0 = Debug|Any CPU
+ {E08F5B84-2B4A-4E09-82D1-E0715775CE5E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E08F5B84-2B4A-4E09-82D1-E0715775CE5E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E08F5B84-2B4A-4E09-82D1-E0715775CE5E}.Release|x64.ActiveCfg = Release|Any CPU
+ {E08F5B84-2B4A-4E09-82D1-E0715775CE5E}.Release|x64.Build.0 = Release|Any CPU
+ {E08F5B84-2B4A-4E09-82D1-E0715775CE5E}.Release|x86.ActiveCfg = Release|Any CPU
+ {E08F5B84-2B4A-4E09-82D1-E0715775CE5E}.Release|x86.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {070A5D1D-B29D-4603-999D-693DB444AD0D}
+ EndGlobalSection
+EndGlobal
diff --git a/src/jaegertracing/thrift/tutorial/netcore/build.cmd b/src/jaegertracing/thrift/tutorial/netcore/build.cmd
new file mode 100644
index 000000000..9b84ef276
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/netcore/build.cmd
@@ -0,0 +1,25 @@
+@echo off
+rem /*
+rem * Licensed to the Apache Software Foundation (ASF) under one
+rem * or more contributor license agreements. See the NOTICE file
+rem * distributed with this work for additional information
+rem * regarding copyright ownership. The ASF licenses this file
+rem * to you under the Apache License, Version 2.0 (the
+rem * "License"); you may not use this file except in compliance
+rem * with the License. You may obtain a copy of the License at
+rem *
+rem * http://www.apache.org/licenses/LICENSE-2.0
+rem *
+rem * Unless required by applicable law or agreed to in writing,
+rem * software distributed under the License is distributed on an
+rem * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+rem * KIND, either express or implied. See the License for the
+rem * specific language governing permissions and limitations
+rem * under the License.
+rem */
+setlocal
+
+dotnet --info
+dotnet build
+
+:eof
diff --git a/src/jaegertracing/thrift/tutorial/netcore/build.sh b/src/jaegertracing/thrift/tutorial/netcore/build.sh
new file mode 100755
index 000000000..c97e310f0
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/netcore/build.sh
@@ -0,0 +1,26 @@
+#!/usr/bin/env bash
+
+#
+# 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.
+#
+
+#exit if any command fails
+set -e
+
+dotnet --info
+dotnet build
diff --git a/src/jaegertracing/thrift/tutorial/netstd/.gitignore b/src/jaegertracing/thrift/tutorial/netstd/.gitignore
new file mode 100644
index 000000000..9938bb237
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/netstd/.gitignore
@@ -0,0 +1 @@
+!**/*.pfx \ No newline at end of file
diff --git a/src/jaegertracing/thrift/tutorial/netstd/Client/Client.csproj b/src/jaegertracing/thrift/tutorial/netstd/Client/Client.csproj
new file mode 100644
index 000000000..a1470a9d3
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/netstd/Client/Client.csproj
@@ -0,0 +1,41 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <!--
+ 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.
+ -->
+
+ <PropertyGroup>
+ <TargetFramework>netcoreapp2.0</TargetFramework>
+ <AssemblyName>Client</AssemblyName>
+ <PackageId>Client</PackageId>
+ <OutputType>Exe</OutputType>
+ <GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
+ <GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
+ <GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
+ <GenerateAssemblyCopyrightAttribute>false</GenerateAssemblyCopyrightAttribute>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="2.2.0" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="..\Interfaces\Interfaces.csproj" />
+ <ProjectReference Include="..\..\..\lib\netstd\Thrift\Thrift.csproj" />
+ </ItemGroup>
+
+</Project>
diff --git a/src/jaegertracing/thrift/tutorial/netstd/Client/Program.cs b/src/jaegertracing/thrift/tutorial/netstd/Client/Program.cs
new file mode 100644
index 000000000..f9509fa2d
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/netstd/Client/Program.cs
@@ -0,0 +1,409 @@
+// 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 System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Net;
+using System.Net.Security;
+using System.Security.Cryptography.X509Certificates;
+using System.Threading;
+using System.Threading.Tasks;
+using Microsoft.Extensions.Logging;
+using Thrift;
+using Thrift.Protocol;
+using Thrift.Transport;
+using Thrift.Transport.Client;
+using tutorial;
+using shared;
+using Microsoft.Extensions.DependencyInjection;
+using System.Diagnostics;
+
+namespace Client
+{
+ public class Program
+ {
+ private static ServiceCollection ServiceCollection = new ServiceCollection();
+ private static ILogger Logger;
+
+ private static void DisplayHelp()
+ {
+ Logger.LogInformation(@"
+Usage:
+ Client.exe -help
+ will diplay help information
+
+ Client.exe -tr:<transport> -bf:<buffering> -pr:<protocol> -mc:<numClients>
+ will run client with specified arguments (tcp transport and binary protocol by default) and with 1 client
+
+Options:
+ -tr (transport):
+ tcp - (default) tcp transport will be used (host - ""localhost"", port - 9090)
+ namedpipe - namedpipe transport will be used (pipe address - "".test"")
+ http - http transport will be used (address - ""http://localhost:9090"")
+ tcptls - tcp tls transport will be used (host - ""localhost"", port - 9090)
+
+ -bf (buffering):
+ none - (default) no buffering will be used
+ buffered - buffered transport will be used
+ framed - framed transport will be used
+
+ -pr (protocol):
+ binary - (default) binary protocol will be used
+ compact - compact protocol will be used
+ json - json protocol will be used
+ multiplexed - multiplexed protocol will be used
+
+ -mc (multiple clients):
+ <numClients> - number of multiple clients to connect to server (max 100, default 1)
+
+Sample:
+ Client.exe -tr:tcp -p:binary
+");
+ }
+
+ public static void Main(string[] args)
+ {
+ args = args ?? new string[0];
+
+ ServiceCollection.AddLogging(logging => ConfigureLogging(logging));
+ Logger = ServiceCollection.BuildServiceProvider().GetService<ILoggerFactory>().CreateLogger(nameof(Client));
+
+ if (args.Any(x => x.StartsWith("-help", StringComparison.OrdinalIgnoreCase)))
+ {
+ DisplayHelp();
+ return;
+ }
+
+ Logger.LogInformation("Starting client...");
+
+ using (var source = new CancellationTokenSource())
+ {
+ RunAsync(args, source.Token).GetAwaiter().GetResult();
+ }
+ }
+
+ private static void ConfigureLogging(ILoggingBuilder logging)
+ {
+ logging.SetMinimumLevel(LogLevel.Trace);
+ logging.AddConsole();
+ logging.AddDebug();
+ }
+
+ private static async Task RunAsync(string[] args, CancellationToken cancellationToken)
+ {
+ var numClients = GetNumberOfClients(args);
+
+ Logger.LogInformation($"Selected # of clients: {numClients}");
+
+ var transports = new TTransport[numClients];
+ for (int i = 0; i < numClients; i++)
+ {
+ var t = GetTransport(args);
+ transports[i] = t;
+ }
+
+ Logger.LogInformation($"Selected client transport: {transports[0]}");
+
+ var protocols = new Tuple<Protocol, TProtocol>[numClients];
+ for (int i = 0; i < numClients; i++)
+ {
+ var p = GetProtocol(args, transports[i]);
+ protocols[i] = p;
+ }
+
+ Logger.LogInformation($"Selected client protocol: {protocols[0].Item1}");
+
+ var tasks = new Task[numClients];
+ for (int i = 0; i < numClients; i++)
+ {
+ var task = RunClientAsync(protocols[i], cancellationToken);
+ tasks[i] = task;
+ }
+
+ Task.WaitAll(tasks);
+
+ await Task.CompletedTask;
+ }
+
+ private static TTransport GetTransport(string[] args)
+ {
+ TTransport transport = new TSocketTransport(IPAddress.Loopback, 9090);
+
+ // construct endpoint transport
+ var transportArg = args.FirstOrDefault(x => x.StartsWith("-tr"))?.Split(':')?[1];
+ if (Enum.TryParse(transportArg, true, out Transport selectedTransport))
+ {
+ switch (selectedTransport)
+ {
+ case Transport.Tcp:
+ transport = new TSocketTransport(IPAddress.Loopback, 9090);
+ break;
+
+ case Transport.NamedPipe:
+ transport = new TNamedPipeTransport(".test");
+ break;
+
+ case Transport.Http:
+ transport = new THttpTransport(new Uri("http://localhost:9090"), null);
+ break;
+
+ case Transport.TcpTls:
+ transport = new TTlsSocketTransport(IPAddress.Loopback, 9090, GetCertificate(), CertValidator, LocalCertificateSelectionCallback);
+ break;
+
+ default:
+ Debug.Assert(false, "unhandled case");
+ break;
+ }
+ }
+
+ // optionally add layered transport(s)
+ var bufferingArg = args.FirstOrDefault(x => x.StartsWith("-bf"))?.Split(':')?[1];
+ if (Enum.TryParse<Buffering>(bufferingArg, out var selectedBuffering))
+ {
+ switch (selectedBuffering)
+ {
+ case Buffering.Buffered:
+ transport = new TBufferedTransport(transport);
+ break;
+
+ case Buffering.Framed:
+ transport = new TFramedTransport(transport);
+ break;
+
+ default: // layered transport(s) are optional
+ Debug.Assert(selectedBuffering == Buffering.None, "unhandled case");
+ break;
+ }
+ }
+
+ return transport;
+ }
+
+ private static int GetNumberOfClients(string[] args)
+ {
+ var numClients = args.FirstOrDefault(x => x.StartsWith("-mc"))?.Split(':')?[1];
+
+ Logger.LogInformation($"Selected # of clients: {numClients}");
+
+ int c;
+ if( int.TryParse(numClients, out c) && (0 < c) && (c <= 100))
+ return c;
+ else
+ return 1;
+ }
+
+ private static X509Certificate2 GetCertificate()
+ {
+ // due to files location in net core better to take certs from top folder
+ var certFile = GetCertPath(Directory.GetParent(Directory.GetCurrentDirectory()));
+ return new X509Certificate2(certFile, "ThriftTest");
+ }
+
+ private static string GetCertPath(DirectoryInfo di, int maxCount = 6)
+ {
+ var topDir = di;
+ var certFile =
+ topDir.EnumerateFiles("ThriftTest.pfx", SearchOption.AllDirectories)
+ .FirstOrDefault();
+ if (certFile == null)
+ {
+ if (maxCount == 0)
+ throw new FileNotFoundException("Cannot find file in directories");
+ return GetCertPath(di.Parent, maxCount - 1);
+ }
+
+ return certFile.FullName;
+ }
+
+ private static X509Certificate LocalCertificateSelectionCallback(object sender,
+ string targetHost, X509CertificateCollection localCertificates,
+ X509Certificate remoteCertificate, string[] acceptableIssuers)
+ {
+ return GetCertificate();
+ }
+
+ private static bool CertValidator(object sender, X509Certificate certificate,
+ X509Chain chain, SslPolicyErrors sslPolicyErrors)
+ {
+ return true;
+ }
+
+ private static Tuple<Protocol, TProtocol> GetProtocol(string[] args, TTransport transport)
+ {
+ var protocol = args.FirstOrDefault(x => x.StartsWith("-pr"))?.Split(':')?[1];
+
+ Protocol selectedProtocol;
+ if (Enum.TryParse(protocol, true, out selectedProtocol))
+ {
+ switch (selectedProtocol)
+ {
+ case Protocol.Binary:
+ return new Tuple<Protocol, TProtocol>(selectedProtocol, new TBinaryProtocol(transport));
+ case Protocol.Compact:
+ return new Tuple<Protocol, TProtocol>(selectedProtocol, new TCompactProtocol(transport));
+ case Protocol.Json:
+ return new Tuple<Protocol, TProtocol>(selectedProtocol, new TJsonProtocol(transport));
+ case Protocol.Multiplexed:
+ // it returns BinaryProtocol to avoid making wrapped protocol as public in TProtocolDecorator (in RunClientAsync it will be wrapped into Multiplexed protocol)
+ return new Tuple<Protocol, TProtocol>(selectedProtocol, new TBinaryProtocol(transport));
+ default:
+ Debug.Assert(false, "unhandled case");
+ break;
+ }
+ }
+
+ return new Tuple<Protocol, TProtocol>(selectedProtocol, new TBinaryProtocol(transport));
+ }
+
+ private static async Task RunClientAsync(Tuple<Protocol, TProtocol> protocolTuple, CancellationToken cancellationToken)
+ {
+ try
+ {
+ var protocol = protocolTuple.Item2;
+ var protocolType = protocolTuple.Item1;
+
+ TBaseClient client = null;
+
+ try
+ {
+ if (protocolType != Protocol.Multiplexed)
+ {
+
+ client = new Calculator.Client(protocol);
+ await ExecuteCalculatorClientOperations(cancellationToken, (Calculator.Client)client);
+ }
+ else
+ {
+ // it uses binary protocol there to create Multiplexed protocols
+ var multiplex = new TMultiplexedProtocol(protocol, nameof(Calculator));
+ client = new Calculator.Client(multiplex);
+ await ExecuteCalculatorClientOperations(cancellationToken, (Calculator.Client)client);
+
+ multiplex = new TMultiplexedProtocol(protocol, nameof(SharedService));
+ client = new SharedService.Client(multiplex);
+ await ExecuteSharedServiceClientOperations(cancellationToken, (SharedService.Client)client);
+ }
+ }
+ catch (Exception ex)
+ {
+ Logger.LogError($"{client?.ClientId} " + ex);
+ }
+ finally
+ {
+ protocol.Transport.Close();
+ }
+ }
+ catch (TApplicationException x)
+ {
+ Logger.LogError(x.ToString());
+ }
+ }
+
+ private static async Task ExecuteCalculatorClientOperations(CancellationToken cancellationToken, Calculator.Client client)
+ {
+ await client.OpenTransportAsync(cancellationToken);
+
+ // Async version
+
+ Logger.LogInformation($"{client.ClientId} PingAsync()");
+ await client.pingAsync(cancellationToken);
+
+ Logger.LogInformation($"{client.ClientId} AddAsync(1,1)");
+ var sum = await client.addAsync(1, 1, cancellationToken);
+ Logger.LogInformation($"{client.ClientId} AddAsync(1,1)={sum}");
+
+ var work = new Work
+ {
+ Op = Operation.DIVIDE,
+ Num1 = 1,
+ Num2 = 0
+ };
+
+ try
+ {
+ Logger.LogInformation($"{client.ClientId} CalculateAsync(1)");
+ await client.calculateAsync(1, work, cancellationToken);
+ Logger.LogInformation($"{client.ClientId} Whoa we can divide by 0");
+ }
+ catch (InvalidOperation io)
+ {
+ Logger.LogInformation($"{client.ClientId} Invalid operation: " + io);
+ }
+
+ work.Op = Operation.SUBTRACT;
+ work.Num1 = 15;
+ work.Num2 = 10;
+
+ try
+ {
+ Logger.LogInformation($"{client.ClientId} CalculateAsync(1)");
+ var diff = await client.calculateAsync(1, work, cancellationToken);
+ Logger.LogInformation($"{client.ClientId} 15-10={diff}");
+ }
+ catch (InvalidOperation io)
+ {
+ Logger.LogInformation($"{client.ClientId} Invalid operation: " + io);
+ }
+
+ Logger.LogInformation($"{client.ClientId} GetStructAsync(1)");
+ var log = await client.getStructAsync(1, cancellationToken);
+ Logger.LogInformation($"{client.ClientId} Check log: {log.Value}");
+
+ Logger.LogInformation($"{client.ClientId} ZipAsync() with delay 100mc on server side");
+ await client.zipAsync(cancellationToken);
+ }
+ private static async Task ExecuteSharedServiceClientOperations(CancellationToken cancellationToken, SharedService.Client client)
+ {
+ await client.OpenTransportAsync(cancellationToken);
+
+ // Async version
+
+ Logger.LogInformation($"{client.ClientId} SharedService GetStructAsync(1)");
+ var log = await client.getStructAsync(1, cancellationToken);
+ Logger.LogInformation($"{client.ClientId} SharedService Value: {log.Value}");
+ }
+
+
+ private enum Transport
+ {
+ Tcp,
+ NamedPipe,
+ Http,
+ TcpBuffered,
+ Framed,
+ TcpTls
+ }
+
+ private enum Protocol
+ {
+ Binary,
+ Compact,
+ Json,
+ Multiplexed
+ }
+
+ private enum Buffering
+ {
+ None,
+ Buffered,
+ Framed
+ }
+ }
+}
diff --git a/src/jaegertracing/thrift/tutorial/netstd/Client/Properties/AssemblyInfo.cs b/src/jaegertracing/thrift/tutorial/netstd/Client/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000..568382e66
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/netstd/Client/Properties/AssemblyInfo.cs
@@ -0,0 +1,40 @@
+// 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 System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("The Apache Software Foundation")]
+[assembly: AssemblyProduct("Thrift")]
+[assembly: AssemblyCopyright("The Apache Software Foundation")]
+[assembly: AssemblyTrademark("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+
+[assembly: Guid("de78a01b-f7c6-49d1-97da-669d2ed37641")] \ No newline at end of file
diff --git a/src/jaegertracing/thrift/tutorial/netstd/Client/Properties/launchSettings.json b/src/jaegertracing/thrift/tutorial/netstd/Client/Properties/launchSettings.json
new file mode 100644
index 000000000..6b7b60d78
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/netstd/Client/Properties/launchSettings.json
@@ -0,0 +1,8 @@
+{
+ "profiles": {
+ "Client": {
+ "commandName": "Project",
+ "commandLineArgs": "-p:multiplexed"
+ }
+ }
+} \ No newline at end of file
diff --git a/src/jaegertracing/thrift/tutorial/netstd/Client/ThriftTest.pfx b/src/jaegertracing/thrift/tutorial/netstd/Client/ThriftTest.pfx
new file mode 100644
index 000000000..f0ded2817
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/netstd/Client/ThriftTest.pfx
Binary files differ
diff --git a/src/jaegertracing/thrift/tutorial/netstd/Interfaces/.gitignore b/src/jaegertracing/thrift/tutorial/netstd/Interfaces/.gitignore
new file mode 100644
index 000000000..2e7446e33
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/netstd/Interfaces/.gitignore
@@ -0,0 +1,3 @@
+# ignore for autogenerated files
+/shared
+/tutorial
diff --git a/src/jaegertracing/thrift/tutorial/netstd/Interfaces/Interfaces.csproj b/src/jaegertracing/thrift/tutorial/netstd/Interfaces/Interfaces.csproj
new file mode 100644
index 000000000..4ebeb4f42
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/netstd/Interfaces/Interfaces.csproj
@@ -0,0 +1,48 @@
+<Project Sdk="Microsoft.NET.Sdk">
+ <!--
+ 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.
+ -->
+
+ <PropertyGroup>
+ <TargetFramework>netstandard2.0</TargetFramework>
+ <AssemblyName>Interfaces</AssemblyName>
+ <PackageId>Interfaces</PackageId>
+ <GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
+ <GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
+ <GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
+ <GenerateAssemblyCopyrightAttribute>false</GenerateAssemblyCopyrightAttribute>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="../../../lib/netstd/Thrift/Thrift.csproj" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <PackageReference Include="System.ServiceModel.Primitives" Version="4.5.3" />
+ </ItemGroup>
+
+ <Target Name="PreBuild" BeforeTargets="_GenerateRestoreProjectSpec;Restore;Compile">
+ <Exec Condition="'$(OS)' == 'Windows_NT'" Command="where thrift" ConsoleToMSBuild="true">
+ <Output TaskParameter="ConsoleOutput" PropertyName="PathToThrift" />
+ </Exec>
+ <Exec Condition="Exists('$(PathToThrift)')" Command="$(PathToThrift) -out $(ProjectDir) -gen netstd:wcf,union,serial -r ./../../tutorial.thrift" />
+ <Exec Condition="Exists('thrift')" Command="thrift -out $(ProjectDir) -gen netstd:wcf,union,serial -r ./../../tutorial.thrift" />
+ <Exec Condition="Exists('./../../../compiler/cpp/thrift')" Command="./../../../compiler/cpp/thrift -out $(ProjectDir) -gen netstd:wcf,union,serial -r ./../../tutorial.thrift" />
+ </Target>
+
+</Project>
diff --git a/src/jaegertracing/thrift/tutorial/netstd/Interfaces/Properties/AssemblyInfo.cs b/src/jaegertracing/thrift/tutorial/netstd/Interfaces/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000..9126b173e
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/netstd/Interfaces/Properties/AssemblyInfo.cs
@@ -0,0 +1,40 @@
+// 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 System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("The Apache Software Foundation")]
+[assembly: AssemblyProduct("Thrift")]
+[assembly: AssemblyCopyright("The Apache Software Foundation")]
+[assembly: AssemblyTrademark("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+
+[assembly: Guid("4d13163d-9067-4c9c-8af0-64e08451397d")] \ No newline at end of file
diff --git a/src/jaegertracing/thrift/tutorial/netstd/Makefile.am b/src/jaegertracing/thrift/tutorial/netstd/Makefile.am
new file mode 100644
index 000000000..e30555655
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/netstd/Makefile.am
@@ -0,0 +1,42 @@
+#
+# 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.
+#
+
+SUBDIRS = .
+
+all-local:
+ $(DOTNETCORE) build
+
+clean-local:
+ $(RM) Interfaces.dll
+ $(RM) -r Client/bin
+ $(RM) -r Client/obj
+ $(RM) -r Server/bin
+ $(RM) -r Server/obj
+ $(RM) -r Interfaces/bin
+ $(RM) -r Interfaces/obj
+
+EXTRA_DIST = \
+ Client \
+ Interfaces \
+ README.md \
+ Server \
+ Tutorial.sln \
+ build.cmd \
+ build.sh
+
diff --git a/src/jaegertracing/thrift/tutorial/netstd/README.md b/src/jaegertracing/thrift/tutorial/netstd/README.md
new file mode 100644
index 000000000..b1dea4ecb
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/netstd/README.md
@@ -0,0 +1,284 @@
+# Building of samples for different platforms
+
+# Reused components
+- NET Core Standard 2.0
+- NET Core App 2.0
+
+# How to build
+- Download and install the latest .NET Core SDK for your platform https://www.microsoft.com/net/core#windowsvs2015 (archive for SDK 1.0.0-preview2-003121 located by: https://github.com/dotnet/core/blob/master/release-notes/download-archive.md)
+- Ensure that you have thrift.exe which supports netstd lib and it added to PATH
+- Go to current folder
+- Run **build.sh** or **build.cmd** from the root of cloned repository
+- Check tests in **src/Tests** folder
+- Continue with /tutorials/netstd
+
+# How to run
+
+Notes: dotnet run supports passing arguments to app after -- symbols (https://docs.microsoft.com/en-us/dotnet/articles/core/tools/dotnet-run) - example: **dotnet run -- -h** will show help for app
+
+- build
+- go to folder (Client/Server)
+- run with specifying of correct parameters **dotnet run -tr:tcp -pr:multiplexed**, **dotnet run -help** (later, after migration to csproj and latest SDK will be possibility to use more usable form **dotnet run -- arguments**)
+
+#Notes
+- Possible adding additional platforms after stabilization of .NET Core (runtimes, platforms (Red Hat Linux, OpenSuse, etc.)
+
+#Known issues
+- In trace logging mode you can see some not important internal exceptions
+
+# Running of samples
+Please install Thrift C# .NET Core library or copy sources and build them to correcly build and run samples
+
+# NetCore Server
+
+Usage:
+
+ Server.exe -h
+ will diplay help information
+
+ Server.exe -tr:<transport> -pr:<protocol>
+ will run server with specified arguments (tcp transport and binary protocol by default)
+
+Options:
+
+ -tr (transport):
+ tcp - (default) tcp transport will be used (host - ""localhost"", port - 9090)
+ namedpipe - namedpipe transport will be used (pipe address - "".test"")
+ http - http transport will be used (http address - ""localhost:9090"")
+ tcptls - tcp transport with tls will be used (host - ""localhost"", port - 9090)
+
+ -bf (buffering):
+ none - (default) no transport factory will be used
+ buffered - buffered transport factory will be used
+ framed - framed transport factory will be used (this must match the client)
+
+ -pr (protocol):
+ binary - (default) binary protocol will be used
+ compact - compact protocol will be used
+ json - json protocol will be used
+
+Sample:
+
+ Server.exe -tr:tcp
+
+**Remarks**:
+
+ For TcpTls mode certificate's file ThriftTest.pfx should be in directory with binaries in case of command line usage (or at project level in case of debugging from IDE).
+ Password for certificate - "ThriftTest".
+
+
+
+# NetCore Client
+
+Usage:
+
+ Client.exe -h
+ will diplay help information
+
+ Client.exe -tr:<transport> -pr:<protocol> -mc:<numClients>
+ will run client with specified arguments (tcp transport and binary protocol by default)
+
+Options:
+
+ -tr (transport):
+ tcp - (default) tcp transport will be used (host - ""localhost"", port - 9090)
+ namedpipe - namedpipe transport will be used (pipe address - "".test"")
+ http - http transport will be used (address - ""http://localhost:9090"")
+ tcptls - tcp tls transport will be used (host - ""localhost"", port - 9090)
+
+ -bf (buffering):
+ none - (default) no transport factory will be used
+ buffered - buffered transport factory will be used
+ framed - framed transport factory will be used (this must match the client)
+
+ -pr (protocol):
+ binary - (default) binary protocol will be used
+ compact - compact protocol will be used
+ json - json protocol will be used
+
+ -mc (multiple clients):
+ <numClients> - number of multiple clients to connect to server (max 100, default 1)
+
+Sample:
+
+ Client.exe -tr:tcp -pr:binary -mc:10
+
+Remarks:
+
+ For TcpTls mode certificate's file ThriftTest.pfx should be in directory
+ with binaries in case of command line usage (or at project level in case of debugging from IDE).
+ Password for certificate - "ThriftTest".
+
+# How to test communication between NetCore and Python
+
+* Generate code with the latest **thrift.exe** util
+* Ensure that **thrift.exe** util generated folder **gen-py** with generated code for Python
+* Create **client.py** and **server.py** from the code examples below and save them to the folder with previosly generated folder **gen-py**
+* Run netstd samples (client and server) and python samples (client and server)
+
+Remarks:
+
+Samples of client and server code below use correct methods (operations)
+and fields (properties) according to generated contracts from *.thrift files
+
+At Windows 10 add record **127.0.0.1 testserver** to **C:\Windows\System32\drivers\etc\hosts** file
+for correct work of python server
+
+
+**Python Client:**
+
+```python
+import sys
+import glob
+sys.path.append('gen-py')
+
+from tutorial import Calculator
+from tutorial.ttypes import InvalidOperation, Operation, Work
+
+from thrift import Thrift
+from thrift.transport import TSocket
+from thrift.transport import TTransport
+from thrift.protocol import TBinaryProtocol
+
+
+def main():
+ # Make socket
+ transport = TSocket.TSocket('127.0.0.1', 9090)
+
+ # Buffering is critical. Raw sockets are very slow
+ transport = TTransport.TBufferedTransport(transport)
+
+ # Wrap in a protocol
+ protocol = TBinaryProtocol.TBinaryProtocol(transport)
+
+ # Create a client to use the protocol encoder
+ client = Calculator.Client(protocol)
+
+ # Connect!
+ transport.open()
+
+ client.Ping()
+ print('ping()')
+
+ sum = client.Add(1, 1)
+ print(('1+1=%d' % (sum)))
+
+ work = Work()
+
+ work.Op = Operation.Divide
+ work.Num1 = 1
+ work.Num2 = 0
+
+ try:
+ quotient = client.Calculate(1, work)
+ print('Whoa? You know how to divide by zero?')
+ print('FYI the answer is %d' % quotient)
+ except InvalidOperation as e:
+ print(('InvalidOperation: %r' % e))
+
+ work.Op = Operation.Substract
+ work.Num1 = 15
+ work.Num2 = 10
+
+ diff = client.Calculate(1, work)
+ print(('15-10=%d' % (diff)))
+
+ log = client.GetStruct(1)
+ print(('Check log: %s' % (log.Value)))
+
+ client.Zip()
+ print('zip()')
+
+ # Close!
+ transport.close()
+
+if __name__ == '__main__':
+ try:
+ main()
+ except Thrift.TException as tx:
+ print('%s' % tx.message)
+```
+
+
+**Python Server:**
+
+
+```python
+import glob
+import sys
+sys.path.append('gen-py')
+
+from tutorial import Calculator
+from tutorial.ttypes import InvalidOperation, Operation
+
+from shared.ttypes import SharedStruct
+
+from thrift.transport import TSocket
+from thrift.transport import TTransport
+from thrift.protocol import TBinaryProtocol
+from thrift.server import TServer
+
+
+class CalculatorHandler:
+ def __init__(self):
+ self.log = {}
+
+ def Ping(self):
+ print('ping()')
+
+ def Add(self, n1, n2):
+ print('add(%d,%d)' % (n1, n2))
+ return n1 + n2
+
+ def Calculate(self, logid, work):
+ print('calculate(%d, %r)' % (logid, work))
+
+ if work.Op == Operation.Add:
+ val = work.Num1 + work.Num2
+ elif work.Op == Operation.Substract:
+ val = work.Num1 - work.Num2
+ elif work.Op == Operation.Multiply:
+ val = work.Num1 * work.Num2
+ elif work.Op == Operation.Divide:
+ if work.Num2 == 0:
+ x = InvalidOperation()
+ x.WhatOp = work.Op
+ x.Why = 'Cannot divide by 0'
+ raise x
+ val = work.Num1 / work.Num2
+ else:
+ x = InvalidOperation()
+ x.WhatOp = work.Op
+ x.Why = 'Invalid operation'
+ raise x
+
+ log = SharedStruct()
+ log.Key = logid
+ log.Value = '%d' % (val)
+ self.log[logid] = log
+
+ return val
+
+ def GetStruct(self, key):
+ print('getStruct(%d)' % (key))
+ return self.log[key]
+
+ def Zip(self):
+ print('zip()')
+
+if __name__ == '__main__':
+ handler = CalculatorHandler()
+ processor = Calculator.Processor(handler)
+ transport = TSocket.TServerSocket(host="testserver", port=9090)
+ tfactory = TTransport.TBufferedTransportFactory()
+ pfactory = TBinaryProtocol.TBinaryProtocolFactory()
+
+ server = TServer.TSimpleServer(processor, transport, tfactory, pfactory)
+ print('Starting the server...')
+ server.serve()
+ print('done.')
+
+ # You could do one of these for a multithreaded server
+ # server = TServer.TThreadedServer(processor, transport, tfactory, pfactory)
+ # server = TServer.TThreadPoolServer(processor, transport, tfactory, pfactory)
+```
diff --git a/src/jaegertracing/thrift/tutorial/netstd/Server/Program.cs b/src/jaegertracing/thrift/tutorial/netstd/Server/Program.cs
new file mode 100644
index 000000000..25e7daeed
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/netstd/Server/Program.cs
@@ -0,0 +1,479 @@
+// 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 System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
+using System.Net.Security;
+using System.Security.Cryptography.X509Certificates;
+using System.Threading;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.Extensions.Logging;
+using Thrift;
+using Thrift.Protocol;
+using Thrift.Server;
+using Thrift.Transport;
+using Thrift.Transport.Server;
+using tutorial;
+using shared;
+using Thrift.Processor;
+using System.Diagnostics;
+
+namespace Server
+{
+ public class Program
+ {
+ private static ServiceCollection ServiceCollection = new ServiceCollection();
+ private static ILogger Logger;
+
+ public static void Main(string[] args)
+ {
+ args = args ?? new string[0];
+
+ ServiceCollection.AddLogging(logging => ConfigureLogging(logging));
+ Logger = ServiceCollection.BuildServiceProvider().GetService<ILoggerFactory>().CreateLogger(nameof(Server));
+
+
+ if (args.Any(x => x.StartsWith("-help", StringComparison.OrdinalIgnoreCase)))
+ {
+ DisplayHelp();
+ return;
+ }
+
+ using (var source = new CancellationTokenSource())
+ {
+ RunAsync(args, source.Token).GetAwaiter().GetResult();
+
+ Logger.LogInformation("Press any key to stop...");
+
+ Console.ReadLine();
+ source.Cancel();
+ }
+
+ Logger.LogInformation("Server stopped");
+ }
+
+ private static void ConfigureLogging(ILoggingBuilder logging)
+ {
+ logging.SetMinimumLevel(LogLevel.Trace);
+ logging.AddConsole();
+ logging.AddDebug();
+ }
+
+ private static void DisplayHelp()
+ {
+ Logger.LogInformation(@"
+Usage:
+ Server.exe -help
+ will diplay help information
+
+ Server.exe -tr:<transport> -bf:<buffering> -pr:<protocol>
+ will run server with specified arguments (tcp transport, no buffering, and binary protocol by default)
+
+Options:
+ -tr (transport):
+ tcp - (default) tcp transport will be used (host - ""localhost"", port - 9090)
+ namedpipe - namedpipe transport will be used (pipe address - "".test"")
+ http - http transport will be used (http address - ""localhost:9090"")
+ tcptls - tcp transport with tls will be used (host - ""localhost"", port - 9090)
+
+ -bf (buffering):
+ none - (default) no buffering will be used
+ buffered - buffered transport will be used
+ framed - framed transport will be used
+
+ -pr (protocol):
+ binary - (default) binary protocol will be used
+ compact - compact protocol will be used
+ json - json protocol will be used
+ multiplexed - multiplexed protocol will be used
+
+Sample:
+ Server.exe -tr:tcp
+");
+ }
+
+ private static async Task RunAsync(string[] args, CancellationToken cancellationToken)
+ {
+ var selectedTransport = GetTransport(args);
+ var selectedBuffering = GetBuffering(args);
+ var selectedProtocol = GetProtocol(args);
+
+ if (selectedTransport == Transport.Http)
+ {
+ new HttpServerSample().Run(cancellationToken);
+ }
+ else
+ {
+ await RunSelectedConfigurationAsync(selectedTransport, selectedBuffering, selectedProtocol, cancellationToken);
+ }
+ }
+
+ private static Protocol GetProtocol(string[] args)
+ {
+ var transport = args.FirstOrDefault(x => x.StartsWith("-pr"))?.Split(':')?[1];
+
+ Enum.TryParse(transport, true, out Protocol selectedProtocol);
+
+ return selectedProtocol;
+ }
+
+ private static Buffering GetBuffering(string[] args)
+ {
+ var buffering = args.FirstOrDefault(x => x.StartsWith("-bf"))?.Split(":")?[1];
+
+ Enum.TryParse<Buffering>(buffering, out var selectedBuffering);
+
+ return selectedBuffering;
+ }
+
+ private static Transport GetTransport(string[] args)
+ {
+ var transport = args.FirstOrDefault(x => x.StartsWith("-tr"))?.Split(':')?[1];
+
+ Enum.TryParse(transport, true, out Transport selectedTransport);
+
+ return selectedTransport;
+ }
+
+ private static async Task RunSelectedConfigurationAsync(Transport transport, Buffering buffering, Protocol protocol, CancellationToken cancellationToken)
+ {
+ var handler = new CalculatorAsyncHandler();
+
+ TServerTransport serverTransport = null;
+ switch (transport)
+ {
+ case Transport.Tcp:
+ serverTransport = new TServerSocketTransport(9090);
+ break;
+ case Transport.NamedPipe:
+ serverTransport = new TNamedPipeServerTransport(".test");
+ break;
+ case Transport.TcpTls:
+ serverTransport = new TTlsServerSocketTransport(9090, GetCertificate(), ClientCertValidator, LocalCertificateSelectionCallback);
+ break;
+ }
+
+ TTransportFactory inputTransportFactory = null;
+ TTransportFactory outputTransportFactory = null;
+ switch (buffering)
+ {
+ case Buffering.Buffered:
+ inputTransportFactory = new TBufferedTransport.Factory();
+ outputTransportFactory = new TBufferedTransport.Factory();
+ break;
+
+ case Buffering.Framed:
+ inputTransportFactory = new TFramedTransport.Factory();
+ outputTransportFactory = new TFramedTransport.Factory();
+ break;
+
+ default: // layered transport(s) are optional
+ Debug.Assert(buffering == Buffering.None, "unhandled case");
+ break;
+ }
+
+ TProtocolFactory inputProtocolFactory = null;
+ TProtocolFactory outputProtocolFactory = null;
+ ITAsyncProcessor processor = null;
+ switch (protocol)
+ {
+ case Protocol.Binary:
+ inputProtocolFactory = new TBinaryProtocol.Factory();
+ outputProtocolFactory = new TBinaryProtocol.Factory();
+ processor = new Calculator.AsyncProcessor(handler);
+ break;
+
+ case Protocol.Compact:
+ inputProtocolFactory = new TCompactProtocol.Factory();
+ outputProtocolFactory = new TCompactProtocol.Factory();
+ processor = new Calculator.AsyncProcessor(handler);
+ break;
+
+ case Protocol.Json:
+ inputProtocolFactory = new TJsonProtocol.Factory();
+ outputProtocolFactory = new TJsonProtocol.Factory();
+ processor = new Calculator.AsyncProcessor(handler);
+ break;
+
+ case Protocol.Multiplexed:
+ inputProtocolFactory = new TBinaryProtocol.Factory();
+ outputProtocolFactory = new TBinaryProtocol.Factory();
+
+ var calcHandler = new CalculatorAsyncHandler();
+ var calcProcessor = new Calculator.AsyncProcessor(calcHandler);
+
+ var sharedServiceHandler = new SharedServiceAsyncHandler();
+ var sharedServiceProcessor = new SharedService.AsyncProcessor(sharedServiceHandler);
+
+ var multiplexedProcessor = new TMultiplexedProcessor();
+ multiplexedProcessor.RegisterProcessor(nameof(Calculator), calcProcessor);
+ multiplexedProcessor.RegisterProcessor(nameof(SharedService), sharedServiceProcessor);
+
+ processor = multiplexedProcessor;
+ break;
+
+ default:
+ throw new ArgumentOutOfRangeException(nameof(protocol), protocol, null);
+ }
+
+
+ try
+ {
+ Logger.LogInformation(
+ $"Selected TAsyncServer with {serverTransport} transport, {processor} processor and {inputProtocolFactory} protocol factories");
+
+ var loggerFactory = ServiceCollection.BuildServiceProvider().GetService<ILoggerFactory>();
+
+ var server = new TSimpleAsyncServer(
+ itProcessorFactory: new TSingletonProcessorFactory(processor),
+ serverTransport: serverTransport,
+ inputTransportFactory: inputTransportFactory,
+ outputTransportFactory: outputTransportFactory,
+ inputProtocolFactory: inputProtocolFactory,
+ outputProtocolFactory: outputProtocolFactory,
+ logger: loggerFactory.CreateLogger<TSimpleAsyncServer>());
+
+ Logger.LogInformation("Starting the server...");
+
+ await server.ServeAsync(cancellationToken);
+ }
+ catch (Exception x)
+ {
+ Logger.LogInformation(x.ToString());
+ }
+ }
+
+ private static X509Certificate2 GetCertificate()
+ {
+ // due to files location in net core better to take certs from top folder
+ var certFile = GetCertPath(Directory.GetParent(Directory.GetCurrentDirectory()));
+ return new X509Certificate2(certFile, "ThriftTest");
+ }
+
+ private static string GetCertPath(DirectoryInfo di, int maxCount = 6)
+ {
+ var topDir = di;
+ var certFile =
+ topDir.EnumerateFiles("ThriftTest.pfx", SearchOption.AllDirectories)
+ .FirstOrDefault();
+ if (certFile == null)
+ {
+ if (maxCount == 0)
+ throw new FileNotFoundException("Cannot find file in directories");
+ return GetCertPath(di.Parent, maxCount - 1);
+ }
+
+ return certFile.FullName;
+ }
+
+ private static X509Certificate LocalCertificateSelectionCallback(object sender,
+ string targetHost, X509CertificateCollection localCertificates,
+ X509Certificate remoteCertificate, string[] acceptableIssuers)
+ {
+ return GetCertificate();
+ }
+
+ private static bool ClientCertValidator(object sender, X509Certificate certificate,
+ X509Chain chain, SslPolicyErrors sslPolicyErrors)
+ {
+ return true;
+ }
+
+ private enum Transport
+ {
+ Tcp,
+ NamedPipe,
+ Http,
+ TcpTls,
+ }
+
+ private enum Buffering
+ {
+ None,
+ Buffered,
+ Framed,
+ }
+
+ private enum Protocol
+ {
+ Binary,
+ Compact,
+ Json,
+ Multiplexed
+ }
+
+ public class HttpServerSample
+ {
+ public void Run(CancellationToken cancellationToken)
+ {
+ var config = new ConfigurationBuilder()
+ .AddEnvironmentVariables(prefix: "ASPNETCORE_")
+ .Build();
+
+ var host = new WebHostBuilder()
+ .UseConfiguration(config)
+ .UseKestrel()
+ .UseUrls("http://localhost:9090")
+ .UseContentRoot(Directory.GetCurrentDirectory())
+ .UseStartup<Startup>()
+ .ConfigureLogging((ctx,logging) => ConfigureLogging(logging))
+ .Build();
+
+ Logger.LogTrace("test");
+ Logger.LogCritical("test");
+ host.RunAsync(cancellationToken).GetAwaiter().GetResult();
+ }
+
+ public class Startup
+ {
+ public Startup(IHostingEnvironment env)
+ {
+ var builder = new ConfigurationBuilder()
+ .SetBasePath(env.ContentRootPath)
+ .AddEnvironmentVariables();
+
+ Configuration = builder.Build();
+ }
+
+ public IConfigurationRoot Configuration { get; }
+
+ // This method gets called by the runtime. Use this method to add services to the container.
+ public void ConfigureServices(IServiceCollection services)
+ {
+ services.AddTransient<Calculator.IAsync, CalculatorAsyncHandler>();
+ services.AddTransient<ITAsyncProcessor, Calculator.AsyncProcessor>();
+ services.AddTransient<THttpServerTransport, THttpServerTransport>();
+ }
+
+ // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
+ public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
+ {
+ app.UseMiddleware<THttpServerTransport>();
+ }
+ }
+ }
+
+ public class CalculatorAsyncHandler : Calculator.IAsync
+ {
+ private readonly Dictionary<int, SharedStruct> _log = new Dictionary<int, SharedStruct>();
+
+ public CalculatorAsyncHandler()
+ {
+ }
+
+ public async Task<SharedStruct> getStructAsync(int key,
+ CancellationToken cancellationToken)
+ {
+ Logger.LogInformation("GetStructAsync({0})", key);
+ return await Task.FromResult(_log[key]);
+ }
+
+ public async Task pingAsync(CancellationToken cancellationToken)
+ {
+ Logger.LogInformation("PingAsync()");
+ await Task.CompletedTask;
+ }
+
+ public async Task<int> addAsync(int num1, int num2, CancellationToken cancellationToken)
+ {
+ Logger.LogInformation($"AddAsync({num1},{num2})");
+ return await Task.FromResult(num1 + num2);
+ }
+
+ public async Task<int> calculateAsync(int logid, Work w, CancellationToken cancellationToken)
+ {
+ Logger.LogInformation($"CalculateAsync({logid}, [{w.Op},{w.Num1},{w.Num2}])");
+
+ var val = 0;
+ switch (w.Op)
+ {
+ case Operation.ADD:
+ val = w.Num1 + w.Num2;
+ break;
+
+ case Operation.SUBTRACT:
+ val = w.Num1 - w.Num2;
+ break;
+
+ case Operation.MULTIPLY:
+ val = w.Num1 * w.Num2;
+ break;
+
+ case Operation.DIVIDE:
+ if (w.Num2 == 0)
+ {
+ var io = new InvalidOperation
+ {
+ WhatOp = (int) w.Op,
+ Why = "Cannot divide by 0"
+ };
+
+ throw io;
+ }
+ val = w.Num1 / w.Num2;
+ break;
+
+ default:
+ {
+ var io = new InvalidOperation
+ {
+ WhatOp = (int) w.Op,
+ Why = "Unknown operation"
+ };
+
+ throw io;
+ }
+ }
+
+ var entry = new SharedStruct
+ {
+ Key = logid,
+ Value = val.ToString()
+ };
+
+ _log[logid] = entry;
+
+ return await Task.FromResult(val);
+ }
+
+ public async Task zipAsync(CancellationToken cancellationToken)
+ {
+ Logger.LogInformation("ZipAsync() with delay 100mc");
+ await Task.Delay(100, CancellationToken.None);
+ }
+ }
+
+ public class SharedServiceAsyncHandler : SharedService.IAsync
+ {
+ public async Task<SharedStruct> getStructAsync(int key, CancellationToken cancellationToken)
+ {
+ Logger.LogInformation("GetStructAsync({0})", key);
+ return await Task.FromResult(new SharedStruct()
+ {
+ Key = key,
+ Value = "GetStructAsync"
+ });
+ }
+ }
+ }
+}
diff --git a/src/jaegertracing/thrift/tutorial/netstd/Server/Properties/AssemblyInfo.cs b/src/jaegertracing/thrift/tutorial/netstd/Server/Properties/AssemblyInfo.cs
new file mode 100644
index 000000000..a0442350b
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/netstd/Server/Properties/AssemblyInfo.cs
@@ -0,0 +1,40 @@
+// 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 System.Reflection;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+
+// General Information about an assembly is controlled through the following
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+
+[assembly: AssemblyConfiguration("")]
+[assembly: AssemblyCompany("The Apache Software Foundation")]
+[assembly: AssemblyProduct("Thrift")]
+[assembly: AssemblyCopyright("The Apache Software Foundation")]
+[assembly: AssemblyTrademark("")]
+
+// Setting ComVisible to false makes the types in this assembly not visible
+// to COM components. If you need to access a type in this assembly from
+// COM, set the ComVisible attribute to true on that type.
+
+[assembly: ComVisible(false)]
+
+// The following GUID is for the ID of the typelib if this project is exposed to COM
+
+[assembly: Guid("e210fc10-5aff-4b04-ac21-58afc7b74b0c")] \ No newline at end of file
diff --git a/src/jaegertracing/thrift/tutorial/netstd/Server/Properties/launchSettings.json b/src/jaegertracing/thrift/tutorial/netstd/Server/Properties/launchSettings.json
new file mode 100644
index 000000000..78076ff7c
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/netstd/Server/Properties/launchSettings.json
@@ -0,0 +1,8 @@
+{
+ "profiles": {
+ "Server": {
+ "commandName": "Project",
+ "commandLineArgs": "-p:multiplexed"
+ }
+ }
+} \ No newline at end of file
diff --git a/src/jaegertracing/thrift/tutorial/netstd/Server/Server.csproj b/src/jaegertracing/thrift/tutorial/netstd/Server/Server.csproj
new file mode 100644
index 000000000..fbc2c0370
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/netstd/Server/Server.csproj
@@ -0,0 +1,44 @@
+<Project Sdk="Microsoft.NET.Sdk.Web">
+ <!--
+ 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.
+ -->
+
+ <PropertyGroup>
+ <TargetFramework>netcoreapp2.0</TargetFramework>
+ <AssemblyName>Server</AssemblyName>
+ <PackageId>Server</PackageId>
+ <OutputType>Exe</OutputType>
+ <GenerateAssemblyConfigurationAttribute>false</GenerateAssemblyConfigurationAttribute>
+ <GenerateAssemblyCompanyAttribute>false</GenerateAssemblyCompanyAttribute>
+ <GenerateAssemblyProductAttribute>false</GenerateAssemblyProductAttribute>
+ <GenerateAssemblyCopyrightAttribute>false</GenerateAssemblyCopyrightAttribute>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <ProjectReference Include="../Interfaces/Interfaces.csproj" />
+ <ProjectReference Include="../../../lib/netstd/Thrift/Thrift.csproj" />
+ </ItemGroup>
+
+ <ItemGroup>
+ <PackageReference Include="Microsoft.AspNetCore" Version="2.2.0" />
+ <PackageReference Include="Microsoft.AspNetCore.Server.IISIntegration" Version="2.2.1" />
+ <PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="2.2.0" />
+ <PackageReference Include="Microsoft.Extensions.Configuration.FileExtensions" Version="2.2.0" />
+ </ItemGroup>
+
+</Project>
diff --git a/src/jaegertracing/thrift/tutorial/netstd/Server/ThriftTest.pfx b/src/jaegertracing/thrift/tutorial/netstd/Server/ThriftTest.pfx
new file mode 100644
index 000000000..f0ded2817
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/netstd/Server/ThriftTest.pfx
Binary files differ
diff --git a/src/jaegertracing/thrift/tutorial/netstd/Tutorial.sln b/src/jaegertracing/thrift/tutorial/netstd/Tutorial.sln
new file mode 100644
index 000000000..84b257902
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/netstd/Tutorial.sln
@@ -0,0 +1,78 @@
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio 15
+VisualStudioVersion = 15.0.26114.2
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Thrift", "..\..\lib\netstd\Thrift\Thrift.csproj", "{C20EA2A9-7660-47DE-9A49-D1EF12FB2895}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Interfaces", "Interfaces\Interfaces.csproj", "{B9E24D84-2712-4158-8F1A-DDE44CD1BB0A}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Client", "Client\Client.csproj", "{E4CA1EF0-B181-4A5D-A02C-DB0750A59CDF}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Server", "Server\Server.csproj", "{E08F5B84-2B4A-4E09-82D1-E0715775CE5E}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Debug|x64 = Debug|x64
+ Debug|x86 = Debug|x86
+ Release|Any CPU = Release|Any CPU
+ Release|x64 = Release|x64
+ Release|x86 = Release|x86
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {C20EA2A9-7660-47DE-9A49-D1EF12FB2895}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C20EA2A9-7660-47DE-9A49-D1EF12FB2895}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C20EA2A9-7660-47DE-9A49-D1EF12FB2895}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {C20EA2A9-7660-47DE-9A49-D1EF12FB2895}.Debug|x64.Build.0 = Debug|Any CPU
+ {C20EA2A9-7660-47DE-9A49-D1EF12FB2895}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {C20EA2A9-7660-47DE-9A49-D1EF12FB2895}.Debug|x86.Build.0 = Debug|Any CPU
+ {C20EA2A9-7660-47DE-9A49-D1EF12FB2895}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C20EA2A9-7660-47DE-9A49-D1EF12FB2895}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C20EA2A9-7660-47DE-9A49-D1EF12FB2895}.Release|x64.ActiveCfg = Release|Any CPU
+ {C20EA2A9-7660-47DE-9A49-D1EF12FB2895}.Release|x64.Build.0 = Release|Any CPU
+ {C20EA2A9-7660-47DE-9A49-D1EF12FB2895}.Release|x86.ActiveCfg = Release|Any CPU
+ {C20EA2A9-7660-47DE-9A49-D1EF12FB2895}.Release|x86.Build.0 = Release|Any CPU
+ {B9E24D84-2712-4158-8F1A-DDE44CD1BB0A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {B9E24D84-2712-4158-8F1A-DDE44CD1BB0A}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {B9E24D84-2712-4158-8F1A-DDE44CD1BB0A}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {B9E24D84-2712-4158-8F1A-DDE44CD1BB0A}.Debug|x64.Build.0 = Debug|Any CPU
+ {B9E24D84-2712-4158-8F1A-DDE44CD1BB0A}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {B9E24D84-2712-4158-8F1A-DDE44CD1BB0A}.Debug|x86.Build.0 = Debug|Any CPU
+ {B9E24D84-2712-4158-8F1A-DDE44CD1BB0A}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {B9E24D84-2712-4158-8F1A-DDE44CD1BB0A}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B9E24D84-2712-4158-8F1A-DDE44CD1BB0A}.Release|x64.ActiveCfg = Release|Any CPU
+ {B9E24D84-2712-4158-8F1A-DDE44CD1BB0A}.Release|x64.Build.0 = Release|Any CPU
+ {B9E24D84-2712-4158-8F1A-DDE44CD1BB0A}.Release|x86.ActiveCfg = Release|Any CPU
+ {B9E24D84-2712-4158-8F1A-DDE44CD1BB0A}.Release|x86.Build.0 = Release|Any CPU
+ {E4CA1EF0-B181-4A5D-A02C-DB0750A59CDF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E4CA1EF0-B181-4A5D-A02C-DB0750A59CDF}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E4CA1EF0-B181-4A5D-A02C-DB0750A59CDF}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {E4CA1EF0-B181-4A5D-A02C-DB0750A59CDF}.Debug|x64.Build.0 = Debug|Any CPU
+ {E4CA1EF0-B181-4A5D-A02C-DB0750A59CDF}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {E4CA1EF0-B181-4A5D-A02C-DB0750A59CDF}.Debug|x86.Build.0 = Debug|Any CPU
+ {E4CA1EF0-B181-4A5D-A02C-DB0750A59CDF}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E4CA1EF0-B181-4A5D-A02C-DB0750A59CDF}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E4CA1EF0-B181-4A5D-A02C-DB0750A59CDF}.Release|x64.ActiveCfg = Release|Any CPU
+ {E4CA1EF0-B181-4A5D-A02C-DB0750A59CDF}.Release|x64.Build.0 = Release|Any CPU
+ {E4CA1EF0-B181-4A5D-A02C-DB0750A59CDF}.Release|x86.ActiveCfg = Release|Any CPU
+ {E4CA1EF0-B181-4A5D-A02C-DB0750A59CDF}.Release|x86.Build.0 = Release|Any CPU
+ {E08F5B84-2B4A-4E09-82D1-E0715775CE5E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {E08F5B84-2B4A-4E09-82D1-E0715775CE5E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {E08F5B84-2B4A-4E09-82D1-E0715775CE5E}.Debug|x64.ActiveCfg = Debug|Any CPU
+ {E08F5B84-2B4A-4E09-82D1-E0715775CE5E}.Debug|x64.Build.0 = Debug|Any CPU
+ {E08F5B84-2B4A-4E09-82D1-E0715775CE5E}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {E08F5B84-2B4A-4E09-82D1-E0715775CE5E}.Debug|x86.Build.0 = Debug|Any CPU
+ {E08F5B84-2B4A-4E09-82D1-E0715775CE5E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {E08F5B84-2B4A-4E09-82D1-E0715775CE5E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {E08F5B84-2B4A-4E09-82D1-E0715775CE5E}.Release|x64.ActiveCfg = Release|Any CPU
+ {E08F5B84-2B4A-4E09-82D1-E0715775CE5E}.Release|x64.Build.0 = Release|Any CPU
+ {E08F5B84-2B4A-4E09-82D1-E0715775CE5E}.Release|x86.ActiveCfg = Release|Any CPU
+ {E08F5B84-2B4A-4E09-82D1-E0715775CE5E}.Release|x86.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {070A5D1D-B29D-4603-999D-693DB444AD0D}
+ EndGlobalSection
+EndGlobal
diff --git a/src/jaegertracing/thrift/tutorial/netstd/build.cmd b/src/jaegertracing/thrift/tutorial/netstd/build.cmd
new file mode 100644
index 000000000..9b84ef276
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/netstd/build.cmd
@@ -0,0 +1,25 @@
+@echo off
+rem /*
+rem * Licensed to the Apache Software Foundation (ASF) under one
+rem * or more contributor license agreements. See the NOTICE file
+rem * distributed with this work for additional information
+rem * regarding copyright ownership. The ASF licenses this file
+rem * to you under the Apache License, Version 2.0 (the
+rem * "License"); you may not use this file except in compliance
+rem * with the License. You may obtain a copy of the License at
+rem *
+rem * http://www.apache.org/licenses/LICENSE-2.0
+rem *
+rem * Unless required by applicable law or agreed to in writing,
+rem * software distributed under the License is distributed on an
+rem * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+rem * KIND, either express or implied. See the License for the
+rem * specific language governing permissions and limitations
+rem * under the License.
+rem */
+setlocal
+
+dotnet --info
+dotnet build
+
+:eof
diff --git a/src/jaegertracing/thrift/tutorial/netstd/build.sh b/src/jaegertracing/thrift/tutorial/netstd/build.sh
new file mode 100644
index 000000000..c97e310f0
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/netstd/build.sh
@@ -0,0 +1,26 @@
+#!/usr/bin/env bash
+
+#
+# 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.
+#
+
+#exit if any command fails
+set -e
+
+dotnet --info
+dotnet build
diff --git a/src/jaegertracing/thrift/tutorial/nodejs/Makefile.am b/src/jaegertracing/thrift/tutorial/nodejs/Makefile.am
new file mode 100644
index 000000000..1516fec2c
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/nodejs/Makefile.am
@@ -0,0 +1,45 @@
+#
+# 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.
+#
+
+gen-nodejs/Calculator.js gen-nodejs/SharedService.js: $(top_srcdir)/tutorial/tutorial.thrift
+ $(THRIFT) --gen js:node -r $<
+
+all-local: gen-nodejs/Calculator.js
+
+tutorialserver: all
+ NODE_PATH="$(top_builddir)/lib/nodejs:$(top_builddir)/lib/nodejs/lib:$(NODEPATH)" $(NODEJS) NodeServer.js
+
+tutorialclient: all
+ NODE_PATH="$(top_builddir)/lib/nodejs:$(top_builddir)/lib/nodejs/lib:$(NODEPATH)" $(NODEJS) NodeClient.js
+
+tutorialserver_promise: all
+ NODE_PATH="$(top_builddir)/lib/nodejs:$(top_builddir)/lib/nodejs/lib:$(NODEPATH)" $(NODEJS) NodeServerPromise.js
+
+tutorialclient_promise: all
+ NODE_PATH="$(top_builddir)/lib/nodejs:$(top_builddir)/lib/nodejs/lib:$(NODEPATH)" $(NODEJS) NodeClientPromise.js
+
+
+clean-local:
+ $(RM) -r gen-*
+
+EXTRA_DIST = \
+ NodeServer.js \
+ NodeClient.js \
+ NodeServerPromise.js \
+ NodeClientPromise.js
diff --git a/src/jaegertracing/thrift/tutorial/nodejs/NodeClient.js b/src/jaegertracing/thrift/tutorial/nodejs/NodeClient.js
new file mode 100644
index 000000000..b4886e826
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/nodejs/NodeClient.js
@@ -0,0 +1,77 @@
+/*
+ * 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.
+ */
+
+var thrift = require('thrift');
+var Calculator = require('./gen-nodejs/Calculator');
+var ttypes = require('./gen-nodejs/tutorial_types');
+const assert = require('assert');
+
+var transport = thrift.TBufferedTransport;
+var protocol = thrift.TBinaryProtocol;
+
+var connection = thrift.createConnection("localhost", 9090, {
+ transport : transport,
+ protocol : protocol
+});
+
+connection.on('error', function(err) {
+ assert(false, err);
+});
+
+// Create a Calculator client with the connection
+var client = thrift.createClient(Calculator, connection);
+
+
+client.ping(function(err, response) {
+ console.log('ping()');
+});
+
+
+client.add(1,1, function(err, response) {
+ console.log("1+1=" + response);
+});
+
+
+work = new ttypes.Work();
+work.op = ttypes.Operation.DIVIDE;
+work.num1 = 1;
+work.num2 = 0;
+
+client.calculate(1, work, function(err, message) {
+ if (err) {
+ console.log("InvalidOperation " + err);
+ } else {
+ console.log('Whoa? You know how to divide by zero?');
+ }
+});
+
+work.op = ttypes.Operation.SUBTRACT;
+work.num1 = 15;
+work.num2 = 10;
+
+client.calculate(1, work, function(err, message) {
+ console.log('15-10=' + message);
+
+ client.getStruct(1, function(err, message){
+ console.log('Check log: ' + message.value);
+
+ //close the connection once we're done
+ connection.end();
+ });
+});
diff --git a/src/jaegertracing/thrift/tutorial/nodejs/NodeClientPromise.js b/src/jaegertracing/thrift/tutorial/nodejs/NodeClientPromise.js
new file mode 100644
index 000000000..2cdc184f9
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/nodejs/NodeClientPromise.js
@@ -0,0 +1,80 @@
+/*
+ * 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.
+ */
+
+var thrift = require('thrift');
+var Calculator = require('./gen-nodejs/Calculator');
+var ttypes = require('./gen-nodejs/tutorial_types');
+const assert = require('assert');
+
+var transport = thrift.TBufferedTransport;
+var protocol = thrift.TBinaryProtocol;
+
+var connection = thrift.createConnection("localhost", 9090, {
+ transport : transport,
+ protocol : protocol
+});
+
+connection.on('error', function(err) {
+ assert(false, err);
+});
+
+// Create a Calculator client with the connection
+var client = thrift.createClient(Calculator, connection);
+
+
+client.ping()
+ .then(function() {
+ console.log('ping()');
+ });
+
+client.add(1,1)
+ .then(function(response) {
+ console.log("1+1=" + response);
+ });
+
+work = new ttypes.Work();
+work.op = ttypes.Operation.DIVIDE;
+work.num1 = 1;
+work.num2 = 0;
+
+client.calculate(1, work)
+ .then(function(message) {
+ console.log('Whoa? You know how to divide by zero?');
+ })
+ .fail(function(err) {
+ console.log("InvalidOperation " + err);
+ });
+
+
+work.op = ttypes.Operation.SUBTRACT;
+work.num1 = 15;
+work.num2 = 10;
+
+client.calculate(1, work)
+ .then(function(value) {
+ console.log('15-10=' + value);
+ return client.getStruct(1);
+ })
+ .then(function(message) {
+ console.log('Check log: ' + message.value);
+ })
+ .fin(function() {
+ //close the connection once we're done
+ connection.end();
+ });
diff --git a/src/jaegertracing/thrift/tutorial/nodejs/NodeServer.js b/src/jaegertracing/thrift/tutorial/nodejs/NodeServer.js
new file mode 100644
index 000000000..2e198825c
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/nodejs/NodeServer.js
@@ -0,0 +1,84 @@
+/*
+ * 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.
+ */
+
+var thrift = require("thrift");
+var Calculator = require("./gen-nodejs/Calculator");
+var ttypes = require("./gen-nodejs/tutorial_types");
+var SharedStruct = require("./gen-nodejs/shared_types").SharedStruct;
+
+var data = {};
+
+var server = thrift.createServer(Calculator, {
+ ping: function(result) {
+ console.log("ping()");
+ result(null);
+ },
+
+ add: function(n1, n2, result) {
+ console.log("add(", n1, ",", n2, ")");
+ result(null, n1 + n2);
+ },
+
+ calculate: function(logid, work, result) {
+ console.log("calculate(", logid, ",", work, ")");
+
+ var val = 0;
+ if (work.op == ttypes.Operation.ADD) {
+ val = work.num1 + work.num2;
+ } else if (work.op === ttypes.Operation.SUBTRACT) {
+ val = work.num1 - work.num2;
+ } else if (work.op === ttypes.Operation.MULTIPLY) {
+ val = work.num1 * work.num2;
+ } else if (work.op === ttypes.Operation.DIVIDE) {
+ if (work.num2 === 0) {
+ var x = new ttypes.InvalidOperation();
+ x.whatOp = work.op;
+ x.why = 'Cannot divide by 0';
+ result(x);
+ return;
+ }
+ val = work.num1 / work.num2;
+ } else {
+ var x = new ttypes.InvalidOperation();
+ x.whatOp = work.op;
+ x.why = 'Invalid operation';
+ result(x);
+ return;
+ }
+
+ var entry = new SharedStruct();
+ entry.key = logid;
+ entry.value = ""+val;
+ data[logid] = entry;
+
+ result(null, val);
+ },
+
+ getStruct: function(key, result) {
+ console.log("getStruct(", key, ")");
+ result(null, data[key]);
+ },
+
+ zip: function() {
+ console.log("zip()");
+ }
+
+});
+
+server.listen(9090);
diff --git a/src/jaegertracing/thrift/tutorial/nodejs/NodeServerPromise.js b/src/jaegertracing/thrift/tutorial/nodejs/NodeServerPromise.js
new file mode 100644
index 000000000..bff287b18
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/nodejs/NodeServerPromise.js
@@ -0,0 +1,80 @@
+/*
+ * 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.
+ */
+
+var thrift = require("thrift");
+var Calculator = require("./gen-nodejs/Calculator");
+var ttypes = require("./gen-nodejs/tutorial_types");
+var SharedStruct = require("./gen-nodejs/shared_types").SharedStruct;
+
+var data = {};
+
+var server = thrift.createServer(Calculator, {
+ ping: function() {
+ console.log("ping()");
+ },
+
+ add: function(n1, n2) {
+ console.log("add(", n1, ",", n2, ")");
+ return n1 + n2;
+ },
+
+ calculate: function(logid, work) {
+ console.log("calculate(", logid, ",", work, ")");
+
+ var val = 0;
+ if (work.op == ttypes.Operation.ADD) {
+ val = work.num1 + work.num2;
+ } else if (work.op === ttypes.Operation.SUBTRACT) {
+ val = work.num1 - work.num2;
+ } else if (work.op === ttypes.Operation.MULTIPLY) {
+ val = work.num1 * work.num2;
+ } else if (work.op === ttypes.Operation.DIVIDE) {
+ if (work.num2 === 0) {
+ var x = new ttypes.InvalidOperation();
+ x.whatOp = work.op;
+ x.why = 'Cannot divide by 0';
+ throw x;
+ }
+ val = work.num1 / work.num2;
+ } else {
+ var x = new ttypes.InvalidOperation();
+ x.whatOp = work.op;
+ x.why = 'Invalid operation';
+ throw x;
+ }
+
+ var entry = new SharedStruct();
+ entry.key = logid;
+ entry.value = ""+val;
+ data[logid] = entry;
+ return val;
+ },
+
+ getStruct: function(key) {
+ console.log("getStruct(", key, ")");
+ return data[key];
+ },
+
+ zip: function() {
+ console.log("zip()");
+ }
+
+});
+
+server.listen(9090);
diff --git a/src/jaegertracing/thrift/tutorial/ocaml/CalcClient.ml b/src/jaegertracing/thrift/tutorial/ocaml/CalcClient.ml
new file mode 100755
index 000000000..5a8467be2
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/ocaml/CalcClient.ml
@@ -0,0 +1,74 @@
+(*
+ 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.
+*)
+
+open Arg
+open Thrift
+open Tutorial_types
+open Shared_types
+
+exception Die;;
+let sod = function
+ Some v -> v
+ | None -> raise Die;;
+
+type connection = {
+ trans : Transport.t ;
+ proto : Thrift.Protocol.t;
+ calc : Calculator.client ;
+}
+
+let connect ~host port =
+ let tx = new TSocket.t host port in
+ let proto = new TBinaryProtocol.t tx in
+ let calc = new Calculator.client proto proto in
+ tx#opn;
+ { trans = tx ; proto = proto; calc = calc }
+;;
+
+let doclient () =
+ let cli = connect ~host:"127.0.0.1" 9090 in
+ try
+ cli.calc#ping ;
+ Printf.printf "ping()\n" ; flush stdout ;
+ (let sum = cli.calc#add (Int32.of_int 1) (Int32.of_int 1) in
+ Printf.printf "1+1=%ld\n" sum ;
+ flush stdout) ;
+ (let w = new work in
+ w#set_op Operation.DIVIDE ;
+ w#set_num1 (Int32.of_int 1) ;
+ w#set_num2 (Int32.of_int 0) ;
+ try
+ let quotient = cli.calc#calculate (Int32.of_int 1) w in
+ Printf.printf "Whoa? We can divide by zero!\n" ; flush stdout
+ with InvalidOperation io ->
+ Printf.printf "InvalidOperation: %s\n" io#grab_why ; flush stdout) ;
+ (let w = new work in
+ w#set_op Operation.SUBTRACT ;
+ w#set_num1 (Int32.of_int 15) ;
+ w#set_num2 (Int32.of_int 10) ;
+ let diff = cli.calc#calculate (Int32.of_int 1) w in
+ Printf.printf "15-10=%ld\n" diff ; flush stdout) ;
+ (let ss = cli.calc#getStruct (Int32.of_int 1) in
+ Printf.printf "Check log: %s\n" ss#grab_value ; flush stdout) ;
+ cli.trans#close
+ with Transport.E (_,what) ->
+ Printf.printf "ERROR: %s\n" what ; flush stdout
+;;
+
+doclient();;
diff --git a/src/jaegertracing/thrift/tutorial/ocaml/CalcServer.ml b/src/jaegertracing/thrift/tutorial/ocaml/CalcServer.ml
new file mode 100755
index 000000000..b5facb79b
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/ocaml/CalcServer.ml
@@ -0,0 +1,89 @@
+(*
+ 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.
+*)
+
+open Arg
+open Thrift
+open Tutorial_types
+open Shared_types
+
+exception Die;;
+let sod = function
+ Some v -> v
+ | None -> raise Die;;
+
+class calc_handler =
+object (self)
+ inherit Calculator.iface
+ val log = Hashtbl.create 23
+ method ping = Printf.printf "ping()\n" ; flush stdout
+ method add a b =
+ Printf.printf"add(%ld,%ld)\n" (sod a) (sod b); flush stdout ;
+ Int32.add (sod a) (sod b)
+ method calculate logid w =
+ let w = sod w in
+ Printf.printf "calculate(%ld,{%ld,%ld,%ld})\n" (sod logid) (Operation.to_i w#grab_op) w#grab_num1 w#grab_num2; flush stdout ;
+ let rv =
+ match w#grab_op with
+ Operation.ADD ->
+ Int32.add w#grab_num1 w#grab_num2
+ | Operation.SUBTRACT ->
+ Int32.sub w#grab_num1 w#grab_num2
+ | Operation.MULTIPLY ->
+ Int32.mul w#grab_num1 w#grab_num2
+ | Operation.DIVIDE ->
+ if w#grab_num2 = Int32.zero then
+ let io = new invalidOperation in
+ io#set_whatOp (Operation.to_i w#grab_op) ;
+ io#set_why "Cannot divide by 0" ;
+ raise (InvalidOperation io)
+ else
+ Int32.div w#grab_num1 w#grab_num2 in
+
+ let ss = new sharedStruct in
+ ss#set_key (sod logid) ;
+ let buffer = Int32.to_string rv in
+ ss#set_value buffer ;
+ Hashtbl.add log (sod logid) ss ;
+ rv
+
+ method zip =
+ Printf.printf "zip()\n"; flush stdout
+
+ method getStruct logid =
+ Printf.printf "getStruct(%ld)\n" (sod logid) ; flush stdout ;
+ Hashtbl.find log (sod logid)
+
+end
+
+let doserver () =
+ let h = new calc_handler in
+ let proc = new Calculator.processor h in
+ let port = 9090 in
+ let pf = new TBinaryProtocol.factory in
+ let server = new TThreadedServer.t
+ proc
+ (new TServerSocket.t port)
+ (new Transport.factory)
+ pf
+ pf
+ in
+ server#serve
+;;
+
+doserver();;
diff --git a/src/jaegertracing/thrift/tutorial/ocaml/README.md b/src/jaegertracing/thrift/tutorial/ocaml/README.md
new file mode 100644
index 000000000..f68e83525
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/ocaml/README.md
@@ -0,0 +1,15 @@
+
+This is the ocaml tutorial example. It assumes that you've already
+built and installed the thrift ocaml runtime libraries in lib/ocaml.
+
+To compile this, you will need to generate the Thrift sources for
+ocaml in this directory (due to limitations in the OASIS build-tool):
+
+ % thrift -r --gen ocaml ../tutorial.thrift
+ % oasis setup
+ % make
+
+This will produce two executables Calc{Server,Client}.<type> where
+<type> is one of "byte" or "native", depending on your ocaml
+installation. Just run the server in the background, then the client
+(as you would do for the C++ example).
diff --git a/src/jaegertracing/thrift/tutorial/ocaml/_oasis b/src/jaegertracing/thrift/tutorial/ocaml/_oasis
new file mode 100644
index 000000000..4a4f337b3
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/ocaml/_oasis
@@ -0,0 +1,32 @@
+Name: tutorial
+Version: 0.13.0
+OASISFormat: 0.3
+Synopsis: OCaml Tutorial example
+Authors: Apache Thrift Developers <dev@thrift.apache.org>
+License: Apache-2.0
+Homepage: http://thrift.apache.org
+BuildTools: ocamlbuild
+Plugins: META (0.3),
+ DevFiles (0.3)
+
+Library tutorial_thrift
+ Path: gen-ocaml
+ FindlibName: tutorial_thrift
+ buildTools: ocamlbuild
+ BuildDepends: threads,thrift
+ Modules: Calculator,Shared_consts,Tutorial_consts,SharedService,Shared_types,Tutorial_types
+ XMETARequires: threads
+
+Executable CalcClient
+ Path: .
+ MainIs: CalcClient.ml
+ Build$: true
+ CompiledObject: best
+ BuildDepends: thrift, tutorial_thrift, threads
+
+Executable CalcServer
+ Path: .
+ MainIs: CalcServer.ml
+ Build$: true
+ CompiledObject: best
+ BuildDepends: thrift, tutorial_thrift, threads
diff --git a/src/jaegertracing/thrift/tutorial/perl/PerlClient.pl b/src/jaegertracing/thrift/tutorial/perl/PerlClient.pl
new file mode 100644
index 000000000..7c23289ce
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/perl/PerlClient.pl
@@ -0,0 +1,82 @@
+#!/usr/bin/env perl
+
+#
+# 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.
+#
+
+use strict;
+use warnings;
+
+use lib '../../lib/perl/lib';
+use lib '../gen-perl';
+
+use Thrift;
+use Thrift::BinaryProtocol;
+use Thrift::Socket;
+use Thrift::BufferedTransport;
+
+use shared::SharedService;
+use tutorial::Calculator;
+use shared::Types;
+use tutorial::Types;
+
+use Data::Dumper;
+
+my $socket = Thrift::Socket->new('localhost',9090);
+my $transport = Thrift::BufferedTransport->new($socket,1024,1024);
+my $protocol = Thrift::BinaryProtocol->new($transport);
+my $client = tutorial::CalculatorClient->new($protocol);
+
+
+eval{
+ $transport->open();
+
+ $client->ping();
+ print "ping()\n";
+
+
+ my $sum = $client->add(1,1);
+ print "1+1=$sum\n";
+
+ my $work = tutorial::Work->new();
+
+ $work->op(tutorial::Operation::DIVIDE);
+ $work->num1(1);
+ $work->num2(0);
+
+ eval {
+ $client->calculate(1, $work);
+ print "Whoa! We can divide by zero?\n";
+ }; if($@) {
+ warn 'InvalidOperation: '.Dumper($@);
+ }
+
+ $work->op(tutorial::Operation::SUBTRACT);
+ $work->num1(15);
+ $work->num2(10);
+ my $diff = $client->calculate(1, $work);
+ print "15-10=$diff\n";
+
+ my $log = $client->getStruct(1);
+ print "Log: $log->{value}\n";
+
+ $transport->close();
+
+}; if($@){
+ warn(Dumper($@));
+}
diff --git a/src/jaegertracing/thrift/tutorial/perl/PerlServer.pl b/src/jaegertracing/thrift/tutorial/perl/PerlServer.pl
new file mode 100644
index 000000000..ee5d93674
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/perl/PerlServer.pl
@@ -0,0 +1,125 @@
+#!/usr/bin/env perl
+
+#
+# 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.
+#
+
+use strict;
+use lib '../gen-perl';
+use Thrift::Socket;
+use Thrift::Server;
+use Thrift::ServerSocket;
+use tutorial::Calculator;
+
+package CalculatorHandler;
+use base qw(tutorial::CalculatorIf);
+
+sub new {
+ my $classname = shift;
+ my $self = {};
+
+ return bless($self,$classname);
+}
+
+
+sub ping
+{
+ print "ping()\n";
+}
+
+sub add
+{
+ my($self, $n1, $n2) = @_;
+ printf("add(%d,%d)\n", $n1, $n2);
+ return $n1 + $n2;
+}
+
+sub calculate
+{
+ my($self, $logid, $work) = @_;
+ my $op = $work->{op};
+ my $num1 = $work->{num1};
+ my $num2 = $work->{num2};
+ printf("calculate(%d, %d %d %d)\n", $logid, $num1, $num2, $op);
+
+ my $val;
+
+ if ($op == tutorial::Operation::ADD) {
+ $val = $num1 + $num2;
+ } elsif ($op == tutorial::Operation::SUBTRACT) {
+ $val = $num1 - $num2;
+ } elsif ($op == tutorial::Operation::MULTIPLY) {
+ $val = $num1 * $num2;
+ } elsif ($op == tutorial::Operation::DIVIDE) {
+ if ($num2 == 0)
+ {
+ my $x = tutorial::InvalidOperation->new();
+ $x->whatOp($op);
+ $x->why('Cannot divide by 0');
+ die $x;
+ }
+ $val = $num1 / $num2;
+ } else {
+ my $x = tutorial::InvalidOperation->new();
+ $x->whatOp($op);
+ $x->why('Invalid operation');
+ die $x;
+ }
+
+ my $log = shared::SharedStruct->new();
+ $log->key($logid);
+ $log->value(int($val));
+ $self->{log}->{$logid} = $log;
+
+ return $val;
+}
+
+sub getStruct
+{
+ my($self, $key) = @_;
+ printf("getStruct(%d)\n", $key);
+ return $self->{log}->{$key};
+}
+
+sub zip
+{
+ my($self) = @_;
+ print "zip()\n";
+}
+
+
+
+eval {
+ my $handler = CalculatorHandler->new();
+ my $processor = tutorial::CalculatorProcessor->new($handler);
+ my $serversocket = Thrift::ServerSocket->new(9090);
+ my $forkingserver = Thrift::ForkingServer->new($processor, $serversocket);
+ print "Starting the server...\n";
+ $forkingserver->serve();
+ print "done.\n";
+}; if ($@) {
+ if ($@ =~ m/TException/ and exists $@->{message}) {
+ my $message = $@->{message};
+ my $code = $@->{code};
+ my $out = $code . ':' . $message;
+ die $out;
+ } else {
+ die $@;
+ }
+}
+
diff --git a/src/jaegertracing/thrift/tutorial/php/PhpClient.php b/src/jaegertracing/thrift/tutorial/php/PhpClient.php
new file mode 100755
index 000000000..eb2c2e5ee
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/php/PhpClient.php
@@ -0,0 +1,91 @@
+#!/usr/bin/env php
+<?php
+
+namespace tutorial\php;
+
+error_reporting(E_ALL);
+
+require_once __DIR__.'/../../vendor/autoload.php';
+
+use Thrift\ClassLoader\ThriftClassLoader;
+
+$GEN_DIR = realpath(dirname(__FILE__).'/..').'/gen-php';
+
+$loader = new ThriftClassLoader();
+$loader->registerNamespace('Thrift', __DIR__ . '/../../lib/php/lib');
+$loader->registerNamespace('shared', $GEN_DIR);
+$loader->registerNamespace('tutorial', $GEN_DIR);
+$loader->register();
+
+/*
+ * 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.
+ */
+
+use Thrift\Protocol\TBinaryProtocol;
+use Thrift\Transport\TSocket;
+use Thrift\Transport\THttpClient;
+use Thrift\Transport\TBufferedTransport;
+use Thrift\Exception\TException;
+
+try {
+ if (array_search('--http', $argv)) {
+ $socket = new THttpClient('localhost', 8080, '/php/PhpServer.php');
+ } else {
+ $socket = new TSocket('localhost', 9090);
+ }
+ $transport = new TBufferedTransport($socket, 1024, 1024);
+ $protocol = new TBinaryProtocol($transport);
+ $client = new \tutorial\CalculatorClient($protocol);
+
+ $transport->open();
+
+ $client->ping();
+ print "ping()\n";
+
+ $sum = $client->add(1,1);
+ print "1+1=$sum\n";
+
+ $work = new \tutorial\Work();
+
+ $work->op = \tutorial\Operation::DIVIDE;
+ $work->num1 = 1;
+ $work->num2 = 0;
+
+ try {
+ $client->calculate(1, $work);
+ print "Whoa! We can divide by zero?\n";
+ } catch (\tutorial\InvalidOperation $io) {
+ print "InvalidOperation: $io->why\n";
+ }
+
+ $work->op = \tutorial\Operation::SUBTRACT;
+ $work->num1 = 15;
+ $work->num2 = 10;
+ $diff = $client->calculate(1, $work);
+ print "15-10=$diff\n";
+
+ $log = $client->getStruct(1);
+ print "Log: $log->value\n";
+
+ $transport->close();
+
+} catch (TException $tx) {
+ print 'TException: '.$tx->getMessage()."\n";
+}
+
+?>
diff --git a/src/jaegertracing/thrift/tutorial/php/PhpServer.php b/src/jaegertracing/thrift/tutorial/php/PhpServer.php
new file mode 100755
index 000000000..749da3a0b
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/php/PhpServer.php
@@ -0,0 +1,130 @@
+#!/usr/bin/env php
+<?php
+
+namespace tutorial\php;
+
+error_reporting(E_ALL);
+
+require_once __DIR__.'/../../vendor/autoload.php';
+
+use Thrift\ClassLoader\ThriftClassLoader;
+
+$GEN_DIR = realpath(dirname(__FILE__).'/..').'/gen-php';
+
+$loader = new ThriftClassLoader();
+$loader->registerNamespace('Thrift', __DIR__ . '/../../lib/php/lib');
+$loader->registerNamespace('shared', $GEN_DIR);
+$loader->registerNamespace('tutorial', $GEN_DIR);
+$loader->register();
+
+/*
+ * 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 is not a stand-alone server. It should be run as a normal
+ * php web script (like through Apache's mod_php) or as a cgi script
+ * (like with the included runserver.py). You can connect to it with
+ * THttpClient in any language that supports it. The PHP tutorial client
+ * will work if you pass it the argument "--http".
+ */
+
+if (php_sapi_name() == 'cli') {
+ ini_set("display_errors", "stderr");
+}
+
+use Thrift\Protocol\TBinaryProtocol;
+use Thrift\Transport\TPhpStream;
+use Thrift\Transport\TBufferedTransport;
+
+class CalculatorHandler implements \tutorial\CalculatorIf {
+ protected $log = array();
+
+ public function ping() {
+ error_log("ping()");
+ }
+
+ public function add($num1, $num2) {
+ error_log("add({$num1}, {$num2})");
+ return $num1 + $num2;
+ }
+
+ public function calculate($logid, \tutorial\Work $w) {
+ error_log("calculate({$logid}, {{$w->op}, {$w->num1}, {$w->num2}})");
+ switch ($w->op) {
+ case \tutorial\Operation::ADD:
+ $val = $w->num1 + $w->num2;
+ break;
+ case \tutorial\Operation::SUBTRACT:
+ $val = $w->num1 - $w->num2;
+ break;
+ case \tutorial\Operation::MULTIPLY:
+ $val = $w->num1 * $w->num2;
+ break;
+ case \tutorial\Operation::DIVIDE:
+ if ($w->num2 == 0) {
+ $io = new \tutorial\InvalidOperation();
+ $io->whatOp = $w->op;
+ $io->why = "Cannot divide by 0";
+ throw $io;
+ }
+ $val = $w->num1 / $w->num2;
+ break;
+ default:
+ $io = new \tutorial\InvalidOperation();
+ $io->whatOp = $w->op;
+ $io->why = "Invalid Operation";
+ throw $io;
+ }
+
+ $log = new \shared\SharedStruct();
+ $log->key = $logid;
+ $log->value = (string)$val;
+ $this->log[$logid] = $log;
+
+ return $val;
+ }
+
+ public function getStruct($key) {
+ error_log("getStruct({$key})");
+ // This actually doesn't work because the PHP interpreter is
+ // restarted for every request.
+ //return $this->log[$key];
+ return new \shared\SharedStruct(array("key" => $key, "value" => "PHP is stateless!"));
+ }
+
+ public function zip() {
+ error_log("zip()");
+ }
+
+};
+
+header('Content-Type', 'application/x-thrift');
+if (php_sapi_name() == 'cli') {
+ echo "\r\n";
+}
+
+$handler = new CalculatorHandler();
+$processor = new \tutorial\CalculatorProcessor($handler);
+
+$transport = new TBufferedTransport(new TPhpStream(TPhpStream::MODE_R | TPhpStream::MODE_W));
+$protocol = new TBinaryProtocol($transport, true, true);
+
+$transport->open();
+$processor->process($protocol, $protocol);
+$transport->close();
diff --git a/src/jaegertracing/thrift/tutorial/php/runserver.py b/src/jaegertracing/thrift/tutorial/php/runserver.py
new file mode 100755
index 000000000..8cc30fbe5
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/php/runserver.py
@@ -0,0 +1,34 @@
+#!/usr/bin/env python
+
+#
+# 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.
+#
+
+import os
+import BaseHTTPServer
+import CGIHTTPServer
+
+# chdir(2) into the tutorial directory.
+os.chdir(os.path.dirname(os.path.dirname(os.path.realpath(__file__))))
+
+
+class Handler(CGIHTTPServer.CGIHTTPRequestHandler):
+ cgi_directories = ['/php']
+
+
+BaseHTTPServer.HTTPServer(('', 8080), Handler).serve_forever()
diff --git a/src/jaegertracing/thrift/tutorial/py.tornado/Makefile.am b/src/jaegertracing/thrift/tutorial/py.tornado/Makefile.am
new file mode 100755
index 000000000..4b73c1e72
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/py.tornado/Makefile.am
@@ -0,0 +1,36 @@
+#
+# 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.
+#
+
+gen-py.tornado/tutorial/Calculator.py gen-py.tornado/shared/SharedService.py: $(top_srcdir)/tutorial/tutorial.thrift
+ $(THRIFT) --gen py:tornado -r $<
+
+all-local: gen-py.tornado/tutorial/Calculator.py
+
+tutorialserver: all
+ ${PYTHON} PythonServer.py
+
+tutorialclient: all
+ ${PYTHON} PythonClient.py
+
+clean-local:
+ $(RM) -r gen-*
+
+EXTRA_DIST = \
+ PythonServer.py \
+ PythonClient.py
diff --git a/src/jaegertracing/thrift/tutorial/py.tornado/PythonClient.py b/src/jaegertracing/thrift/tutorial/py.tornado/PythonClient.py
new file mode 100755
index 000000000..426146fc9
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/py.tornado/PythonClient.py
@@ -0,0 +1,108 @@
+#!/usr/bin/env python
+
+#
+# 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.
+#
+
+import glob
+import logging
+import sys
+
+sys.path.append('gen-py.tornado')
+sys.path.insert(0, glob.glob('../../lib/py/build/lib*')[0])
+
+from tutorial import Calculator
+from tutorial.ttypes import Operation, Work, InvalidOperation
+
+from thrift import TTornado
+from thrift.transport import TTransport
+from thrift.protocol import TBinaryProtocol
+
+from tornado import gen
+from tornado import ioloop
+
+
+@gen.coroutine
+def communicate():
+ # create client
+ transport = TTornado.TTornadoStreamTransport('localhost', 9090)
+ # open the transport, bail on error
+ try:
+ yield transport.open()
+ print('Transport is opened')
+ except TTransport.TTransportException as ex:
+ logging.error(ex)
+ raise gen.Return()
+
+ pfactory = TBinaryProtocol.TBinaryProtocolFactory()
+ client = Calculator.Client(transport, pfactory)
+
+ # ping
+ yield client.ping()
+ print("ping()")
+
+ # add
+ sum_ = yield client.add(1, 1)
+ print("1 + 1 = {0}".format(sum_))
+
+ # make a oneway call without a callback (schedule the write and continue
+ # without blocking)
+ client.zip()
+ print("zip() without callback")
+
+ # make a oneway call with a callback (we'll wait for the stream write to
+ # complete before continuing)
+ client.zip()
+ print("zip() with callback")
+
+ # calculate 1/0
+ work = Work()
+ work.op = Operation.DIVIDE
+ work.num1 = 1
+ work.num2 = 0
+
+ try:
+ quotient = yield client.calculate(1, work)
+ print("Whoa? You know how to divide by zero ? -> {0}".format(quotient))
+ except InvalidOperation as io:
+ print("InvalidOperation: {0}".format(io))
+
+ # calculate 15-10
+ work.op = Operation.SUBTRACT
+ work.num1 = 15
+ work.num2 = 10
+
+ diff = yield client.calculate(1, work)
+ print("15 - 10 = {0}".format(diff))
+
+ # getStruct
+ log = yield client.getStruct(1)
+ print("Check log: {0}".format(log.value))
+
+ # close the transport
+ client._transport.close()
+ raise gen.Return()
+
+
+def main():
+ # create an ioloop, do the above, then stop
+ ioloop.IOLoop.current().run_sync(communicate)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/src/jaegertracing/thrift/tutorial/py.tornado/PythonServer.py b/src/jaegertracing/thrift/tutorial/py.tornado/PythonServer.py
new file mode 100755
index 000000000..e0229a26e
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/py.tornado/PythonServer.py
@@ -0,0 +1,100 @@
+#!/usr/bin/env python
+
+#
+# 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.
+#
+
+import glob
+import sys
+
+sys.path.append('gen-py.tornado')
+sys.path.insert(0, glob.glob('../../lib/py/build/lib*')[0])
+
+from tutorial import Calculator
+from tutorial.ttypes import Operation, InvalidOperation
+
+from shared.ttypes import SharedStruct
+
+from thrift import TTornado
+from thrift.protocol import TBinaryProtocol
+
+from tornado import ioloop
+
+
+class CalculatorHandler(object):
+ def __init__(self):
+ self.log = {}
+
+ def ping(self):
+ print("ping()")
+
+ def add(self, n1, n2):
+ print("add({}, {})".format(n1, n2))
+ return n1 + n2
+
+ def calculate(self, logid, work):
+ print("calculate({}, {})".format(logid, work))
+
+ if work.op == Operation.ADD:
+ val = work.num1 + work.num2
+ elif work.op == Operation.SUBTRACT:
+ val = work.num1 - work.num2
+ elif work.op == Operation.MULTIPLY:
+ val = work.num1 * work.num2
+ elif work.op == Operation.DIVIDE:
+ if work.num2 == 0:
+ x = InvalidOperation()
+ x.whatOp = work.op
+ x.why = "Cannot divide by 0"
+ raise x
+ val = work.num1 / work.num2
+ else:
+ x = InvalidOperation()
+ x.whatOp = work.op
+ x.why = "Invalid operation"
+ raise x
+
+ log = SharedStruct()
+ log.key = logid
+ log.value = '%d' % (val)
+ self.log[logid] = log
+ return val
+
+ def getStruct(self, key):
+ print("getStruct({})".format(key))
+ return self.log[key]
+
+ def zip(self):
+ print("zip()")
+
+
+def main():
+ handler = CalculatorHandler()
+ processor = Calculator.Processor(handler)
+ pfactory = TBinaryProtocol.TBinaryProtocolFactory()
+ server = TTornado.TTornadoServer(processor, pfactory)
+
+ print("Starting the server...")
+ server.bind(9090)
+ server.start(1)
+ ioloop.IOLoop.instance().start()
+ print("done.")
+
+
+if __name__ == "__main__":
+ main()
diff --git a/src/jaegertracing/thrift/tutorial/py.twisted/Makefile.am b/src/jaegertracing/thrift/tutorial/py.twisted/Makefile.am
new file mode 100755
index 000000000..50cd3429d
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/py.twisted/Makefile.am
@@ -0,0 +1,37 @@
+#
+# 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.
+#
+
+gen-py/tutorial/Calculator.py gen-py/shared/SharedService.py: $(top_srcdir)/tutorial/tutorial.thrift
+ $(THRIFT) --gen py:twisted -r $<
+
+all-local: gen-py/tutorial/Calculator.py
+
+tutorialserver: all
+ ${PYTHON} PythonServer.py
+
+tutorialclient: all
+ ${PYTHON} PythonClient.py
+
+clean-local:
+ $(RM) -r gen-*
+
+EXTRA_DIST = \
+ PythonClient.py \
+ PythonServer.py \
+ PythonServer.tac
diff --git a/src/jaegertracing/thrift/tutorial/py.twisted/PythonClient.py b/src/jaegertracing/thrift/tutorial/py.twisted/PythonClient.py
new file mode 100755
index 000000000..2976495e3
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/py.twisted/PythonClient.py
@@ -0,0 +1,80 @@
+#!/usr/bin/env python
+
+#
+# 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.
+#
+
+import glob
+import sys
+sys.path.append('gen-py.twisted')
+sys.path.insert(0, glob.glob('../../lib/py/build/lib*')[0])
+
+from tutorial import Calculator
+from tutorial.ttypes import InvalidOperation, Operation, Work
+
+from twisted.internet.defer import inlineCallbacks
+from twisted.internet import reactor
+from twisted.internet.protocol import ClientCreator
+
+from thrift.transport import TTwisted
+from thrift.protocol import TBinaryProtocol
+
+
+@inlineCallbacks
+def main(client):
+ yield client.ping()
+ print('ping()')
+
+ sum = yield client.add(1, 1)
+ print(('1+1=%d' % (sum)))
+
+ work = Work()
+
+ work.op = Operation.DIVIDE
+ work.num1 = 1
+ work.num2 = 0
+
+ try:
+ quotient = yield client.calculate(1, work)
+ print('Whoa? You know how to divide by zero?')
+ print('FYI the answer is %d' % quotient)
+ except InvalidOperation as e:
+ print(('InvalidOperation: %r' % e))
+
+ work.op = Operation.SUBTRACT
+ work.num1 = 15
+ work.num2 = 10
+
+ diff = yield client.calculate(1, work)
+ print(('15-10=%d' % (diff)))
+
+ log = yield client.getStruct(1)
+ print(('Check log: %s' % (log.value)))
+ reactor.stop()
+
+
+if __name__ == '__main__':
+ d = ClientCreator(reactor,
+ TTwisted.ThriftClientProtocol,
+ Calculator.Client,
+ TBinaryProtocol.TBinaryProtocolFactory(),
+ ).connectTCP("127.0.0.1", 9090)
+ d.addCallback(lambda conn: conn.client)
+ d.addCallback(main)
+
+ reactor.run()
diff --git a/src/jaegertracing/thrift/tutorial/py.twisted/PythonServer.py b/src/jaegertracing/thrift/tutorial/py.twisted/PythonServer.py
new file mode 100755
index 000000000..034e4a312
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/py.twisted/PythonServer.py
@@ -0,0 +1,97 @@
+#!/usr/bin/env python
+
+#
+# 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.
+#
+
+import glob
+import sys
+sys.path.append('gen-py.twisted')
+sys.path.insert(0, glob.glob('../../lib/py/build/lib*')[0])
+
+from tutorial import Calculator
+from tutorial.ttypes import InvalidOperation, Operation
+
+from shared.ttypes import SharedStruct
+
+from zope.interface import implements
+from twisted.internet import reactor
+
+from thrift.transport import TTwisted
+from thrift.protocol import TBinaryProtocol
+
+
+class CalculatorHandler:
+ implements(Calculator.Iface)
+
+ def __init__(self):
+ self.log = {}
+
+ def ping(self):
+ print('ping()')
+
+ def add(self, n1, n2):
+ print('add(%d,%d)' % (n1, n2))
+ return n1 + n2
+
+ def calculate(self, logid, work):
+ print('calculate(%d, %r)' % (logid, work))
+
+ if work.op == Operation.ADD:
+ val = work.num1 + work.num2
+ elif work.op == Operation.SUBTRACT:
+ val = work.num1 - work.num2
+ elif work.op == Operation.MULTIPLY:
+ val = work.num1 * work.num2
+ elif work.op == Operation.DIVIDE:
+ if work.num2 == 0:
+ x = InvalidOperation()
+ x.whatOp = work.op
+ x.why = 'Cannot divide by 0'
+ raise x
+ val = work.num1 / work.num2
+ else:
+ x = InvalidOperation()
+ x.whatOp = work.op
+ x.why = 'Invalid operation'
+ raise x
+
+ log = SharedStruct()
+ log.key = logid
+ log.value = '%d' % (val)
+ self.log[logid] = log
+
+ return val
+
+ def getStruct(self, key):
+ print('getStruct(%d)' % (key))
+ return self.log[key]
+
+ def zip(self):
+ print('zip()')
+
+
+if __name__ == '__main__':
+ handler = CalculatorHandler()
+ processor = Calculator.Processor(handler)
+ pfactory = TBinaryProtocol.TBinaryProtocolFactory()
+ server = reactor.listenTCP(
+ 9090,
+ TTwisted.ThriftServerFactory(processor, pfactory),
+ interface="127.0.0.1")
+ reactor.run()
diff --git a/src/jaegertracing/thrift/tutorial/py.twisted/PythonServer.tac b/src/jaegertracing/thrift/tutorial/py.twisted/PythonServer.tac
new file mode 100755
index 000000000..0479636de
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/py.twisted/PythonServer.tac
@@ -0,0 +1,53 @@
+#!/usr/bin/env python
+
+#
+# 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.
+#
+
+from twisted.application import internet, service
+from thrift.transport import TTwisted
+
+import glob
+import sys
+sys.path.append('gen-py.twisted')
+sys.path.insert(0, glob.glob('../../lib/py/build/lib*')[0])
+from tutorial import Calculator
+from PythonServer import CalculatorHandler
+from thrift.protocol import TBinaryProtocol
+
+
+def make_application():
+ application = service.Application('CalcServer')
+
+ handler = CalculatorHandler()
+ processor = Calculator.Processor(handler)
+
+ serverFactory = TTwisted.ThriftServerFactory(
+ processor,
+ TBinaryProtocol.TBinaryProtocolFactory())
+
+ calcService = internet.TCPServer(9090, serverFactory)
+
+ multiService = service.MultiService()
+ calcService.setServiceParent(multiService)
+ multiService.setServiceParent(application)
+
+ return application
+
+if __name__ == '__main__':
+ application = make_application()
diff --git a/src/jaegertracing/thrift/tutorial/py/Makefile.am b/src/jaegertracing/thrift/tutorial/py/Makefile.am
new file mode 100755
index 000000000..7db816d3b
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/py/Makefile.am
@@ -0,0 +1,37 @@
+#
+# 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.
+#
+
+gen-py/tutorial/Calculator.py gen-py/shared/SharedService.py: $(top_srcdir)/tutorial/tutorial.thrift
+ $(THRIFT) --gen py -r $<
+
+all-local: gen-py/tutorial/Calculator.py
+
+tutorialserver: all
+ ${PYTHON} PythonServer.py
+
+tutorialclient: all
+ ${PYTHON} PythonClient.py
+
+clean-local:
+ $(RM) -r gen-*
+
+EXTRA_DIST = \
+ setup.cfg \
+ PythonServer.py \
+ PythonClient.py
diff --git a/src/jaegertracing/thrift/tutorial/py/PythonClient.py b/src/jaegertracing/thrift/tutorial/py/PythonClient.py
new file mode 100755
index 000000000..a6c196641
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/py/PythonClient.py
@@ -0,0 +1,89 @@
+#!/usr/bin/env python
+
+#
+# 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.
+#
+
+import sys
+import glob
+sys.path.append('gen-py')
+sys.path.insert(0, glob.glob('../../lib/py/build/lib*')[0])
+
+from tutorial import Calculator
+from tutorial.ttypes import InvalidOperation, Operation, Work
+
+from thrift import Thrift
+from thrift.transport import TSocket
+from thrift.transport import TTransport
+from thrift.protocol import TBinaryProtocol
+
+
+def main():
+ # Make socket
+ transport = TSocket.TSocket('localhost', 9090)
+
+ # Buffering is critical. Raw sockets are very slow
+ transport = TTransport.TBufferedTransport(transport)
+
+ # Wrap in a protocol
+ protocol = TBinaryProtocol.TBinaryProtocol(transport)
+
+ # Create a client to use the protocol encoder
+ client = Calculator.Client(protocol)
+
+ # Connect!
+ transport.open()
+
+ client.ping()
+ print('ping()')
+
+ sum_ = client.add(1, 1)
+ print('1+1=%d' % sum_)
+
+ work = Work()
+
+ work.op = Operation.DIVIDE
+ work.num1 = 1
+ work.num2 = 0
+
+ try:
+ quotient = client.calculate(1, work)
+ print('Whoa? You know how to divide by zero?')
+ print('FYI the answer is %d' % quotient)
+ except InvalidOperation as e:
+ print('InvalidOperation: %r' % e)
+
+ work.op = Operation.SUBTRACT
+ work.num1 = 15
+ work.num2 = 10
+
+ diff = client.calculate(1, work)
+ print('15-10=%d' % diff)
+
+ log = client.getStruct(1)
+ print('Check log: %s' % log.value)
+
+ # Close!
+ transport.close()
+
+
+if __name__ == '__main__':
+ try:
+ main()
+ except Thrift.TException as tx:
+ print('%s' % tx.message)
diff --git a/src/jaegertracing/thrift/tutorial/py/PythonServer.py b/src/jaegertracing/thrift/tutorial/py/PythonServer.py
new file mode 100755
index 000000000..e6421ef08
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/py/PythonServer.py
@@ -0,0 +1,103 @@
+#!/usr/bin/env python
+
+#
+# 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.
+#
+
+import glob
+import sys
+sys.path.append('gen-py')
+sys.path.insert(0, glob.glob('../../lib/py/build/lib*')[0])
+
+from tutorial import Calculator
+from tutorial.ttypes import InvalidOperation, Operation
+
+from shared.ttypes import SharedStruct
+
+from thrift.transport import TSocket
+from thrift.transport import TTransport
+from thrift.protocol import TBinaryProtocol
+from thrift.server import TServer
+
+
+class CalculatorHandler:
+ def __init__(self):
+ self.log = {}
+
+ def ping(self):
+ print('ping()')
+
+ def add(self, n1, n2):
+ print('add(%d,%d)' % (n1, n2))
+ return n1 + n2
+
+ def calculate(self, logid, work):
+ print('calculate(%d, %r)' % (logid, work))
+
+ if work.op == Operation.ADD:
+ val = work.num1 + work.num2
+ elif work.op == Operation.SUBTRACT:
+ val = work.num1 - work.num2
+ elif work.op == Operation.MULTIPLY:
+ val = work.num1 * work.num2
+ elif work.op == Operation.DIVIDE:
+ if work.num2 == 0:
+ x = InvalidOperation()
+ x.whatOp = work.op
+ x.why = 'Cannot divide by 0'
+ raise x
+ val = work.num1 / work.num2
+ else:
+ x = InvalidOperation()
+ x.whatOp = work.op
+ x.why = 'Invalid operation'
+ raise x
+
+ log = SharedStruct()
+ log.key = logid
+ log.value = '%d' % (val)
+ self.log[logid] = log
+
+ return val
+
+ def getStruct(self, key):
+ print('getStruct(%d)' % (key))
+ return self.log[key]
+
+ def zip(self):
+ print('zip()')
+
+
+if __name__ == '__main__':
+ handler = CalculatorHandler()
+ processor = Calculator.Processor(handler)
+ transport = TSocket.TServerSocket(host='127.0.0.1', port=9090)
+ tfactory = TTransport.TBufferedTransportFactory()
+ pfactory = TBinaryProtocol.TBinaryProtocolFactory()
+
+ server = TServer.TSimpleServer(processor, transport, tfactory, pfactory)
+
+ # You could do one of these for a multithreaded server
+ # server = TServer.TThreadedServer(
+ # processor, transport, tfactory, pfactory)
+ # server = TServer.TThreadPoolServer(
+ # processor, transport, tfactory, pfactory)
+
+ print('Starting the server...')
+ server.serve()
+ print('done.')
diff --git a/src/jaegertracing/thrift/tutorial/py/setup.cfg b/src/jaegertracing/thrift/tutorial/py/setup.cfg
new file mode 100644
index 000000000..2a7120a29
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/py/setup.cfg
@@ -0,0 +1,2 @@
+[flake8]
+ignore = E402
diff --git a/src/jaegertracing/thrift/tutorial/rb/Makefile.am b/src/jaegertracing/thrift/tutorial/rb/Makefile.am
new file mode 100755
index 000000000..885cd9231
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/rb/Makefile.am
@@ -0,0 +1,36 @@
+#
+# 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.
+#
+
+gen-rb/calculator.rb gen-rb/shared_service.rb: $(top_srcdir)/tutorial/tutorial.thrift
+ $(THRIFT) --gen rb -r $<
+
+all-local: gen-rb/calculator.rb
+
+tutorialserver: all
+ ${RUBY} RubyServer.rb
+
+tutorialclient: all
+ ${RUBY} RubyClient.rb
+
+clean-local:
+ $(RM) -r gen-*
+
+EXTRA_DIST = \
+ RubyServer.rb \
+ RubyClient.rb
diff --git a/src/jaegertracing/thrift/tutorial/rb/RubyClient.rb b/src/jaegertracing/thrift/tutorial/rb/RubyClient.rb
new file mode 100755
index 000000000..9a5aa432f
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/rb/RubyClient.rb
@@ -0,0 +1,75 @@
+#!/usr/bin/env ruby
+
+#
+# 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.
+#
+
+$:.push('gen-rb')
+$:.unshift '../../lib/rb/lib'
+
+require 'thrift'
+
+require 'calculator'
+
+begin
+ port = ARGV[0] || 9090
+
+ transport = Thrift::BufferedTransport.new(Thrift::Socket.new('localhost', port))
+ protocol = Thrift::BinaryProtocol.new(transport)
+ client = Calculator::Client.new(protocol)
+
+ transport.open()
+
+ client.ping()
+ print "ping()\n"
+
+ sum = client.add(1,1)
+ print "1+1=", sum, "\n"
+
+ sum = client.add(1,4)
+ print "1+4=", sum, "\n"
+
+ work = Work.new()
+
+ work.op = Operation::SUBTRACT
+ work.num1 = 15
+ work.num2 = 10
+ diff = client.calculate(1, work)
+ print "15-10=", diff, "\n"
+
+ log = client.getStruct(1)
+ print "Log: ", log.value, "\n"
+
+ begin
+ work.op = Operation::DIVIDE
+ work.num1 = 1
+ work.num2 = 0
+ quot = client.calculate(1, work)
+ puts "Whoa, we can divide by 0 now?"
+ rescue InvalidOperation => io
+ print "InvalidOperation: ", io.why, "\n"
+ end
+
+ client.zip()
+ print "zip\n"
+
+ transport.close()
+
+rescue Thrift::Exception => tx
+ print 'Thrift::Exception: ', tx.message, "\n"
+end
diff --git a/src/jaegertracing/thrift/tutorial/rb/RubyServer.rb b/src/jaegertracing/thrift/tutorial/rb/RubyServer.rb
new file mode 100755
index 000000000..1d707d740
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/rb/RubyServer.rb
@@ -0,0 +1,95 @@
+#!/usr/bin/env ruby
+
+#
+# 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.
+#
+
+$:.push('gen-rb')
+$:.unshift '../../lib/rb/lib'
+
+require 'thrift'
+
+require 'calculator'
+require 'shared_types'
+
+class CalculatorHandler
+ def initialize()
+ @log = {}
+ end
+
+ def ping()
+ puts "ping()"
+ end
+
+ def add(n1, n2)
+ print "add(", n1, ",", n2, ")\n"
+ return n1 + n2
+ end
+
+ def calculate(logid, work)
+ print "calculate(", logid, ", {", work.op, ",", work.num1, ",", work.num2,"})\n"
+ if work.op == Operation::ADD
+ val = work.num1 + work.num2
+ elsif work.op == Operation::SUBTRACT
+ val = work.num1 - work.num2
+ elsif work.op == Operation::MULTIPLY
+ val = work.num1 * work.num2
+ elsif work.op == Operation::DIVIDE
+ if work.num2 == 0
+ x = InvalidOperation.new()
+ x.whatOp = work.op
+ x.why = "Cannot divide by 0"
+ raise x
+ end
+ val = work.num1 / work.num2
+ else
+ x = InvalidOperation.new()
+ x.whatOp = work.op
+ x.why = "Invalid operation"
+ raise x
+ end
+
+ entry = SharedStruct.new()
+ entry.key = logid
+ entry.value = "#{val}"
+ @log[logid] = entry
+
+ return val
+
+ end
+
+ def getStruct(key)
+ print "getStruct(", key, ")\n"
+ return @log[key]
+ end
+
+ def zip()
+ print "zip\n"
+ end
+
+end
+
+handler = CalculatorHandler.new()
+processor = Calculator::Processor.new(handler)
+transport = Thrift::ServerSocket.new(9090)
+transportFactory = Thrift::BufferedTransportFactory.new()
+server = Thrift::SimpleServer.new(processor, transport, transportFactory)
+
+puts "Starting the server..."
+server.serve()
+puts "done."
diff --git a/src/jaegertracing/thrift/tutorial/rs/Cargo.toml b/src/jaegertracing/thrift/tutorial/rs/Cargo.toml
new file mode 100644
index 000000000..60f02d73c
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/rs/Cargo.toml
@@ -0,0 +1,16 @@
+[package]
+name = "thrift-tutorial"
+version = "0.1.0"
+license = "Apache-2.0"
+authors = ["Apache Thrift Developers <dev@thrift.apache.org>"]
+exclude = ["Makefile*", "shared.rs", "tutorial.rs"]
+publish = false
+
+[dependencies]
+clap = "2.33"
+ordered-float = "1.0"
+try_from = "0.3"
+
+[dependencies.thrift]
+path = "../../lib/rs"
+
diff --git a/src/jaegertracing/thrift/tutorial/rs/Makefile.am b/src/jaegertracing/thrift/tutorial/rs/Makefile.am
new file mode 100644
index 000000000..666331e4a
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/rs/Makefile.am
@@ -0,0 +1,52 @@
+#
+# 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.
+#
+
+THRIFT = $(top_builddir)/compiler/cpp/thrift
+
+gen-rs/tutorial.rs gen-rs/shared.rs: $(top_srcdir)/tutorial/tutorial.thrift
+ $(THRIFT) -out src --gen rs -r $<
+
+all-local: gen-rs/tutorial.rs
+ $(CARGO) build
+ [ -d bin ] || mkdir bin
+ cp target/debug/tutorial_server bin/tutorial_server
+ cp target/debug/tutorial_client bin/tutorial_client
+
+check: all
+
+tutorialserver: all
+ bin/tutorial_server
+
+tutorialclient: all
+ bin/tutorial_client
+
+clean-local:
+ $(CARGO) clean
+ -$(RM) Cargo.lock
+ -$(RM) src/shared.rs
+ -$(RM) src/tutorial.rs
+ -$(RM) -r bin
+
+EXTRA_DIST = \
+ Cargo.toml \
+ src/lib.rs \
+ src/bin/tutorial_server.rs \
+ src/bin/tutorial_client.rs \
+ README.md
+
diff --git a/src/jaegertracing/thrift/tutorial/rs/README.md b/src/jaegertracing/thrift/tutorial/rs/README.md
new file mode 100644
index 000000000..166854bea
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/rs/README.md
@@ -0,0 +1,318 @@
+# Rust Language Bindings for Thrift
+
+## Getting Started
+
+1. Get the [Thrift compiler](https://thrift.apache.org).
+
+2. Add the following crates to your `Cargo.toml`.
+
+```toml
+thrift = "x.y.z" # x.y.z is the version of the thrift compiler
+ordered-float = "0.3.0"
+try_from = "0.2.0"
+```
+
+3. Add the same crates to your `lib.rs` or `main.rs`.
+
+```rust
+extern crate ordered_float;
+extern crate thrift;
+extern crate try_from;
+```
+
+4. Generate Rust sources for your IDL (for example, `Tutorial.thrift`).
+
+```shell
+thrift -out my_rust_program/src --gen rs -r Tutorial.thrift
+```
+
+5. Use the generated source in your code.
+
+```rust
+// add extern crates here, or in your lib.rs
+extern crate ordered_float;
+extern crate thrift;
+extern crate try_from;
+
+// generated Rust module
+mod tutorial;
+
+use thrift::protocol::{TCompactInputProtocol, TCompactOutputProtocol};
+use thrift::protocol::{TInputProtocol, TOutputProtocol};
+use thrift::transport::{TFramedReadTransport, TFramedWriteTransport};
+use thrift::transport::{TIoChannel, TTcpChannel};
+
+use tutorial::{CalculatorSyncClient, TCalculatorSyncClient};
+use tutorial::{Operation, Work};
+
+fn main() {
+ match run() {
+ Ok(()) => println!("client ran successfully"),
+ Err(e) => {
+ println!("client failed with {:?}", e);
+ std::process::exit(1);
+ }
+ }
+}
+
+fn run() -> thrift::Result<()> {
+ //
+ // build client
+ //
+
+ println!("connect to server on 127.0.0.1:9090");
+ let mut c = TTcpChannel::new();
+ c.open("127.0.0.1:9090")?;
+
+ let (i_chan, o_chan) = c.split()?;
+
+ let i_prot = TCompactInputProtocol::new(
+ TFramedReadTransport::new(i_chan)
+ );
+ let o_prot = TCompactOutputProtocol::new(
+ TFramedWriteTransport::new(o_chan)
+ );
+
+ let mut client = CalculatorSyncClient::new(i_prot, o_prot);
+
+ //
+ // alright! - let's make some calls
+ //
+
+ // two-way, void return
+ client.ping()?;
+
+ // two-way with some return
+ let res = client.calculate(
+ 72,
+ Work::new(7, 8, Operation::Multiply, None)
+ )?;
+ println!("multiplied 7 and 8, got {}", res);
+
+ // two-way and returns a Thrift-defined exception
+ let res = client.calculate(
+ 77,
+ Work::new(2, 0, Operation::Divide, None)
+ );
+ match res {
+ Ok(v) => panic!("shouldn't have succeeded with result {}", v),
+ Err(e) => println!("divide by zero failed with {:?}", e),
+ }
+
+ // one-way
+ client.zip()?;
+
+ // done!
+ Ok(())
+}
+```
+
+## Code Generation
+
+### Thrift Files and Generated Modules
+
+The Thrift code generator takes each Thrift file and generates a Rust module
+with the same name snake-cased. For example, running the compiler on
+`ThriftTest.thrift` creates `thrift_test.rs`. To use these generated files add
+`mod ...` and `use ...` declarations to your `lib.rs` or `main.rs` - one for
+each generated file.
+
+### Results and Errors
+
+The Thrift runtime library defines a `thrift::Result` and a `thrift::Error` type,
+both of which are used throught the runtime library and in all generated code.
+Conversions are defined from `std::io::Error`, `str` and `String` into
+`thrift::Error`.
+
+### Thrift Type and their Rust Equivalents
+
+Thrift defines a number of types, each of which is translated into its Rust
+equivalent by the code generator.
+
+* Primitives (bool, i8, i16, i32, i64, double, string, binary)
+* Typedefs
+* Enums
+* Containers
+* Structs
+* Unions
+* Exceptions
+* Services
+* Constants (primitives, containers, structs)
+
+In addition, unless otherwise noted, thrift includes are translated into
+`use ...` statements in the generated code, and all declarations, parameters,
+traits and types in the generated code are namespaced appropriately.
+
+The following subsections cover each type and their generated Rust equivalent.
+
+### Primitives
+
+Thrift primitives have straightforward Rust equivalents.
+
+* bool: `bool`
+* i8: `i8`
+* i16: `i16`
+* i32: `i32`
+* i64: `i64`
+* double: `OrderedFloat<f64>`
+* string: `String`
+* binary: `Vec<u8>`
+
+### Typedefs
+
+A typedef is translated to a `pub type` declaration.
+
+```thrift
+typedef i64 UserId
+
+typedef map<string, UserId> MapType
+```
+```rust
+pub type UserId = i64;
+
+pub type MapType = BTreeMap<String, Bonk>;
+```
+
+### Enums
+
+A Thrift enum is represented as a Rust enum, and each variant is transcribed 1:1.
+
+```thrift
+enum Numberz
+{
+ ONE = 1,
+ TWO,
+ THREE,
+ FIVE = 5,
+ SIX,
+ EIGHT = 8
+}
+```
+
+```rust
+#[derive(Copy, Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
+pub enum Numberz {
+ ONE = 1,
+ TWO = 2,
+ THREE = 3,
+ FIVE = 5,
+ SIX = 6,
+ EIGHT = 8,
+}
+
+impl TryFrom<i32> for Numberz {
+ // ...
+}
+
+```
+
+### Containers
+
+Thrift has three container types: list, set and map. They are translated into
+Rust `Vec`, `BTreeSet` and `BTreeMap` respectively. Any Thrift type (this
+includes structs, enums and typedefs) can be a list/set element or a map
+key/value.
+
+#### List
+
+```thrift
+list <i32> numbers
+```
+
+```rust
+numbers: Vec<i32>
+```
+
+#### Set
+
+```thrift
+set <i32> numbers
+```
+
+```rust
+numbers: BTreeSet<i32>
+```
+
+#### Map
+
+```thrift
+map <string, i32> numbers
+```
+
+```rust
+numbers: BTreeMap<String, i32>
+```
+
+### Structs
+
+A Thrift struct is represented as a Rust struct, and each field transcribed 1:1.
+
+```thrift
+struct CrazyNesting {
+ 1: string string_field,
+ 2: optional set<Insanity> set_field,
+ 3: required list<
+ map<set<i32>, map<i32,set<list<map<Insanity,string>>>>>
+ >
+ 4: binary binary_field
+}
+```
+```rust
+#[derive(Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
+pub struct CrazyNesting {
+ pub string_field: Option<String>,
+ pub set_field: Option<BTreeSet<Insanity>>,
+ pub list_field: Vec<
+ BTreeMap<
+ BTreeSet<i32>,
+ BTreeMap<i32, BTreeSet<Vec<BTreeMap<Insanity, String>>>>
+ >
+ >,
+ pub binary_field: Option<Vec<u8>>,
+}
+
+impl CrazyNesting {
+ pub fn read_from_in_protocol(i_prot: &mut TInputProtocol)
+ ->
+ thrift::Result<CrazyNesting> {
+ // ...
+ }
+ pub fn write_to_out_protocol(&self, o_prot: &mut TOutputProtocol)
+ ->
+ thrift::Result<()> {
+ // ...
+ }
+}
+
+```
+##### Optionality
+
+Thrift has 3 "optionality" types:
+
+1. Required
+2. Optional
+3. Default
+
+The Rust code generator encodes *Required* fields as the bare type itself, while
+*Optional* and *Default* fields are encoded as `Option<TypeName>`.
+
+```thrift
+struct Foo {
+ 1: required string bar // 1. required
+ 2: optional string baz // 2. optional
+ 3: string qux // 3. default
+}
+```
+
+```rust
+pub struct Foo {
+ bar: String, // 1. required
+ baz: Option<String>, // 2. optional
+ qux: Option<String>, // 3. default
+}
+```
+
+## Known Issues
+
+* Struct constants are not supported
+* Map, list and set constants require a const holder struct
diff --git a/src/jaegertracing/thrift/tutorial/rs/src/bin/tutorial_client.rs b/src/jaegertracing/thrift/tutorial/rs/src/bin/tutorial_client.rs
new file mode 100644
index 000000000..bfd81d4c3
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/rs/src/bin/tutorial_client.rs
@@ -0,0 +1,130 @@
+// 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.
+
+#[macro_use]
+extern crate clap;
+
+extern crate thrift;
+extern crate thrift_tutorial;
+
+use thrift::protocol::{TCompactInputProtocol, TCompactOutputProtocol};
+use thrift::transport::{
+ ReadHalf, TFramedReadTransport, TFramedWriteTransport, TIoChannel, TTcpChannel, WriteHalf,
+};
+
+use thrift_tutorial::shared::TSharedServiceSyncClient;
+use thrift_tutorial::tutorial::{CalculatorSyncClient, Operation, TCalculatorSyncClient, Work};
+
+fn main() {
+ match run() {
+ Ok(()) => println!("tutorial client ran successfully"),
+ Err(e) => {
+ println!("tutorial client failed with error {:?}", e);
+ std::process::exit(1);
+ }
+ }
+}
+
+fn run() -> thrift::Result<()> {
+ let options = clap_app!(rust_tutorial_client =>
+ (version: "0.1.0")
+ (author: "Apache Thrift Developers <dev@thrift.apache.org>")
+ (about: "Thrift Rust tutorial client")
+ (@arg host: --host +takes_value "host on which the tutorial server listens")
+ (@arg port: --port +takes_value "port on which the tutorial server listens")
+ );
+ let matches = options.get_matches();
+
+ // get any passed-in args or the defaults
+ let host = matches.value_of("host").unwrap_or("127.0.0.1");
+ let port = value_t!(matches, "port", u16).unwrap_or(9090);
+
+ // build our client and connect to the host:port
+ let mut client = new_client(host, port)?;
+
+ // alright!
+ // let's start making some calls
+
+ // let's start with a ping; the server should respond
+ println!("ping!");
+ client.ping()?;
+
+ // simple add
+ println!("add");
+ let res = client.add(1, 2)?;
+ println!("added 1, 2 and got {}", res);
+
+ let logid = 32;
+
+ // let's do...a multiply!
+ let res = client.calculate(logid, Work::new(7, 8, Operation::Multiply, None))?;
+ println!("multiplied 7 and 8 and got {}", res);
+
+ // let's get the log for it
+ let res = client.get_struct(logid /* 32 */)?;
+ println!("got log {:?} for operation {}", res, logid);
+
+ // ok - let's be bad :(
+ // do a divide by 0
+ // logid doesn't matter; won't be recorded
+ let res = client.calculate(77, Work::new(2, 0, Operation::Divide, "we bad".to_owned()));
+
+ // we should have gotten an exception back
+ match res {
+ Ok(v) => panic!("should not have succeeded with result {}", v),
+ Err(e) => println!("divide by zero failed with error {:?}", e),
+ }
+
+ // let's do a one-way call
+ println!("zip");
+ client.zip()?;
+
+ // and then close out with a final ping
+ println!("ping!");
+ client.ping()?;
+
+ Ok(())
+}
+
+type ClientInputProtocol = TCompactInputProtocol<TFramedReadTransport<ReadHalf<TTcpChannel>>>;
+type ClientOutputProtocol = TCompactOutputProtocol<TFramedWriteTransport<WriteHalf<TTcpChannel>>>;
+
+fn new_client(
+ host: &str,
+ port: u16,
+) -> thrift::Result<CalculatorSyncClient<ClientInputProtocol, ClientOutputProtocol>> {
+ let mut c = TTcpChannel::new();
+
+ // open the underlying TCP stream
+ println!("connecting to tutorial server on {}:{}", host, port);
+ c.open(&format!("{}:{}", host, port))?;
+
+ // clone the TCP channel into two halves, one which
+ // we'll use for reading, the other for writing
+ let (i_chan, o_chan) = c.split()?;
+
+ // wrap the raw sockets (slow) with a buffered transport of some kind
+ let i_tran = TFramedReadTransport::new(i_chan);
+ let o_tran = TFramedWriteTransport::new(o_chan);
+
+ // now create the protocol implementations
+ let i_prot = TCompactInputProtocol::new(i_tran);
+ let o_prot = TCompactOutputProtocol::new(o_tran);
+
+ // we're done!
+ Ok(CalculatorSyncClient::new(i_prot, o_prot))
+}
diff --git a/src/jaegertracing/thrift/tutorial/rs/src/bin/tutorial_server.rs b/src/jaegertracing/thrift/tutorial/rs/src/bin/tutorial_server.rs
new file mode 100644
index 000000000..95b1a2b6e
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/rs/src/bin/tutorial_server.rs
@@ -0,0 +1,179 @@
+// 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.
+
+#[macro_use]
+extern crate clap;
+
+extern crate thrift;
+extern crate thrift_tutorial;
+
+use std::collections::HashMap;
+use std::convert::{From, Into};
+use std::default::Default;
+use std::sync::Mutex;
+
+use thrift::protocol::{TCompactInputProtocolFactory, TCompactOutputProtocolFactory};
+use thrift::server::TServer;
+
+use thrift::transport::{TFramedReadTransportFactory, TFramedWriteTransportFactory};
+use thrift_tutorial::shared::{SharedServiceSyncHandler, SharedStruct};
+use thrift_tutorial::tutorial::{CalculatorSyncHandler, CalculatorSyncProcessor};
+use thrift_tutorial::tutorial::{InvalidOperation, Operation, Work};
+
+fn main() {
+ match run() {
+ Ok(()) => println!("tutorial server ran successfully"),
+ Err(e) => {
+ println!("tutorial server failed with error {:?}", e);
+ std::process::exit(1);
+ }
+ }
+}
+
+fn run() -> thrift::Result<()> {
+ let options = clap_app!(rust_tutorial_server =>
+ (version: "0.1.0")
+ (author: "Apache Thrift Developers <dev@thrift.apache.org>")
+ (about: "Thrift Rust tutorial server")
+ (@arg port: --port +takes_value "port on which the tutorial server listens")
+ );
+ let matches = options.get_matches();
+
+ let port = value_t!(matches, "port", u16).unwrap_or(9090);
+ let listen_address = format!("127.0.0.1:{}", port);
+
+ println!("binding to {}", listen_address);
+
+ let i_tran_fact = TFramedReadTransportFactory::new();
+ let i_prot_fact = TCompactInputProtocolFactory::new();
+
+ let o_tran_fact = TFramedWriteTransportFactory::new();
+ let o_prot_fact = TCompactOutputProtocolFactory::new();
+
+ // demux incoming messages
+ let processor = CalculatorSyncProcessor::new(CalculatorServer {
+ ..Default::default()
+ });
+
+ // create the server and start listening
+ let mut server = TServer::new(
+ i_tran_fact,
+ i_prot_fact,
+ o_tran_fact,
+ o_prot_fact,
+ processor,
+ 10,
+ );
+
+ server.listen(&listen_address)
+}
+
+/// Handles incoming Calculator service calls.
+struct CalculatorServer {
+ log: Mutex<HashMap<i32, SharedStruct>>,
+}
+
+impl Default for CalculatorServer {
+ fn default() -> CalculatorServer {
+ CalculatorServer {
+ log: Mutex::new(HashMap::new()),
+ }
+ }
+}
+
+// since Calculator extends SharedService we have to implement the
+// handler for both traits.
+//
+
+// SharedService handler
+impl SharedServiceSyncHandler for CalculatorServer {
+ fn handle_get_struct(&self, key: i32) -> thrift::Result<SharedStruct> {
+ let log = self.log.lock().unwrap();
+ log.get(&key)
+ .cloned()
+ .ok_or_else(|| format!("could not find log for key {}", key).into())
+ }
+}
+
+// Calculator handler
+impl CalculatorSyncHandler for CalculatorServer {
+ fn handle_ping(&self) -> thrift::Result<()> {
+ println!("pong!");
+ Ok(())
+ }
+
+ fn handle_add(&self, num1: i32, num2: i32) -> thrift::Result<i32> {
+ println!("handling add: n1:{} n2:{}", num1, num2);
+ Ok(num1 + num2)
+ }
+
+ fn handle_calculate(&self, logid: i32, w: Work) -> thrift::Result<i32> {
+ println!("handling calculate: l:{}, w:{:?}", logid, w);
+
+ let res = if let Some(ref op) = w.op {
+ if w.num1.is_none() || w.num2.is_none() {
+ Err(InvalidOperation {
+ what_op: Some(*op as i32),
+ why: Some("no operands specified".to_owned()),
+ })
+ } else {
+ // so that I don't have to call unwrap() multiple times below
+ let num1 = w.num1.as_ref().expect("operands checked");
+ let num2 = w.num2.as_ref().expect("operands checked");
+
+ match *op {
+ Operation::Add => Ok(num1 + num2),
+ Operation::Subtract => Ok(num1 - num2),
+ Operation::Multiply => Ok(num1 * num2),
+ Operation::Divide => {
+ if *num2 == 0 {
+ Err(InvalidOperation {
+ what_op: Some(*op as i32),
+ why: Some("divide by 0".to_owned()),
+ })
+ } else {
+ Ok(num1 / num2)
+ }
+ }
+ }
+ }
+ } else {
+ Err(InvalidOperation::new(
+ None,
+ "no operation specified".to_owned(),
+ ))
+ };
+
+ // if the operation was successful log it
+ if let Ok(ref v) = res {
+ let mut log = self.log.lock().unwrap();
+ log.insert(logid, SharedStruct::new(logid, format!("{}", v)));
+ }
+
+ // the try! macro automatically maps errors
+ // but, since we aren't using that here we have to map errors manually
+ //
+ // exception structs defined in the IDL have an auto-generated
+ // impl of From::from
+ res.map_err(From::from)
+ }
+
+ fn handle_zip(&self) -> thrift::Result<()> {
+ println!("handling zip");
+ Ok(())
+ }
+}
diff --git a/src/jaegertracing/thrift/tutorial/rs/src/lib.rs b/src/jaegertracing/thrift/tutorial/rs/src/lib.rs
new file mode 100644
index 000000000..40007e5d3
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/rs/src/lib.rs
@@ -0,0 +1,23 @@
+// 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.
+
+extern crate ordered_float;
+extern crate thrift;
+extern crate try_from;
+
+pub mod shared;
+pub mod tutorial;
diff --git a/src/jaegertracing/thrift/tutorial/shared.thrift b/src/jaegertracing/thrift/tutorial/shared.thrift
new file mode 100644
index 000000000..5747f06bf
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/shared.thrift
@@ -0,0 +1,44 @@
+/*
+ * 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 Thrift file can be included by other Thrift files that want to share
+ * these definitions.
+ */
+
+namespace cl shared
+namespace cpp shared
+namespace d share // "shared" would collide with the eponymous D keyword.
+namespace dart shared
+namespace java shared
+namespace perl shared
+namespace php shared
+namespace haxe shared
+namespace netcore shared
+namespace netstd shared
+
+
+struct SharedStruct {
+ 1: i32 key
+ 2: string value
+}
+
+service SharedService {
+ SharedStruct getStruct(1: i32 key)
+}
diff --git a/src/jaegertracing/thrift/tutorial/tutorial.thrift b/src/jaegertracing/thrift/tutorial/tutorial.thrift
new file mode 100644
index 000000000..ea18b73dd
--- /dev/null
+++ b/src/jaegertracing/thrift/tutorial/tutorial.thrift
@@ -0,0 +1,158 @@
+/*
+ * 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.
+ */
+
+# Thrift Tutorial
+# Mark Slee (mcslee@facebook.com)
+#
+# This file aims to teach you how to use Thrift, in a .thrift file. Neato. The
+# first thing to notice is that .thrift files support standard shell comments.
+# This lets you make your thrift file executable and include your Thrift build
+# step on the top line. And you can place comments like this anywhere you like.
+#
+# Before running this file, you will need to have installed the thrift compiler
+# into /usr/local/bin.
+
+/**
+ * The first thing to know about are types. The available types in Thrift are:
+ *
+ * bool Boolean, one byte
+ * i8 (byte) Signed 8-bit integer
+ * i16 Signed 16-bit integer
+ * i32 Signed 32-bit integer
+ * i64 Signed 64-bit integer
+ * double 64-bit floating point value
+ * string String
+ * binary Blob (byte array)
+ * map<t1,t2> Map from one type to another
+ * list<t1> Ordered list of one type
+ * set<t1> Set of unique elements of one type
+ *
+ * Did you also notice that Thrift supports C style comments?
+ */
+
+// Just in case you were wondering... yes. We support simple C comments too.
+
+/**
+ * Thrift files can reference other Thrift files to include common struct
+ * and service definitions. These are found using the current path, or by
+ * searching relative to any paths specified with the -I compiler flag.
+ *
+ * Included objects are accessed using the name of the .thrift file as a
+ * prefix. i.e. shared.SharedObject
+ */
+include "shared.thrift"
+
+/**
+ * Thrift files can namespace, package, or prefix their output in various
+ * target languages.
+ */
+
+namespace cl tutorial
+namespace cpp tutorial
+namespace d tutorial
+namespace dart tutorial
+namespace java tutorial
+namespace php tutorial
+namespace perl tutorial
+namespace haxe tutorial
+namespace netcore tutorial
+namespace netstd tutorial
+
+/**
+ * Thrift lets you do typedefs to get pretty names for your types. Standard
+ * C style here.
+ */
+typedef i32 MyInteger
+
+/**
+ * Thrift also lets you define constants for use across languages. Complex
+ * types and structs are specified using JSON notation.
+ */
+const i32 INT32CONSTANT = 9853
+const map<string,string> MAPCONSTANT = {'hello':'world', 'goodnight':'moon'}
+
+/**
+ * You can define enums, which are just 32 bit integers. Values are optional
+ * and start at 1 if not supplied, C style again.
+ */
+enum Operation {
+ ADD = 1,
+ SUBTRACT = 2,
+ MULTIPLY = 3,
+ DIVIDE = 4
+}
+
+/**
+ * Structs are the basic complex data structures. They are comprised of fields
+ * which each have an integer identifier, a type, a symbolic name, and an
+ * optional default value.
+ *
+ * Fields can be declared "optional", which ensures they will not be included
+ * in the serialized output if they aren't set. Note that this requires some
+ * manual management in some languages.
+ */
+struct Work {
+ 1: i32 num1 = 0,
+ 2: i32 num2,
+ 3: Operation op,
+ 4: optional string comment,
+}
+
+/**
+ * Structs can also be exceptions, if they are nasty.
+ */
+exception InvalidOperation {
+ 1: i32 whatOp,
+ 2: string why
+}
+
+/**
+ * Ahh, now onto the cool part, defining a service. Services just need a name
+ * and can optionally inherit from another service using the extends keyword.
+ */
+service Calculator extends shared.SharedService {
+
+ /**
+ * A method definition looks like C code. It has a return type, arguments,
+ * and optionally a list of exceptions that it may throw. Note that argument
+ * lists and exception lists are specified using the exact same syntax as
+ * field lists in struct or exception definitions.
+ */
+
+ void ping(),
+
+ i32 add(1:i32 num1, 2:i32 num2),
+
+ i32 calculate(1:i32 logid, 2:Work w) throws (1:InvalidOperation ouch),
+
+ /**
+ * This method has a oneway modifier. That means the client only makes
+ * a request and does not listen for any response at all. Oneway methods
+ * must be void.
+ */
+ oneway void zip()
+
+}
+
+/**
+ * That just about covers the basics. Take a look in the test/ folder for more
+ * detailed examples. After you run this file, your generated code shows up
+ * in folders with names gen-<language>. The generated code isn't too scary
+ * to look at. It even has pretty indentation.
+ */