diff options
Diffstat (limited to 'tutorial')
-rw-r--r-- | tutorial/README | 42 | ||||
-rw-r--r-- | tutorial/cpp/CppClient.cpp | 84 | ||||
-rw-r--r-- | tutorial/cpp/CppServer.cpp | 154 | ||||
-rw-r--r-- | tutorial/cpp/Makefile | 35 | ||||
-rw-r--r-- | tutorial/erl/client.erl | 74 | ||||
l--------- | tutorial/erl/client.sh | 1 | ||||
-rw-r--r-- | tutorial/erl/server.erl | 82 | ||||
-rwxr-xr-x | tutorial/erl/server.sh | 37 | ||||
-rwxr-xr-x | tutorial/java/JavaClient | 22 | ||||
-rwxr-xr-x | tutorial/java/JavaServer | 22 | ||||
-rw-r--r-- | tutorial/java/build.xml | 47 | ||||
-rw-r--r-- | tutorial/java/src/JavaClient.java | 85 | ||||
-rw-r--r-- | tutorial/java/src/JavaServer.java | 119 | ||||
-rw-r--r-- | tutorial/perl/PerlClient.pl | 82 | ||||
-rwxr-xr-x | tutorial/php/PhpClient.php | 92 | ||||
-rwxr-xr-x | tutorial/php/PhpServer.php | 132 | ||||
-rwxr-xr-x | tutorial/php/runserver.py | 32 | ||||
-rwxr-xr-x | tutorial/py/PythonClient.py | 82 | ||||
-rwxr-xr-x | tutorial/py/PythonServer.py | 96 | ||||
-rwxr-xr-x | tutorial/rb/RubyClient.rb | 75 | ||||
-rwxr-xr-x | tutorial/rb/RubyServer.rb | 95 | ||||
-rw-r--r-- | tutorial/shared.thrift | 36 | ||||
-rw-r--r-- | tutorial/tutorial.thrift | 152 |
23 files changed, 1678 insertions, 0 deletions
diff --git a/tutorial/README b/tutorial/README new file mode 100644 index 000000000..a29f977b0 --- /dev/null +++ b/tutorial/README @@ -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 file. + +2) Read tutorial.thrift to learn about the syntax of a Thrift file + +3) Compile the code for the language of your choice: + + $ thrift + $ thrift -r --gen cpp tutorial.thrift + +4) Take a look at the generated code. + +5) Look in the language directories for sample client/server code. + +6) That's about it for now. This tutorial is intentionally brief. It should be + just enough to get you started and ready to build your own project. diff --git a/tutorial/cpp/CppClient.cpp b/tutorial/cpp/CppClient.cpp new file mode 100644 index 000000000..a3f17feec --- /dev/null +++ b/tutorial/cpp/CppClient.cpp @@ -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. + */ + +#include <stdio.h> +#include <unistd.h> +#include <sys/time.h> + +#include <protocol/TBinaryProtocol.h> +#include <transport/TSocket.h> +#include <transport/TTransportUtils.h> + +#include "../gen-cpp/Calculator.h" + +using namespace std; +using namespace apache::thrift; +using namespace apache::thrift::protocol; +using namespace apache::thrift::transport; + +using namespace tutorial; +using namespace shared; + +using namespace boost; + +int main(int argc, char** argv) { + shared_ptr<TTransport> socket(new TSocket("localhost", 9090)); + shared_ptr<TTransport> transport(new TBufferedTransport(socket)); + shared_ptr<TProtocol> protocol(new TBinaryProtocol(transport)); + CalculatorClient client(protocol); + + try { + transport->open(); + + client.ping(); + printf("ping()\n"); + + int32_t sum = client.add(1,1); + printf("1+1=%d\n", sum); + + Work work; + work.op = DIVIDE; + work.num1 = 1; + work.num2 = 0; + + try { + int32_t quotient = client.calculate(1, work); + printf("Whoa? We can divide by zero!\n"); + } catch (InvalidOperation &io) { + printf("InvalidOperation: %s\n", io.why.c_str()); + } + + work.op = SUBTRACT; + work.num1 = 15; + work.num2 = 10; + int32_t diff = client.calculate(1, work); + printf("15-10=%d\n", diff); + + // Note that C++ uses return by reference for complex types to avoid + // costly copy construction + SharedStruct ss; + client.getStruct(ss, 1); + printf("Check log: %s\n", ss.value.c_str()); + + transport->close(); + } catch (TException &tx) { + printf("ERROR: %s\n", tx.what()); + } + +} diff --git a/tutorial/cpp/CppServer.cpp b/tutorial/cpp/CppServer.cpp new file mode 100644 index 000000000..23c2b8339 --- /dev/null +++ b/tutorial/cpp/CppServer.cpp @@ -0,0 +1,154 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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 <concurrency/ThreadManager.h> +#include <concurrency/PosixThreadFactory.h> +#include <protocol/TBinaryProtocol.h> +#include <server/TSimpleServer.h> +#include <server/TThreadPoolServer.h> +#include <server/TThreadedServer.h> +#include <transport/TServerSocket.h> +#include <transport/TTransportUtils.h> + +#include <iostream> +#include <stdexcept> +#include <sstream> + +#include "../gen-cpp/Calculator.h" + +using namespace std; +using namespace apache::thrift; +using namespace apache::thrift::protocol; +using namespace apache::thrift::transport; +using namespace apache::thrift::server; + +using namespace tutorial; +using namespace shared; + +using namespace boost; + +class CalculatorHandler : public CalculatorIf { + public: + CalculatorHandler() {} + + void ping() { + printf("ping()\n"); + } + + int32_t add(const int32_t n1, const int32_t n2) { + printf("add(%d,%d)\n", n1, n2); + return n1 + n2; + } + + int32_t calculate(const int32_t logid, const Work &work) { + printf("calculate(%d,{%d,%d,%d})\n", logid, work.op, work.num1, work.num2); + int32_t val; + + 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; + io.what = work.op; + io.why = "Cannot divide by 0"; + throw io; + } + val = work.num1 / work.num2; + break; + default: + InvalidOperation io; + io.what = work.op; + io.why = "Invalid Operation"; + throw io; + } + + SharedStruct ss; + ss.key = logid; + char buffer[12]; + snprintf(buffer, sizeof(buffer), "%d", val); + ss.value = buffer; + + log[logid] = ss; + + return val; + } + + void getStruct(SharedStruct &ret, const int32_t logid) { + printf("getStruct(%d)\n", logid); + ret = log[logid]; + } + + void zip() { + printf("zip()\n"); + } + +protected: + map<int32_t, SharedStruct> log; + +}; + +int main(int argc, char **argv) { + + shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory()); + shared_ptr<CalculatorHandler> handler(new CalculatorHandler()); + shared_ptr<TProcessor> processor(new CalculatorProcessor(handler)); + shared_ptr<TServerTransport> serverTransport(new TServerSocket(9090)); + shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory()); + + TSimpleServer server(processor, + serverTransport, + transportFactory, + protocolFactory); + + + /** + * Or you could do one of these + + shared_ptr<ThreadManager> threadManager = + ThreadManager::newSimpleThreadManager(workerCount); + shared_ptr<PosixThreadFactory> threadFactory = + shared_ptr<PosixThreadFactory>(new PosixThreadFactory()); + threadManager->threadFactory(threadFactory); + threadManager->start(); + TThreadPoolServer server(processor, + serverTransport, + transportFactory, + protocolFactory, + threadManager); + + TThreadedServer server(processor, + serverTransport, + transportFactory, + protocolFactory); + + */ + + printf("Starting the server...\n"); + server.serve(); + printf("done.\n"); + return 0; +} diff --git a/tutorial/cpp/Makefile b/tutorial/cpp/Makefile new file mode 100644 index 000000000..e834dee23 --- /dev/null +++ b/tutorial/cpp/Makefile @@ -0,0 +1,35 @@ +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +BOOST_DIR = /usr/local/boost/include/boost-1_33_1/ +THRIFT_DIR = /usr/local/include/thrift +LIB_DIR = /usr/local/lib + +GEN_SRC = ../gen-cpp/SharedService.cpp ../gen-cpp/shared_types.cpp ../gen-cpp/tutorial_types.cpp ../gen-cpp/Calculator.cpp + +default: server client + +server: CppServer.cpp + g++ -o CppServer -I${THRIFT_DIR} -I${BOOST_DIR} -I../gen-cpp -L${LIB_DIR} -lthrift CppServer.cpp ${GEN_SRC} + +client: CppClient.cpp + g++ -o CppClient -I${THRIFT_DIR} -I${BOOST_DIR} -I../gen-cpp -L${LIB_DIR} -lthrift CppClient.cpp ${GEN_SRC} + +clean: + $(RM) -r CppClient CppServer diff --git a/tutorial/erl/client.erl b/tutorial/erl/client.erl new file mode 100644 index 000000000..978033496 --- /dev/null +++ b/tutorial/erl/client.erl @@ -0,0 +1,74 @@ +%% +%% Licensed to the Apache Software Foundation (ASF) under one +%% or more contributor license agreements. See the NOTICE file +%% distributed with this work for additional information +%% regarding copyright ownership. The ASF licenses this file +%% to you under the Apache License, Version 2.0 (the +%% "License"); you may not use this file except in compliance +%% with the License. You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, +%% software distributed under the License is distributed on an +%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +%% KIND, either express or implied. See the License for the +%% specific language governing permissions and limitations +%% under the License. +%% + +-module(client). + +-include("calculator_thrift.hrl"). + +-export([t/0]). + +p(X) -> + io:format("~p~n", [X]), + ok. + +t() -> + Port = 9999, + + {ok, Client} = thrift_client:start_link("127.0.0.1", + Port, + calculator_thrift), + + thrift_client:call(Client, ping, []), + io:format("ping~n", []), + + {ok, Sum} = thrift_client:call(Client, add, [1, 1]), + io:format("1+1=~p~n", [Sum]), + + {ok, Sum1} = thrift_client:call(Client, add, [1, 4]), + io:format("1+4=~p~n", [Sum1]), + + Work = #work{op=?tutorial_SUBTRACT, + num1=15, + num2=10}, + {ok, Diff} = thrift_client:call(Client, calculate, [1, Work]), + io:format("15-10=~p~n", [Diff]), + + {ok, Log} = thrift_client:call(Client, getStruct, [1]), + io:format("Log: ~p~n", [Log]), + + try + Work1 = #work{op=?tutorial_DIVIDE, + num1=1, + num2=0}, + {ok, _Quot} = thrift_client:call(Client, calculate, [2, Work1]), + + io:format("LAME: exception handling is broken~n", []) + catch + Z -> + io:format("Got exception where expecting - the " ++ + "following is NOT a problem!!!~n"), + p(Z) + end, + + + {ok, ok} = thrift_client:call(Client, zip, []), + io:format("zip~n", []), + + ok = thrift_client:close(Client), + ok. diff --git a/tutorial/erl/client.sh b/tutorial/erl/client.sh new file mode 120000 index 000000000..a417e0da9 --- /dev/null +++ b/tutorial/erl/client.sh @@ -0,0 +1 @@ +server.sh
\ No newline at end of file diff --git a/tutorial/erl/server.erl b/tutorial/erl/server.erl new file mode 100644 index 000000000..5a994ce79 --- /dev/null +++ b/tutorial/erl/server.erl @@ -0,0 +1,82 @@ +%% +%% Licensed to the Apache Software Foundation (ASF) under one +%% or more contributor license agreements. See the NOTICE file +%% distributed with this work for additional information +%% regarding copyright ownership. The ASF licenses this file +%% to you under the Apache License, Version 2.0 (the +%% "License"); you may not use this file except in compliance +%% with the License. You may obtain a copy of the License at +%% +%% http://www.apache.org/licenses/LICENSE-2.0 +%% +%% Unless required by applicable law or agreed to in writing, +%% software distributed under the License is distributed on an +%% "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +%% KIND, either express or implied. See the License for the +%% specific language governing permissions and limitations +%% under the License. +%% + +-module(server). + +-include("calculator_thrift.hrl"). + +-export([start/0, start/1, handle_function/2, + stop/1, ping/0, add/2, calculate/2, getStruct/1, zip/0]). + +debug(Format, Data) -> + error_logger:info_msg(Format, Data). + +ping() -> + debug("ping()",[]), + ok. + +add(N1, N2) -> + debug("add(~p,~p)",[N1,N2]), + N1+N2. + +calculate(Logid, Work) -> + { Op, Num1, Num2 } = { Work#work.op, Work#work.num1, Work#work.num2 }, + debug("calculate(~p, {~p,~p,~p})", [Logid, Op, Num1, Num2]), + case Op of + ?tutorial_ADD -> Num1 + Num2; + ?tutorial_SUBTRACT -> Num1 - Num2; + ?tutorial_MULTIPLY -> Num1 * Num2; + + ?tutorial_DIVIDE when Num2 == 0 -> + throw(#invalidOperation{what=Op, why="Cannot divide by 0"}); + ?tutorial_DIVIDE -> + Num1 div Num2; + + _Else -> + throw(#invalidOperation{what=Op, why="Invalid operation"}) + end. + +getStruct(Key) -> + debug("getStruct(~p)", [Key]), + #sharedStruct{key=Key, value="RARG"}. + +zip() -> + debug("zip", []), + ok. + +%% + +start() -> + start(9999). + +start(Port) -> + Handler = ?MODULE, + thrift_socket_server:start([{handler, Handler}, + {service, calculator_thrift}, + {port, Port}, + {name, tutorial_server}]). + +stop(Server) -> + thrift_socket_server:stop(Server). + +handle_function(Function, Args) when is_atom(Function), is_tuple(Args) -> + case apply(?MODULE, Function, tuple_to_list(Args)) of + ok -> ok; + Reply -> {reply, Reply} + end. diff --git a/tutorial/erl/server.sh b/tutorial/erl/server.sh new file mode 100755 index 000000000..106c89e91 --- /dev/null +++ b/tutorial/erl/server.sh @@ -0,0 +1,37 @@ +#!/bin/sh + +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +ERL_THRIFT=../../lib/erl + +if ! [ -d ${ERL_THRIFT}/ebin ]; then + echo "Please build the Thrift library by running \`make' in ${ERL_THRIFT}" + exit 1 +fi + +if ! [ -d ../gen-erl ]; then + echo "Please run thrift first to generate ../gen-erl/" + exit 1 +fi + + +erlc -I ${ERL_THRIFT}/include -I ../gen-erl -o ../gen-erl ../gen-erl/*.erl && + erlc -I ${ERL_THRIFT}/include -I ../gen-erl *.erl && + erl +K true -pa ${ERL_THRIFT}/ebin -pa ../gen-erl diff --git a/tutorial/java/JavaClient b/tutorial/java/JavaClient new file mode 100755 index 000000000..68d87b813 --- /dev/null +++ b/tutorial/java/JavaClient @@ -0,0 +1,22 @@ +#!/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. +# + +java -cp tutorial.jar:/usr/local/lib/libthrift.jar JavaClient diff --git a/tutorial/java/JavaServer b/tutorial/java/JavaServer new file mode 100755 index 000000000..896160012 --- /dev/null +++ b/tutorial/java/JavaServer @@ -0,0 +1,22 @@ +#!/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. +# + +java -cp tutorial.jar:/usr/local/lib/libthrift.jar JavaServer diff --git a/tutorial/java/build.xml b/tutorial/java/build.xml new file mode 100644 index 000000000..0ec1ea405 --- /dev/null +++ b/tutorial/java/build.xml @@ -0,0 +1,47 @@ +<!-- + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +--> +<project name="tutorial" default="tutorial" basedir="."> + + <description>Thrift Tutorial</description> + + <property name="src" location="src" /> + <property name="gen" location="../gen-java" /> + <property name="build" location="build" /> + <property name="cpath" location="/usr/local/lib/libthrift.jar" /> + + <target name="init"> + <tstamp /> + <mkdir dir="${build}"/> + </target> + + <target name="compile" depends="init"> + <javac srcdir="${gen}" destdir="${build}" classpath="${cpath}" /> + <javac srcdir="${src}" destdir="${build}" classpath="${cpath}:${gen}" /> + </target> + + <target name="tutorial" depends="compile"> + <jar jarfile="tutorial.jar" basedir="${build}"/> + </target> + + <target name="clean"> + <delete dir="${build}" /> + <delete file="tutorial.jar" /> + </target> + +</project> diff --git a/tutorial/java/src/JavaClient.java b/tutorial/java/src/JavaClient.java new file mode 100644 index 000000000..5dc70ed5d --- /dev/null +++ b/tutorial/java/src/JavaClient.java @@ -0,0 +1,85 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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.TTransport; +import org.apache.thrift.transport.TSocket; +import org.apache.thrift.transport.TTransportException; +import org.apache.thrift.protocol.TBinaryProtocol; +import org.apache.thrift.protocol.TProtocol; + +import java.util.AbstractMap; +import java.util.HashMap; +import java.util.HashSet; +import java.util.ArrayList; + +public class JavaClient { + public static void main(String [] args) { + try { + + TTransport transport = new TSocket("localhost", 9090); + TProtocol protocol = new TBinaryProtocol(transport); + Calculator.Client client = new Calculator.Client(protocol); + + transport.open(); + + 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); + + transport.close(); + + } catch (TException x) { + x.printStackTrace(); + } + + } + +} diff --git a/tutorial/java/src/JavaServer.java b/tutorial/java/src/JavaServer.java new file mode 100644 index 000000000..14440eb7a --- /dev/null +++ b/tutorial/java/src/JavaServer.java @@ -0,0 +1,119 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT 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; +import org.apache.thrift.protocol.TBinaryProtocol; +import org.apache.thrift.protocol.TProtocol; +import org.apache.thrift.server.TServer; +import org.apache.thrift.server.TSimpleServer; +import org.apache.thrift.transport.TServerSocket; +import org.apache.thrift.transport.TServerTransport; + +// Generated code +import tutorial.*; +import shared.*; + +import java.util.HashMap; + +public class JavaServer { + + public static 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 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.what = work.op; + io.why = "Cannot divide by 0"; + throw io; + } + val = work.num1 / work.num2; + break; + default: + InvalidOperation io = new InvalidOperation(); + io.what = work.op; + 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()"); + } + + } + + public static void main(String [] args) { + 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); + + System.out.println("Starting the server..."); + server.serve(); + + } catch (Exception x) { + x.printStackTrace(); + } + System.out.println("done."); + } +} diff --git a/tutorial/perl/PerlClient.pl b/tutorial/perl/PerlClient.pl new file mode 100644 index 000000000..1d596568d --- /dev/null +++ b/tutorial/perl/PerlClient.pl @@ -0,0 +1,82 @@ +#!/usr/bin/env perl + +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +use strict; +use warnings; + +use lib '../../lib/perl/lib'; +use lib '../gen-perl'; + +use Thrift; +use Thrift::BinaryProtocol; +use Thrift::Socket; +use Thrift::BufferedTransport; + +use shared::SharedService; +use tutorial::Calculator; +use shared::Types; +use tutorial::Types; + +use Data::Dumper; + +my $socket = new Thrift::Socket('localhost',9090); +my $transport = new Thrift::BufferedTransport($socket,1024,1024); +my $protocol = new Thrift::BinaryProtocol($transport); +my $client = new tutorial::CalculatorClient($protocol); + + +eval{ + $transport->open(); + + $client->ping(); + print "ping()\n"; + + + my $sum = $client->add(1,1); + print "1+1=$sum\n"; + + my $work = new tutorial::Work(); + + $work->op(tutorial::Operation::DIVIDE); + $work->num1(1); + $work->num2(0); + + eval { + $client->calculate(1, $work); + print "Whoa! We can divide by zero?\n"; + }; if($@) { + warn "InvalidOperation: ".Dumper($@); + } + + $work->op(tutorial::Operation::SUBTRACT); + $work->num1(15); + $work->num2(10); + my $diff = $client->calculate(1, $work); + print "15-10=$diff\n"; + + my $log = $client->getStruct(1); + print "Log: $log->{value}\n"; + + $transport->close(); + +}; if($@){ + warn(Dumper($@)); +} diff --git a/tutorial/php/PhpClient.php b/tutorial/php/PhpClient.php new file mode 100755 index 000000000..c5c081012 --- /dev/null +++ b/tutorial/php/PhpClient.php @@ -0,0 +1,92 @@ +#!/usr/bin/env php +<?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. + */ + +$GLOBALS['THRIFT_ROOT'] = '../../lib/php/src'; + +require_once $GLOBALS['THRIFT_ROOT'].'/Thrift.php'; +require_once $GLOBALS['THRIFT_ROOT'].'/protocol/TBinaryProtocol.php'; +require_once $GLOBALS['THRIFT_ROOT'].'/transport/TSocket.php'; +require_once $GLOBALS['THRIFT_ROOT'].'/transport/THttpClient.php'; +require_once $GLOBALS['THRIFT_ROOT'].'/transport/TBufferedTransport.php'; + +/** + * Suppress errors in here, which happen because we have not installed into + * $GLOBALS['THRIFT_ROOT'].'/packages/tutorial' like we are supposed to! + * + * Normally we would only have to include Calculator.php which would properly + * include the other files from their packages/ folder locations, but we + * include everything here due to the bogus path setup. + */ +error_reporting(E_NONE); +$GEN_DIR = '../gen-php'; +require_once $GEN_DIR.'/SharedService.php'; +require_once $GEN_DIR.'/shared_types.php'; +require_once $GEN_DIR.'/Calculator.php'; +require_once $GEN_DIR.'/tutorial_types.php'; +error_reporting(E_ALL); + +try { + if (array_search('--http', $argv)) { + $socket = new THttpClient('localhost', 8080, '/php/PhpServer.php'); + } else { + $socket = new TSocket('localhost', 9090); + } + $transport = new TBufferedTransport($socket, 1024, 1024); + $protocol = new TBinaryProtocol($transport); + $client = new CalculatorClient($protocol); + + $transport->open(); + + $client->ping(); + print "ping()\n"; + + $sum = $client->add(1,1); + print "1+1=$sum\n"; + + $work = new tutorial_Work(); + + $work->op = tutorial_Operation::DIVIDE; + $work->num1 = 1; + $work->num2 = 0; + + try { + $client->calculate(1, $work); + print "Whoa! We can divide by zero?\n"; + } catch (tutorial_InvalidOperation $io) { + print "InvalidOperation: $io->why\n"; + } + + $work->op = tutorial_Operation::SUBTRACT; + $work->num1 = 15; + $work->num2 = 10; + $diff = $client->calculate(1, $work); + print "15-10=$diff\n"; + + $log = $client->getStruct(1); + print "Log: $log->value\n"; + + $transport->close(); + +} catch (TException $tx) { + print 'TException: '.$tx->getMessage()."\n"; +} + +?> diff --git a/tutorial/php/PhpServer.php b/tutorial/php/PhpServer.php new file mode 100755 index 000000000..9482c6496 --- /dev/null +++ b/tutorial/php/PhpServer.php @@ -0,0 +1,132 @@ +#!/usr/bin/env php +<?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. + */ + +/* + * This is not a stand-alone server. It should be run as a normal + * php web script (like through Apache's mod_php) or as a cgi script + * (like with the included runserver.py). You can connect to it with + * THttpClient in any language that supports it. The PHP tutorial client + * will work if you pass it the argument "--http". + */ + +if (php_sapi_name() == 'cli') { + ini_set("display_errors", "stderr"); +} + +$GLOBALS['THRIFT_ROOT'] = realpath(dirname(__FILE__).'/../..').'/lib/php/src'; + +require_once $GLOBALS['THRIFT_ROOT'].'/Thrift.php'; +require_once $GLOBALS['THRIFT_ROOT'].'/protocol/TBinaryProtocol.php'; +require_once $GLOBALS['THRIFT_ROOT'].'/transport/TPhpStream.php'; +require_once $GLOBALS['THRIFT_ROOT'].'/transport/TBufferedTransport.php'; + +/** + * Suppress errors in here, which happen because we have not installed into + * $GLOBALS['THRIFT_ROOT'].'/packages/tutorial' like we are supposed to! + * + * Normally we would only have to include Calculator.php which would properly + * include the other files from their packages/ folder locations, but we + * include everything here due to the bogus path setup. + */ +error_reporting(E_NONE); +$GEN_DIR = realpath(dirname(__FILE__).'/..').'/gen-php'; +require_once $GEN_DIR.'/SharedService.php'; +require_once $GEN_DIR.'/shared_types.php'; +require_once $GEN_DIR.'/Calculator.php'; +require_once $GEN_DIR.'/tutorial_types.php'; +error_reporting(E_ALL); + +class CalculatorHandler implements CalculatorIf { + protected $log = array(); + + public function ping() { + error_log("ping()"); + } + + public function add($num1, $num2) { + error_log("add({$num1}, {$num2})"); + return $num1 + $num2; + } + + public function calculate($logid, $w) { + error_log("calculate({$logid}, {{$w->op}, {$w->num1}, {$w->num2}})"); + switch ($w->op) { + case tutorial_Operation::ADD: + $val = $w->num1 + $w->num2; + break; + case tutorial_Operation::SUBTRACT: + $val = $w->num1 - $w->num2; + break; + case tutorial_Operation::MULTIPLY: + $val = $w->num1 * $w->num2; + break; + case tutorial_Operation::DIVIDE: + if ($w->num2 == 0) { + $io = new tutorial_InvalidOperation(); + $io->what = $w->op; + $io->why = "Cannot divide by 0"; + throw $io; + } + $val = $w->num1 / $w->num2; + break; + default: + $io = new tutorial_InvalidOperation(); + $io->what = $w->op; + $io->why = "Invalid Operation"; + throw $io; + } + + $log = new SharedStruct(); + $log->key = $logid; + $log->value = (string)$val; + $this->log[$logid] = $log; + + return $val; + } + + public function getStruct($key) { + error_log("getStruct({$key})"); + // This actually doesn't work because the PHP interpreter is + // restarted for every request. + //return $this->log[$key]; + return new SharedStruct(array("key" => $key, "value" => "PHP is stateless!")); + } + + public function zip() { + error_log("zip()"); + } + +}; + +header('Content-Type', 'application/x-thrift'); +if (php_sapi_name() == 'cli') { + echo "\r\n"; +} + +$handler = new CalculatorHandler(); +$processor = new CalculatorProcessor($handler); + +$transport = new TBufferedTransport(new TPhpStream(TPhpStream::MODE_R | TPhpStream::MODE_W)); +$protocol = new TBinaryProtocol($transport, true, true); + +$transport->open(); +$processor->process($protocol, $protocol); +$transport->close(); diff --git a/tutorial/php/runserver.py b/tutorial/php/runserver.py new file mode 100755 index 000000000..ae29fed9c --- /dev/null +++ b/tutorial/php/runserver.py @@ -0,0 +1,32 @@ +#!/usr/bin/env python + +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +import os +import BaseHTTPServer +import CGIHTTPServer + +# chdir(2) into the tutorial directory. +os.chdir(os.path.dirname(os.path.dirname(os.path.realpath(__file__)))) + +class Handler(CGIHTTPServer.CGIHTTPRequestHandler): + cgi_directories = ['/php'] + +BaseHTTPServer.HTTPServer(('', 8080), Handler).serve_forever() diff --git a/tutorial/py/PythonClient.py b/tutorial/py/PythonClient.py new file mode 100755 index 000000000..916e91570 --- /dev/null +++ b/tutorial/py/PythonClient.py @@ -0,0 +1,82 @@ +#!/usr/bin/env python + +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +import sys +sys.path.append('../gen-py') + +from tutorial import Calculator +from tutorial.ttypes import * + +from thrift import Thrift +from thrift.transport import TSocket +from thrift.transport import TTransport +from thrift.protocol import TBinaryProtocol + +try: + + # Make socket + transport = TSocket.TSocket('localhost', 9090) + + # Buffering is critical. Raw sockets are very slow + transport = TTransport.TBufferedTransport(transport) + + # Wrap in a protocol + protocol = TBinaryProtocol.TBinaryProtocol(transport) + + # Create a client to use the protocol encoder + client = Calculator.Client(protocol) + + # Connect! + transport.open() + + client.ping() + print 'ping()' + + sum = client.add(1,1) + print '1+1=%d' % (sum) + + work = Work() + + work.op = Operation.DIVIDE + work.num1 = 1 + work.num2 = 0 + + try: + quotient = client.calculate(1, work) + print 'Whoa? You know how to divide by zero?' + except InvalidOperation, io: + print 'InvalidOperation: %r' % io + + work.op = Operation.SUBTRACT + work.num1 = 15 + work.num2 = 10 + + diff = client.calculate(1, work) + print '15-10=%d' % (diff) + + log = client.getStruct(1) + print 'Check log: %s' % (log.value) + + # Close! + transport.close() + +except Thrift.TException, tx: + print '%s' % (tx.message) diff --git a/tutorial/py/PythonServer.py b/tutorial/py/PythonServer.py new file mode 100755 index 000000000..63f993bc6 --- /dev/null +++ b/tutorial/py/PythonServer.py @@ -0,0 +1,96 @@ +#!/usr/bin/env python + +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +import sys +sys.path.append('../gen-py') + +from tutorial import Calculator +from tutorial.ttypes import * + +from shared.ttypes import SharedStruct + +from thrift.transport import TSocket +from thrift.transport import TTransport +from thrift.protocol import TBinaryProtocol +from thrift.server import TServer + +class CalculatorHandler: + def __init__(self): + self.log = {} + + def ping(self): + print 'ping()' + + def add(self, n1, n2): + print 'add(%d,%d)' % (n1, n2) + return n1+n2 + + def calculate(self, logid, work): + print 'calculate(%d, %r)' % (logid, work) + + if work.op == Operation.ADD: + val = work.num1 + work.num2 + elif work.op == Operation.SUBTRACT: + val = work.num1 - work.num2 + elif work.op == Operation.MULTIPLY: + val = work.num1 * work.num2 + elif work.op == Operation.DIVIDE: + if work.num2 == 0: + x = InvalidOperation() + x.what = work.op + x.why = 'Cannot divide by 0' + raise x + val = work.num1 / work.num2 + else: + x = InvalidOperation() + x.what = 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()' + +handler = CalculatorHandler() +processor = Calculator.Processor(handler) +transport = TSocket.TServerSocket(9090) +tfactory = TTransport.TBufferedTransportFactory() +pfactory = TBinaryProtocol.TBinaryProtocolFactory() + +server = TServer.TSimpleServer(processor, transport, tfactory, pfactory) + +# You could do one of these for a multithreaded server +#server = TServer.TThreadedServer(processor, transport, tfactory, pfactory) +#server = TServer.TThreadPoolServer(processor, transport, tfactory, pfactory) + +print 'Starting the server...' +server.serve() +print 'done.' diff --git a/tutorial/rb/RubyClient.rb b/tutorial/rb/RubyClient.rb new file mode 100755 index 000000000..8971fed98 --- /dev/null +++ b/tutorial/rb/RubyClient.rb @@ -0,0 +1,75 @@ +#!/usr/bin/env ruby + +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +$:.push('../gen-rb') +$:.unshift '../../lib/rb/lib' + +require 'thrift' + +require 'Calculator' + +begin + port = ARGV[0] || 9090 + + transport = Thrift::BufferedTransport.new(Thrift::Socket.new('localhost', port)) + protocol = Thrift::BinaryProtocol.new(transport) + client = Calculator::Client.new(protocol) + + transport.open() + + client.ping() + print "ping()\n" + + sum = client.add(1,1) + print "1+1=", sum, "\n" + + sum = client.add(1,4) + print "1+4=", sum, "\n" + + work = Work.new() + + work.op = Operation::SUBTRACT + work.num1 = 15 + work.num2 = 10 + diff = client.calculate(1, work) + print "15-10=", diff, "\n" + + log = client.getStruct(1) + print "Log: ", log.value, "\n" + + begin + work.op = Operation::DIVIDE + work.num1 = 1 + work.num2 = 0 + quot = client.calculate(1, work) + puts "Whoa, we can divide by 0 now?" + rescue InvalidOperation => io + print "InvalidOperation: ", io.why, "\n" + end + + client.zip() + print "zip\n" + + transport.close() + +rescue Thrift::Exception => tx + print 'Thrift::Exception: ', tx.message, "\n" +end diff --git a/tutorial/rb/RubyServer.rb b/tutorial/rb/RubyServer.rb new file mode 100755 index 000000000..89eb37389 --- /dev/null +++ b/tutorial/rb/RubyServer.rb @@ -0,0 +1,95 @@ +#!/usr/bin/env ruby + +# +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. +# + +$:.push('../gen-rb') +$:.unshift '../../lib/rb/lib' + +require 'thrift' + +require 'Calculator' +require 'shared_types' + +class CalculatorHandler + def initialize() + @log = {} + end + + def ping() + puts "ping()" + end + + def add(n1, n2) + print "add(", n1, ",", n2, ")\n" + return n1 + n2 + end + + def calculate(logid, work) + print "calculate(", logid, ", {", work.op, ",", work.num1, ",", work.num2,"})\n" + if work.op == Operation::ADD + val = work.num1 + work.num2 + elsif work.op == Operation::SUBTRACT + val = work.num1 - work.num2 + elsif work.op == Operation::MULTIPLY + val = work.num1 * work.num2 + elsif work.op == Operation::DIVIDE + if work.num2 == 0 + x = InvalidOperation.new() + x.what = work.op + x.why = "Cannot divide by 0" + raise x + end + val = work.num1 / work.num2 + else + x = InvalidOperation.new() + x.what = work.op + x.why = "Invalid operation" + raise x + end + + entry = SharedStruct.new() + entry.key = logid + entry.value = "#{val}" + @log[logid] = entry + + return val + + end + + def getStruct(key) + print "getStruct(", key, ")\n" + return @log[key] + end + + def zip() + print "zip\n" + end + +end + +handler = CalculatorHandler.new() +processor = Calculator::Processor.new(handler) +transport = Thrift::ServerSocket.new(9090) +transportFactory = Thrift::BufferedTransportFactory.new() +server = Thrift::SimpleServer.new(processor, transport, transportFactory) + +puts "Starting the server..." +server.serve() +puts "done." diff --git a/tutorial/shared.thrift b/tutorial/shared.thrift new file mode 100644 index 000000000..475e7f803 --- /dev/null +++ b/tutorial/shared.thrift @@ -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. + */ + +/** + * This Thrift file can be included by other Thrift files that want to share + * these definitions. + */ + +namespace cpp shared +namespace java shared +namespace perl shared + +struct SharedStruct { + 1: i32 key + 2: string value +} + +service SharedService { + SharedStruct getStruct(1: i32 key) +} diff --git a/tutorial/tutorial.thrift b/tutorial/tutorial.thrift new file mode 100644 index 000000000..86e433dd3 --- /dev/null +++ b/tutorial/tutorial.thrift @@ -0,0 +1,152 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +# Thrift Tutorial +# Mark Slee (mcslee@facebook.com) +# +# This file aims to teach you how to use Thrift, in a .thrift file. Neato. The +# first thing to notice is that .thrift files support standard shell comments. +# This lets you make your thrift file executable and include your Thrift build +# step on the top line. And you can place comments like this anywhere you like. +# +# Before running this file, you will need to have installed the thrift compiler +# into /usr/local/bin. + +/** + * The first thing to know about are types. The available types in Thrift are: + * + * bool Boolean, one byte + * byte Signed byte + * i16 Signed 16-bit integer + * i32 Signed 32-bit integer + * i64 Signed 64-bit integer + * double 64-bit floating point value + * string String + * binary Blob (byte array) + * map<t1,t2> Map from one type to another + * list<t1> Ordered list of one type + * set<t1> Set of unique elements of one type + * + * Did you also notice that Thrift supports C style comments? + */ + +// Just in case you were wondering... yes. We support simple C comments too. + +/** + * Thrift files can reference other Thrift files to include common struct + * and service definitions. These are found using the current path, or by + * searching relative to any paths specified with the -I compiler flag. + * + * Included objects are accessed using the name of the .thrift file as a + * prefix. i.e. shared.SharedObject + */ +include "shared.thrift" + +/** + * Thrift files can namespace, package, or prefix their output in various + * target languages. + */ +namespace cpp tutorial +namespace java tutorial +namespace php tutorial +namespace perl tutorial +namespace smalltalk.category Thrift.Tutorial + +/** + * Thrift lets you do typedefs to get pretty names for your types. Standard + * C style here. + */ +typedef i32 MyInteger + +/** + * Thrift also lets you define constants for use across languages. Complex + * types and structs are specified using JSON notation. + */ +const i32 INT32CONSTANT = 9853 +const map<string,string> MAPCONSTANT = {'hello':'world', 'goodnight':'moon'} + +/** + * You can define enums, which are just 32 bit integers. Values are optional + * and start at 1 if not supplied, C style again. + */ +enum Operation { + ADD = 1, + SUBTRACT = 2, + MULTIPLY = 3, + DIVIDE = 4 +} + +/** + * Structs are the basic complex data structures. They are comprised of fields + * which each have an integer identifier, a type, a symbolic name, and an + * optional default value. + * + * Fields can be declared "optional", which ensures they will not be included + * in the serialized output if they aren't set. Note that this requires some + * manual management in some languages. + */ +struct Work { + 1: i32 num1 = 0, + 2: i32 num2, + 3: Operation op, + 4: optional string comment, +} + +/** + * Structs can also be exceptions, if they are nasty. + */ +exception InvalidOperation { + 1: i32 what, + 2: string why +} + +/** + * Ahh, now onto the cool part, defining a service. Services just need a name + * and can optionally inherit from another service using the extends keyword. + */ +service Calculator extends shared.SharedService { + + /** + * A method definition looks like C code. It has a return type, arguments, + * and optionally a list of exceptions that it may throw. Note that argument + * lists and exception lists are specified using the exact same syntax as + * field lists in struct or exception definitions. + */ + + void ping(), + + i32 add(1:i32 num1, 2:i32 num2), + + i32 calculate(1:i32 logid, 2:Work w) throws (1:InvalidOperation ouch), + + /** + * This method has a oneway modifier. That means the client only makes + * a request and does not listen for any response at all. Oneway methods + * must be void. + */ + oneway void zip() + +} + +/** + * That just about covers the basics. Take a look in the test/ folder for more + * detailed examples. After you run this file, your generated code shows up + * in folders with names gen-<language>. The generated code isn't too scary + * to look at. It even has pretty indentation. + */ |