blob: 471d6c824821ed9814c8c193e2ca810cb6a0c2e0 [file] [log] [blame]
Jens Geyeraa0c8b32019-01-28 23:27:45 +01001// 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
18using System;
19using System.Collections.Generic;
Jens Geyeradde44b2019-02-05 01:00:02 +010020using System.Diagnostics;
Jens Geyeraa0c8b32019-01-28 23:27:45 +010021using System.IO;
22using System.Linq;
23using System.Security.Authentication;
24using System.Security.Cryptography.X509Certificates;
25using System.Text;
26using System.Threading;
27using System.Threading.Tasks;
28using Microsoft.Extensions.Logging;
29using Thrift;
30using Thrift.Collections;
31using Thrift.Processor;
32using Thrift.Protocol;
33using Thrift.Server;
34using Thrift.Transport;
35using Thrift.Transport.Server;
36
Jens Geyer828ffa82020-11-21 15:15:32 +010037#pragma warning disable IDE0063 // using can be simplified, we don't
Jens Geyer2b2ea622021-04-09 22:55:11 +020038#pragma warning disable IDE0057 // substr can be simplified, we don't
Jens Geyer828ffa82020-11-21 15:15:32 +010039
Jens Geyeraa0c8b32019-01-28 23:27:45 +010040namespace ThriftTest
41{
Jens Geyeradde44b2019-02-05 01:00:02 +010042 internal enum ProtocolChoice
43 {
44 Binary,
45 Compact,
46 Json
47 }
48
Jens Geyeradde44b2019-02-05 01:00:02 +010049 internal enum TransportChoice
50 {
51 Socket,
52 TlsSocket,
53 NamedPipe
54 }
55
Kyle Smith7b94dd42019-03-23 17:26:56 +010056 internal enum BufferChoice
57 {
58 None,
59 Buffered,
60 Framed
61 }
62
Jens Geyer63d114d2021-05-25 23:42:35 +020063 internal enum ServerChoice
64 {
65 Simple,
66 ThreadPool
67 }
68
69
Jens Geyeraa0c8b32019-01-28 23:27:45 +010070 internal class ServerParam
71 {
Kyle Smith7b94dd42019-03-23 17:26:56 +010072 internal BufferChoice buffering = BufferChoice.None;
Jens Geyeradde44b2019-02-05 01:00:02 +010073 internal ProtocolChoice protocol = ProtocolChoice.Binary;
74 internal TransportChoice transport = TransportChoice.Socket;
Jens Geyer63d114d2021-05-25 23:42:35 +020075 internal ServerChoice server = ServerChoice.Simple;
Jens Geyeraa0c8b32019-01-28 23:27:45 +010076 internal int port = 9090;
77 internal string pipe = null;
78
79 internal void Parse(List<string> args)
80 {
81 for (var i = 0; i < args.Count; i++)
82 {
83 if (args[i].StartsWith("--pipe="))
84 {
85 pipe = args[i].Substring(args[i].IndexOf("=") + 1);
Jens Geyeradde44b2019-02-05 01:00:02 +010086 transport = TransportChoice.NamedPipe;
Jens Geyeraa0c8b32019-01-28 23:27:45 +010087 }
88 else if (args[i].StartsWith("--port="))
89 {
90 port = int.Parse(args[i].Substring(args[i].IndexOf("=") + 1));
Jens Geyeradde44b2019-02-05 01:00:02 +010091 if(transport != TransportChoice.TlsSocket)
92 transport = TransportChoice.Socket;
Jens Geyeraa0c8b32019-01-28 23:27:45 +010093 }
94 else if (args[i] == "-b" || args[i] == "--buffered" || args[i] == "--transport=buffered")
95 {
Kyle Smith7b94dd42019-03-23 17:26:56 +010096 buffering = BufferChoice.Buffered;
Jens Geyeraa0c8b32019-01-28 23:27:45 +010097 }
98 else if (args[i] == "-f" || args[i] == "--framed" || args[i] == "--transport=framed")
99 {
Kyle Smith7b94dd42019-03-23 17:26:56 +0100100 buffering = BufferChoice.Framed;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100101 }
102 else if (args[i] == "--binary" || args[i] == "--protocol=binary")
103 {
Jens Geyeradde44b2019-02-05 01:00:02 +0100104 protocol = ProtocolChoice.Binary;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100105 }
106 else if (args[i] == "--compact" || args[i] == "--protocol=compact")
107 {
Jens Geyeradde44b2019-02-05 01:00:02 +0100108 protocol = ProtocolChoice.Compact;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100109 }
110 else if (args[i] == "--json" || args[i] == "--protocol=json")
111 {
Jens Geyeradde44b2019-02-05 01:00:02 +0100112 protocol = ProtocolChoice.Json;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100113 }
Jens Geyer63d114d2021-05-25 23:42:35 +0200114 else if (args[i] == "--server-type=simple")
115 {
116 server = ServerChoice.Simple;
117 }
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100118 else if (args[i] == "--threaded" || args[i] == "--server-type=threaded")
119 {
120 throw new NotImplementedException(args[i]);
121 }
122 else if (args[i] == "--threadpool" || args[i] == "--server-type=threadpool")
123 {
Jens Geyer63d114d2021-05-25 23:42:35 +0200124 server = ServerChoice.ThreadPool;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100125 }
126 else if (args[i] == "--prototype" || args[i] == "--processor=prototype")
127 {
128 throw new NotImplementedException(args[i]);
129 }
130 else if (args[i] == "--ssl")
131 {
Jens Geyeradde44b2019-02-05 01:00:02 +0100132 transport = TransportChoice.TlsSocket;
133 }
134 else if (args[i] == "--help")
135 {
136 PrintOptionsHelp();
137 return;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100138 }
139 else
140 {
Jens Geyeradde44b2019-02-05 01:00:02 +0100141 Console.WriteLine("Invalid argument: {0}", args[i]);
142 PrintOptionsHelp();
143 return;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100144 }
145 }
146
147 }
Jens Geyeradde44b2019-02-05 01:00:02 +0100148
149 internal static void PrintOptionsHelp()
150 {
151 Console.WriteLine("Server options:");
152 Console.WriteLine(" --pipe=<pipe name>");
153 Console.WriteLine(" --port=<port number>");
154 Console.WriteLine(" --transport=<transport name> one of buffered,framed (defaults to none)");
155 Console.WriteLine(" --protocol=<protocol name> one of compact,json (defaults to binary)");
156 Console.WriteLine(" --server-type=<type> one of threaded,threadpool (defaults to simple)");
157 Console.WriteLine(" --processor=<prototype>");
158 Console.WriteLine(" --ssl");
159 Console.WriteLine();
160 }
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100161 }
162
163 public class TestServer
164 {
Jens Geyeref0cb012021-04-02 12:18:15 +0200165 #pragma warning disable CA2211
166 public static int _clientID = -1; // use with Interlocked only!
167 #pragma warning restore CA2211
168
Jens Geyereacd1d42019-11-20 19:03:14 +0100169 private static readonly TConfiguration Configuration = null; // or new TConfiguration() if needed
170
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100171 public delegate void TestLogDelegate(string msg, params object[] values);
172
173 public class MyServerEventHandler : TServerEventHandler
174 {
175 public int callCount = 0;
176
177 public Task PreServeAsync(CancellationToken cancellationToken)
178 {
179 callCount++;
180 return Task.CompletedTask;
181 }
182
183 public Task<object> CreateContextAsync(TProtocol input, TProtocol output, CancellationToken cancellationToken)
184 {
185 callCount++;
186 return Task.FromResult<object>(null);
187 }
188
189 public Task DeleteContextAsync(object serverContext, TProtocol input, TProtocol output, CancellationToken cancellationToken)
190 {
191 callCount++;
192 return Task.CompletedTask;
193 }
194
195 public Task ProcessContextAsync(object serverContext, TTransport transport, CancellationToken cancellationToken)
196 {
197 callCount++;
198 return Task.CompletedTask;
199 }
200 }
201
202 public class TestHandlerAsync : ThriftTest.IAsync
203 {
Jens Geyer261cad32019-11-20 19:03:14 +0100204 public TServer Server { get; set; }
205 private readonly int handlerID;
Jens Geyer2b2ea622021-04-09 22:55:11 +0200206 private readonly StringBuilder sb = new();
Jens Geyer261cad32019-11-20 19:03:14 +0100207 private readonly TestLogDelegate logger;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100208
209 public TestHandlerAsync()
210 {
211 handlerID = Interlocked.Increment(ref _clientID);
Jens Geyer261cad32019-11-20 19:03:14 +0100212 logger += TestConsoleLogger;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100213 logger.Invoke("New TestHandler instance created");
214 }
215
Jens Geyer261cad32019-11-20 19:03:14 +0100216 public void TestConsoleLogger(string msg, params object[] values)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100217 {
218 sb.Clear();
219 sb.AppendFormat("handler{0:D3}:", handlerID);
220 sb.AppendFormat(msg, values);
221 sb.AppendLine();
222 Console.Write(sb.ToString());
223 }
224
Jens Geyer2b2ea622021-04-09 22:55:11 +0200225 public Task testVoid(CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100226 {
227 logger.Invoke("testVoid()");
228 return Task.CompletedTask;
229 }
230
Jens Geyer2b2ea622021-04-09 22:55:11 +0200231 public Task<string> testString(string thing, CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100232 {
233 logger.Invoke("testString({0})", thing);
234 return Task.FromResult(thing);
235 }
236
Jens Geyer2b2ea622021-04-09 22:55:11 +0200237 public Task<bool> testBool(bool thing, CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100238 {
239 logger.Invoke("testBool({0})", thing);
240 return Task.FromResult(thing);
241 }
242
Jens Geyer2b2ea622021-04-09 22:55:11 +0200243 public Task<sbyte> testByte(sbyte thing, CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100244 {
245 logger.Invoke("testByte({0})", thing);
246 return Task.FromResult(thing);
247 }
248
Jens Geyer2b2ea622021-04-09 22:55:11 +0200249 public Task<int> testI32(int thing, CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100250 {
251 logger.Invoke("testI32({0})", thing);
252 return Task.FromResult(thing);
253 }
254
Jens Geyer2b2ea622021-04-09 22:55:11 +0200255 public Task<long> testI64(long thing, CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100256 {
257 logger.Invoke("testI64({0})", thing);
258 return Task.FromResult(thing);
259 }
260
Jens Geyer2b2ea622021-04-09 22:55:11 +0200261 public Task<double> testDouble(double thing, CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100262 {
263 logger.Invoke("testDouble({0})", thing);
264 return Task.FromResult(thing);
265 }
266
Jens Geyer2b2ea622021-04-09 22:55:11 +0200267 public Task<byte[]> testBinary(byte[] thing, CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100268 {
Jens Geyerbd1a2732019-06-26 22:52:44 +0200269 logger.Invoke("testBinary({0} bytes)", thing.Length);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100270 return Task.FromResult(thing);
271 }
272
Jens Geyer2b2ea622021-04-09 22:55:11 +0200273 public Task<Xtruct> testStruct(Xtruct thing, CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100274 {
Jens Geyerffb97e12019-12-06 23:43:08 +0100275 logger.Invoke("testStruct({{\"{0}\", {1}, {2}, {3}}})", thing.String_thing, thing.Byte_thing, thing.I32_thing, thing.I64_thing);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100276 return Task.FromResult(thing);
277 }
278
Jens Geyer2b2ea622021-04-09 22:55:11 +0200279 public Task<Xtruct2> testNest(Xtruct2 nest, CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100280 {
Jens Geyerffb97e12019-12-06 23:43:08 +0100281 var thing = nest.Struct_thing;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100282 logger.Invoke("testNest({{{0}, {{\"{1}\", {2}, {3}, {4}, {5}}}}})",
Jens Geyerffb97e12019-12-06 23:43:08 +0100283 nest.Byte_thing,
284 thing.String_thing,
285 thing.Byte_thing,
286 thing.I32_thing,
287 thing.I64_thing,
288 nest.I32_thing);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100289 return Task.FromResult(nest);
290 }
291
Jens Geyer2b2ea622021-04-09 22:55:11 +0200292 public Task<Dictionary<int, int>> testMap(Dictionary<int, int> thing, CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100293 {
294 sb.Clear();
295 sb.Append("testMap({{");
296 var first = true;
297 foreach (var key in thing.Keys)
298 {
299 if (first)
300 {
301 first = false;
302 }
303 else
304 {
305 sb.Append(", ");
306 }
307 sb.AppendFormat("{0} => {1}", key, thing[key]);
308 }
309 sb.Append("}})");
310 logger.Invoke(sb.ToString());
311 return Task.FromResult(thing);
312 }
313
Jens Geyer2b2ea622021-04-09 22:55:11 +0200314 public Task<Dictionary<string, string>> testStringMap(Dictionary<string, string> thing, CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100315 {
316 sb.Clear();
317 sb.Append("testStringMap({{");
318 var first = true;
319 foreach (var key in thing.Keys)
320 {
321 if (first)
322 {
323 first = false;
324 }
325 else
326 {
327 sb.Append(", ");
328 }
329 sb.AppendFormat("{0} => {1}", key, thing[key]);
330 }
331 sb.Append("}})");
332 logger.Invoke(sb.ToString());
333 return Task.FromResult(thing);
334 }
335
Jens Geyer2b2ea622021-04-09 22:55:11 +0200336 public Task<THashSet<int>> testSet(THashSet<int> thing, CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100337 {
338 sb.Clear();
339 sb.Append("testSet({{");
340 var first = true;
341 foreach (int elem in thing)
342 {
343 if (first)
344 {
345 first = false;
346 }
347 else
348 {
349 sb.Append(", ");
350 }
351 sb.AppendFormat("{0}", elem);
352 }
353 sb.Append("}})");
354 logger.Invoke(sb.ToString());
355 return Task.FromResult(thing);
356 }
357
Jens Geyer2b2ea622021-04-09 22:55:11 +0200358 public Task<List<int>> testList(List<int> thing, CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100359 {
360 sb.Clear();
361 sb.Append("testList({{");
362 var first = true;
363 foreach (var elem in thing)
364 {
365 if (first)
366 {
367 first = false;
368 }
369 else
370 {
371 sb.Append(", ");
372 }
373 sb.AppendFormat("{0}", elem);
374 }
375 sb.Append("}})");
376 logger.Invoke(sb.ToString());
377 return Task.FromResult(thing);
378 }
379
Jens Geyer2b2ea622021-04-09 22:55:11 +0200380 public Task<Numberz> testEnum(Numberz thing, CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100381 {
382 logger.Invoke("testEnum({0})", thing);
383 return Task.FromResult(thing);
384 }
385
Jens Geyer2b2ea622021-04-09 22:55:11 +0200386 public Task<long> testTypedef(long thing, CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100387 {
388 logger.Invoke("testTypedef({0})", thing);
389 return Task.FromResult(thing);
390 }
391
Jens Geyer2b2ea622021-04-09 22:55:11 +0200392 public Task<Dictionary<int, Dictionary<int, int>>> testMapMap(int hello, CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100393 {
394 logger.Invoke("testMapMap({0})", hello);
395 var mapmap = new Dictionary<int, Dictionary<int, int>>();
396
397 var pos = new Dictionary<int, int>();
398 var neg = new Dictionary<int, int>();
399 for (var i = 1; i < 5; i++)
400 {
401 pos[i] = i;
402 neg[-i] = -i;
403 }
404
405 mapmap[4] = pos;
406 mapmap[-4] = neg;
407
408 return Task.FromResult(mapmap);
409 }
410
Jens Geyer2b2ea622021-04-09 22:55:11 +0200411 public Task<Dictionary<long, Dictionary<Numberz, Insanity>>> testInsanity(Insanity argument, CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100412 {
413 logger.Invoke("testInsanity()");
414
415 /** from ThriftTest.thrift:
416 * So you think you've got this all worked, out eh?
417 *
418 * Creates a the returned map with these values and prints it out:
419 * { 1 => { 2 => argument,
420 * 3 => argument,
421 * },
422 * 2 => { 6 => <empty Insanity struct>, },
423 * }
424 * @return map<UserId, map<Numberz,Insanity>> - a map with the above values
425 */
426
427 var first_map = new Dictionary<Numberz, Insanity>();
428 var second_map = new Dictionary<Numberz, Insanity>(); ;
429
430 first_map[Numberz.TWO] = argument;
431 first_map[Numberz.THREE] = argument;
432
433 second_map[Numberz.SIX] = new Insanity();
434
435 var insane = new Dictionary<long, Dictionary<Numberz, Insanity>>
436 {
437 [1] = first_map,
438 [2] = second_map
439 };
440
441 return Task.FromResult(insane);
442 }
443
Jens Geyer2b2ea622021-04-09 22:55:11 +0200444 public Task<Xtruct> testMulti(sbyte arg0, int arg1, long arg2, Dictionary<short, string> arg3, Numberz arg4, long arg5,
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100445 CancellationToken cancellationToken)
446 {
447 logger.Invoke("testMulti()");
448
449 var hello = new Xtruct(); ;
Jens Geyerffb97e12019-12-06 23:43:08 +0100450 hello.String_thing = "Hello2";
451 hello.Byte_thing = arg0;
452 hello.I32_thing = arg1;
453 hello.I64_thing = arg2;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100454 return Task.FromResult(hello);
455 }
456
Jens Geyer2b2ea622021-04-09 22:55:11 +0200457 public Task testException(string arg, CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100458 {
459 logger.Invoke("testException({0})", arg);
460 if (arg == "Xception")
461 {
462 var x = new Xception
463 {
464 ErrorCode = 1001,
465 Message = arg
466 };
467 throw x;
468 }
469 if (arg == "TException")
470 {
471 throw new TException();
472 }
473 return Task.CompletedTask;
474 }
475
Jens Geyer2b2ea622021-04-09 22:55:11 +0200476 public Task<Xtruct> testMultiException(string arg0, string arg1, CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100477 {
478 logger.Invoke("testMultiException({0}, {1})", arg0, arg1);
479 if (arg0 == "Xception")
480 {
481 var x = new Xception
482 {
483 ErrorCode = 1001,
484 Message = "This is an Xception"
485 };
486 throw x;
487 }
488
489 if (arg0 == "Xception2")
490 {
491 var x = new Xception2
492 {
493 ErrorCode = 2002,
Jens Geyerffb97e12019-12-06 23:43:08 +0100494 Struct_thing = new Xtruct { String_thing = "This is an Xception2" }
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100495 };
496 throw x;
497 }
498
Jens Geyerffb97e12019-12-06 23:43:08 +0100499 var result = new Xtruct { String_thing = arg1 };
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100500 return Task.FromResult(result);
501 }
502
Jens Geyer2b2ea622021-04-09 22:55:11 +0200503 public Task testOneway(int secondsToSleep, CancellationToken cancellationToken)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100504 {
505 logger.Invoke("testOneway({0}), sleeping...", secondsToSleep);
506 Task.Delay(secondsToSleep * 1000, cancellationToken).GetAwaiter().GetResult();
507 logger.Invoke("testOneway finished");
508
509 return Task.CompletedTask;
510 }
511 }
512
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100513
514 private static X509Certificate2 GetServerCert()
515 {
516 var serverCertName = "server.p12";
517 var possiblePaths = new List<string>
518 {
519 "../../../keys/",
520 "../../keys/",
521 "../keys/",
522 "keys/",
523 };
524
525 string existingPath = null;
526 foreach (var possiblePath in possiblePaths)
527 {
528 var path = Path.GetFullPath(possiblePath + serverCertName);
529 if (File.Exists(path))
530 {
531 existingPath = path;
532 break;
533 }
534 }
535
536 if (string.IsNullOrEmpty(existingPath))
537 {
538 throw new FileNotFoundException($"Cannot find file: {serverCertName}");
539 }
540
541 var cert = new X509Certificate2(existingPath, "thrift");
542
543 return cert;
544 }
545
546 public static int Execute(List<string> args)
547 {
Jens Geyer261cad32019-11-20 19:03:14 +0100548 using (var loggerFactory = new LoggerFactory()) //.AddConsole().AddDebug();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100549 {
Jens Geyer261cad32019-11-20 19:03:14 +0100550 var logger = loggerFactory.CreateLogger("Test");
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100551
552 try
553 {
Jens Geyer261cad32019-11-20 19:03:14 +0100554 var param = new ServerParam();
555
556 try
557 {
558 param.Parse(args);
559 }
560 catch (Exception ex)
561 {
562 Console.WriteLine("*** FAILED ***");
563 Console.WriteLine("Error while parsing arguments");
564 Console.WriteLine(ex.Message + " ST: " + ex.StackTrace);
565 return 1;
566 }
567
568
569 // Endpoint transport (mandatory)
570 TServerTransport trans;
571 switch (param.transport)
572 {
573 case TransportChoice.NamedPipe:
574 Debug.Assert(param.pipe != null);
Jens Geyeref0cb012021-04-02 12:18:15 +0200575 trans = new TNamedPipeServerTransport(param.pipe, Configuration, NamedPipeClientFlags.OnlyLocalClients);
Jens Geyer261cad32019-11-20 19:03:14 +0100576 break;
577
578
579 case TransportChoice.TlsSocket:
580 var cert = GetServerCert();
581 if (cert == null || !cert.HasPrivateKey)
582 {
583 cert?.Dispose();
584 throw new InvalidOperationException("Certificate doesn't contain private key");
585 }
586
Jens Geyereacd1d42019-11-20 19:03:14 +0100587 trans = new TTlsServerSocketTransport(param.port, Configuration,
588 cert,
Jens Geyer261cad32019-11-20 19:03:14 +0100589 (sender, certificate, chain, errors) => true,
590 null, SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12);
591 break;
592
593 case TransportChoice.Socket:
594 default:
Jens Geyereacd1d42019-11-20 19:03:14 +0100595 trans = new TServerSocketTransport(param.port, Configuration);
Jens Geyer261cad32019-11-20 19:03:14 +0100596 break;
597 }
598
599 // Layered transport (mandatory)
600 TTransportFactory transFactory = null;
601 switch (param.buffering)
602 {
603 case BufferChoice.Framed:
604 transFactory = new TFramedTransport.Factory();
605 break;
606 case BufferChoice.Buffered:
607 transFactory = new TBufferedTransport.Factory();
608 break;
609 default:
610 Debug.Assert(param.buffering == BufferChoice.None, "unhandled case");
611 transFactory = null; // no layered transprt
612 break;
613 }
614
Jens Geyer828ffa82020-11-21 15:15:32 +0100615 TProtocolFactory proto = param.protocol switch
Jens Geyer261cad32019-11-20 19:03:14 +0100616 {
Jens Geyer828ffa82020-11-21 15:15:32 +0100617 ProtocolChoice.Compact => new TCompactProtocol.Factory(),
618 ProtocolChoice.Json => new TJsonProtocol.Factory(),
619 ProtocolChoice.Binary => new TBinaryProtocol.Factory(),
620 _ => new TBinaryProtocol.Factory(),
621 };
Jens Geyer261cad32019-11-20 19:03:14 +0100622
623 // Processor
624 var testHandler = new TestHandlerAsync();
625 var testProcessor = new ThriftTest.AsyncProcessor(testHandler);
626 var processorFactory = new TSingletonProcessorFactory(testProcessor);
627
Jens Geyer63d114d2021-05-25 23:42:35 +0200628 var poolconfig = new TThreadPoolAsyncServer.Configuration(); // use platform defaults
629 TServer serverEngine = param.server switch
630 {
631 ServerChoice.Simple => new TSimpleAsyncServer(processorFactory, trans, transFactory, transFactory, proto, proto, logger),
632 ServerChoice.ThreadPool => new TThreadPoolAsyncServer(processorFactory, trans, transFactory, transFactory, proto, proto, poolconfig, logger),
633 _ => new TSimpleAsyncServer(processorFactory, trans, transFactory, transFactory, proto, proto, logger)
634 };
Jens Geyer261cad32019-11-20 19:03:14 +0100635
636 //Server event handler
637 var serverEvents = new MyServerEventHandler();
638 serverEngine.SetEventHandler(serverEvents);
639
640 // Run it
Jens Geyer63d114d2021-05-25 23:42:35 +0200641 var where = (!string.IsNullOrEmpty(param.pipe)) ? "pipe " + param.pipe : "port " + param.port;
642 Console.WriteLine("Running "+ serverEngine.GetType().Name +
643 " at "+ where +
644 " using "+ processorFactory.GetType().Name + " processor prototype factory " +
Jens Geyer261cad32019-11-20 19:03:14 +0100645 (param.buffering == BufferChoice.Buffered ? " with buffered transport" : "") +
646 (param.buffering == BufferChoice.Framed ? " with framed transport" : "") +
647 (param.transport == TransportChoice.TlsSocket ? " with encryption" : "") +
648 (param.protocol == ProtocolChoice.Compact ? " with compact protocol" : "") +
649 (param.protocol == ProtocolChoice.Json ? " with json protocol" : "") +
650 "...");
651 serverEngine.ServeAsync(CancellationToken.None).GetAwaiter().GetResult();
652 Console.ReadLine();
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100653 }
Jens Geyer261cad32019-11-20 19:03:14 +0100654 catch (Exception x)
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100655 {
Jens Geyer261cad32019-11-20 19:03:14 +0100656 Console.Error.Write(x);
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100657 return 1;
658 }
659
Jens Geyer261cad32019-11-20 19:03:14 +0100660 Console.WriteLine("done.");
661 return 0;
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100662 }
Jens Geyeraa0c8b32019-01-28 23:27:45 +0100663 }
664 }
665
666}