blob: aa8191cf959307d1fb581ae4dbb5e1f3b92c7cb8 [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
Allen George55c3e4c2021-03-01 23:19:52 -050018use clap::{clap_app, value_t};
Allen George7ddbcc02020-11-08 09:51:19 -050019use log::*;
Allen Georgebc1344d2017-04-28 10:22:03 -040020
Allen George8b96bfb2016-11-02 08:01:08 -040021use std::collections::{BTreeMap, BTreeSet};
22use std::thread;
23use std::time::Duration;
24
Allen George55c3e4c2021-03-01 23:19:52 -050025use thrift::protocol::{
26 TBinaryInputProtocolFactory, TBinaryOutputProtocolFactory, TCompactInputProtocolFactory,
27 TCompactOutputProtocolFactory, TInputProtocolFactory, TOutputProtocolFactory,
28};
Allen Georgebc1344d2017-04-28 10:22:03 -040029use thrift::server::{TMultiplexedProcessor, TServer};
Allen George55c3e4c2021-03-01 23:19:52 -050030use thrift::transport::{
31 TBufferedReadTransportFactory, TBufferedWriteTransportFactory, TFramedReadTransportFactory,
32 TFramedWriteTransportFactory, TReadTransportFactory, TWriteTransportFactory,
33};
34use thrift::OrderedFloat;
Allen George8b96bfb2016-11-02 08:01:08 -040035use thrift_test::*;
36
37fn main() {
Allen George7ddbcc02020-11-08 09:51:19 -050038 env_logger::init();
Allen Georgebc1344d2017-04-28 10:22:03 -040039
40 debug!("initialized logger - running cross-test server");
41
Allen George8b96bfb2016-11-02 08:01:08 -040042 match run() {
Allen Georgebc1344d2017-04-28 10:22:03 -040043 Ok(()) => info!("cross-test server succeeded"),
Allen George8b96bfb2016-11-02 08:01:08 -040044 Err(e) => {
Allen Georgebc1344d2017-04-28 10:22:03 -040045 info!("cross-test server failed with error {:?}", e);
Allen George8b96bfb2016-11-02 08:01:08 -040046 std::process::exit(1);
47 }
48 }
49}
50
51fn run() -> thrift::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -040052 // unsupported options:
Jens Geyer4a33b182020-03-22 13:46:34 +010053 // --pipe
Allen George8b96bfb2016-11-02 08:01:08 -040054 // --ssl
Allen George8b96bfb2016-11-02 08:01:08 -040055 let matches = clap_app!(rust_test_client =>
56 (version: "1.0")
57 (author: "Apache Thrift Developers <dev@thrift.apache.org>")
58 (about: "Rust Thrift test server")
59 (@arg port: --port +takes_value "port on which the test server listens")
tokcumf0336412022-03-30 11:39:08 +020060 (@arg domain_socket: --("domain-socket") +takes_value "Unix Domain Socket on which the test server listens")
Allen George8b96bfb2016-11-02 08:01:08 -040061 (@arg transport: --transport +takes_value "transport implementation to use (\"buffered\", \"framed\")")
62 (@arg protocol: --protocol +takes_value "protocol implementation to use (\"binary\", \"compact\")")
tokcumf0336412022-03-30 11:39:08 +020063 (@arg server_type: --("server-type") +takes_value "type of server instantiated (\"simple\", \"thread-pool\")")
Allen George0e22c362017-01-30 07:15:00 -050064 (@arg workers: -n --workers +takes_value "number of thread-pool workers (\"4\")")
65 )
tokcumf0336412022-03-30 11:39:08 +020066 .get_matches();
Allen George8b96bfb2016-11-02 08:01:08 -040067
68 let port = value_t!(matches, "port", u16).unwrap_or(9090);
tokcumf0336412022-03-30 11:39:08 +020069 let domain_socket = matches.value_of("domain_socket");
Allen George8b96bfb2016-11-02 08:01:08 -040070 let transport = matches.value_of("transport").unwrap_or("buffered");
71 let protocol = matches.value_of("protocol").unwrap_or("binary");
Allen George0e22c362017-01-30 07:15:00 -050072 let server_type = matches.value_of("server_type").unwrap_or("thread-pool");
73 let workers = value_t!(matches, "workers", usize).unwrap_or(4);
Allen George8b96bfb2016-11-02 08:01:08 -040074 let listen_address = format!("127.0.0.1:{}", port);
75
tokcumf0336412022-03-30 11:39:08 +020076 match domain_socket {
77 None => info!("Server is binding to {}", listen_address),
78 Some(domain_socket) => info!("Server is binding to {} (UDS)", domain_socket),
79 }
Allen George8b96bfb2016-11-02 08:01:08 -040080
Allen George55c3e4c2021-03-01 23:19:52 -050081 let (i_transport_factory, o_transport_factory): (
82 Box<dyn TReadTransportFactory>,
83 Box<dyn TWriteTransportFactory>,
Jiayu Liufbfa52c2023-11-07 13:47:24 +080084 ) = match transport {
Allen George55c3e4c2021-03-01 23:19:52 -050085 "buffered" => (
86 Box::new(TBufferedReadTransportFactory::new()),
87 Box::new(TBufferedWriteTransportFactory::new()),
88 ),
89 "framed" => (
90 Box::new(TFramedReadTransportFactory::new()),
91 Box::new(TFramedWriteTransportFactory::new()),
92 ),
93 unknown => {
94 return Err(format!("unsupported transport type {}", unknown).into());
95 }
96 };
Allen George8b96bfb2016-11-02 08:01:08 -040097
Allen George55c3e4c2021-03-01 23:19:52 -050098 let (i_protocol_factory, o_protocol_factory): (
99 Box<dyn TInputProtocolFactory>,
100 Box<dyn TOutputProtocolFactory>,
Jiayu Liufbfa52c2023-11-07 13:47:24 +0800101 ) = match protocol {
Allen George55c3e4c2021-03-01 23:19:52 -0500102 "binary" | "multi" | "multi:binary" => (
103 Box::new(TBinaryInputProtocolFactory::new()),
104 Box::new(TBinaryOutputProtocolFactory::new()),
105 ),
106 "compact" | "multic" | "multi:compact" => (
107 Box::new(TCompactInputProtocolFactory::new()),
108 Box::new(TCompactOutputProtocolFactory::new()),
109 ),
110 unknown => {
111 return Err(format!("unsupported transport type {}", unknown).into());
112 }
113 };
Allen George8b96bfb2016-11-02 08:01:08 -0400114
Allen Georgebc1344d2017-04-28 10:22:03 -0400115 let test_processor = ThriftTestSyncProcessor::new(ThriftTestSyncHandlerImpl {});
Allen George8b96bfb2016-11-02 08:01:08 -0400116
Jiayu Liufbfa52c2023-11-07 13:47:24 +0800117 match server_type {
Allen Georgebc1344d2017-04-28 10:22:03 -0400118 "simple" | "thread-pool" => {
119 if protocol == "multi" || protocol == "multic" {
Allen George55c3e4c2021-03-01 23:19:52 -0500120 let second_service_processor =
121 SecondServiceSyncProcessor::new(SecondServiceSyncHandlerImpl {});
Allen George8b96bfb2016-11-02 08:01:08 -0400122
Allen Georgebc1344d2017-04-28 10:22:03 -0400123 let mut multiplexed_processor = TMultiplexedProcessor::new();
Allen George55c3e4c2021-03-01 23:19:52 -0500124 multiplexed_processor.register("ThriftTest", Box::new(test_processor), true)?;
125 multiplexed_processor.register(
126 "SecondService",
127 Box::new(second_service_processor),
128 false,
129 )?;
Allen Georgebc1344d2017-04-28 10:22:03 -0400130
131 let mut server = TServer::new(
132 i_transport_factory,
133 i_protocol_factory,
134 o_transport_factory,
135 o_protocol_factory,
136 multiplexed_processor,
137 workers,
138 );
139
tokcumf0336412022-03-30 11:39:08 +0200140 match domain_socket {
141 None => server.listen(&listen_address),
142 Some(domain_socket) => server.listen_uds(domain_socket),
143 }
Allen Georgebc1344d2017-04-28 10:22:03 -0400144 } else {
145 let mut server = TServer::new(
146 i_transport_factory,
147 i_protocol_factory,
148 o_transport_factory,
149 o_protocol_factory,
150 test_processor,
151 workers,
152 );
153
tokcumf0336412022-03-30 11:39:08 +0200154 match domain_socket {
155 None => server.listen(&listen_address),
156 Some(domain_socket) => server.listen_uds(domain_socket),
157 }
Allen Georgebc1344d2017-04-28 10:22:03 -0400158 }
159 }
tokcumf0336412022-03-30 11:39:08 +0200160
Allen Georgebc1344d2017-04-28 10:22:03 -0400161 unknown => Err(format!("unsupported server type {}", unknown).into()),
162 }
Allen George8b96bfb2016-11-02 08:01:08 -0400163}
164
165struct ThriftTestSyncHandlerImpl;
166impl ThriftTestSyncHandler for ThriftTestSyncHandlerImpl {
Allen George0e22c362017-01-30 07:15:00 -0500167 fn handle_test_void(&self) -> thrift::Result<()> {
Allen Georgebc1344d2017-04-28 10:22:03 -0400168 info!("testVoid()");
Allen George8b96bfb2016-11-02 08:01:08 -0400169 Ok(())
170 }
171
Allen George0e22c362017-01-30 07:15:00 -0500172 fn handle_test_string(&self, thing: String) -> thrift::Result<String> {
Allen Georgebc1344d2017-04-28 10:22:03 -0400173 info!("testString({})", &thing);
Allen George8b96bfb2016-11-02 08:01:08 -0400174 Ok(thing)
175 }
176
Jiayu Liub6b6dc72022-10-08 14:28:44 +0800177 fn handle_test_uuid(&self, thing: uuid::Uuid) -> thrift::Result<uuid::Uuid> {
178 info!("testUUID({})", &thing);
179 Ok(thing)
180 }
181
Allen George0e22c362017-01-30 07:15:00 -0500182 fn handle_test_bool(&self, thing: bool) -> thrift::Result<bool> {
Allen Georgebc1344d2017-04-28 10:22:03 -0400183 info!("testBool({})", thing);
Allen George8b96bfb2016-11-02 08:01:08 -0400184 Ok(thing)
185 }
186
Allen George0e22c362017-01-30 07:15:00 -0500187 fn handle_test_byte(&self, thing: i8) -> thrift::Result<i8> {
Allen Georgebc1344d2017-04-28 10:22:03 -0400188 info!("testByte({})", thing);
Allen George8b96bfb2016-11-02 08:01:08 -0400189 Ok(thing)
190 }
191
Allen George0e22c362017-01-30 07:15:00 -0500192 fn handle_test_i32(&self, thing: i32) -> thrift::Result<i32> {
Allen Georgebc1344d2017-04-28 10:22:03 -0400193 info!("testi32({})", thing);
Allen George8b96bfb2016-11-02 08:01:08 -0400194 Ok(thing)
195 }
196
Allen George0e22c362017-01-30 07:15:00 -0500197 fn handle_test_i64(&self, thing: i64) -> thrift::Result<i64> {
Allen Georgebc1344d2017-04-28 10:22:03 -0400198 info!("testi64({})", thing);
Allen George8b96bfb2016-11-02 08:01:08 -0400199 Ok(thing)
200 }
201
Allen George0e22c362017-01-30 07:15:00 -0500202 fn handle_test_double(&self, thing: OrderedFloat<f64>) -> thrift::Result<OrderedFloat<f64>> {
Allen Georgebc1344d2017-04-28 10:22:03 -0400203 info!("testDouble({})", thing);
Allen George8b96bfb2016-11-02 08:01:08 -0400204 Ok(thing)
205 }
206
Allen George0e22c362017-01-30 07:15:00 -0500207 fn handle_test_binary(&self, thing: Vec<u8>) -> thrift::Result<Vec<u8>> {
Allen Georgebc1344d2017-04-28 10:22:03 -0400208 info!("testBinary({:?})", thing);
Allen George8b96bfb2016-11-02 08:01:08 -0400209 Ok(thing)
210 }
211
Allen George0e22c362017-01-30 07:15:00 -0500212 fn handle_test_struct(&self, thing: Xtruct) -> thrift::Result<Xtruct> {
Allen Georgebc1344d2017-04-28 10:22:03 -0400213 info!("testStruct({:?})", thing);
Allen George8b96bfb2016-11-02 08:01:08 -0400214 Ok(thing)
215 }
216
Allen George0e22c362017-01-30 07:15:00 -0500217 fn handle_test_nest(&self, thing: Xtruct2) -> thrift::Result<Xtruct2> {
Allen Georgebc1344d2017-04-28 10:22:03 -0400218 info!("testNest({:?})", thing);
Allen George8b96bfb2016-11-02 08:01:08 -0400219 Ok(thing)
220 }
221
Allen George0e22c362017-01-30 07:15:00 -0500222 fn handle_test_map(&self, thing: BTreeMap<i32, i32>) -> thrift::Result<BTreeMap<i32, i32>> {
Allen Georgebc1344d2017-04-28 10:22:03 -0400223 info!("testMap({:?})", thing);
Allen George8b96bfb2016-11-02 08:01:08 -0400224 Ok(thing)
225 }
226
Allen George0e22c362017-01-30 07:15:00 -0500227 fn handle_test_string_map(
228 &self,
229 thing: BTreeMap<String, String>,
230 ) -> thrift::Result<BTreeMap<String, String>> {
Allen Georgebc1344d2017-04-28 10:22:03 -0400231 info!("testStringMap({:?})", thing);
Allen George8b96bfb2016-11-02 08:01:08 -0400232 Ok(thing)
233 }
234
Allen George0e22c362017-01-30 07:15:00 -0500235 fn handle_test_set(&self, thing: BTreeSet<i32>) -> thrift::Result<BTreeSet<i32>> {
Allen Georgebc1344d2017-04-28 10:22:03 -0400236 info!("testSet({:?})", thing);
Allen George8b96bfb2016-11-02 08:01:08 -0400237 Ok(thing)
238 }
239
Allen George0e22c362017-01-30 07:15:00 -0500240 fn handle_test_list(&self, thing: Vec<i32>) -> thrift::Result<Vec<i32>> {
Allen Georgebc1344d2017-04-28 10:22:03 -0400241 info!("testList({:?})", thing);
Allen George8b96bfb2016-11-02 08:01:08 -0400242 Ok(thing)
243 }
244
Allen George0e22c362017-01-30 07:15:00 -0500245 fn handle_test_enum(&self, thing: Numberz) -> thrift::Result<Numberz> {
Allen Georgebc1344d2017-04-28 10:22:03 -0400246 info!("testEnum({:?})", thing);
Allen George8b96bfb2016-11-02 08:01:08 -0400247 Ok(thing)
248 }
249
Allen George0e22c362017-01-30 07:15:00 -0500250 fn handle_test_typedef(&self, thing: UserId) -> thrift::Result<UserId> {
Allen Georgebc1344d2017-04-28 10:22:03 -0400251 info!("testTypedef({})", thing);
Allen George8b96bfb2016-11-02 08:01:08 -0400252 Ok(thing)
253 }
254
255 /// @return map<i32,map<i32,i32>> - returns a dictionary with these values:
Allen George0e22c362017-01-30 07:15:00 -0500256 /// {-4 => {-4 => -4, -3 => -3, -2 => -2, -1 => -1, }, 4 => {1 => 1, 2 =>
257 /// 2, 3 => 3, 4 => 4, }, }
258 fn handle_test_map_map(&self, hello: i32) -> thrift::Result<BTreeMap<i32, BTreeMap<i32, i32>>> {
Allen Georgebc1344d2017-04-28 10:22:03 -0400259 info!("testMapMap({})", hello);
Allen George8b96bfb2016-11-02 08:01:08 -0400260
261 let mut inner_map_0: BTreeMap<i32, i32> = BTreeMap::new();
Jiayu Liuaa855932022-06-26 05:00:25 +0200262 for i in -4..0_i32 {
Allen George8b96bfb2016-11-02 08:01:08 -0400263 inner_map_0.insert(i, i);
264 }
265
266 let mut inner_map_1: BTreeMap<i32, i32> = BTreeMap::new();
267 for i in 1..5 {
268 inner_map_1.insert(i, i);
269 }
270
271 let mut ret_map: BTreeMap<i32, BTreeMap<i32, i32>> = BTreeMap::new();
272 ret_map.insert(-4, inner_map_0);
273 ret_map.insert(4, inner_map_1);
274
275 Ok(ret_map)
276 }
277
278 /// Creates a the returned map with these values and prints it out:
279 /// { 1 => { 2 => argument,
280 /// 3 => argument,
281 /// },
282 /// 2 => { 6 => <empty Insanity struct>, },
283 /// }
284 /// return map<UserId, map<Numberz,Insanity>> - a map with the above values
Allen George0e22c362017-01-30 07:15:00 -0500285 fn handle_test_insanity(
286 &self,
287 argument: Insanity,
288 ) -> thrift::Result<BTreeMap<UserId, BTreeMap<Numberz, Insanity>>> {
Allen Georgebc1344d2017-04-28 10:22:03 -0400289 info!("testInsanity({:?})", argument);
Allen George8b96bfb2016-11-02 08:01:08 -0400290 let mut map_0: BTreeMap<Numberz, Insanity> = BTreeMap::new();
Allen George2e90ef52021-03-01 14:47:04 -0500291 map_0.insert(Numberz::TWO, argument.clone());
292 map_0.insert(Numberz::THREE, argument);
Allen George8b96bfb2016-11-02 08:01:08 -0400293
294 let mut map_1: BTreeMap<Numberz, Insanity> = BTreeMap::new();
295 let insanity = Insanity {
296 user_map: None,
297 xtructs: None,
298 };
Allen George2e90ef52021-03-01 14:47:04 -0500299 map_1.insert(Numberz::SIX, insanity);
Allen George8b96bfb2016-11-02 08:01:08 -0400300
301 let mut ret: BTreeMap<UserId, BTreeMap<Numberz, Insanity>> = BTreeMap::new();
302 ret.insert(1, map_0);
303 ret.insert(2, map_1);
304
305 Ok(ret)
306 }
307
Allen George0e22c362017-01-30 07:15:00 -0500308 /// returns an Xtruct with:
309 /// string_thing = "Hello2", byte_thing = arg0, i32_thing = arg1 and
310 /// i64_thing = arg2
311 fn handle_test_multi(
312 &self,
313 arg0: i8,
314 arg1: i32,
315 arg2: i64,
316 _: BTreeMap<i16, String>,
317 _: Numberz,
318 _: UserId,
319 ) -> thrift::Result<Xtruct> {
Allen George8b96bfb2016-11-02 08:01:08 -0400320 let x_ret = Xtruct {
321 string_thing: Some("Hello2".to_owned()),
322 byte_thing: Some(arg0),
323 i32_thing: Some(arg1),
324 i64_thing: Some(arg2),
325 };
326
327 Ok(x_ret)
328 }
329
Allen George0e22c362017-01-30 07:15:00 -0500330 /// if arg == "Xception" throw Xception with errorCode = 1001 and message =
331 /// arg
Allen George8b96bfb2016-11-02 08:01:08 -0400332 /// else if arg == "TException" throw TException
333 /// else do not throw anything
Allen George0e22c362017-01-30 07:15:00 -0500334 fn handle_test_exception(&self, arg: String) -> thrift::Result<()> {
Allen Georgebc1344d2017-04-28 10:22:03 -0400335 info!("testException({})", arg);
Allen George8b96bfb2016-11-02 08:01:08 -0400336
337 match &*arg {
Allen George55c3e4c2021-03-01 23:19:52 -0500338 "Xception" => Err((Xception {
339 error_code: Some(1001),
340 message: Some(arg),
341 })
342 .into()),
Allen George8b96bfb2016-11-02 08:01:08 -0400343 "TException" => Err("this is a random error".into()),
344 _ => Ok(()),
345 }
346 }
347
Allen George0e22c362017-01-30 07:15:00 -0500348 /// if arg0 == "Xception":
349 /// throw Xception with errorCode = 1001 and message = "This is an
350 /// Xception"
351 /// else if arg0 == "Xception2":
352 /// throw Xception2 with errorCode = 2002 and struct_thing.string_thing =
353 /// "This is an Xception2"
354 // else:
355 // do not throw anything and return Xtruct with string_thing = arg1
356 fn handle_test_multi_exception(&self, arg0: String, arg1: String) -> thrift::Result<Xtruct> {
Allen George8b96bfb2016-11-02 08:01:08 -0400357 match &*arg0 {
Allen George55c3e4c2021-03-01 23:19:52 -0500358 "Xception" => Err((Xception {
359 error_code: Some(1001),
360 message: Some("This is an Xception".to_owned()),
361 })
362 .into()),
363 "Xception2" => Err((Xception2 {
364 error_code: Some(2002),
365 struct_thing: Some(Xtruct {
366 string_thing: Some("This is an Xception2".to_owned()),
367 byte_thing: None,
368 i32_thing: None,
369 i64_thing: None,
370 }),
371 })
372 .into()),
373 _ => Ok(Xtruct {
374 string_thing: Some(arg1),
375 byte_thing: None,
376 i32_thing: None,
377 i64_thing: None,
378 }),
Allen George8b96bfb2016-11-02 08:01:08 -0400379 }
380 }
381
Allen George0e22c362017-01-30 07:15:00 -0500382 fn handle_test_oneway(&self, seconds_to_sleep: i32) -> thrift::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400383 thread::sleep(Duration::from_secs(seconds_to_sleep as u64));
384 Ok(())
385 }
386}
Allen Georgebc1344d2017-04-28 10:22:03 -0400387
388struct SecondServiceSyncHandlerImpl;
389impl SecondServiceSyncHandler for SecondServiceSyncHandlerImpl {
Allen Georgebc1344d2017-04-28 10:22:03 -0400390 fn handle_secondtest_string(&self, thing: String) -> thrift::Result<String> {
James E. King, III20e16bc2017-11-18 22:37:54 -0500391 info!("(second)testString({})", &thing);
Allen Georgebc1344d2017-04-28 10:22:03 -0400392 let ret = format!("testString(\"{}\")", &thing);
393 Ok(ret)
394 }
395}