blob: 7e6d08f1c96f7f29c09c42fbdf48474c5f3130c3 [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 env_logger;
20use log::*;
Allen Georgebc1344d2017-04-28 10:22:03 -040021
Allen George8b96bfb2016-11-02 08:01:08 -040022use std::collections::{BTreeMap, BTreeSet};
23use std::thread;
24use std::time::Duration;
25
Allen George7ddbcc02020-11-08 09:51:19 -050026use thrift;
Allen George55c3e4c2021-03-01 23:19:52 -050027use thrift::protocol::{
28 TBinaryInputProtocolFactory, TBinaryOutputProtocolFactory, TCompactInputProtocolFactory,
29 TCompactOutputProtocolFactory, TInputProtocolFactory, TOutputProtocolFactory,
30};
Allen Georgebc1344d2017-04-28 10:22:03 -040031use thrift::server::{TMultiplexedProcessor, TServer};
Allen George55c3e4c2021-03-01 23:19:52 -050032use thrift::transport::{
33 TBufferedReadTransportFactory, TBufferedWriteTransportFactory, TFramedReadTransportFactory,
34 TFramedWriteTransportFactory, TReadTransportFactory, TWriteTransportFactory,
35};
36use thrift::OrderedFloat;
Allen George8b96bfb2016-11-02 08:01:08 -040037use thrift_test::*;
38
39fn main() {
Allen George7ddbcc02020-11-08 09:51:19 -050040 env_logger::init();
Allen Georgebc1344d2017-04-28 10:22:03 -040041
42 debug!("initialized logger - running cross-test server");
43
Allen George8b96bfb2016-11-02 08:01:08 -040044 match run() {
Allen Georgebc1344d2017-04-28 10:22:03 -040045 Ok(()) => info!("cross-test server succeeded"),
Allen George8b96bfb2016-11-02 08:01:08 -040046 Err(e) => {
Allen Georgebc1344d2017-04-28 10:22:03 -040047 info!("cross-test server failed with error {:?}", e);
Allen George8b96bfb2016-11-02 08:01:08 -040048 std::process::exit(1);
49 }
50 }
51}
52
53fn run() -> thrift::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -040054 // unsupported options:
Jens Geyer4a33b182020-03-22 13:46:34 +010055 // --pipe
Allen George8b96bfb2016-11-02 08:01:08 -040056 // --ssl
Allen George8b96bfb2016-11-02 08:01:08 -040057 let matches = clap_app!(rust_test_client =>
58 (version: "1.0")
59 (author: "Apache Thrift Developers <dev@thrift.apache.org>")
60 (about: "Rust Thrift test server")
61 (@arg port: --port +takes_value "port on which the test server listens")
tokcumf0336412022-03-30 11:39:08 +020062 (@arg domain_socket: --("domain-socket") +takes_value "Unix Domain Socket on which the test server listens")
Allen George8b96bfb2016-11-02 08:01:08 -040063 (@arg transport: --transport +takes_value "transport implementation to use (\"buffered\", \"framed\")")
64 (@arg protocol: --protocol +takes_value "protocol implementation to use (\"binary\", \"compact\")")
tokcumf0336412022-03-30 11:39:08 +020065 (@arg server_type: --("server-type") +takes_value "type of server instantiated (\"simple\", \"thread-pool\")")
Allen George0e22c362017-01-30 07:15:00 -050066 (@arg workers: -n --workers +takes_value "number of thread-pool workers (\"4\")")
67 )
tokcumf0336412022-03-30 11:39:08 +020068 .get_matches();
Allen George8b96bfb2016-11-02 08:01:08 -040069
70 let port = value_t!(matches, "port", u16).unwrap_or(9090);
tokcumf0336412022-03-30 11:39:08 +020071 let domain_socket = matches.value_of("domain_socket");
Allen George8b96bfb2016-11-02 08:01:08 -040072 let transport = matches.value_of("transport").unwrap_or("buffered");
73 let protocol = matches.value_of("protocol").unwrap_or("binary");
Allen George0e22c362017-01-30 07:15:00 -050074 let server_type = matches.value_of("server_type").unwrap_or("thread-pool");
75 let workers = value_t!(matches, "workers", usize).unwrap_or(4);
Allen George8b96bfb2016-11-02 08:01:08 -040076 let listen_address = format!("127.0.0.1:{}", port);
77
tokcumf0336412022-03-30 11:39:08 +020078 match domain_socket {
79 None => info!("Server is binding to {}", listen_address),
80 Some(domain_socket) => info!("Server is binding to {} (UDS)", domain_socket),
81 }
Allen George8b96bfb2016-11-02 08:01:08 -040082
Allen George55c3e4c2021-03-01 23:19:52 -050083 let (i_transport_factory, o_transport_factory): (
84 Box<dyn TReadTransportFactory>,
85 Box<dyn TWriteTransportFactory>,
86 ) = match &*transport {
87 "buffered" => (
88 Box::new(TBufferedReadTransportFactory::new()),
89 Box::new(TBufferedWriteTransportFactory::new()),
90 ),
91 "framed" => (
92 Box::new(TFramedReadTransportFactory::new()),
93 Box::new(TFramedWriteTransportFactory::new()),
94 ),
95 unknown => {
96 return Err(format!("unsupported transport type {}", unknown).into());
97 }
98 };
Allen George8b96bfb2016-11-02 08:01:08 -040099
Allen George55c3e4c2021-03-01 23:19:52 -0500100 let (i_protocol_factory, o_protocol_factory): (
101 Box<dyn TInputProtocolFactory>,
102 Box<dyn TOutputProtocolFactory>,
103 ) = match &*protocol {
104 "binary" | "multi" | "multi:binary" => (
105 Box::new(TBinaryInputProtocolFactory::new()),
106 Box::new(TBinaryOutputProtocolFactory::new()),
107 ),
108 "compact" | "multic" | "multi:compact" => (
109 Box::new(TCompactInputProtocolFactory::new()),
110 Box::new(TCompactOutputProtocolFactory::new()),
111 ),
112 unknown => {
113 return Err(format!("unsupported transport type {}", unknown).into());
114 }
115 };
Allen George8b96bfb2016-11-02 08:01:08 -0400116
Allen Georgebc1344d2017-04-28 10:22:03 -0400117 let test_processor = ThriftTestSyncProcessor::new(ThriftTestSyncHandlerImpl {});
Allen George8b96bfb2016-11-02 08:01:08 -0400118
Allen Georgebc1344d2017-04-28 10:22:03 -0400119 match &*server_type {
120 "simple" | "thread-pool" => {
121 if protocol == "multi" || protocol == "multic" {
Allen George55c3e4c2021-03-01 23:19:52 -0500122 let second_service_processor =
123 SecondServiceSyncProcessor::new(SecondServiceSyncHandlerImpl {});
Allen George8b96bfb2016-11-02 08:01:08 -0400124
Allen Georgebc1344d2017-04-28 10:22:03 -0400125 let mut multiplexed_processor = TMultiplexedProcessor::new();
Allen George55c3e4c2021-03-01 23:19:52 -0500126 multiplexed_processor.register("ThriftTest", Box::new(test_processor), true)?;
127 multiplexed_processor.register(
128 "SecondService",
129 Box::new(second_service_processor),
130 false,
131 )?;
Allen Georgebc1344d2017-04-28 10:22:03 -0400132
133 let mut server = TServer::new(
134 i_transport_factory,
135 i_protocol_factory,
136 o_transport_factory,
137 o_protocol_factory,
138 multiplexed_processor,
139 workers,
140 );
141
tokcumf0336412022-03-30 11:39:08 +0200142 match domain_socket {
143 None => server.listen(&listen_address),
144 Some(domain_socket) => server.listen_uds(domain_socket),
145 }
Allen Georgebc1344d2017-04-28 10:22:03 -0400146 } else {
147 let mut server = TServer::new(
148 i_transport_factory,
149 i_protocol_factory,
150 o_transport_factory,
151 o_protocol_factory,
152 test_processor,
153 workers,
154 );
155
tokcumf0336412022-03-30 11:39:08 +0200156 match domain_socket {
157 None => server.listen(&listen_address),
158 Some(domain_socket) => server.listen_uds(domain_socket),
159 }
Allen Georgebc1344d2017-04-28 10:22:03 -0400160 }
161 }
tokcumf0336412022-03-30 11:39:08 +0200162
Allen Georgebc1344d2017-04-28 10:22:03 -0400163 unknown => Err(format!("unsupported server type {}", unknown).into()),
164 }
Allen George8b96bfb2016-11-02 08:01:08 -0400165}
166
167struct ThriftTestSyncHandlerImpl;
168impl ThriftTestSyncHandler for ThriftTestSyncHandlerImpl {
Allen George0e22c362017-01-30 07:15:00 -0500169 fn handle_test_void(&self) -> thrift::Result<()> {
Allen Georgebc1344d2017-04-28 10:22:03 -0400170 info!("testVoid()");
Allen George8b96bfb2016-11-02 08:01:08 -0400171 Ok(())
172 }
173
Allen George0e22c362017-01-30 07:15:00 -0500174 fn handle_test_string(&self, thing: String) -> thrift::Result<String> {
Allen Georgebc1344d2017-04-28 10:22:03 -0400175 info!("testString({})", &thing);
Allen George8b96bfb2016-11-02 08:01:08 -0400176 Ok(thing)
177 }
178
Allen George0e22c362017-01-30 07:15:00 -0500179 fn handle_test_bool(&self, thing: bool) -> thrift::Result<bool> {
Allen Georgebc1344d2017-04-28 10:22:03 -0400180 info!("testBool({})", thing);
Allen George8b96bfb2016-11-02 08:01:08 -0400181 Ok(thing)
182 }
183
Allen George0e22c362017-01-30 07:15:00 -0500184 fn handle_test_byte(&self, thing: i8) -> thrift::Result<i8> {
Allen Georgebc1344d2017-04-28 10:22:03 -0400185 info!("testByte({})", thing);
Allen George8b96bfb2016-11-02 08:01:08 -0400186 Ok(thing)
187 }
188
Allen George0e22c362017-01-30 07:15:00 -0500189 fn handle_test_i32(&self, thing: i32) -> thrift::Result<i32> {
Allen Georgebc1344d2017-04-28 10:22:03 -0400190 info!("testi32({})", thing);
Allen George8b96bfb2016-11-02 08:01:08 -0400191 Ok(thing)
192 }
193
Allen George0e22c362017-01-30 07:15:00 -0500194 fn handle_test_i64(&self, thing: i64) -> thrift::Result<i64> {
Allen Georgebc1344d2017-04-28 10:22:03 -0400195 info!("testi64({})", thing);
Allen George8b96bfb2016-11-02 08:01:08 -0400196 Ok(thing)
197 }
198
Allen George0e22c362017-01-30 07:15:00 -0500199 fn handle_test_double(&self, thing: OrderedFloat<f64>) -> thrift::Result<OrderedFloat<f64>> {
Allen Georgebc1344d2017-04-28 10:22:03 -0400200 info!("testDouble({})", thing);
Allen George8b96bfb2016-11-02 08:01:08 -0400201 Ok(thing)
202 }
203
Allen George0e22c362017-01-30 07:15:00 -0500204 fn handle_test_binary(&self, thing: Vec<u8>) -> thrift::Result<Vec<u8>> {
Allen Georgebc1344d2017-04-28 10:22:03 -0400205 info!("testBinary({:?})", thing);
Allen George8b96bfb2016-11-02 08:01:08 -0400206 Ok(thing)
207 }
208
Allen George0e22c362017-01-30 07:15:00 -0500209 fn handle_test_struct(&self, thing: Xtruct) -> thrift::Result<Xtruct> {
Allen Georgebc1344d2017-04-28 10:22:03 -0400210 info!("testStruct({:?})", thing);
Allen George8b96bfb2016-11-02 08:01:08 -0400211 Ok(thing)
212 }
213
Allen George0e22c362017-01-30 07:15:00 -0500214 fn handle_test_nest(&self, thing: Xtruct2) -> thrift::Result<Xtruct2> {
Allen Georgebc1344d2017-04-28 10:22:03 -0400215 info!("testNest({:?})", thing);
Allen George8b96bfb2016-11-02 08:01:08 -0400216 Ok(thing)
217 }
218
Allen George0e22c362017-01-30 07:15:00 -0500219 fn handle_test_map(&self, thing: BTreeMap<i32, i32>) -> thrift::Result<BTreeMap<i32, i32>> {
Allen Georgebc1344d2017-04-28 10:22:03 -0400220 info!("testMap({:?})", thing);
Allen George8b96bfb2016-11-02 08:01:08 -0400221 Ok(thing)
222 }
223
Allen George0e22c362017-01-30 07:15:00 -0500224 fn handle_test_string_map(
225 &self,
226 thing: BTreeMap<String, String>,
227 ) -> thrift::Result<BTreeMap<String, String>> {
Allen Georgebc1344d2017-04-28 10:22:03 -0400228 info!("testStringMap({:?})", thing);
Allen George8b96bfb2016-11-02 08:01:08 -0400229 Ok(thing)
230 }
231
Allen George0e22c362017-01-30 07:15:00 -0500232 fn handle_test_set(&self, thing: BTreeSet<i32>) -> thrift::Result<BTreeSet<i32>> {
Allen Georgebc1344d2017-04-28 10:22:03 -0400233 info!("testSet({:?})", thing);
Allen George8b96bfb2016-11-02 08:01:08 -0400234 Ok(thing)
235 }
236
Allen George0e22c362017-01-30 07:15:00 -0500237 fn handle_test_list(&self, thing: Vec<i32>) -> thrift::Result<Vec<i32>> {
Allen Georgebc1344d2017-04-28 10:22:03 -0400238 info!("testList({:?})", thing);
Allen George8b96bfb2016-11-02 08:01:08 -0400239 Ok(thing)
240 }
241
Allen George0e22c362017-01-30 07:15:00 -0500242 fn handle_test_enum(&self, thing: Numberz) -> thrift::Result<Numberz> {
Allen Georgebc1344d2017-04-28 10:22:03 -0400243 info!("testEnum({:?})", thing);
Allen George8b96bfb2016-11-02 08:01:08 -0400244 Ok(thing)
245 }
246
Allen George0e22c362017-01-30 07:15:00 -0500247 fn handle_test_typedef(&self, thing: UserId) -> thrift::Result<UserId> {
Allen Georgebc1344d2017-04-28 10:22:03 -0400248 info!("testTypedef({})", thing);
Allen George8b96bfb2016-11-02 08:01:08 -0400249 Ok(thing)
250 }
251
252 /// @return map<i32,map<i32,i32>> - returns a dictionary with these values:
Allen George0e22c362017-01-30 07:15:00 -0500253 /// {-4 => {-4 => -4, -3 => -3, -2 => -2, -1 => -1, }, 4 => {1 => 1, 2 =>
254 /// 2, 3 => 3, 4 => 4, }, }
255 fn handle_test_map_map(&self, hello: i32) -> thrift::Result<BTreeMap<i32, BTreeMap<i32, i32>>> {
Allen Georgebc1344d2017-04-28 10:22:03 -0400256 info!("testMapMap({})", hello);
Allen George8b96bfb2016-11-02 08:01:08 -0400257
258 let mut inner_map_0: BTreeMap<i32, i32> = BTreeMap::new();
259 for i in -4..(0 as i32) {
260 inner_map_0.insert(i, i);
261 }
262
263 let mut inner_map_1: BTreeMap<i32, i32> = BTreeMap::new();
264 for i in 1..5 {
265 inner_map_1.insert(i, i);
266 }
267
268 let mut ret_map: BTreeMap<i32, BTreeMap<i32, i32>> = BTreeMap::new();
269 ret_map.insert(-4, inner_map_0);
270 ret_map.insert(4, inner_map_1);
271
272 Ok(ret_map)
273 }
274
275 /// Creates a the returned map with these values and prints it out:
276 /// { 1 => { 2 => argument,
277 /// 3 => argument,
278 /// },
279 /// 2 => { 6 => <empty Insanity struct>, },
280 /// }
281 /// return map<UserId, map<Numberz,Insanity>> - a map with the above values
Allen George0e22c362017-01-30 07:15:00 -0500282 fn handle_test_insanity(
283 &self,
284 argument: Insanity,
285 ) -> thrift::Result<BTreeMap<UserId, BTreeMap<Numberz, Insanity>>> {
Allen Georgebc1344d2017-04-28 10:22:03 -0400286 info!("testInsanity({:?})", argument);
Allen George8b96bfb2016-11-02 08:01:08 -0400287 let mut map_0: BTreeMap<Numberz, Insanity> = BTreeMap::new();
Allen George2e90ef52021-03-01 14:47:04 -0500288 map_0.insert(Numberz::TWO, argument.clone());
289 map_0.insert(Numberz::THREE, argument);
Allen George8b96bfb2016-11-02 08:01:08 -0400290
291 let mut map_1: BTreeMap<Numberz, Insanity> = BTreeMap::new();
292 let insanity = Insanity {
293 user_map: None,
294 xtructs: None,
295 };
Allen George2e90ef52021-03-01 14:47:04 -0500296 map_1.insert(Numberz::SIX, insanity);
Allen George8b96bfb2016-11-02 08:01:08 -0400297
298 let mut ret: BTreeMap<UserId, BTreeMap<Numberz, Insanity>> = BTreeMap::new();
299 ret.insert(1, map_0);
300 ret.insert(2, map_1);
301
302 Ok(ret)
303 }
304
Allen George0e22c362017-01-30 07:15:00 -0500305 /// returns an Xtruct with:
306 /// string_thing = "Hello2", byte_thing = arg0, i32_thing = arg1 and
307 /// i64_thing = arg2
308 fn handle_test_multi(
309 &self,
310 arg0: i8,
311 arg1: i32,
312 arg2: i64,
313 _: BTreeMap<i16, String>,
314 _: Numberz,
315 _: UserId,
316 ) -> thrift::Result<Xtruct> {
Allen George8b96bfb2016-11-02 08:01:08 -0400317 let x_ret = Xtruct {
318 string_thing: Some("Hello2".to_owned()),
319 byte_thing: Some(arg0),
320 i32_thing: Some(arg1),
321 i64_thing: Some(arg2),
322 };
323
324 Ok(x_ret)
325 }
326
Allen George0e22c362017-01-30 07:15:00 -0500327 /// if arg == "Xception" throw Xception with errorCode = 1001 and message =
328 /// arg
Allen George8b96bfb2016-11-02 08:01:08 -0400329 /// else if arg == "TException" throw TException
330 /// else do not throw anything
Allen George0e22c362017-01-30 07:15:00 -0500331 fn handle_test_exception(&self, arg: String) -> thrift::Result<()> {
Allen Georgebc1344d2017-04-28 10:22:03 -0400332 info!("testException({})", arg);
Allen George8b96bfb2016-11-02 08:01:08 -0400333
334 match &*arg {
Allen George55c3e4c2021-03-01 23:19:52 -0500335 "Xception" => Err((Xception {
336 error_code: Some(1001),
337 message: Some(arg),
338 })
339 .into()),
Allen George8b96bfb2016-11-02 08:01:08 -0400340 "TException" => Err("this is a random error".into()),
341 _ => Ok(()),
342 }
343 }
344
Allen George0e22c362017-01-30 07:15:00 -0500345 /// if arg0 == "Xception":
346 /// throw Xception with errorCode = 1001 and message = "This is an
347 /// Xception"
348 /// else if arg0 == "Xception2":
349 /// throw Xception2 with errorCode = 2002 and struct_thing.string_thing =
350 /// "This is an Xception2"
351 // else:
352 // do not throw anything and return Xtruct with string_thing = arg1
353 fn handle_test_multi_exception(&self, arg0: String, arg1: String) -> thrift::Result<Xtruct> {
Allen George8b96bfb2016-11-02 08:01:08 -0400354 match &*arg0 {
Allen George55c3e4c2021-03-01 23:19:52 -0500355 "Xception" => Err((Xception {
356 error_code: Some(1001),
357 message: Some("This is an Xception".to_owned()),
358 })
359 .into()),
360 "Xception2" => Err((Xception2 {
361 error_code: Some(2002),
362 struct_thing: Some(Xtruct {
363 string_thing: Some("This is an Xception2".to_owned()),
364 byte_thing: None,
365 i32_thing: None,
366 i64_thing: None,
367 }),
368 })
369 .into()),
370 _ => Ok(Xtruct {
371 string_thing: Some(arg1),
372 byte_thing: None,
373 i32_thing: None,
374 i64_thing: None,
375 }),
Allen George8b96bfb2016-11-02 08:01:08 -0400376 }
377 }
378
Allen George0e22c362017-01-30 07:15:00 -0500379 fn handle_test_oneway(&self, seconds_to_sleep: i32) -> thrift::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400380 thread::sleep(Duration::from_secs(seconds_to_sleep as u64));
381 Ok(())
382 }
383}
Allen Georgebc1344d2017-04-28 10:22:03 -0400384
385struct SecondServiceSyncHandlerImpl;
386impl SecondServiceSyncHandler for SecondServiceSyncHandlerImpl {
Allen Georgebc1344d2017-04-28 10:22:03 -0400387 fn handle_secondtest_string(&self, thing: String) -> thrift::Result<String> {
James E. King, III20e16bc2017-11-18 22:37:54 -0500388 info!("(second)testString({})", &thing);
Allen Georgebc1344d2017-04-28 10:22:03 -0400389 let ret = format!("testString(\"{}\")", &thing);
390 Ok(ret)
391 }
392}