blob: 613cd55592e967e297ae7f645be0becda6c39a06 [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]
19extern crate clap;
20extern crate ordered_float;
21extern crate thrift;
22extern crate thrift_test;
23
24use ordered_float::OrderedFloat;
25use std::collections::{BTreeMap, BTreeSet};
26use std::thread;
27use std::time::Duration;
28
29use thrift::protocol::{TBinaryInputProtocolFactory, TBinaryOutputProtocolFactory,
30 TCompactInputProtocolFactory, TCompactOutputProtocolFactory,
31 TInputProtocolFactory, TOutputProtocolFactory};
32use thrift::server::TSimpleServer;
33use thrift::transport::{TBufferedTransportFactory, TFramedTransportFactory, TTransportFactory};
34use thrift_test::*;
35
36fn main() {
37 match run() {
38 Ok(()) => println!("cross-test server succeeded"),
39 Err(e) => {
40 println!("cross-test server failed with error {:?}", e);
41 std::process::exit(1);
42 }
43 }
44}
45
46fn run() -> thrift::Result<()> {
47
48 // unsupported options:
49 // --domain-socket
50 // --named-pipe
51 // --ssl
52 // --workers
53 let matches = clap_app!(rust_test_client =>
54 (version: "1.0")
55 (author: "Apache Thrift Developers <dev@thrift.apache.org>")
56 (about: "Rust Thrift test server")
57 (@arg port: --port +takes_value "port on which the test server listens")
58 (@arg transport: --transport +takes_value "transport implementation to use (\"buffered\", \"framed\")")
59 (@arg protocol: --protocol +takes_value "protocol implementation to use (\"binary\", \"compact\")")
60 (@arg server_type: --server_type +takes_value "type of server instantiated (\"simple\", \"thread-pool\", \"threaded\", \"non-blocking\")")
61 ).get_matches();
62
63 let port = value_t!(matches, "port", u16).unwrap_or(9090);
64 let transport = matches.value_of("transport").unwrap_or("buffered");
65 let protocol = matches.value_of("protocol").unwrap_or("binary");
66 let server_type = matches.value_of("server_type").unwrap_or("simple");
67 let listen_address = format!("127.0.0.1:{}", port);
68
69 println!("binding to {}", listen_address);
70
71 let (i_transport_factory, o_transport_factory): (Box<TTransportFactory>,
72 Box<TTransportFactory>) = match &*transport {
73 "buffered" => {
74 (Box::new(TBufferedTransportFactory::new()), Box::new(TBufferedTransportFactory::new()))
75 }
76 "framed" => {
77 (Box::new(TFramedTransportFactory::new()), Box::new(TFramedTransportFactory::new()))
78 }
79 unknown => {
80 return Err(format!("unsupported transport type {}", unknown).into());
81 }
82 };
83
84 let (i_protocol_factory, o_protocol_factory): (Box<TInputProtocolFactory>,
85 Box<TOutputProtocolFactory>) =
86 match &*protocol {
87 "binary" => {
88 (Box::new(TBinaryInputProtocolFactory::new()),
89 Box::new(TBinaryOutputProtocolFactory::new()))
90 }
91 "compact" => {
92 (Box::new(TCompactInputProtocolFactory::new()),
93 Box::new(TCompactOutputProtocolFactory::new()))
94 }
95 unknown => {
96 return Err(format!("unsupported transport type {}", unknown).into());
97 }
98 };
99
100 let processor = ThriftTestSyncProcessor::new(ThriftTestSyncHandlerImpl {});
101
102 let mut server = match &*server_type {
103 "simple" => {
104 TSimpleServer::new(i_transport_factory,
105 i_protocol_factory,
106 o_transport_factory,
107 o_protocol_factory,
108 processor)
109 }
110 unknown => {
111 return Err(format!("unsupported server type {}", unknown).into());
112 }
113 };
114
115 server.listen(&listen_address)
116}
117
118struct ThriftTestSyncHandlerImpl;
119impl ThriftTestSyncHandler for ThriftTestSyncHandlerImpl {
120 fn handle_test_void(&mut self) -> thrift::Result<()> {
121 println!("testVoid()");
122 Ok(())
123 }
124
125 fn handle_test_string(&mut self, thing: String) -> thrift::Result<String> {
126 println!("testString({})", &thing);
127 Ok(thing)
128 }
129
130 fn handle_test_bool(&mut self, thing: bool) -> thrift::Result<bool> {
131 println!("testBool({})", thing);
132 Ok(thing)
133 }
134
135 fn handle_test_byte(&mut self, thing: i8) -> thrift::Result<i8> {
136 println!("testByte({})", thing);
137 Ok(thing)
138 }
139
140 fn handle_test_i32(&mut self, thing: i32) -> thrift::Result<i32> {
141 println!("testi32({})", thing);
142 Ok(thing)
143 }
144
145 fn handle_test_i64(&mut self, thing: i64) -> thrift::Result<i64> {
146 println!("testi64({})", thing);
147 Ok(thing)
148 }
149
150 fn handle_test_double(&mut self,
151 thing: OrderedFloat<f64>)
152 -> thrift::Result<OrderedFloat<f64>> {
153 println!("testDouble({})", thing);
154 Ok(thing)
155 }
156
157 fn handle_test_binary(&mut self, thing: Vec<u8>) -> thrift::Result<Vec<u8>> {
158 println!("testBinary({:?})", thing);
159 Ok(thing)
160 }
161
162 fn handle_test_struct(&mut self, thing: Xtruct) -> thrift::Result<Xtruct> {
163 println!("testStruct({:?})", thing);
164 Ok(thing)
165 }
166
167 fn handle_test_nest(&mut self, thing: Xtruct2) -> thrift::Result<Xtruct2> {
168 println!("testNest({:?})", thing);
169 Ok(thing)
170 }
171
172 fn handle_test_map(&mut self, thing: BTreeMap<i32, i32>) -> thrift::Result<BTreeMap<i32, i32>> {
173 println!("testMap({:?})", thing);
174 Ok(thing)
175 }
176
177 fn handle_test_string_map(&mut self,
178 thing: BTreeMap<String, String>)
179 -> thrift::Result<BTreeMap<String, String>> {
180 println!("testStringMap({:?})", thing);
181 Ok(thing)
182 }
183
184 fn handle_test_set(&mut self, thing: BTreeSet<i32>) -> thrift::Result<BTreeSet<i32>> {
185 println!("testSet({:?})", thing);
186 Ok(thing)
187 }
188
189 fn handle_test_list(&mut self, thing: Vec<i32>) -> thrift::Result<Vec<i32>> {
190 println!("testList({:?})", thing);
191 Ok(thing)
192 }
193
194 fn handle_test_enum(&mut self, thing: Numberz) -> thrift::Result<Numberz> {
195 println!("testEnum({:?})", thing);
196 Ok(thing)
197 }
198
199 fn handle_test_typedef(&mut self, thing: UserId) -> thrift::Result<UserId> {
200 println!("testTypedef({})", thing);
201 Ok(thing)
202 }
203
204 /// @return map<i32,map<i32,i32>> - returns a dictionary with these values:
205 /// {-4 => {-4 => -4, -3 => -3, -2 => -2, -1 => -1, }, 4 => {1 => 1, 2 => 2, 3 => 3, 4 => 4, }, }
206 fn handle_test_map_map(&mut self,
207 hello: i32)
208 -> thrift::Result<BTreeMap<i32, BTreeMap<i32, i32>>> {
209 println!("testMapMap({})", hello);
210
211 let mut inner_map_0: BTreeMap<i32, i32> = BTreeMap::new();
212 for i in -4..(0 as i32) {
213 inner_map_0.insert(i, i);
214 }
215
216 let mut inner_map_1: BTreeMap<i32, i32> = BTreeMap::new();
217 for i in 1..5 {
218 inner_map_1.insert(i, i);
219 }
220
221 let mut ret_map: BTreeMap<i32, BTreeMap<i32, i32>> = BTreeMap::new();
222 ret_map.insert(-4, inner_map_0);
223 ret_map.insert(4, inner_map_1);
224
225 Ok(ret_map)
226 }
227
228 /// Creates a the returned map with these values and prints it out:
229 /// { 1 => { 2 => argument,
230 /// 3 => argument,
231 /// },
232 /// 2 => { 6 => <empty Insanity struct>, },
233 /// }
234 /// return map<UserId, map<Numberz,Insanity>> - a map with the above values
235 fn handle_test_insanity(&mut self,
236 argument: Insanity)
237 -> thrift::Result<BTreeMap<UserId, BTreeMap<Numberz, Insanity>>> {
238 println!("testInsanity({:?})", argument);
239 let mut map_0: BTreeMap<Numberz, Insanity> = BTreeMap::new();
240 map_0.insert(Numberz::TWO, argument.clone());
241 map_0.insert(Numberz::THREE, argument.clone());
242
243 let mut map_1: BTreeMap<Numberz, Insanity> = BTreeMap::new();
244 let insanity = Insanity {
245 user_map: None,
246 xtructs: None,
247 };
248 map_1.insert(Numberz::SIX, insanity);
249
250 let mut ret: BTreeMap<UserId, BTreeMap<Numberz, Insanity>> = BTreeMap::new();
251 ret.insert(1, map_0);
252 ret.insert(2, map_1);
253
254 Ok(ret)
255 }
256
257 /// returns an Xtruct with string_thing = "Hello2", byte_thing = arg0, i32_thing = arg1 and i64_thing = arg2
258 fn handle_test_multi(&mut self,
259 arg0: i8,
260 arg1: i32,
261 arg2: i64,
262 _: BTreeMap<i16, String>,
263 _: Numberz,
264 _: UserId)
265 -> thrift::Result<Xtruct> {
266 let x_ret = Xtruct {
267 string_thing: Some("Hello2".to_owned()),
268 byte_thing: Some(arg0),
269 i32_thing: Some(arg1),
270 i64_thing: Some(arg2),
271 };
272
273 Ok(x_ret)
274 }
275
276 /// if arg == "Xception" throw Xception with errorCode = 1001 and message = arg
277 /// else if arg == "TException" throw TException
278 /// else do not throw anything
279 fn handle_test_exception(&mut self, arg: String) -> thrift::Result<()> {
280 println!("testException({})", arg);
281
282 match &*arg {
283 "Xception" => {
284 Err((Xception {
285 error_code: Some(1001),
286 message: Some(arg),
287 })
288 .into())
289 }
290 "TException" => Err("this is a random error".into()),
291 _ => Ok(()),
292 }
293 }
294
295 /// if arg0 == "Xception" throw Xception with errorCode = 1001 and message = "This is an Xception"
296 /// else if arg0 == "Xception2" throw Xception2 with errorCode = 2002 and struct_thing.string_thing = "This is an Xception2"
297 // else do not throw anything and return Xtruct with string_thing = arg1
298 fn handle_test_multi_exception(&mut self,
299 arg0: String,
300 arg1: String)
301 -> thrift::Result<Xtruct> {
302 match &*arg0 {
303 "Xception" => {
304 Err((Xception {
305 error_code: Some(1001),
306 message: Some("This is an Xception".to_owned()),
307 })
308 .into())
309 }
310 "Xception2" => {
311 Err((Xception2 {
312 error_code: Some(2002),
313 struct_thing: Some(Xtruct {
314 string_thing: Some("This is an Xception2".to_owned()),
315 byte_thing: None,
316 i32_thing: None,
317 i64_thing: None,
318 }),
319 })
320 .into())
321 }
322 _ => {
323 Ok(Xtruct {
324 string_thing: Some(arg1),
325 byte_thing: None,
326 i32_thing: None,
327 i64_thing: None,
328 })
329 }
330 }
331 }
332
333 fn handle_test_oneway(&mut self, seconds_to_sleep: i32) -> thrift::Result<()> {
334 thread::sleep(Duration::from_secs(seconds_to_sleep as u64));
335 Ok(())
336 }
337}