| #!/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 5.10.0; |
| use strict; |
| use warnings; |
| use Data::Dumper; |
| use Getopt::Long qw(GetOptions); |
| use Time::HiRes qw(gettimeofday); |
| |
| $SIG{INT} = \&sigint_handler; |
| |
| use lib '../../lib/perl/lib'; |
| use lib 'gen-perl'; |
| |
| use Thrift; |
| use Thrift::BinaryProtocol; |
| use Thrift::BufferedTransport; |
| use Thrift::FramedTransport; |
| use Thrift::MultiplexedProcessor; |
| use Thrift::SSLServerSocket; |
| use Thrift::ServerSocket; |
| use Thrift::Server; |
| use Thrift::UnixServerSocket; |
| |
| use ThriftTest::SecondService; |
| use ThriftTest::ThriftTest; |
| use ThriftTest::Types; |
| |
| $|++; |
| |
| sub usage { |
| print <<"EOF"; |
| Usage: $0 [OPTIONS] |
| |
| Options: (default) |
| --ca Certificate authority file (optional). |
| --cert Certificate file. |
| Required if using --ssl. |
| --ciphers Acceptable cipher list. |
| --domain-socket <file> Use a unix domain socket. |
| --help Show usage. |
| --key Private key file for certificate. |
| Required if using --ssl and private key is |
| not in the certificate file. |
| --port <portnum> 9090 Port to use. |
| --protocol {binary} binary Protocol to use. |
| --ssl If present, use SSL/TLS. |
| --transport {buffered|framed} buffered Transport to use. |
| |
| EOF |
| } |
| |
| my %opts = ( |
| 'port' => 9090, |
| 'protocol' => 'binary', |
| 'transport' => 'buffered' |
| ); |
| |
| GetOptions(\%opts, qw ( |
| ca=s |
| cert=s |
| ciphers=s |
| domain-socket=s |
| help |
| host=s |
| key=s |
| port=i |
| protocol=s |
| ssl |
| transport=s |
| )) || exit 1; |
| |
| if ($opts{help}) { |
| usage(); |
| exit 0; |
| } |
| |
| if ($opts{ssl} and not defined $opts{cert}) { |
| usage(); |
| exit 1; |
| } |
| |
| my $handler = ThriftTestHandler->new(); |
| my $handler2 = SecondServiceHandler->new(); |
| my $processor = ThriftTest::ThriftTestProcessor->new($handler); |
| my $processor2 = ThriftTest::SecondServiceProcessor->new($handler2); |
| |
| my $serversocket; |
| if ($opts{'domain-socket'}) { |
| unlink($opts{'domain-socket'}); |
| $serversocket = Thrift::UnixServerSocket->new($opts{'domain-socket'}); |
| } |
| elsif ($opts{ssl}) { |
| $serversocket = Thrift::SSLServerSocket->new(\%opts); |
| } |
| else { |
| $serversocket = Thrift::ServerSocket->new(\%opts); |
| } |
| my $transport; |
| if ($opts{transport} eq 'buffered') { |
| $transport = Thrift::BufferedTransportFactory->new(); |
| } |
| elsif ($opts{transport} eq 'framed') { |
| $transport = Thrift::FramedTransportFactory->new(); |
| } |
| else { |
| usage(); |
| exit 1; |
| } |
| my $protocol; |
| if ($opts{protocol} eq 'binary' || $opts{protocol} eq 'multi') { |
| $protocol = Thrift::BinaryProtocolFactory->new(); |
| } |
| else { |
| usage(); |
| exit 1; |
| } |
| |
| if (index($opts{protocol}, 'multi') == 0) { |
| my $newProcessor = Thrift::MultiplexedProcessor->new($protocol); |
| $newProcessor->defaultProcessor($processor); |
| $newProcessor->registerProcessor('ThriftTest', $processor); |
| $newProcessor->registerProcessor('SecondService', $processor2); |
| $processor = $newProcessor; |
| } |
| |
| my $ssltag = ''; |
| if ($opts{ssl}) { |
| $ssltag = '(SSL)'; |
| } |
| my $listening_on = "$opts{port} $ssltag"; |
| if ($opts{'domain-socket'}) { |
| $listening_on = $opts{'domain-socket'}; |
| } |
| my $server = Thrift::SimpleServer->new($processor, $serversocket, $transport, $protocol); |
| print qq|Starting "simple" server ($opts{transport}/$opts{protocol}) listen on: $listening_on\n|; |
| $server->serve(); |
| print "done.\n"; |
| |
| sub sigint_handler { |
| print "received SIGINT, stopping...\n"; |
| $server->stop(); |
| } |
| |
| ### |
| ### Test server implementation |
| ### |
| |
| package ThriftTestHandler; |
| |
| use base qw( ThriftTest::ThriftTestIf ); |
| |
| sub new { |
| my $classname = shift; |
| my $self = {}; |
| return bless($self, $classname); |
| } |
| |
| sub testVoid { |
| print("testVoid()\n"); |
| } |
| |
| sub testString { |
| my $self = shift; |
| my $thing = shift; |
| print("testString($thing)\n"); |
| return $thing; |
| } |
| |
| sub testBool { |
| my $self = shift; |
| my $thing = shift; |
| my $str = $thing ? 'true' : 'false'; |
| print("testBool($str)\n"); |
| return $thing; |
| } |
| |
| sub testByte { |
| my $self = shift; |
| my $thing = shift; |
| print("testByte($thing)\n"); |
| return $thing; |
| } |
| |
| sub testI32 { |
| my $self = shift; |
| my $thing = shift; |
| print("testI32($thing)\n"); |
| return $thing; |
| } |
| |
| sub testI64 { |
| my $self = shift; |
| my $thing = shift; |
| print("testI64($thing)\n"); |
| return $thing; |
| } |
| |
| sub testDouble { |
| my $self = shift; |
| my $thing = shift; |
| print("testDouble($thing)\n"); |
| return $thing; |
| } |
| |
| sub testBinary { |
| my $self = shift; |
| my $thing = shift; |
| my @bytes = split //, $thing; |
| print 'testBinary('; |
| printf( '%02lx', ord $_ ) foreach (@bytes); |
| print ")\n"; |
| return $thing; |
| } |
| |
| sub testStruct { |
| my $self = shift; |
| my $thing = shift; |
| printf(qq|testStruct({"%s", %d, %d, %lld})\n|, |
| $thing->{string_thing}, |
| $thing->{byte_thing}, |
| $thing->{i32_thing}, |
| $thing->{i64_thing}); |
| return $thing; |
| } |
| |
| sub testNest { |
| my $self = shift; |
| my $nest = shift; |
| my $thing = $nest->{struct_thing}; |
| printf(qq|testNest({%d, {"%s", %d, %d, %lld}, %d})\n|, |
| $nest->{byte_thing}, |
| $thing->{string_thing}, |
| $thing->{byte_thing}, |
| $thing->{i32_thing}, |
| $thing->{i64_thing}, |
| $nest->{i32_thing}); |
| return $nest; |
| } |
| |
| sub testMap { |
| my $self = shift; |
| my $thing = shift; |
| printf "testMap({%s})\n", |
| join( ', ', |
| map { $_ . ' => ' . $thing->{$_} } |
| sort keys %$thing |
| ); |
| return $thing; |
| } |
| |
| sub testStringMap { |
| my $self = shift; |
| my $thing = shift; |
| printf "testStringMap({%s})\n", |
| join( ', ', |
| map { $_ . ' => ' . $thing->{$_} } |
| sort keys %$thing |
| ); |
| return $thing; |
| } |
| |
| sub testSet { |
| my $self = shift; |
| my $thing = shift; |
| my @result = sort keys %$thing; |
| printf "testSet({%s})\n", join(', ', @result ); |
| return \@result; |
| } |
| |
| sub testList { |
| my $self = shift; |
| my $thing = shift; |
| print "testList({%s})\n", join(', ', @$thing); |
| return $thing; |
| } |
| |
| sub testEnum { |
| my $self = shift; |
| my $thing = shift; |
| print "testEnum($thing)\n"; |
| return $thing; |
| } |
| |
| sub testTypedef { |
| my $self = shift; |
| my $thing = shift; |
| print("testTypedef($thing)\n"); |
| return $thing; |
| } |
| |
| sub testMapMap { |
| my $self = shift; |
| my $hello = shift; |
| |
| printf("testMapMap(%d)\n", $hello); |
| my $result = { 4 => { 1 => 1, 2 => 2, 3 => 3, 4 => 4 }, -4 => { -1 => -1, -2 => -2, -3 => -3, -4 => -4 } }; |
| return $result; |
| } |
| |
| sub testInsanity { |
| my $self = shift; |
| my $argument = shift; |
| print("testInsanity()\n"); |
| |
| my $hello = ThriftTest::Xtruct->new({string_thing => 'Hello2', byte_thing => 2, i32_thing => 2, i64_thing => 2}); |
| my @hellos; |
| push(@hellos, $hello); |
| my $goodbye = ThriftTest::Xtruct->new({string_thing => 'Goodbye4', byte_thing => 4, i32_thing => 4, i64_thing => 4}); |
| my @goodbyes; |
| push(@goodbyes, $goodbye); |
| my $crazy = ThriftTest::Insanity->new({userMap => { ThriftTest::Numberz::EIGHT => 8 }, xtructs => \@goodbyes}); |
| my $loony = ThriftTest::Insanity->new(); |
| my $result = { 1 => { ThriftTest::Numberz::TWO => $argument, ThriftTest::Numberz::THREE => $argument }, |
| 2 => { ThriftTest::Numberz::SIX => $loony } }; |
| return $result; |
| } |
| |
| sub testMulti { |
| my $self = shift; |
| my $arg0 = shift; |
| my $arg1 = shift; |
| my $arg2 = shift; |
| my $arg3 = shift; |
| my $arg4 = shift; |
| my $arg5 = shift; |
| |
| print("testMulti()\n"); |
| return ThriftTest::Xtruct->new({string_thing => 'Hello2', byte_thing => $arg0, i32_thing => $arg1, i64_thing => $arg2}); |
| } |
| |
| sub testException { |
| my $self = shift; |
| my $arg = shift; |
| print("testException($arg)\n"); |
| if ($arg eq 'Xception') { |
| die ThriftTest::Xception->new({errorCode => 1001, message => $arg}); |
| } |
| elsif ($arg eq 'TException') { |
| die 'astring'; # all unhandled exceptions become TExceptions |
| } |
| else { |
| return ThriftTest::Xtruct->new({string_thing => $arg}); |
| } |
| } |
| |
| sub testMultiException { |
| my $self = shift; |
| my $arg0 = shift; |
| my $arg1 = shift; |
| |
| printf("testMultiException(%s, %s)\n", $arg0, $arg1); |
| if ($arg0 eq 'Xception') { |
| die ThriftTest::Xception->new({errorCode => 1001, message => 'This is an Xception'}); |
| } |
| elsif ($arg0 eq 'Xception2') { |
| my $struct_thing = ThriftTest::Xtruct->new({string_thing => 'This is an Xception2'}); |
| die ThriftTest::Xception2->new({errorCode => 2002, struct_thing => $struct_thing}); |
| } |
| else { |
| return ThriftTest::Xtruct->new({string_thing => $arg1}); |
| } |
| } |
| |
| sub testOneway { |
| my $self = shift; |
| my $num = shift; |
| print("testOneway($num): received\n"); |
| } |
| |
| ### |
| ### Test server implementation |
| ### |
| |
| package SecondServiceHandler; |
| |
| use base qw( ThriftTest::SecondServiceIf ); |
| |
| sub new { |
| my $classname = shift; |
| my $self = {}; |
| return bless($self, $classname); |
| } |
| |
| sub secondtestString { |
| my $self = shift; |
| my $thing = shift; |
| print("testString($thing)\n"); |
| return qq|testString("$thing")|; |
| } |
| |
| 1; |