blob: 6a05e79e54cb56f30b58bb563770fb868be0502a [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:
55 // --domain-socket
Jens Geyer4a33b182020-03-22 13:46:34 +010056 // --pipe
Allen George8b96bfb2016-11-02 08:01:08 -040057 // --ssl
Allen George8b96bfb2016-11-02 08:01:08 -040058 let matches = clap_app!(rust_test_client =>
59 (version: "1.0")
60 (author: "Apache Thrift Developers <dev@thrift.apache.org>")
61 (about: "Rust Thrift test server")
62 (@arg port: --port +takes_value "port on which the test server listens")
63 (@arg transport: --transport +takes_value "transport implementation to use (\"buffered\", \"framed\")")
64 (@arg protocol: --protocol +takes_value "protocol implementation to use (\"binary\", \"compact\")")
Allen George0e22c362017-01-30 07:15:00 -050065 (@arg server_type: --server_type +takes_value "type of server instantiated (\"simple\", \"thread-pool\")")
66 (@arg workers: -n --workers +takes_value "number of thread-pool workers (\"4\")")
67 )
68 .get_matches();
Allen George8b96bfb2016-11-02 08:01:08 -040069
70 let port = value_t!(matches, "port", u16).unwrap_or(9090);
71 let transport = matches.value_of("transport").unwrap_or("buffered");
72 let protocol = matches.value_of("protocol").unwrap_or("binary");
Allen George0e22c362017-01-30 07:15:00 -050073 let server_type = matches.value_of("server_type").unwrap_or("thread-pool");
74 let workers = value_t!(matches, "workers", usize).unwrap_or(4);
Allen George8b96bfb2016-11-02 08:01:08 -040075 let listen_address = format!("127.0.0.1:{}", port);
76
Allen Georgebc1344d2017-04-28 10:22:03 -040077 info!("binding to {}", listen_address);
Allen George8b96bfb2016-11-02 08:01:08 -040078
Allen George55c3e4c2021-03-01 23:19:52 -050079 let (i_transport_factory, o_transport_factory): (
80 Box<dyn TReadTransportFactory>,
81 Box<dyn TWriteTransportFactory>,
82 ) = match &*transport {
83 "buffered" => (
84 Box::new(TBufferedReadTransportFactory::new()),
85 Box::new(TBufferedWriteTransportFactory::new()),
86 ),
87 "framed" => (
88 Box::new(TFramedReadTransportFactory::new()),
89 Box::new(TFramedWriteTransportFactory::new()),
90 ),
91 unknown => {
92 return Err(format!("unsupported transport type {}", unknown).into());
93 }
94 };
Allen George8b96bfb2016-11-02 08:01:08 -040095
Allen George55c3e4c2021-03-01 23:19:52 -050096 let (i_protocol_factory, o_protocol_factory): (
97 Box<dyn TInputProtocolFactory>,
98 Box<dyn TOutputProtocolFactory>,
99 ) = match &*protocol {
100 "binary" | "multi" | "multi:binary" => (
101 Box::new(TBinaryInputProtocolFactory::new()),
102 Box::new(TBinaryOutputProtocolFactory::new()),
103 ),
104 "compact" | "multic" | "multi:compact" => (
105 Box::new(TCompactInputProtocolFactory::new()),
106 Box::new(TCompactOutputProtocolFactory::new()),
107 ),
108 unknown => {
109 return Err(format!("unsupported transport type {}", unknown).into());
110 }
111 };
Allen George8b96bfb2016-11-02 08:01:08 -0400112
Allen Georgebc1344d2017-04-28 10:22:03 -0400113 let test_processor = ThriftTestSyncProcessor::new(ThriftTestSyncHandlerImpl {});
Allen George8b96bfb2016-11-02 08:01:08 -0400114
Allen Georgebc1344d2017-04-28 10:22:03 -0400115 match &*server_type {
116 "simple" | "thread-pool" => {
117 if protocol == "multi" || protocol == "multic" {
Allen George55c3e4c2021-03-01 23:19:52 -0500118 let second_service_processor =
119 SecondServiceSyncProcessor::new(SecondServiceSyncHandlerImpl {});
Allen George8b96bfb2016-11-02 08:01:08 -0400120
Allen Georgebc1344d2017-04-28 10:22:03 -0400121 let mut multiplexed_processor = TMultiplexedProcessor::new();
Allen George55c3e4c2021-03-01 23:19:52 -0500122 multiplexed_processor.register("ThriftTest", Box::new(test_processor), true)?;
123 multiplexed_processor.register(
124 "SecondService",
125 Box::new(second_service_processor),
126 false,
127 )?;
Allen Georgebc1344d2017-04-28 10:22:03 -0400128
129 let mut server = TServer::new(
130 i_transport_factory,
131 i_protocol_factory,
132 o_transport_factory,
133 o_protocol_factory,
134 multiplexed_processor,
135 workers,
136 );
137
138 server.listen(&listen_address)
139 } else {
140 let mut server = TServer::new(
141 i_transport_factory,
142 i_protocol_factory,
143 o_transport_factory,
144 o_protocol_factory,
145 test_processor,
146 workers,
147 );
148
149 server.listen(&listen_address)
150 }
151 }
152 unknown => Err(format!("unsupported server type {}", unknown).into()),
153 }
Allen George8b96bfb2016-11-02 08:01:08 -0400154}
155
156struct ThriftTestSyncHandlerImpl;
157impl ThriftTestSyncHandler for ThriftTestSyncHandlerImpl {
Allen George0e22c362017-01-30 07:15:00 -0500158 fn handle_test_void(&self) -> thrift::Result<()> {
Allen Georgebc1344d2017-04-28 10:22:03 -0400159 info!("testVoid()");
Allen George8b96bfb2016-11-02 08:01:08 -0400160 Ok(())
161 }
162
Allen George0e22c362017-01-30 07:15:00 -0500163 fn handle_test_string(&self, thing: String) -> thrift::Result<String> {
Allen Georgebc1344d2017-04-28 10:22:03 -0400164 info!("testString({})", &thing);
Allen George8b96bfb2016-11-02 08:01:08 -0400165 Ok(thing)
166 }
167
Allen George0e22c362017-01-30 07:15:00 -0500168 fn handle_test_bool(&self, thing: bool) -> thrift::Result<bool> {
Allen Georgebc1344d2017-04-28 10:22:03 -0400169 info!("testBool({})", thing);
Allen George8b96bfb2016-11-02 08:01:08 -0400170 Ok(thing)
171 }
172
Allen George0e22c362017-01-30 07:15:00 -0500173 fn handle_test_byte(&self, thing: i8) -> thrift::Result<i8> {
Allen Georgebc1344d2017-04-28 10:22:03 -0400174 info!("testByte({})", thing);
Allen George8b96bfb2016-11-02 08:01:08 -0400175 Ok(thing)
176 }
177
Allen George0e22c362017-01-30 07:15:00 -0500178 fn handle_test_i32(&self, thing: i32) -> thrift::Result<i32> {
Allen Georgebc1344d2017-04-28 10:22:03 -0400179 info!("testi32({})", thing);
Allen George8b96bfb2016-11-02 08:01:08 -0400180 Ok(thing)
181 }
182
Allen George0e22c362017-01-30 07:15:00 -0500183 fn handle_test_i64(&self, thing: i64) -> thrift::Result<i64> {
Allen Georgebc1344d2017-04-28 10:22:03 -0400184 info!("testi64({})", thing);
Allen George8b96bfb2016-11-02 08:01:08 -0400185 Ok(thing)
186 }
187
Allen George0e22c362017-01-30 07:15:00 -0500188 fn handle_test_double(&self, thing: OrderedFloat<f64>) -> thrift::Result<OrderedFloat<f64>> {
Allen Georgebc1344d2017-04-28 10:22:03 -0400189 info!("testDouble({})", thing);
Allen George8b96bfb2016-11-02 08:01:08 -0400190 Ok(thing)
191 }
192
Allen George0e22c362017-01-30 07:15:00 -0500193 fn handle_test_binary(&self, thing: Vec<u8>) -> thrift::Result<Vec<u8>> {
Allen Georgebc1344d2017-04-28 10:22:03 -0400194 info!("testBinary({:?})", thing);
Allen George8b96bfb2016-11-02 08:01:08 -0400195 Ok(thing)
196 }
197
Allen George0e22c362017-01-30 07:15:00 -0500198 fn handle_test_struct(&self, thing: Xtruct) -> thrift::Result<Xtruct> {
Allen Georgebc1344d2017-04-28 10:22:03 -0400199 info!("testStruct({:?})", thing);
Allen George8b96bfb2016-11-02 08:01:08 -0400200 Ok(thing)
201 }
202
Allen George0e22c362017-01-30 07:15:00 -0500203 fn handle_test_nest(&self, thing: Xtruct2) -> thrift::Result<Xtruct2> {
Allen Georgebc1344d2017-04-28 10:22:03 -0400204 info!("testNest({:?})", thing);
Allen George8b96bfb2016-11-02 08:01:08 -0400205 Ok(thing)
206 }
207
Allen George0e22c362017-01-30 07:15:00 -0500208 fn handle_test_map(&self, thing: BTreeMap<i32, i32>) -> thrift::Result<BTreeMap<i32, i32>> {
Allen Georgebc1344d2017-04-28 10:22:03 -0400209 info!("testMap({:?})", thing);
Allen George8b96bfb2016-11-02 08:01:08 -0400210 Ok(thing)
211 }
212
Allen George0e22c362017-01-30 07:15:00 -0500213 fn handle_test_string_map(
214 &self,
215 thing: BTreeMap<String, String>,
216 ) -> thrift::Result<BTreeMap<String, String>> {
Allen Georgebc1344d2017-04-28 10:22:03 -0400217 info!("testStringMap({:?})", thing);
Allen George8b96bfb2016-11-02 08:01:08 -0400218 Ok(thing)
219 }
220
Allen George0e22c362017-01-30 07:15:00 -0500221 fn handle_test_set(&self, thing: BTreeSet<i32>) -> thrift::Result<BTreeSet<i32>> {
Allen Georgebc1344d2017-04-28 10:22:03 -0400222 info!("testSet({:?})", thing);
Allen George8b96bfb2016-11-02 08:01:08 -0400223 Ok(thing)
224 }
225
Allen George0e22c362017-01-30 07:15:00 -0500226 fn handle_test_list(&self, thing: Vec<i32>) -> thrift::Result<Vec<i32>> {
Allen Georgebc1344d2017-04-28 10:22:03 -0400227 info!("testList({:?})", thing);
Allen George8b96bfb2016-11-02 08:01:08 -0400228 Ok(thing)
229 }
230
Allen George0e22c362017-01-30 07:15:00 -0500231 fn handle_test_enum(&self, thing: Numberz) -> thrift::Result<Numberz> {
Allen Georgebc1344d2017-04-28 10:22:03 -0400232 info!("testEnum({:?})", thing);
Allen George8b96bfb2016-11-02 08:01:08 -0400233 Ok(thing)
234 }
235
Allen George0e22c362017-01-30 07:15:00 -0500236 fn handle_test_typedef(&self, thing: UserId) -> thrift::Result<UserId> {
Allen Georgebc1344d2017-04-28 10:22:03 -0400237 info!("testTypedef({})", thing);
Allen George8b96bfb2016-11-02 08:01:08 -0400238 Ok(thing)
239 }
240
241 /// @return map<i32,map<i32,i32>> - returns a dictionary with these values:
Allen George0e22c362017-01-30 07:15:00 -0500242 /// {-4 => {-4 => -4, -3 => -3, -2 => -2, -1 => -1, }, 4 => {1 => 1, 2 =>
243 /// 2, 3 => 3, 4 => 4, }, }
244 fn handle_test_map_map(&self, hello: i32) -> thrift::Result<BTreeMap<i32, BTreeMap<i32, i32>>> {
Allen Georgebc1344d2017-04-28 10:22:03 -0400245 info!("testMapMap({})", hello);
Allen George8b96bfb2016-11-02 08:01:08 -0400246
247 let mut inner_map_0: BTreeMap<i32, i32> = BTreeMap::new();
248 for i in -4..(0 as i32) {
249 inner_map_0.insert(i, i);
250 }
251
252 let mut inner_map_1: BTreeMap<i32, i32> = BTreeMap::new();
253 for i in 1..5 {
254 inner_map_1.insert(i, i);
255 }
256
257 let mut ret_map: BTreeMap<i32, BTreeMap<i32, i32>> = BTreeMap::new();
258 ret_map.insert(-4, inner_map_0);
259 ret_map.insert(4, inner_map_1);
260
261 Ok(ret_map)
262 }
263
264 /// Creates a the returned map with these values and prints it out:
265 /// { 1 => { 2 => argument,
266 /// 3 => argument,
267 /// },
268 /// 2 => { 6 => <empty Insanity struct>, },
269 /// }
270 /// return map<UserId, map<Numberz,Insanity>> - a map with the above values
Allen George0e22c362017-01-30 07:15:00 -0500271 fn handle_test_insanity(
272 &self,
273 argument: Insanity,
274 ) -> thrift::Result<BTreeMap<UserId, BTreeMap<Numberz, Insanity>>> {
Allen Georgebc1344d2017-04-28 10:22:03 -0400275 info!("testInsanity({:?})", argument);
Allen George8b96bfb2016-11-02 08:01:08 -0400276 let mut map_0: BTreeMap<Numberz, Insanity> = BTreeMap::new();
Allen George2e90ef52021-03-01 14:47:04 -0500277 map_0.insert(Numberz::TWO, argument.clone());
278 map_0.insert(Numberz::THREE, argument);
Allen George8b96bfb2016-11-02 08:01:08 -0400279
280 let mut map_1: BTreeMap<Numberz, Insanity> = BTreeMap::new();
281 let insanity = Insanity {
282 user_map: None,
283 xtructs: None,
284 };
Allen George2e90ef52021-03-01 14:47:04 -0500285 map_1.insert(Numberz::SIX, insanity);
Allen George8b96bfb2016-11-02 08:01:08 -0400286
287 let mut ret: BTreeMap<UserId, BTreeMap<Numberz, Insanity>> = BTreeMap::new();
288 ret.insert(1, map_0);
289 ret.insert(2, map_1);
290
291 Ok(ret)
292 }
293
Allen George0e22c362017-01-30 07:15:00 -0500294 /// returns an Xtruct with:
295 /// string_thing = "Hello2", byte_thing = arg0, i32_thing = arg1 and
296 /// i64_thing = arg2
297 fn handle_test_multi(
298 &self,
299 arg0: i8,
300 arg1: i32,
301 arg2: i64,
302 _: BTreeMap<i16, String>,
303 _: Numberz,
304 _: UserId,
305 ) -> thrift::Result<Xtruct> {
Allen George8b96bfb2016-11-02 08:01:08 -0400306 let x_ret = Xtruct {
307 string_thing: Some("Hello2".to_owned()),
308 byte_thing: Some(arg0),
309 i32_thing: Some(arg1),
310 i64_thing: Some(arg2),
311 };
312
313 Ok(x_ret)
314 }
315
Allen George0e22c362017-01-30 07:15:00 -0500316 /// if arg == "Xception" throw Xception with errorCode = 1001 and message =
317 /// arg
Allen George8b96bfb2016-11-02 08:01:08 -0400318 /// else if arg == "TException" throw TException
319 /// else do not throw anything
Allen George0e22c362017-01-30 07:15:00 -0500320 fn handle_test_exception(&self, arg: String) -> thrift::Result<()> {
Allen Georgebc1344d2017-04-28 10:22:03 -0400321 info!("testException({})", arg);
Allen George8b96bfb2016-11-02 08:01:08 -0400322
323 match &*arg {
Allen George55c3e4c2021-03-01 23:19:52 -0500324 "Xception" => Err((Xception {
325 error_code: Some(1001),
326 message: Some(arg),
327 })
328 .into()),
Allen George8b96bfb2016-11-02 08:01:08 -0400329 "TException" => Err("this is a random error".into()),
330 _ => Ok(()),
331 }
332 }
333
Allen George0e22c362017-01-30 07:15:00 -0500334 /// if arg0 == "Xception":
335 /// throw Xception with errorCode = 1001 and message = "This is an
336 /// Xception"
337 /// else if arg0 == "Xception2":
338 /// throw Xception2 with errorCode = 2002 and struct_thing.string_thing =
339 /// "This is an Xception2"
340 // else:
341 // do not throw anything and return Xtruct with string_thing = arg1
342 fn handle_test_multi_exception(&self, arg0: String, arg1: String) -> thrift::Result<Xtruct> {
Allen George8b96bfb2016-11-02 08:01:08 -0400343 match &*arg0 {
Allen George55c3e4c2021-03-01 23:19:52 -0500344 "Xception" => Err((Xception {
345 error_code: Some(1001),
346 message: Some("This is an Xception".to_owned()),
347 })
348 .into()),
349 "Xception2" => Err((Xception2 {
350 error_code: Some(2002),
351 struct_thing: Some(Xtruct {
352 string_thing: Some("This is an Xception2".to_owned()),
353 byte_thing: None,
354 i32_thing: None,
355 i64_thing: None,
356 }),
357 })
358 .into()),
359 _ => Ok(Xtruct {
360 string_thing: Some(arg1),
361 byte_thing: None,
362 i32_thing: None,
363 i64_thing: None,
364 }),
Allen George8b96bfb2016-11-02 08:01:08 -0400365 }
366 }
367
Allen George0e22c362017-01-30 07:15:00 -0500368 fn handle_test_oneway(&self, seconds_to_sleep: i32) -> thrift::Result<()> {
Allen George8b96bfb2016-11-02 08:01:08 -0400369 thread::sleep(Duration::from_secs(seconds_to_sleep as u64));
370 Ok(())
371 }
372}
Allen Georgebc1344d2017-04-28 10:22:03 -0400373
374struct SecondServiceSyncHandlerImpl;
375impl SecondServiceSyncHandler for SecondServiceSyncHandlerImpl {
Allen Georgebc1344d2017-04-28 10:22:03 -0400376 fn handle_secondtest_string(&self, thing: String) -> thrift::Result<String> {
James E. King, III20e16bc2017-11-18 22:37:54 -0500377 info!("(second)testString({})", &thing);
Allen Georgebc1344d2017-04-28 10:22:03 -0400378 let ret = format!("testString(\"{}\")", &thing);
379 Ok(ret)
380 }
381}