blob: d87ef7527d7848c3b24d5299b895bdd2fa181548 [file] [log] [blame]
Allen George8b96bfb2016-11-02 08:01:08 -04001// Licensed to the Apache Software Foundation (ASF) under one
2// or more contributor license agreements. See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership. The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License. You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied. See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18#[macro_use]
Allen Georgebc1344d2017-04-28 10:22:03 -040019extern crate log;
20extern crate env_logger;
21
22#[macro_use]
Allen George8b96bfb2016-11-02 08:01:08 -040023extern crate clap;
24extern crate ordered_float;
25extern crate thrift;
26extern crate thrift_test;
27
28use ordered_float::OrderedFloat;
29use std::collections::{BTreeMap, BTreeSet};
30use std::thread;
31use std::time::Duration;
32
33use thrift::protocol::{TBinaryInputProtocolFactory, TBinaryOutputProtocolFactory,
34 TCompactInputProtocolFactory, TCompactOutputProtocolFactory,
35 TInputProtocolFactory, TOutputProtocolFactory};
Allen Georgebc1344d2017-04-28 10:22:03 -040036use thrift::server::{TMultiplexedProcessor, TServer};
Allen George0e22c362017-01-30 07:15:00 -050037use thrift::transport::{TBufferedReadTransportFactory, TBufferedWriteTransportFactory,
38 TFramedReadTransportFactory, TFramedWriteTransportFactory,
39 TReadTransportFactory, TWriteTransportFactory};
Allen George8b96bfb2016-11-02 08:01:08 -040040use thrift_test::*;
41
42fn main() {
Allen Georgebc1344d2017-04-28 10:22:03 -040043 env_logger::init().expect("logger setup failed");
44
45 debug!("initialized logger - running cross-test server");
46
Allen George8b96bfb2016-11-02 08:01:08 -040047 match run() {
Allen Georgebc1344d2017-04-28 10:22:03 -040048 Ok(()) => info!("cross-test server succeeded"),
Allen George8b96bfb2016-11-02 08:01:08 -040049 Err(e) => {
Allen Georgebc1344d2017-04-28 10:22:03 -040050 info!("cross-test server failed with error {:?}", e);
Allen George8b96bfb2016-11-02 08:01:08 -040051 std::process::exit(1);
52 }
53 }
54}
55
56fn run() -> thrift::Result<()> {
57
58 // unsupported options:
59 // --domain-socket
Jens Geyer4a33b182020-03-22 13:46:34 +010060 // --pipe
Allen George8b96bfb2016-11-02 08:01:08 -040061 // --ssl
Allen George8b96bfb2016-11-02 08:01:08 -040062 let matches = clap_app!(rust_test_client =>
63 (version: "1.0")
64 (author: "Apache Thrift Developers <dev@thrift.apache.org>")
65 (about: "Rust Thrift test server")
66 (@arg port: --port +takes_value "port on which the test server listens")
67 (@arg transport: --transport +takes_value "transport implementation to use (\"buffered\", \"framed\")")
68 (@arg protocol: --protocol +takes_value "protocol implementation to use (\"binary\", \"compact\")")
Allen George0e22c362017-01-30 07:15:00 -050069 (@arg server_type: --server_type +takes_value "type of server instantiated (\"simple\", \"thread-pool\")")
70 (@arg workers: -n --workers +takes_value "number of thread-pool workers (\"4\")")
71 )
72 .get_matches();
Allen George8b96bfb2016-11-02 08:01:08 -040073
74 let port = value_t!(matches, "port", u16).unwrap_or(9090);
75 let transport = matches.value_of("transport").unwrap_or("buffered");
76 let protocol = matches.value_of("protocol").unwrap_or("binary");
Allen George0e22c362017-01-30 07:15:00 -050077 let server_type = matches.value_of("server_type").unwrap_or("thread-pool");
78 let workers = value_t!(matches, "workers", usize).unwrap_or(4);
Allen George8b96bfb2016-11-02 08:01:08 -040079 let listen_address = format!("127.0.0.1:{}", port);
80
Allen Georgebc1344d2017-04-28 10:22:03 -040081 info!("binding to {}", listen_address);
Allen George8b96bfb2016-11-02 08:01:08 -040082
Allen George0e22c362017-01-30 07:15:00 -050083 let (i_transport_factory, o_transport_factory): (Box<TReadTransportFactory>,
84 Box<TWriteTransportFactory>) =
85 match &*transport {
86 "buffered" => {
87 (Box::new(TBufferedReadTransportFactory::new()),
88 Box::new(TBufferedWriteTransportFactory::new()))
89 }
90 "framed" => {
91 (Box::new(TFramedReadTransportFactory::new()),
92 Box::new(TFramedWriteTransportFactory::new()))
93 }
94 unknown => {
95 return Err(format!("unsupported transport type {}", unknown).into());
96 }
97 };
Allen George8b96bfb2016-11-02 08:01:08 -040098
99 let (i_protocol_factory, o_protocol_factory): (Box<TInputProtocolFactory>,
100 Box<TOutputProtocolFactory>) =
101 match &*protocol {
Allen Georgebc1344d2017-04-28 10:22:03 -0400102 "binary" | "multi" | "multi:binary" => {
Allen George8b96bfb2016-11-02 08:01:08 -0400103 (Box::new(TBinaryInputProtocolFactory::new()),
104 Box::new(TBinaryOutputProtocolFactory::new()))
105 }
Allen Georgebc1344d2017-04-28 10:22:03 -0400106 "compact" | "multic" | "multi:compact" => {
Allen George8b96bfb2016-11-02 08:01:08 -0400107 (Box::new(TCompactInputProtocolFactory::new()),
108 Box::new(TCompactOutputProtocolFactory::new()))
109 }
110 unknown => {
111 return Err(format!("unsupported transport type {}", unknown).into());
112 }
113 };
114
Allen Georgebc1344d2017-04-28 10:22:03 -0400115 let test_processor = ThriftTestSyncProcessor::new(ThriftTestSyncHandlerImpl {});
Allen George8b96bfb2016-11-02 08:01:08 -0400116
Allen Georgebc1344d2017-04-28 10:22:03 -0400117 match &*server_type {
118 "simple" | "thread-pool" => {
119 if protocol == "multi" || protocol == "multic" {
120 let second_service_processor = SecondServiceSyncProcessor::new(SecondServiceSyncHandlerImpl {},);
Allen George8b96bfb2016-11-02 08:01:08 -0400121
Allen Georgebc1344d2017-04-28 10:22:03 -0400122 let mut multiplexed_processor = TMultiplexedProcessor::new();
123 multiplexed_processor
124 .register("ThriftTest", Box::new(test_processor), true)?;
125 multiplexed_processor
126 .register("SecondService", Box::new(second_service_processor), false)?;
127
128 let mut server = TServer::new(
129 i_transport_factory,
130 i_protocol_factory,
131 o_transport_factory,
132 o_protocol_factory,
133 multiplexed_processor,
134 workers,
135 );
136
137 server.listen(&listen_address)
138 } else {
139 let mut server = TServer::new(
140 i_transport_factory,
141 i_protocol_factory,
142 o_transport_factory,
143 o_protocol_factory,
144 test_processor,
145 workers,
146 );
147
148 server.listen(&listen_address)
149 }
150 }
151 unknown => Err(format!("unsupported server type {}", unknown).into()),
152 }
Allen George8b96bfb2016-11-02 08:01:08 -0400153}
154
155struct ThriftTestSyncHandlerImpl;
156impl ThriftTestSyncHandler for ThriftTestSyncHandlerImpl {
Allen George0e22c362017-01-30 07:15:00 -0500157 fn handle_test_void(&self) -> thrift::Result<()> {
Allen Georgebc1344d2017-04-28 10:22:03 -0400158 info!("testVoid()");
Allen George8b96bfb2016-11-02 08:01:08 -0400159 Ok(())
160 }
161
Allen George0e22c362017-01-30 07:15:00 -0500162 fn handle_test_string(&self, thing: String) -> thrift::Result<String> {
Allen Georgebc1344d2017-04-28 10:22:03 -0400163 info!("testString({})", &thing);
Allen George8b96bfb2016-11-02 08:01:08 -0400164 Ok(thing)
165 }
166
Allen George0e22c362017-01-30 07:15:00 -0500167 fn handle_test_bool(&self, thing: bool) -> thrift::Result<bool> {
Allen Georgebc1344d2017-04-28 10:22:03 -0400168 info!("testBool({})", thing);
Allen George8b96bfb2016-11-02 08:01:08 -0400169 Ok(thing)
170 }
171
Allen George0e22c362017-01-30 07:15:00 -0500172 fn handle_test_byte(&self, thing: i8) -> thrift::Result<i8> {
Allen Georgebc1344d2017-04-28 10:22:03 -0400173 info!("testByte({})", thing);
Allen George8b96bfb2016-11-02 08:01:08 -0400174 Ok(thing)
175 }
176
Allen George0e22c362017-01-30 07:15:00 -0500177 fn handle_test_i32(&self, thing: i32) -> thrift::Result<i32> {
Allen Georgebc1344d2017-04-28 10:22:03 -0400178 info!("testi32({})", thing);
Allen George8b96bfb2016-11-02 08:01:08 -0400179 Ok(thing)
180 }
181
Allen George0e22c362017-01-30 07:15:00 -0500182 fn handle_test_i64(&self, thing: i64) -> thrift::Result<i64> {
Allen Georgebc1344d2017-04-28 10:22:03 -0400183 info!("testi64({})", thing);
Allen George8b96bfb2016-11-02 08:01:08 -0400184 Ok(thing)
185 }
186
Allen George0e22c362017-01-30 07:15:00 -0500187 fn handle_test_double(&self, thing: OrderedFloat<f64>) -> thrift::Result<OrderedFloat<f64>> {
Allen Georgebc1344d2017-04-28 10:22:03 -0400188 info!("testDouble({})", thing);
Allen George8b96bfb2016-11-02 08:01:08 -0400189 Ok(thing)
190 }
191
Allen George0e22c362017-01-30 07:15:00 -0500192 fn handle_test_binary(&self, thing: Vec<u8>) -> thrift::Result<Vec<u8>> {
Allen Georgebc1344d2017-04-28 10:22:03 -0400193 info!("testBinary({:?})", thing);
Allen George8b96bfb2016-11-02 08:01:08 -0400194 Ok(thing)
195 }
196
Allen George0e22c362017-01-30 07:15:00 -0500197 fn handle_test_struct(&self, thing: Xtruct) -> thrift::Result<Xtruct> {
Allen Georgebc1344d2017-04-28 10:22:03 -0400198 info!("testStruct({:?})", thing);
Allen George8b96bfb2016-11-02 08:01:08 -0400199 Ok(thing)
200 }
201
Allen George0e22c362017-01-30 07:15:00 -0500202 fn handle_test_nest(&self, thing: Xtruct2) -> thrift::Result<Xtruct2> {
Allen Georgebc1344d2017-04-28 10:22:03 -0400203 info!("testNest({:?})", thing);
Allen George8b96bfb2016-11-02 08:01:08 -0400204 Ok(thing)
205 }
206
Allen George0e22c362017-01-30 07:15:00 -0500207 fn handle_test_map(&self, thing: BTreeMap<i32, i32>) -> thrift::Result<BTreeMap<i32, i32>> {
Allen Georgebc1344d2017-04-28 10:22:03 -0400208 info!("testMap({:?})", thing);
Allen George8b96bfb2016-11-02 08:01:08 -0400209 Ok(thing)
210 }
211
Allen George0e22c362017-01-30 07:15:00 -0500212 fn handle_test_string_map(
213 &self,
214 thing: BTreeMap<String, String>,
215 ) -> thrift::Result<BTreeMap<String, String>> {
Allen Georgebc1344d2017-04-28 10:22:03 -0400216 info!("testStringMap({:?})", thing);
Allen George8b96bfb2016-11-02 08:01:08 -0400217 Ok(thing)
218 }
219
Allen George0e22c362017-01-30 07:15:00 -0500220 fn handle_test_set(&self, thing: BTreeSet<i32>) -> thrift::Result<BTreeSet<i32>> {
Allen Georgebc1344d2017-04-28 10:22:03 -0400221 info!("testSet({:?})", thing);
Allen George8b96bfb2016-11-02 08:01:08 -0400222 Ok(thing)
223 }
224
Allen George0e22c362017-01-30 07:15:00 -0500225 fn handle_test_list(&self, thing: Vec<i32>) -> thrift::Result<Vec<i32>> {
Allen Georgebc1344d2017-04-28 10:22:03 -0400226 info!("testList({:?})", thing);
Allen George8b96bfb2016-11-02 08:01:08 -0400227 Ok(thing)
228 }
229
Allen George0e22c362017-01-30 07:15:00 -0500230 fn handle_test_enum(&self, thing: Numberz) -> thrift::Result<Numberz> {
Allen Georgebc1344d2017-04-28 10:22:03 -0400231 info!("testEnum({:?})", thing);
Allen George8b96bfb2016-11-02 08:01:08 -0400232 Ok(thing)
233 }
234
Allen George0e22c362017-01-30 07:15:00 -0500235 fn handle_test_typedef(&self, thing: UserId) -> thrift::Result<UserId> {
Allen Georgebc1344d2017-04-28 10:22:03 -0400236 info!("testTypedef({})", thing);
Allen George8b96bfb2016-11-02 08:01:08 -0400237 Ok(thing)
238 }
239
240 /// @return map<i32,map<i32,i32>> - returns a dictionary with these values:
Allen George0e22c362017-01-30 07:15:00 -0500241 /// {-4 => {-4 => -4, -3 => -3, -2 => -2, -1 => -1, }, 4 => {1 => 1, 2 =>
242 /// 2, 3 => 3, 4 => 4, }, }
243 fn handle_test_map_map(&self, hello: i32) -> thrift::Result<BTreeMap<i32, BTreeMap<i32, i32>>> {
Allen Georgebc1344d2017-04-28 10:22:03 -0400244 info!("testMapMap({})", hello);
Allen George8b96bfb2016-11-02 08:01:08 -0400245
246 let mut inner_map_0: BTreeMap<i32, i32> = BTreeMap::new();
247 for i in -4..(0 as i32) {
248 inner_map_0.insert(i, i);
249 }
250
251 let mut inner_map_1: BTreeMap<i32, i32> = BTreeMap::new();
252 for i in 1..5 {
253 inner_map_1.insert(i, i);
254 }
255
256 let mut ret_map: BTreeMap<i32, BTreeMap<i32, i32>> = BTreeMap::new();
257 ret_map.insert(-4, inner_map_0);
258 ret_map.insert(4, inner_map_1);
259
260 Ok(ret_map)
261 }
262
263 /// Creates a the returned map with these values and prints it out:
264 /// { 1 => { 2 => argument,
265 /// 3 => argument,
266 /// },
267 /// 2 => { 6 => <empty Insanity struct>, },
268 /// }
269 /// return map<UserId, map<Numberz,Insanity>> - a map with the above values
Allen George0e22c362017-01-30 07:15:00 -0500270 fn handle_test_insanity(
271 &self,
272 argument: Insanity,
273 ) -> thrift::Result<BTreeMap<UserId, BTreeMap<Numberz, Insanity>>> {
Allen Georgebc1344d2017-04-28 10:22:03 -0400274 info!("testInsanity({:?})", argument);
Allen George8b96bfb2016-11-02 08:01:08 -0400275 let mut map_0: BTreeMap<Numberz, Insanity> = BTreeMap::new();
GREATEST Wiggler EvaR!b57d1262018-11-09 07:54:32 -0500276 map_0.insert(Numberz::Two, argument.clone());
277 map_0.insert(Numberz::Three, argument.clone());
Allen George8b96bfb2016-11-02 08:01:08 -0400278
279 let mut map_1: BTreeMap<Numberz, Insanity> = BTreeMap::new();
280 let insanity = Insanity {
281 user_map: None,
282 xtructs: None,
283 };
GREATEST Wiggler EvaR!b57d1262018-11-09 07:54:32 -0500284 map_1.insert(Numberz::Six, insanity);
Allen George8b96bfb2016-11-02 08:01:08 -0400285
286 let mut ret: BTreeMap<UserId, BTreeMap<Numberz, Insanity>> = BTreeMap::new();
287 ret.insert(1, map_0);
288 ret.insert(2, map_1);
289
290 Ok(ret)
291 }
292
Allen George0e22c362017-01-30 07:15:00 -0500293 /// returns an Xtruct with:
294 /// string_thing = "Hello2", byte_thing = arg0, i32_thing = arg1 and
295 /// i64_thing = arg2
296 fn handle_test_multi(
297 &self,
298 arg0: i8,
299 arg1: i32,
300 arg2: i64,
301 _: BTreeMap<i16, String>,
302 _: Numberz,
303 _: UserId,
304 ) -> thrift::Result<Xtruct> {
Allen George8b96bfb2016-11-02 08:01:08 -0400305 let x_ret = Xtruct {
306 string_thing: Some("Hello2".to_owned()),
307 byte_thing: Some(arg0),
308 i32_thing: Some(arg1),
309 i64_thing: Some(arg2),
310 };
311
312 Ok(x_ret)
313 }
314
Allen George0e22c362017-01-30 07:15:00 -0500315 /// if arg == "Xception" throw Xception with errorCode = 1001 and message =
316 /// arg
Allen George8b96bfb2016-11-02 08:01:08 -0400317 /// else if arg == "TException" throw TException
318 /// else do not throw anything
Allen George0e22c362017-01-30 07:15:00 -0500319 fn handle_test_exception(&self, arg: String) -> thrift::Result<()> {
Allen Georgebc1344d2017-04-28 10:22:03 -0400320 info!("testException({})", arg);
Allen George8b96bfb2016-11-02 08:01:08 -0400321
322 match &*arg {
323 "Xception" => {
Allen George0e22c362017-01-30 07:15:00 -0500324 Err(
325 (Xception {
326 error_code: Some(1001),
327 message: Some(arg),
328 })
329 .into(),
330 )
Allen George8b96bfb2016-11-02 08:01:08 -0400331 }
332 "TException" => Err("this is a random error".into()),
333 _ => Ok(()),
334 }
335 }
336
Allen George0e22c362017-01-30 07:15:00 -0500337 /// if arg0 == "Xception":
338 /// throw Xception with errorCode = 1001 and message = "This is an
339 /// Xception"
340 /// else if arg0 == "Xception2":
341 /// throw Xception2 with errorCode = 2002 and struct_thing.string_thing =
342 /// "This is an Xception2"
343 // else:
344 // do not throw anything and return Xtruct with string_thing = arg1
345 fn handle_test_multi_exception(&self, arg0: String, arg1: String) -> thrift::Result<Xtruct> {
Allen George8b96bfb2016-11-02 08:01:08 -0400346 match &*arg0 {
347 "Xception" => {
Allen George0e22c362017-01-30 07:15:00 -0500348 Err(
349 (Xception {
350 error_code: Some(1001),
351 message: Some("This is an Xception".to_owned()),
352 })
353 .into(),
354 )
Allen George8b96bfb2016-11-02 08:01:08 -0400355 }
356 "Xception2" => {
Allen George0e22c362017-01-30 07:15:00 -0500357 Err(
358 (Xception2 {
359 error_code: Some(2002),
360 struct_thing: Some(
361 Xtruct {
362 string_thing: Some("This is an Xception2".to_owned()),
363 byte_thing: None,
364 i32_thing: None,
365 i64_thing: None,
366 },
367 ),
368 })
369 .into(),
370 )
Allen George8b96bfb2016-11-02 08:01:08 -0400371 }
372 _ => {
Allen George0e22c362017-01-30 07:15:00 -0500373 Ok(
374 Xtruct {
375 string_thing: Some(arg1),
376 byte_thing: None,
377 i32_thing: None,
378 i64_thing: None,
379 },
380 )
Allen George8b96bfb2016-11-02 08:01:08 -0400381 }
382 }
383 }
384
Allen George0e22c362017-01-30 07:15:00 -0500385 fn handle_test_oneway(&self, seconds_to_sleep: i32) -> thrift::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400386 thread::sleep(Duration::from_secs(seconds_to_sleep as u64));
387 Ok(())
388 }
389}
Allen Georgebc1344d2017-04-28 10:22:03 -0400390
391struct SecondServiceSyncHandlerImpl;
392impl SecondServiceSyncHandler for SecondServiceSyncHandlerImpl {
Allen Georgebc1344d2017-04-28 10:22:03 -0400393 fn handle_secondtest_string(&self, thing: String) -> thrift::Result<String> {
James E. King, III20e16bc2017-11-18 22:37:54 -0500394 info!("(second)testString({})", &thing);
Allen Georgebc1344d2017-04-28 10:22:03 -0400395 let ret = format!("testString(\"{}\")", &thing);
396 Ok(ret)
397 }
398}