add jaeger support, link hot container & req span (#840)

* add jaeger support, link hot container & req span

* adds jaeger support now with FN_JAEGER_URL, there's a simple tutorial in the
operating/metrics.md file now and it's pretty easy to get up and running.
* links a hot request span to a hot container span. when we change this to
sample at a lower ratio we'll need to finagle the hot container span to always
sample or something, otherwise we'll hide that info. at least, since we're
sampling at 100% for now if this is flipped on, can see freeze/unfreeze etc.
if they hit. this is useful for debugging. note that zipkin's exporter does
not follow the link at all, hence jaeger... and they're backed by the Cloud
Empire now (CNCF) so we'll probably use it anyway.

* vendor: add thrift for jaeger
This commit is contained in:
Reed Allman
2018-03-13 15:57:12 -07:00
committed by GitHub
parent a7347a88b7
commit 9eaf824398
2953 changed files with 2334535 additions and 35 deletions

106
vendor/git.apache.org/thrift.git/tutorial/Makefile.am generated vendored Executable file
View File

@@ -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.
#
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_DOTNETCORE
SUBDIRS += netcore
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
#
# 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

42
vendor/git.apache.org/thrift.git/tutorial/README.md generated vendored Normal file
View File

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

View File

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

View File

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

84
vendor/git.apache.org/thrift.git/tutorial/c_glib/Makefile.am generated vendored Executable file
View File

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

View File

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

View File

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

View File

@@ -0,0 +1,56 @@
#
# 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_directories(SYSTEM "${Boost_INCLUDE_DIRS}")
#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 ()

View File

@@ -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.
*/
#include <iostream>
#include <thrift/protocol/TBinaryProtocol.h>
#include <thrift/transport/TSocket.h>
#include <thrift/transport/TTransportUtils.h>
#include <thrift/stdcxx.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() {
stdcxx::shared_ptr<TTransport> socket(new TSocket("localhost", 9090));
stdcxx::shared_ptr<TTransport> transport(new TBufferedTransport(socket));
stdcxx::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;
}
}

View File

@@ -0,0 +1,180 @@
/*
* 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/PlatformThreadFactory.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 <thrift/stdcxx.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() {}
void ping() { cout << "ping()" << endl; }
int32_t add(const int32_t n1, const int32_t n2) {
cout << "add(" << n1 << ", " << n2 << ")" << endl;
return n1 + n2;
}
int32_t calculate(const int32_t logid, const Work& work) {
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) {
cout << "getStruct(" << logid << ")" << endl;
ret = log[logid];
}
void zip() { 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:
virtual ~CalculatorCloneFactory() {}
virtual CalculatorIf* getHandler(const ::apache::thrift::TConnectionInfo& connInfo)
{
stdcxx::shared_ptr<TSocket> sock = stdcxx::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;
}
virtual void releaseHandler( ::shared::SharedServiceIf* handler) {
delete handler;
}
};
int main() {
TThreadedServer server(
stdcxx::make_shared<CalculatorProcessorFactory>(stdcxx::make_shared<CalculatorCloneFactory>()),
stdcxx::make_shared<TServerSocket>(9090), //port
stdcxx::make_shared<TBufferedTransportFactory>(),
stdcxx::make_shared<TBinaryProtocolFactory>());
/*
// if you don't need per-connection state, do the following instead
TThreadedServer server(
stdcxx::make_shared<CalculatorProcessor>(stdcxx::make_shared<CalculatorHandler>()),
stdcxx::make_shared<TServerSocket>(9090), //port
stdcxx::make_shared<TBufferedTransportFactory>(),
stdcxx::make_shared<TBinaryProtocolFactory>());
*/
/**
* Here are some alternate server types...
// This server only allows one connection at a time, but spawns no threads
TSimpleServer server(
stdcxx::make_shared<CalculatorProcessor>(stdcxx::make_shared<CalculatorHandler>()),
stdcxx::make_shared<TServerSocket>(9090),
stdcxx::make_shared<TBufferedTransportFactory>(),
stdcxx::make_shared<TBinaryProtocolFactory>());
const int workerCount = 4;
stdcxx::shared_ptr<ThreadManager> threadManager =
ThreadManager::newSimpleThreadManager(workerCount);
threadManager->threadFactory(
stdcxx::make_shared<PlatformThreadFactory>());
threadManager->start();
// This server allows "workerCount" connection at a time, and reuses threads
TThreadPoolServer server(
stdcxx::make_shared<CalculatorProcessorFactory>(stdcxx::make_shared<CalculatorCloneFactory>()),
stdcxx::make_shared<TServerSocket>(9090),
stdcxx::make_shared<TBufferedTransportFactory>(),
stdcxx::make_shared<TBinaryProtocolFactory>(),
threadManager);
*/
cout << "Starting the server..." << endl;
server.serve();
cout << "Done." << endl;
return 0;
}

86
vendor/git.apache.org/thrift.git/tutorial/cpp/Makefile.am generated vendored Executable file
View File

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

View File

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

View File

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

View File

@@ -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.11.0.0")]
[assembly: AssemblyFileVersion("0.11.0.0")]

View File

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

View File

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

View File

@@ -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.11.0.0")]
[assembly: AssemblyFileVersion("0.11.0.0")]

View File

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

View File

@@ -0,0 +1,46 @@
#
# 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)

View File

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

64
vendor/git.apache.org/thrift.git/tutorial/d/client.d generated vendored Normal file
View File

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

111
vendor/git.apache.org/thrift.git/tutorial/d/server.d generated vendored Normal file
View File

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

View File

@@ -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.
#
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 "packages" | xargs $(RM) -r
find . -type f -name ".packages" | xargs $(RM)
find . -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

View File

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

View File

@@ -0,0 +1,2 @@
analyzer:
strong-mode: true

View File

@@ -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_client
version: 0.11.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 <2.0.0"
dependencies:
browser: ^0.11.0
shared:
path: ../gen-dart/shared
thrift:
path: ../../../lib/dart
tutorial:
path: ../gen-dart/tutorial

View File

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

View File

@@ -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.
-->
<!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" type="application/dart"></script>
<script async src="packages/browser/dart.js"></script>
</head>
<body>
<div id="output"></div>
</body>
</html>

View File

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

View File

@@ -0,0 +1,2 @@
analyzer:
strong-mode: true

View File

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

View File

@@ -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.11.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 <2.0.0"
dependencies:
args: ^0.13.0
collection: ^1.1.0
shared:
path: ../gen-dart/shared
thrift:
path: ../../../lib/dart
tutorial:
path: ../gen-dart/tutorial

View File

@@ -0,0 +1,2 @@
analyzer:
strong-mode: true

View File

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

View File

@@ -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.11.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 <2.0.0"
dependencies:
args: ^0.13.0
shared:
path: ../gen-dart/shared
thrift:
path: ../../../lib/dart
tutorial:
path: ../gen-dart/tutorial

View File

@@ -0,0 +1,114 @@
(*
* 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.Console in '..\..\..\lib\delphi\src\Thrift.Console.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',
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;
Console.WriteLine('ping()');
sum := client.add( 1, 1);
Console.WriteLine( Format( '1+1=%d', [sum]));
work := TWorkImpl.Create;
work.Op := TOperation.DIVIDE;
work.Num1 := 1;
work.Num2 := 0;
try
quotient := client.calculate(1, work);
Console.WriteLine( 'Whoa we can divide by 0');
Console.WriteLine( Format('1/0=%d',[quotient]));
except
on io: TInvalidOperation
do Console.WriteLine( 'Invalid operation: ' + io.Why);
end;
work.Op := TOperation.SUBTRACT;
work.Num1 := 15;
work.Num2 := 10;
try
diff := client.calculate( 1, work);
Console.WriteLine( Format('15-10=%d', [diff]));
except
on io: TInvalidOperation
do Console.WriteLine( 'Invalid operation: ' + io.Why);
end;
log := client.getStruct(1);
Console.WriteLine( Format( 'Check log: %s', [log.Value]));
transport.Close();
except
on e : Exception
do Console.WriteLine( e.ClassName+': '+e.Message);
end;
end;
begin
try
DelphiTutorialClient.Main;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.

View File

@@ -0,0 +1,119 @@
 <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.Console.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="..\..\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">1</VersionInfo>
<VersionInfo Name="MinorVer">0</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.11.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.11.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>

View File

@@ -0,0 +1,173 @@
(*
* 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.Console in '..\..\..\lib\delphi\src\Thrift.Console.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',
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
Console.WriteLine( 'ping()');
end;
function TCalculatorHandler.add(num1: Integer; num2: Integer): Integer;
begin
Console.WriteLine( Format( 'add( %d, %d)', [num1, num2]));
result := num1 + num2;
end;
function TCalculatorHandler.calculate(logid: Integer; const w: IWork): Integer;
var entry : ISharedStruct;
begin
try
Console.WriteLine( 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
Console.WriteLine( Format( 'getStruct(%d)', [key]));
result := FLog[key];
end;
procedure TCalculatorHandler.zip;
begin
Console.WriteLine( '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);
Console.WriteLine( 'Starting the server...');
server.Serve();
except
on e: Exception do Console.WriteLine( e.Message);
end;
Console.WriteLine('done.');
end;
begin
try
DelphiTutorialServer.Main;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.

View File

@@ -0,0 +1,118 @@
 <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.Console.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="..\..\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">1</VersionInfo>
<VersionInfo Name="MinorVer">0</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.11.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.11.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>

View File

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

View File

@@ -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().

View File

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

1
vendor/git.apache.org/thrift.git/tutorial/erl/client.sh generated vendored Symbolic link
View File

@@ -0,0 +1 @@
server.sh

View File

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

View File

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

37
vendor/git.apache.org/thrift.git/tutorial/erl/server.sh generated vendored Executable file
View File

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

View File

@@ -0,0 +1,69 @@
#
# 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.
#
if GOVERSION_LT_17
COMPILER_EXTRAFLAG=":legacy_context"
endif
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/git.apache.org/thrift.git/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/git.apache.org/thrift.git/lib/go/thrift:
mkdir -p src/git.apache.org/thrift.git/lib/go
ln -sf $(realpath $(top_srcdir)/lib/go/thrift) src/git.apache.org/thrift.git/lib/go/thrift
thirdparty-dep:
mkdir -p src/golang.org/x/net
GOPATH=`pwd`/gopath $(GO) get golang.org/x/net/context
ln -sf `pwd`/gopath/src/golang.org/x/net/context src/golang.org/x/net/context
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 \
src/go17.go \
src/handler_go17.go \
src/pre_go17.go \
server.crt \
server.key

View File

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

View File

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

View File

@@ -0,0 +1,105 @@
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"
"tutorial"
"git.apache.org/thrift.git/lib/go/thrift"
)
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)))
}

View File

@@ -0,0 +1,26 @@
// +build go1.7
/*
* 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 main
import "context"
var defaultCtx = context.Background()

View File

@@ -0,0 +1,105 @@
// +build !go1.7
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 (
"fmt"
"shared"
"strconv"
"tutorial"
"golang.org/x/net/context"
)
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
}

View File

@@ -0,0 +1,104 @@
// +build go1.7
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
}

View File

@@ -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"
"git.apache.org/thrift.git/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)
}
}
}

View File

@@ -0,0 +1,26 @@
// +build !go1.7
/*
* 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 main
import "golang.org/x/net/context"
var defaultCtx = context.Background()

View File

@@ -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"
"git.apache.org/thrift.git/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()
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

239
vendor/git.apache.org/thrift.git/tutorial/hs/LICENSE generated vendored Normal file
View File

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

42
vendor/git.apache.org/thrift.git/tutorial/hs/Makefile.am generated vendored Executable file
View File

@@ -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.
#
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 gen-*
check-local:
$(CABAL) check
tutorialserver: all
dist/build/HaskellServer/HaskellServer
tutorialclient: all
dist/build/HaskellClient/HaskellClient
EXTRA_DIST = \
LICENSE

21
vendor/git.apache.org/thrift.git/tutorial/hs/Setup.lhs generated vendored Normal file
View File

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

View File

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

45
vendor/git.apache.org/thrift.git/tutorial/java/Makefile.am generated vendored Executable file
View File

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

View File

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

View File

@@ -0,0 +1,113 @@
<!--
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">
<include name="*.jar" />
<exclude name="-test.jar" />
</fileset>
<fileset dir="../../lib/java/build/lib">
<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>

View File

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

View File

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

View File

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

39
vendor/git.apache.org/thrift.git/tutorial/js/Makefile.am generated vendored Executable file
View File

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

90
vendor/git.apache.org/thrift.git/tutorial/js/build.xml generated vendored Normal file
View File

@@ -0,0 +1,90 @@
<!--
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="../../lib/java/build">
<include name="*.jar" />
<exclude name="-test.jar" />
</fileset>
<fileset dir="../../lib/java/build/lib">
<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>

View File

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

109
vendor/git.apache.org/thrift.git/tutorial/js/tutorial.html generated vendored Executable file
View File

@@ -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://git-wip-us.apache.org/repos/asf?p=thrift.git;a=blob;f=tutorial/tutorial.thrift;hb=HEAD">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>

View File

@@ -0,0 +1 @@
!**/*.pfx

View File

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

View File

@@ -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 -h
will diplay help information
Client.exe -t:<transport> -p:<protocol> -mc:<numClients>
will run client with specified arguments (tcp transport and binary protocol by default) and with 1 client
Options:
-t (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)
-p (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 -t:tcp -p:binary
");
}
public static void Main(string[] args)
{
args = args ?? new string[0];
if (args.Any(x => x.StartsWith("-h", 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("-t"))?.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("-p"))?.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
}
}
}

View File

@@ -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")]

View File

@@ -0,0 +1,8 @@
{
"profiles": {
"Client": {
"commandName": "Project",
"commandLineArgs": "-p:multiplexed"
}
}
}

Binary file not shown.

View File

@@ -0,0 +1,20 @@
<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>
</Project>

View File

@@ -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")]

View File

@@ -0,0 +1,75 @@
#
# 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 = .
THRIFT = $(top_builddir)/compiler/cpp/thrift
GENDIR = Interfaces/gen-netcore
# Due to a known issue with "dotnet restore" the Thrift.dll dependency cannot be resolved from cmdline.
# The problem does NOT affect Visual Studio builds, only cmdline.
# - For details see https://github.com/dotnet/cli/issues/3199 and related tickets.
# - Workaround is to temporarily copy the Thrift project into the solution
COPYCMD = cp -u -p -r
THRIFTCODE = \
Interfaces/Properties/AssemblyInfo.cs \
Client/Properties/AssemblyInfo.cs \
Client/Program.cs \
Server/Properties/AssemblyInfo.cs \
Server/Program.cs
all-local: \
Client.exe
Client.exe: $(THRIFTCODE)
$(MKDIR_P) $(GENDIR)
$(THRIFT) -gen netcore:wcf -r -out $(GENDIR) $(top_srcdir)/tutorial/tutorial.thrift
$(DOTNETCORE) --info
$(DOTNETCORE) restore
$(DOTNETCORE) build
clean-local:
$(RM) Client.exe
$(RM) Server.exe
$(RM) Interfaces.dll
$(RM) -r $(GENDIR)
$(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 = \
$(THRIFTCODE) \
Tutorial.sln \
Interfaces/Interfaces.csproj \
Client/Client.csproj \
Client/ThriftTest.pfx \
Client/Properties/launchSettings.json \
Server/Server.csproj \
Server/ThriftTest.pfx \
Server/Properties/launchSettings.json \
build.cmd \
build.sh \
README.md

View File

@@ -0,0 +1,281 @@
# Building of samples for different platforms
# Reused components
- NET Core Standard 1.6 (SDK 1.0.0-preview2-003121)
- NET Core App 1.1
# How to build
- Download and install .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 -t:tcp -p:multiplexed**, **dotnet run -help** (later, after migration to csproj and latest SDK will be possibility to use more usable form **dotnet run -- arguments**)
#Notes
- Migration to .NET Standard 2.0 planned for later (Q1 2017) according to https://blogs.msdn.microsoft.com/dotnet/2016/09/26/introducing-net-standard/
- 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
- Ubuntu 16.10 still not supported fully
- There is some problems with .NET Core CLI and usage specific -r|--runtime for building and publishing projects with different target frameworks (netstandard1.6 and netcoreapp1.1)
# 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 -t:<transport> -p:<protocol>
will run server with specified arguments (tcp transport and binary protocol by default)
Options:
-t (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)
-p (protocol):
binary - (default) binary protocol will be used
compact - compact protocol will be used
json - json protocol will be used
Sample:
Server.exe -t: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 -t:<transport> -p:<protocol> -mc:<numClients>
will run client with specified arguments (tcp transport and binary protocol by default)
Options:
-t (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)
-p (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 -t:tcp -p: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)
```

View File

@@ -0,0 +1,431 @@
// 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("-h", 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 -h
will diplay help information
Server.exe -t:<transport> -p:<protocol>
will run server with specified arguments (tcp transport and binary protocol by default)
Options:
-t (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)
-p (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 -t: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("-p"))?.Split(':')?[1];
Protocol selectedProtocol;
Enum.TryParse(transport, true, out selectedProtocol);
return selectedProtocol;
}
private static Transport GetTransport(string[] args)
{
var transport = args.FirstOrDefault(x => x.StartsWith("-t"))?.Split(':')?[1];
Transport selectedTransport;
Enum.TryParse(transport, true, out 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())
.UseIISIntegration()
.UseStartup<Startup>()
.Build();
host.StartAsync(cancellationToken); // was Run() in earlier .NET Core SDKs?
}
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"
});
}
}
}
}

Some files were not shown because too many files have changed in this diff Show More