thrift/test/perl/TestServer.pl

412 lines
9.7 KiB
Perl

#!/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;